1160

How do I calculate the distance between two points specified by latitude and longitude?

For clarification, I'd like the distance in kilometers; the points use the WGS84 system and I'd like to understand the relative accuracies of the approaches available.

6
  • For better accuracy - see stackoverflow.com/questions/1420045/…
    – Lior Kogan
    Jul 21, 2017 at 7:54
  • 4
    Note that you cannot apply a Haversine formula on an ellipsoid of revolution like WGS 84. You can only apply this method on a sphere with a radius.
    – Mike T
    Jul 23, 2018 at 2:05
  • 8
    Most of the answers here are using simple spherical trigonometry, so the results are rather crude compared to the WGS84 ellipsoid distances used in the GPS system. Some of the answers do refer to Vincenty's formula for ellipsoids, but that algorithm was designed for use on 1960s' era desk calculators and it has stability & accuracy issues; we have better hardware and software now. Please see GeographicLib for a high quality library with implementations in various languages.
    – PM 2Ring
    Aug 3, 2018 at 13:26
  • @MikeT - true though many of the answers here seem useful over small distances: If you take lat/long from WGS 84, and apply Haversine as if those were points on a sphere, don't you get answers whose errors are only due to the earth's flattening factor, so perhaps within 1% of a more accurate formula? With the caveat that these are small distances, say within a single town. Nov 25, 2018 at 15:27
  • 1
    For these plateforms: Mono/.NET 4.5/.NET Core/Windows Phone 8.x/Universal Windows Platform/Xamarin iOS/Xamarin Android see stackoverflow.com/a/54296314/2736742
    – A. Morel
    Jan 21, 2019 at 20:02

49 Answers 49

1380

This link might be helpful to you, as it details the use of the Haversine formula to calculate the distance.

Excerpt:

This script [in Javascript] calculates great-circle distances between the two points – that is, the shortest distance over the earth’s surface – using the ‘Haversine’ formula.

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)
}
26
  • 60
    Does this calculation/method account for the Earth being a spheroid (not a perfect sphere)? The original question asked for distance on between points on a WGS84 globe. Not sure how much error creeps in by using a perfect sphere, but I suspect it can be quite a lot depending on where the points are on the globe, thus the distinction is worth bearing in mind.
    – redcalx
    Nov 8, 2011 at 8:33
  • 20
    The Haversine formula doesn't account for the Earth being a spheroid, so you'll get some error introduced due to that fact. It can't be guaranteed correct to better than 0.5%. That may or may not be an acceptable level of error though.
    – Brandon
    Dec 28, 2011 at 16:20
  • 31
    Is there any reason to use Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) instead of Math.asin(Math.sqrt(h)), which would be the direct implementation of the formula that the Wikipedia article uses? Is it more efficient and/or more numerically stable?
    – musiphil
    Dec 20, 2012 at 3:47
  • 20
    @UsmanMutawakil Well, the 38 miles you get is distance on the road. This algorithm calculates a straight line distance on the earth's surface. Google Maps has a distance tool (bottom left, "Labs") that does the same, use that to compare.
    – Pascal
    Jul 3, 2013 at 17:35
  • 5
    @Forte_201092: Because that is not necessary - as (sin(x))² equals (sin(-x))² May 30, 2014 at 9:16
504

I needed to calculate a lot of distances between the points for my project, so I went ahead and tried to optimize the code, I have found here. On average in different browsers my new implementation runs 2 times faster than the most upvoted answer.

function distance(lat1, lon1, lat2, lon2) {
  const r = 6371; // km
  const p = Math.PI / 180;

  const a = 0.5 - Math.cos((lat2 - lat1) * p) / 2
                + Math.cos(lat1 * p) * Math.cos(lat2 * p) *
                  (1 - Math.cos((lon2 - lon1) * p)) / 2;

  return 2 * r * Math.asin(Math.sqrt(a));
}

You can play with my jsPerf and see the results here.

Recently I needed to do the same in python, so here is a python implementation:

from math import cos, asin, sqrt, pi

def distance(lat1, lon1, lat2, lon2):
    r = 6371 # km
    p = pi / 180

    a = 0.5 - cos((lat2-lat1)*p)/2 + cos(lat1*p) * cos(lat2*p) * (1-cos((lon2-lon1)*p))/2
    return 2 * r * asin(sqrt(a))

And for the sake of completeness: Haversine on Wikipedia.

15
  • 2
    The js one above seems to be 40 miles wrong when I convert it from km to miles
    – AngularM
    Apr 16, 2016 at 13:44
  • 23
    @AngularM and there is highly likely that google calculates distance if you will be taking some roads and not a straight line. Apr 16, 2016 at 23:53
  • 6
    Google calculates driving distance, this calculates "as the crow flies"
    – Hobbyist
    Aug 9, 2016 at 22:24
  • 6
    @Ouadie and will it improve speed? Most probably no, but I will end up with a lot of 'your stuff doesn't work' for people who copypaste it in old browsers Jan 27, 2017 at 19:58
  • 5
    @KhalilKhalaf most probably it is just you. Multiplying a number by another number is not that hard. I will even help you with a number: 0.6213 Aug 22, 2017 at 20:23
78

Here is a C# Implementation:

static class DistanceAlgorithm
{
    const double PIx = 3.141592653589793;
    const double RADIUS = 6378.16;

    /// <summary>
    /// Convert degrees to Radians
    /// </summary>
    /// <param name="x">Degrees</param>
    /// <returns>The equivalent in radians</returns>
    public static double Radians(double x)
    {
        return x * PIx / 180;
    }

    /// <summary>
    /// Calculate the distance between two places.
    /// </summary>
    /// <param name="lon1"></param>
    /// <param name="lat1"></param>
    /// <param name="lon2"></param>
    /// <param name="lat2"></param>
    /// <returns></returns>
    public static double DistanceBetweenPlaces(
        double lon1,
        double lat1,
        double lon2,
        double lat2)
    {
        double dlon = Radians(lon2 - lon1);
        double dlat = Radians(lat2 - lat1);

        double a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos(Radians(lat1)) * Math.Cos(Radians(lat2)) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2));
        double angle = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
        return angle * RADIUS;
    }

}
7
  • 15
    You are using the equatorial radius, but you should be using the mean radius, which is 6371 km Jul 10, 2009 at 12:18
  • 7
    Shouldn't this be double dlon = Radians(lon2 - lon1); and double dlat = Radians(lat2 - lat1); Jan 15, 2010 at 15:40
  • I agree with Chris Marisic. I used the original code and the calculations were wrong. I added the call to convert the deltas to radians and it works properly now. I submitted an edit and am waiting for it to be peer reviewed. Dec 4, 2011 at 4:53
  • I submitted another edit because lat1 & lat2 also need to be converted to radians. I also revised the formula for the assignment to a to match the formula and code found here: movable-type.co.uk/scripts/latlong.html Dec 4, 2011 at 6:48
  • does the RADIUS value need to be 6371 as in the other answers? Jan 23, 2019 at 18:02
72

Here is a java implementation of the Haversine formula.

public final static double AVERAGE_RADIUS_OF_EARTH_KM = 6371;
public int calculateDistanceInKilometer(double userLat, double userLng,
  double venueLat, double venueLng) {

    double latDistance = Math.toRadians(userLat - venueLat);
    double lngDistance = Math.toRadians(userLng - venueLng);

    double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
      + Math.cos(Math.toRadians(userLat)) * Math.cos(Math.toRadians(venueLat))
      * Math.sin(lngDistance / 2) * Math.sin(lngDistance / 2);

    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

    return (int) (Math.round(AVERAGE_RADIUS_OF_EARTH_KM * c));
}

Note that here we are rounding the answer to the nearest km.

2
  • 2
    If we wanted to calculate the distance between between two points in meters, what would be the more accurate way? To use 6371000 as the radius of the earth? (avg. radius of earth is 6371000 meters) or convert kilometers to meters from your function?
    – Micro
    Dec 12, 2016 at 18:29
  • if you want miles, multiple the result by 0.621371
    – lasec0203
    Sep 9, 2019 at 5:20
43

Thanks very much for all this. I used the following code in my Objective-C iPhone app:

const double PIx = 3.141592653589793;
const double RADIO = 6371; // Mean radius of Earth in Km

double convertToRadians(double val) {

   return val * PIx / 180;
}

-(double)kilometresBetweenPlace1:(CLLocationCoordinate2D) place1 andPlace2:(CLLocationCoordinate2D) place2 {

        double dlon = convertToRadians(place2.longitude - place1.longitude);
        double dlat = convertToRadians(place2.latitude - place1.latitude);

        double a = ( pow(sin(dlat / 2), 2) + cos(convertToRadians(place1.latitude))) * cos(convertToRadians(place2.latitude)) * pow(sin(dlon / 2), 2);
        double angle = 2 * asin(sqrt(a));

        return angle * RADIO;
}

Latitude and Longitude are in decimal. I didn't use min() for the asin() call as the distances that I'm using are so small that they don't require it.

It gave incorrect answers until I passed in the values in Radians - now it's pretty much the same as the values obtained from Apple's Map app :-)

Extra update:

If you are using iOS4 or later then Apple provide some methods to do this so the same functionality would be achieved with:

-(double)kilometresBetweenPlace1:(CLLocationCoordinate2D) place1 andPlace2:(CLLocationCoordinate2D) place2 {

    MKMapPoint  start, finish;


    start = MKMapPointForCoordinate(place1);
    finish = MKMapPointForCoordinate(place2);

    return MKMetersBetweenMapPoints(start, finish) / 1000;
}
3
  • 2
    iOS SDK has its own implementation: developer.apple.com/library/ios/documentation/CoreLocation/…:
    – tuler
    Mar 27, 2016 at 12:15
  • I think the parenthesis around pow(sin(dlat / 2), 2) + cos(convertToRadians(place1.latitude)) is incorrect. Remove those, and the result matches what I get when I use other implementations on this page, or implement the Haversine formula from Wikipedia from scratch.
    – zanedp
    Jan 17, 2019 at 19:33
  • Using the coordinates (40.7127837, -74.0059413) for NYC and (34.052234, -118.243685) for LA, with the () around that sum, I get 3869.75. Without them, I get 3935.75, which is pretty much what a web search turns up.
    – zanedp
    Jan 17, 2019 at 19:39
43

This is a simple PHP function that will give a very reasonable approximation (under +/-1% error margin).

<?php
function distance($lat1, $lon1, $lat2, $lon2) {

    $pi80 = M_PI / 180;
    $lat1 *= $pi80;
    $lon1 *= $pi80;
    $lat2 *= $pi80;
    $lon2 *= $pi80;

    $r = 6372.797; // mean radius of Earth in km
    $dlat = $lat2 - $lat1;
    $dlon = $lon2 - $lon1;
    $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlon / 2) * sin($dlon / 2);
    $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
    $km = $r * $c;

    //echo '<br/>'.$km;
    return $km;
}
?>

As said before; the earth is NOT a sphere. It is like an old, old baseball that Mark McGwire decided to practice with - it is full of dents and bumps. The simpler calculations (like this) treat it like a sphere.

Different methods may be more or less precise according to where you are on this irregular ovoid AND how far apart your points are (the closer they are the smaller the absolute error margin). The more precise your expectation, the more complex the math.

For more info: wikipedia geographic distance

1
  • 4
    This works perfectly! I just added $distance_miles = $km * 0.621371; and that's all I needed for approximate distance in miles! Thanks Tony.
    – user321531
    Aug 8, 2014 at 5:17
32

I post here my working example.

List all points in table having distance between a designated point (we use a random point - lat:45.20327, long:23.7806) less than 50 KM, with latitude & longitude, in MySQL (the table fields are coord_lat and coord_long):

List all having DISTANCE<50, in Kilometres (considered Earth radius 6371 KM):

SELECT denumire, (6371 * acos( cos( radians(45.20327) ) * cos( radians( coord_lat ) ) * cos( radians( 23.7806 ) - radians(coord_long) ) + sin( radians(45.20327) ) * sin( radians(coord_lat) ) )) AS distanta 
FROM obiective 
WHERE coord_lat<>'' 
    AND coord_long<>'' 
HAVING distanta<50 
ORDER BY distanta desc

The above example was tested in MySQL 5.0.95 and 5.5.16 (Linux).

1
  • I think a good approach might be pre filtering the results using an aproximation, so the heavy formula is applied only for some cases. Specially usefull if you have other conditions. I'm using this for the initial aprox: stackoverflow.com/questions/1253499/…
    – Pato
    May 19, 2017 at 20:57
32

In the other answers an implementation in is missing.

Calculating the distance between two point is quite straightforward with the distm function from the geosphere package:

distm(p1, p2, fun = distHaversine)

where:

p1 = longitude/latitude for point(s)
p2 = longitude/latitude for point(s)
# type of distance calculation
fun = distCosine / distHaversine / distVincentySphere / distVincentyEllipsoid 

As the earth is not perfectly spherical, the Vincenty formula for ellipsoids is probably the best way to calculate distances. Thus in the geosphere package you use then:

distm(p1, p2, fun = distVincentyEllipsoid)

Off course you don't necessarily have to use geosphere package, you can also calculate the distance in base R with a function:

