Function to calculate distance between two coordinates shows wrong

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Function to calculate distance between two coordinates shows wrong



I'm currently using the function below and it shows a little wrong. According to Google Maps, the distance between these coordinates (from 59.3293371,13.4877472 to 59.3225525,13.4619422) are 2,2 kilometers while the function shows 1,6 kilometers. How can I make Chuck's function show the right distance?


function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2)
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;


function deg2rad(deg)
return deg * (Math.PI/180)



jsFiddle: http://jsfiddle.net/edgren/gAHJB/





possible duplicate of How do I calculate distance between two latitude-longitude points?
– Phillip
May 10 '15 at 3:53




5 Answers
5



What you're using is called the haversine formula, which calculates the distance between two points on a sphere as the crow flies. The Google Maps link you provided shows the distance as 2.2 km because it's not a straight line.



Wolphram Alpha is a great resource for doing geographic calculations, and also shows a distance of 1.652 km between these two points.



Drive distance vs. straight line distance (red line mine).



If you're looking for straight-line distance (as the crow files), your function is working correctly. If what you want is driving distance (or biking distance or public transportation distance or walking distance), you'll have to use a mapping API (Google or Bing being the most popular) to get the appropriate route, which will include the distance.



Incidentally, the Google Maps API provides a packaged method for spherical distance, in its google.maps.geometry.spherical namespace (look for computeDistanceBetween). It's probably better than rolling your own (for starters, it uses a more precise value for the Earth's radius).


google.maps.geometry.spherical


computeDistanceBetween



For the picky among us, when I say "straight-line distance", I'm referring to a "straight line on a sphere", which is actually a curved line (i.e. the great-circle distance), of course.





So that's why! Many thanks for a good answer :)
– Erik
Sep 18 '13 at 23:21





My pleasure! It was fun to answer.
– Ethan Brown
Sep 18 '13 at 23:22





It's a beautiful answer. I say beautiful because the details provided are just too good for understanding the difference even for a novice like me.
– Supreet
Nov 27 '15 at 9:18



I have written a similar equation before - tested it and also got 1.6 km.



Your google maps was showing the DRIVING distance.



Your function is calculating as the crow flies (straight line distance).


alert(calcCrow(59.3293371,13.4877472,59.3225525,13.4619422).toFixed(1));



//This function takes in latitude and longitude of two location and returns the distance between them as the crow flies (in km)
function calcCrow(lat1, lon1, lat2, lon2)

var R = 6371; // km
var dLat = toRad(lat2-lat1);
var dLon = toRad(lon2-lon1);
var lat1 = toRad(lat1);
var lat2 = toRad(lat2);

var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d;


// Converts numeric degrees to radians
function toRad(Value)

return Value * Math.PI / 180;



Derek's solution worked fine for me, and I've just simply converted it to PHP, hope it helps somebody out there !


function calcCrow($lat1, $lon1, $lat2, $lon2)
$R = 6371; // km
$dLat = toRad($lat2-$lat1);
$dLon = toRad($lon2-$lon1);
$lat1 = toRad($lat1);
$lat2 = toRad($lat2);

$a = sin($dLat/2) * sin($dLat/2) +sin($dLon/2) * sin($dLon/2) * cos($lat1) * cos($lat2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
$d = $R * $c;
return $d;


// Converts numeric degrees to radians
function toRad($Value)

return $Value * pi() / 180;



Try this. It is in VB.net and you need to convert it to Javascript. This function accepts parameters in decimal minutes.


Private Function calculateDistance(ByVal long1 As String, ByVal lat1 As String, ByVal long2 As String, ByVal lat2 As String) As Double
long1 = Double.Parse(long1)
lat1 = Double.Parse(lat1)
long2 = Double.Parse(long2)
lat2 = Double.Parse(lat2)

'conversion to radian
lat1 = (lat1 * 2.0 * Math.PI) / 60.0 / 360.0
long1 = (long1 * 2.0 * Math.PI) / 60.0 / 360.0
lat2 = (lat2 * 2.0 * Math.PI) / 60.0 / 360.0
long2 = (long2 * 2.0 * Math.PI) / 60.0 / 360.0

' use to different earth axis length
Dim a As Double = 6378137.0 ' Earth Major Axis (WGS84)
Dim b As Double = 6356752.3142 ' Minor Axis
Dim f As Double = (a - b) / a ' "Flattening"
Dim e As Double = 2.0 * f - f * f ' "Eccentricity"

Dim beta As Double = (a / Math.Sqrt(1.0 - e * Math.Sin(lat1) * Math.Sin(lat1)))
Dim cos As Double = Math.Cos(lat1)
Dim x As Double = beta * cos * Math.Cos(long1)
Dim y As Double = beta * cos * Math.Sin(long1)
Dim z As Double = beta * (1 - e) * Math.Sin(lat1)

beta = (a / Math.Sqrt(1.0 - e * Math.Sin(lat2) * Math.Sin(lat2)))
cos = Math.Cos(lat2)
x -= (beta * cos * Math.Cos(long2))
y -= (beta * cos * Math.Sin(long2))
z -= (beta * (1 - e) * Math.Sin(lat2))

Return Math.Sqrt((x * x) + (y * y) + (z * z))
End Function



Edit
The converted function in javascript


function calculateDistance(lat1, long1, lat2, long2)


//radians
lat1 = (lat1 * 2.0 * Math.PI) / 60.0 / 360.0;
long1 = (long1 * 2.0 * Math.PI) / 60.0 / 360.0;
lat2 = (lat2 * 2.0 * Math.PI) / 60.0 / 360.0;
long2 = (long2 * 2.0 * Math.PI) / 60.0 / 360.0;


// use to different earth axis length
var a = 6378137.0; // Earth Major Axis (WGS84)
var b = 6356752.3142; // Minor Axis
var f = (a-b) / a; // "Flattening"
var e = 2.0*f - f*f; // "Eccentricity"

var beta = (a / Math.sqrt( 1.0 - e * Math.sin( lat1 ) * Math.sin( lat1 )));
var cos = Math.cos( lat1 );
var x = beta * cos * Math.cos( long1 );
var y = beta * cos * Math.sin( long1 );
var z = beta * ( 1 - e ) * Math.sin( lat1 );

beta = ( a / Math.sqrt( 1.0 - e * Math.sin( lat2 ) * Math.sin( lat2 )));
cos = Math.cos( lat2 );
x -= (beta * cos * Math.cos( long2 ));
y -= (beta * cos * Math.sin( long2 ));
z -= (beta * (1 - e) * Math.sin( lat2 ));

return (Math.sqrt( (x*x) + (y*y) + (z*z) )/1000);





reason for downvote?
– Noorul
Sep 2 '15 at 16:56





这个问题问了JavaScript的答案。. You have to convert it to english :)
– Rodolfo Perottoni
Oct 12 '15 at 15:56





added a javascript version
– Noorul
Oct 16 '15 at 3:12



Calculate the Distance between Two Points in javascript


function distance(lat1, lon1, lat2, lon2, unit)
var radlat1 = Math.PI * lat1/180
var radlat2 = Math.PI * lat2/180
var radlon1 = Math.PI * lon1/180
var radlon2 = Math.PI * lon2/180
var theta = lon1-lon2
var radtheta = Math.PI * theta/180
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
dist = Math.acos(dist)
dist = dist * 180/Math.PI
dist = dist * 60 * 1.1515
if (unit=="K") dist = dist * 1.609344
if (unit=="N") dist = dist * 0.8684
return dist



For more details refer this: Reference Link






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard