{{ message }}

Instantly share code, notes, and snippets.

# mathiasbynens/JavaScript function to calculate the destination point given start point latitude and longitude (numeric degrees), bearing (numeric degrees) and distance (in m), based on the Vincenty direct formula.

Created Apr 3, 2010
 /*! * JavaScript function to calculate the destination point given start point latitude / longitude (numeric degrees), bearing (numeric degrees) and distance (in m). * * Original scripts by Chris Veness * Taken from http://movable-type.co.uk/scripts/latlong-vincenty-direct.html and optimized / cleaned up by Mathias Bynens * Based on the Vincenty direct formula by T. Vincenty, “Direct and Inverse Solutions of Geodesics on the Ellipsoid with application of nested equations”, Survey Review, vol XXII no 176, 1975 */ function toRad(n) { return n * Math.PI / 180; }; function toDeg(n) { return n * 180 / Math.PI; }; function destVincenty(lat1, lon1, brng, dist) { var a = 6378137, b = 6356752.3142, f = 1 / 298.257223563, // WGS-84 ellipsiod s = dist, alpha1 = toRad(brng), sinAlpha1 = Math.sin(alpha1), cosAlpha1 = Math.cos(alpha1), tanU1 = (1 - f) * Math.tan(toRad(lat1)), cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1 * cosU1, sigma1 = Math.atan2(tanU1, cosAlpha1), sinAlpha = cosU1 * sinAlpha1, cosSqAlpha = 1 - sinAlpha * sinAlpha, uSq = cosSqAlpha * (a * a - b * b) / (b * b), A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))), B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))), sigma = s / (b * A), sigmaP = 2 * Math.PI; while (Math.abs(sigma - sigmaP) > 1e-12) { var cos2SigmaM = Math.cos(2 * sigma1 + sigma), sinSigma = Math.sin(sigma), cosSigma = Math.cos(sigma), deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))); sigmaP = sigma; sigma = s / (b * A) + deltaSigma; }; var tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1, lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1, (1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp)), lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1), C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)), L = lambda - (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))), revAz = Math.atan2(sinAlpha, -tmp); // final bearing return new LatLon(toDeg(lat2), lon1 + toDeg(L)); };
 /*! * JavaScript function to calculate the geodetic distance between two points specified by latitude/longitude using the Vincenty inverse formula for ellipsoids. * * Original scripts by Chris Veness * Taken from http://movable-type.co.uk/scripts/latlong-vincenty.html and optimized / cleaned up by Mathias Bynens * Based on the Vincenty direct formula by T. Vincenty, “Direct and Inverse Solutions of Geodesics on the Ellipsoid with application of nested equations”, Survey Review, vol XXII no 176, 1975 * * @param {Number} lat1, lon1: first point in decimal degrees * @param {Number} lat2, lon2: second point in decimal degrees * @returns {Number} distance in metres between points */ function toRad(n) { return n * Math.PI / 180; }; function distVincenty(lat1, lon1, lat2, lon2) { var a = 6378137, b = 6356752.3142, f = 1 / 298.257223563, // WGS-84 ellipsoid params L = toRad(lon2-lon1), U1 = Math.atan((1 - f) * Math.tan(toRad(lat1))), U2 = Math.atan((1 - f) * Math.tan(toRad(lat2))), sinU1 = Math.sin(U1), cosU1 = Math.cos(U1), sinU2 = Math.sin(U2), cosU2 = Math.cos(U2), lambda = L, lambdaP, iterLimit = 100; do { var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda), sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda)); if (0 === sinSigma) { return 0; // co-incident points }; var cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda, sigma = Math.atan2(sinSigma, cosSigma), sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma, cosSqAlpha = 1 - sinAlpha * sinAlpha, cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha, C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)); if (isNaN(cos2SigmaM)) { cos2SigmaM = 0; // equatorial line: cosSqAlpha = 0 (§6) }; lambdaP = lambda; lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))); } while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0); if (!iterLimit) { return NaN; // formula failed to converge }; var uSq = cosSqAlpha * (a * a - b * b) / (b * b), A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))), B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))), deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))), s = b * A * (sigma - deltaSigma); return s.toFixed(3); // round to 1mm precision };

### sp-suresh commented Sep 27, 2018

 Where I can find `LatLon` function? I ran the code in the browser console and it was throwing that error

### omonk commented Nov 17, 2018 • edited

 Where I can find `LatLon` function? I ran the code in the browser console and it was throwing that error I found you can just change that line to ``````return { lat: toDeg(lat2), lng: lon1 + toDeg(L), }; ``````