hav.dist <- function(long1, lat1, long2, lat2) {
  R <- 6371
  p <- pi/180
  diff.long <- (long2 - long1) * p
  diff.lat <- (lat2 - lat1) * p
  a <- sin(diff.lat/2)^2 + cos(lat1 * p) * cos(lat2 * p) * sin(diff.long/2)^2
  b <- 2 * asin(pmin(1, sqrt(a))) 
  d = R * b
  return(d)
}
6
  • To make sure I am clear on what you said: The code you give at end of post: Is that an implementation of Vincenty formula? As far as you know, it should give same answer as calling Vincenty in geosphere? [I don't have geosphere or other library; just looking for some code to include in a cross-platform app. I would of course verify some test cases against a known good calculator.] Nov 25, 2018 at 15:16
  • 1
    @ToolmakerSteve the function at the end of my answer is an implementation of the Haversine method
    – Jaap
    Nov 25, 2018 at 15:23
  • Hi @Jaap could I ask what is the unit of measurement for the formula? Is it in metres?
    – Jackson
    Dec 4, 2019 at 1:53
  • 1
    @Jaap I liked the explanation of 'Vincenty formula for ellipsoids' which I tested to be very accurate. @Jackson distm(p1, p2, fun = distVincentyEllipsoid) gives output in metres which you have to divide with 1000 to get values in kilometres. Nov 25, 2020 at 5:28
  • The base R implementation above is incorrect, as it does not convert longitude and latitude to radians. Mar 2 at 21:26
13

The haversine is definitely a good formula for probably most cases, other answers already include it so I am not going to take the space. But it is important to note that no matter what formula is used (yes not just one). Because of the huge range of accuracy possible as well as the computation time required. The choice of formula requires a bit more thought than a simple no brainer answer.

This posting from a person at nasa, is the best one I found at discussing the options

http://www.cs.nyu.edu/visual/home/proj/tiger/gisfaq.html

For example, if you are just sorting rows by distance in a 100 miles radius. The flat earth formula will be much faster than the haversine.

HalfPi = 1.5707963;
R = 3956; /* the radius gives you the measurement unit*/

a = HalfPi - latoriginrad;
b = HalfPi - latdestrad;
u = a * a + b * b;
v = - 2 * a * b * cos(longdestrad - longoriginrad);
c = sqrt(abs(u + v));
return R * c;

Notice there is just one cosine and one square root. Vs 9 of them on the Haversine formula.

1
  • 2
    It's a nice possibility. Just be aware that the recommended maximum distance in the discussion is 12 miles, not 100, and that even so, errors might creep up to 30 meters (100 ft), depending on the globe's position.
    – Eric Wu
    Aug 12, 2019 at 17:00
10

There is some errors in the code provided, I've fixed it below.

All the above answers assumes the earth is a sphere. However, a more accurate approximation would be that of an oblate spheroid.

a= 6378.137#equitorial radius in km
b= 6356.752#polar radius in km

def Distance(lat1, lons1, lat2, lons2):
    lat1=math.radians(lat1)
    lons1=math.radians(lons1)
    R1=(((((a**2)*math.cos(lat1))**2)+(((b**2)*math.sin(lat1))**2))/((a*math.cos(lat1))**2+(b*math.sin(lat1))**2))**0.5 #radius of earth at lat1
    x1=R1*math.cos(lat1)*math.cos(lons1)
    y1=R1*math.cos(lat1)*math.sin(lons1)
    z1=R1*math.sin(lat1)

    lat2=math.radians(lat2)
    lons2=math.radians(lons2)
    R2=(((((a**2)*math.cos(lat2))**2)+(((b**2)*math.sin(lat2))**2))/((a*math.cos(lat2))**2+(b*math.sin(lat2))**2))**0.5 #radius of earth at lat2
    x2=R2*math.cos(lat2)*math.cos(lons2)
    y2=R2*math.cos(lat2)*math.sin(lons2)
    z2=R2*math.sin(lat2)
    
    return ((x1-x2)**2+(y1-y2)**2+(z1-z2)**2)**0.5
1
  • Could you add sources to your formulae?
    – zabop
    Dec 10, 2021 at 12:11
9

There could be a simpler solution, and more correct: The perimeter of earth is 40,000Km at the equator, about 37,000 on Greenwich (or any longitude) cycle. Thus:

pythagoras = function (lat1, lon1, lat2, lon2) {
   function sqr(x) {return x * x;}
   function cosDeg(x) {return Math.cos(x * Math.PI / 180.0);}

   var earthCyclePerimeter = 40000000.0 * cosDeg((lat1 + lat2) / 2.0);
   var dx = (lon1 - lon2) * earthCyclePerimeter / 360.0;
   var dy = 37000000.0 * (lat1 - lat2) / 360.0;

   return Math.sqrt(sqr(dx) + sqr(dy));
};

I agree that it should be fine-tuned as, I myself said that it's an ellipsoid, so the radius to be multiplied by the cosine varies. But it's a bit more accurate. Compared with Google Maps and it did reduce the error significantly.

8
  • Is this function return distance in km?
    – Wikki
    Oct 15, 2016 at 17:34
  • It is, just because the equator and the longitude cycles are in Km. For miles, just divide 40000 and 37000 by 1.6. Feeling geeky, you can convert it to Ris, multiplyung by about 7 or to parasang, dividing by 2.2 ;-)
    – Meymann
    Oct 17, 2016 at 4:46
  • This seems to be the best answer offered here. I wish to use it but I just wonder whether there is a way to verify the correctness of this algorithm. I tested f(50,5,58,3). It gives 832km, whereas movable-type.co.uk/scripts/latlong.html using the 'haversine' formula gives 899km. Is there such a big difference? Apr 19, 2018 at 7:44
  • Moreover, I think the value returned by the above code is in m, and not km. Apr 19, 2018 at 7:45
  • 2
    This formula has an inaccurate number in it. circumference through poles is 6356.752 NASA * 2 Pi = 39940.651 km. Not 37000. So gives low answers for changes in latitude, as Chong saw. Replace "37000000.0" with "39940651.0". With this correction, my guess is accuracy to 1 part in 100, over distances up to one degree. (Not verified.) Nov 25, 2018 at 15:12
9

pip install haversine

Python implementation

Origin is the center of the contiguous United States.

from haversine import haversine, Unit
origin = (39.50, 98.35)
paris = (48.8567, 2.3508)
haversine(origin, paris, unit=Unit.MILES)

To get the answer in kilometers simply set unit=Unit.KILOMETERS (that's the default).

3
  • 4
    You're importing a non-standard package that does all the work. I don't know if that's all that useful.
    – Teepeemm
    Dec 1, 2015 at 1:23
  • The package is in the PyPI, Python Package Index, as a python 3 package along with numpy and scikit-learn. Not sure why one is apposed to packages. They tend to be quite useful. As open source, one could also examine the methods contained. I think many would find this package useful so I will leave the post despite the downvote. Cheers. :) Jun 30, 2016 at 16:55
  • It looks useful, but I would like to include the exact pip command to install this package.
    – Uri
    Aug 2, 2021 at 5:26
8

I don't like adding yet another answer, but the Google maps API v.3 has spherical geometry (and more). After converting your WGS84 to decimal degrees you can do this:

<script src="http://maps.google.com/maps/api/js?sensor=false&libraries=geometry" type="text/javascript"></script>  

distance = google.maps.geometry.spherical.computeDistanceBetween(
    new google.maps.LatLng(fromLat, fromLng), 
    new google.maps.LatLng(toLat, toLng));

No word about how accurate Google's calculations are or even what model is used (though it does say "spherical" rather than "geoid". By the way, the "straight line" distance will obviously be different from the distance if one travels on the surface of the earth which is what everyone seems to be presuming.

1
  • distance is in meters. alternatively one can use computeLength() Feb 26, 2016 at 17:08
8

As pointed out, an accurate calculation should take into account that the earth is not a perfect sphere. Here are some comparisons of the various algorithms offered here:

geoDistance(50,5,58,3)
Haversine: 899 km
Maymenn: 833 km
Keerthana: 897 km
google.maps.geometry.spherical.computeDistanceBetween(): 900 km

geoDistance(50,5,-58,-3)
Haversine: 12030 km
Maymenn: 11135 km
Keerthana: 10310 km
google.maps.geometry.spherical.computeDistanceBetween(): 12044 km

geoDistance(.05,.005,.058,.003)
Haversine: 0.9169 km
Maymenn: 0.851723 km
Keerthana: 0.917964 km
google.maps.geometry.spherical.computeDistanceBetween(): 0.917964 km

geoDistance(.05,80,.058,80.3)
Haversine: 33.37 km
Maymenn: 33.34 km
Keerthana: 33.40767 km
google.maps.geometry.spherical.computeDistanceBetween(): 33.40770 km

Over small distances, Keerthana's algorithm does seem to coincide with that of Google Maps. Google Maps does not seem to follow any simple algorithm, suggesting that it may be the most accurate method here.

Anyway, here is a Javascript implementation of Keerthana's algorithm:

function geoDistance(lat1, lng1, lat2, lng2){
    const a = 6378.137; // equitorial radius in km
    const b = 6356.752; // polar radius in km

    var sq = x => (x*x);
    var sqr = x => Math.sqrt(x);
    var cos = x => Math.cos(x);
    var sin = x => Math.sin(x);
    var radius = lat => sqr((sq(a*a*cos(lat))+sq(b*b*sin(lat)))/(sq(a*cos(lat))+sq(b*sin(lat))));

    lat1 = lat1 * Math.PI / 180;
    lng1 = lng1 * Math.PI / 180;
    lat2 = lat2 * Math.PI / 180;
    lng2 = lng2 * Math.PI / 180;

    var R1 = radius(lat1);
    var x1 = R1*cos(lat1)*cos(lng1);
    var y1 = R1*cos(lat1)*sin(lng1);
    var z1 = R1*sin(lat1);

    var R2 = radius(lat2);
    var x2 = R2*cos(lat2)*cos(lng2);
    var y2 = R2*cos(lat2)*sin(lng2);
    var z2 = R2*sin(lat2);

    return sqr(sq(x1-x2)+sq(y1-y2)+sq(z1-z2));
}
7

You can use the build in CLLocationDistance to calculate this:

CLLocation *location1 = [[CLLocation alloc] initWithLatitude:latitude1 longitude:longitude1];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:latitude2 longitude:longitude2];
[self distanceInMetersFromLocation:location1 toLocation:location2]

- (int)distanceInMetersFromLocation:(CLLocation*)location1 toLocation:(CLLocation*)location2 {
    CLLocationDistance distanceInMeters = [location1 distanceFromLocation:location2];
    return distanceInMeters;
}

In your case if you want kilometers just divide by 1000.

6

Here is a typescript implementation of the Haversine formula

static getDistanceFromLatLonInKm(lat1: number, lon1: number, lat2: number, lon2: number): number {
    var deg2Rad = deg => {
        return deg * Math.PI / 180;
    }

    var r = 6371; // Radius of the earth in km
    var dLat = deg2Rad(lat2 - lat1);   
    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;
}
6

Here is the SQL Implementation to calculate the distance in km,

SELECT UserId, ( 3959 * acos( cos( radians( your latitude here ) ) * cos( radians(latitude) ) * 
cos( radians(longitude) - radians( your longitude here ) ) + sin( radians( your latitude here ) ) * 
sin( radians(latitude) ) ) ) AS distance FROM user HAVING
distance < 5  ORDER BY distance LIMIT 0 , 5;

For further details in the implementation by programming langugage, you can just go through the php script given here

5

This script [in PHP] calculates distances between the two points.

public static function getDistanceOfTwoPoints($source, $dest, $unit='K') {
        $lat1 = $source[0];
        $lon1 = $source[1];
        $lat2 = $dest[0];
        $lon2 = $dest[1];

        $theta = $lon1 - $lon2;
        $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
        $dist = acos($dist);
        $dist = rad2deg($dist);
        $miles = $dist * 60 * 1.1515;
        $unit = strtoupper($unit);

        if ($unit == "K") {
            return ($miles * 1.609344);
        }
        else if ($unit == "M")
        {
            return ($miles * 1.609344 * 1000);
        }
        else if ($unit == "N") {
            return ($miles * 0.8684);
        } 
        else {
            return $miles;
        }
    }
5

Java implementation in according to Haversine formula

double calculateDistance(double latPoint1, double lngPoint1, 
                         double latPoint2, double lngPoint2) {
    if(latPoint1 == latPoint2 && lngPoint1 == lngPoint2) {
        return 0d;
    }

    final double EARTH_RADIUS = 6371.0; //km value;

    //converting to radians
    latPoint1 = Math.toRadians(latPoint1);
    lngPoint1 = Math.toRadians(lngPoint1);
    latPoint2 = Math.toRadians(latPoint2);
    lngPoint2 = Math.toRadians(lngPoint2);

    double distance = Math.pow(Math.sin((latPoint2 - latPoint1) / 2.0), 2) 
            + Math.cos(latPoint1) * Math.cos(latPoint2)
            * Math.pow(Math.sin((lngPoint2 - lngPoint1) / 2.0), 2);
    distance = 2.0 * EARTH_RADIUS * Math.asin(Math.sqrt(distance));

    return distance; //km value
}
4

here is an example in postgres sql (in km, for miles version, replace 1.609344 by 0.8684 version)

CREATE OR REPLACE FUNCTION public.geodistance(alat float, alng float, blat  

float, blng  float)
  RETURNS float AS
$BODY$
DECLARE
    v_distance float;
BEGIN

    v_distance = asin( sqrt(
            sin(radians(blat-alat)/2)^2 
                + (
                    (sin(radians(blng-alng)/2)^2) *
                    cos(radians(alat)) *
                    cos(radians(blat))
                )
          )
        ) * cast('7926.3352' as float) * cast('1.609344' as float) ;


    RETURN v_distance;
END 
$BODY$
language plpgsql VOLATILE SECURITY DEFINER;
alter function geodistance(alat float, alng float, blat float, blng float)
owner to postgres;
4

I made a custom function in R to calculate haversine distance(km) between two spatial points using functions available in R base package.

custom_hav_dist <- function(lat1, lon1, lat2, lon2) {
R <- 6371
Radian_factor <- 0.0174533
lat_1 <- (90-lat1)*Radian_factor
lat_2 <- (90-lat2)*Radian_factor
diff_long <-(lon1-lon2)*Radian_factor

distance_in_km <- 6371*acos((cos(lat_1)*cos(lat_2))+ 
                 (sin(lat_1)*sin(lat_2)*cos(diff_long)))
rm(lat1, lon1, lat2, lon2)
return(distance_in_km)
}

Sample output

custom_hav_dist(50.31,19.08,54.14,19.39)
[1] 426.3987

PS: To calculate distances in miles, substitute R in function (6371) with 3958.756 (and for nautical miles, use 3440.065).

4
  • how to calculate the speed?
    – LeMarque
    Dec 28, 2021 at 4:50
  • The code is about calculating the distance between two geostationary-spatial points. Didn't get the idea why speed calculation is required here ?? Dec 29, 2021 at 5:38
  • Actually, if the timestamps are given, we can calculate the speed, as distance is calculated using the formula. but if there are one minute interval time stamps and we wanted to learn about the speed of (any vehicle moving) at every 5 minute interval, I was wondering how to do that?
    – LeMarque
    Dec 29, 2021 at 6:41
  • You can further add in the code to calculate speed but in my use case, it wasn't necessary hence didn't calculate speed. Would love to hear what's your approach with that Dec 30, 2021 at 22:15
3

To calculate the distance between two points on a sphere you need to do the Great Circle calculation.

There are a number of C/C++ libraries to help with map projection at MapTools if you need to reproject your distances to a flat surface. To do this you will need the projection string of the various coordinate systems.

You may also find MapWindow a useful tool to visualise the points. Also as its open source its a useful guide to how to use the proj.dll library, which appears to be the core open source projection library.

3

Here is my java implementation for calculation distance via decimal degrees after some search. I used mean radius of world (from wikipedia) in km. İf you want result miles then use world radius in miles.

public static double distanceLatLong2(double lat1, double lng1, double lat2, double lng2) 
{
  double earthRadius = 6371.0d; // KM: use mile here if you want mile result

  double dLat = toRadian(lat2 - lat1);
  double dLng = toRadian(lng2 - lng1);

  double a = Math.pow(Math.sin(dLat/2), 2)  + 
          Math.cos(toRadian(lat1)) * Math.cos(toRadian(lat2)) * 
          Math.pow(Math.sin(dLng/2), 2);

  double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

  return earthRadius * c; // returns result kilometers
}

public static double toRadian(double degrees) 
{
  return (degrees * Math.PI) / 180.0d;
}
3

Here's the accepted answer implementation ported to Java in case anyone needs it.

package com.project529.garage.util;


/**
 * Mean radius.
 */
private static double EARTH_RADIUS = 6371;

/**
 * Returns the distance between two sets of latitudes and longitudes in meters.
 * <p/>
 * Based from the following JavaScript SO answer:
 * http://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula,
 * which is based on https://en.wikipedia.org/wiki/Haversine_formula (error rate: ~0.55%).
 */
public double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) {
    double dLat = toRadians(lat2 - lat1);
    double dLon = toRadians(lon2 - lon1);

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

    return d;
}

public double toRadians(double degrees) {
    return degrees * (Math.PI / 180);
}
0
3

For those looking for an Excel formula based on WGS-84 & GRS-80 standards:

=ACOS(COS(RADIANS(90-Lat1))*COS(RADIANS(90-Lat2))+SIN(RADIANS(90-Lat1))*SIN(RADIANS(90-Lat2))*COS(RADIANS(Long1-Long2)))*6371

Source

1
  • 1
    In ƛ format: =LAMBDA(lat₁,lng₁,lat₂,lng₂, LET(R, 6371, ΔLat, RADIANS(lat₂ - lat₁), ΔLng, RADIANS(lng₂ - lng₁), a, SIN(ΔLat / 2)^2 + COS(RADIANS(lat₁)) * COS(RADIANS(lat₂)) * SIN(ΔLng / 2)^2, c, 2 * ATAN2(SQRT(1 - a), SQRT(a)), d, R * c * 0.621371, d))
    – CalvinDale
    Jul 25, 2022 at 18:46
3
function getDistanceFromLatLonInKm(position1, position2) {
    "use strict";
    var deg2rad = function (deg) { return deg * (Math.PI / 180); },
        R = 6371,
        dLat = deg2rad(position2.lat - position1.lat),
        dLng = deg2rad(position2.lng - position1.lng),
        a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
            + Math.cos(deg2rad(position1.lat))
            * Math.cos(deg2rad(position2.lat))
            * Math.sin(dLng / 2) * Math.sin(dLng / 2),
        c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    return R * c;
}

console.log(getDistanceFromLatLonInKm(
    {lat: 48.7931459, lng: 1.9483572},
    {lat: 48.827167, lng: 2.2459745}
));
1
  • 1
    You have got a typo, second cos should be of pos2
    – aleskva
    May 29, 2021 at 10:28
2

there is a good example in here to calculate distance with PHP http://www.geodatasource.com/developers/php :

 function distance($lat1, $lon1, $lat2, $lon2, $unit) {

     $theta = $lon1 - $lon2;
     $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
     $dist = acos($dist);
     $dist = rad2deg($dist);
     $miles = $dist * 60 * 1.1515;
     $unit = strtoupper($unit);

     if ($unit == "K") {
         return ($miles * 1.609344);
     } else if ($unit == "N") {
          return ($miles * 0.8684);
     } else {
          return $miles;
     }
 }
2

Here is the implementation VB.NET, this implementation will give you the result in KM or Miles based on an Enum value you pass.

Public Enum DistanceType
    Miles
    KiloMeters
End Enum

Public Structure Position
    Public Latitude As Double
    Public Longitude As Double
End Structure

Public Class Haversine

    Public Function Distance(Pos1 As Position,
                             Pos2 As Position,
                             DistType As DistanceType) As Double

        Dim R As Double = If((DistType = DistanceType.Miles), 3960, 6371)

        Dim dLat As Double = Me.toRadian(Pos2.Latitude - Pos1.Latitude)

        Dim dLon As Double = Me.toRadian(Pos2.Longitude - Pos1.Longitude)

        Dim a As Double = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(Me.toRadian(Pos1.Latitude)) * Math.Cos(Me.toRadian(Pos2.Latitude)) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2)

        Dim c As Double = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)))

        Dim result As Double = R * c

        Return result

    End Function

    Private Function toRadian(val As Double) As Double

        Return (Math.PI / 180) * val

    End Function

End Class
1
  • Upon calculating "a", did you wrote Math.Sin( dLat ..) twice by mistake? Jul 24, 2019 at 13:32
2

I condensed the computation down by simplifying the formula.

Here it is in Ruby:

include Math
earth_radius_mi = 3959
radians = lambda { |deg| deg * PI / 180 }
coord_radians = lambda { |c| { :lat => radians[c[:lat]], :lng => radians[c[:lng]] } }

# from/to = { :lat => (latitude_in_degrees), :lng => (longitude_in_degrees) }
def haversine_distance(from, to)
  from, to = coord_radians[from], coord_radians[to]
  cosines_product = cos(to[:lat]) * cos(from[:lat]) * cos(from[:lng] - to[:lng])
  sines_product = sin(to[:lat]) * sin(from[:lat])
  return earth_radius_mi * acos(cosines_product + sines_product)
end
0
2
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2,units) {
  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; 
  var miles = d / 1.609344; 

if ( units == 'km' ) {  
return d; 
 } else {
return miles;
}}

Chuck's solution, valid for miles also.

Not the answer you're looking for? Browse other questions tagged or ask your own question.