# Difference between revisions of "Calculate distance between two points on a globe"

## Haversine Formula

The haversine formula is an equation important in navigation, giving great-circle distances between two points on a sphere from their longitudes and latitudes. It is a special case of a more general formula in spherical trigonometry, the law of haversines, relating the sides and angles of spherical "triangles".

## Implementations

### APEX Force.com

```
public class LocatorUtil {

public static Double calculateDistance(Double lat1, Double lon1, Double lat2,   Double lon2){
Double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2);
Double c = 2 * Math.asin(Math.sqrt(a));
}

// Value degree * Pi/180
Double res = degree * 3.1415926 / 180;
return res;
}
}
```

### Java

```import com.google.android.maps.GeoPoint;

public class DistanceCalculator {

// Constructor
DistanceCalculator(double R) {
}

public double CalculationByDistance(GeoPoint StartP, GeoPoint EndP) {
double lat1 = StartP.getLatitudeE6()/1E6;
double lat2 = EndP.getLatitudeE6()/1E6;
double lon1 = StartP.getLongitudeE6()/1E6;
double lon2 = EndP.getLongitudeE6()/1E6;
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2);
double c = 2 * Math.asin(Math.sqrt(a));
}
}
```

### Perl

```# \$lat1 and \$lon1 are the coordinates of the first point in radians
# \$lat2 and \$lon2 are the coordinates of the second point in radians
my \$a = sin((\$lat2 - \$lat1)/2.0);
my \$b = sin((\$lon2 - \$lon1)/2.0);
my \$h = (\$a*\$a) + cos(\$lat1) * cos(\$lat2) * (\$b*\$b);
my \$theta = 2 * asin(sqrt(\$h)); # distance in radians
# in order to find the distance, multiply \$theta by the radius of the earth, e.g.
# \$theta * 6,372.7976 = distance in kilometres (value from http://en.wikipedia.org/wiki/Earth_radius)
```

### PostgreSQL PL/PERLU

```create or replace function distance_in_km (numeric,numeric,numeric,numeric) returns numeric as
\$body\$
use strict;

my \$lat1 = shift(@_);
my \$lon1 = shift(@_);
my \$lat2 = shift(@_);
my \$lon2 = shift(@_);

# Notice the 90 - latitude: phi zero is at the North Pole.
my @L = NESW( \$lat1, \$lon1 );
my @T = NESW( \$lat2, \$lon2 );
my \$km = great_circle_distance(@L, @T, 6378);

return \$km;
\$body\$
language plperlu strict security definer;
```

Query that returns nearest 10 locations within 25 km. Assumes the location is stored as two numeric fields, lat and lng.

```SELECT *, (
) AS distance
FROM table
WHERE lat != search_lat AND lng != search_lng AND distance < 25
ORDER BY distance
FETCH 10 ONLY
```

### JavaScript

```var R = 6371; // km
var dLat = (lat2-lat1)*Math.PI/180;
var dLon = (lon2-lon1)*Math.PI/180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1*Math.PI/180) * Math.cos(lat2*Math.PI/180) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.asin(Math.sqrt(a));
var d = R * c;
```

### C++

```/// @brief The usual PI/180 constant
static const double DEG_TO_RAD = 0.017453292519943295769236907684886;
/// @brief Earth's quatratic mean radius for WGS-84
static const double EARTH_RADIUS_IN_METERS = 6372797.560856;

/** @brief Computes the arc, in radian, between two WGS-84 positions.
*
* The result is equal to <code>Distance(from,to)/EARTH_RADIUS_IN_METERS</code>
*
* where:<ul>
*    <li>d is the distance in meters between 'from' and 'to' positions.</li>
*    <li>h is the haversine function: <code>h(x)=sin²(x/2)</code></li>
* </ul>
*
* The haversine formula gives:
*    <code>h(d/R) = h(from.lat-to.lat)+h(from.lon-to.lon)+cos(from.lat)*cos(to.lat)</code>
*
* @sa http://en.wikipedia.org/wiki/Law_of_haversines
*/
double ArcInRadians(const Position& from, const Position& to) {
double latitudeArc  = (from.lat - to.lat) * DEG_TO_RAD;
double longitudeArc = (from.lon - to.lon) * DEG_TO_RAD;
double latitudeH = sin(latitudeArc * 0.5);
latitudeH *= latitudeH;
double lontitudeH = sin(longitudeArc * 0.5);
lontitudeH *= lontitudeH;
return 2.0 * asin(sqrt(latitudeH + tmp*lontitudeH));
}

/** @brief Computes the distance, in meters, between two WGS-84 positions.
*
*
*/
double DistanceInMeters(const Position& from, const Position& to) {
}
```

### Ruby

```# haversine.rb
#
# haversine formula to compute the great circle distance between two points given their latitude and longitudes
#
# Copyright (C) 2008, 360VL, Inc
# Copyright (C) 2008, Landon Cox
#
# http://www.esawdust.com (Landon Cox)
# contact:
#
# LICENSE: GNU Affero GPL v3
# The ruby implementation of the Haversine formula is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
#
# Landon Cox - 9/25/08
#
# Notes:
#
# translated into Ruby based on information contained in:
#   http://mathforum.org/library/drmath/view/51879.html  Doctors Rick and Peterson - 4/20/99
#   http://www.movable-type.co.uk/scripts/latlong.html
#   http://en.wikipedia.org/wiki/Haversine_formula
#
# This formula can compute accurate distances between two points given latitude and longitude, even for
# short distances.

# PI = 3.1415926535

# the great circle distance d will be in whatever units R is in

Rmiles = 3956           # radius of the great circle in miles
Rkm = 6371              # radius in kilometers...some algorithms use 6367
Rfeet = Rmiles * 5282   # radius in feet
Rmeters = Rkm * 1000    # radius in meters

@distances = Hash.new   # this is global because if computing lots of track point distances, it didn't make
# sense to new a Hash each time over potentially 100's of thousands of points

=begin rdoc
given two lat/lon points, compute the distance between the two points using the haversine formula
the result will be a Hash of distances which are key'd by 'mi','km','ft', and 'm'
=end

def haversine_distance( lat1, lon1, lat2, lon2 )

dlon = lon2 - lon1
dlat = lat2 - lat1

c = 2 * Math.asin( Math.sqrt(a))

dMi = Rmiles * c          # delta between the two points in miles
dKm = Rkm * c             # delta in kilometers
dFeet = Rfeet * c         # delta in feet
dMeters = Rmeters * c     # delta in meters

@distances["mi"] = dMi
@distances["km"] = dKm
@distances["ft"] = dFeet
@distances["m"] = dMeters
end

def test_haversine

lon1 = -104.88544
lat1 = 39.06546

lon2 = -104.80
lat2 = lat1

haversine_distance( lat1, lon1, lat2, lon2 )

puts "the distance from  #{lat1}, #{lon1} to #{lat2}, #{lon2} is:"
puts "#{@distances['mi']} mi"
puts "#{@distances['km']} km"
puts "#{@distances['ft']} ft"
puts "#{@distances['m']} m"

if @distances['km'].to_s =~ /7\.376*/
puts "Test: Success"
else
puts "Test: Failed"
end

end

test_haversine
```

### Python

```#coding:UTF-8
"""
Python implementation of Haversine formula
Copyright (C) <2009>  Bartek GÃ³rny <bartek@gorny.edu.pl>

This program is free software: you can redistribute it and/or modify
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

import math

def recalculate_coordinate(val,  _as=None):
"""
Accepts a coordinate as a tuple (degree, minutes, seconds)
You can give only one of them (e.g. only minutes as a floating point number) and it will be duly
recalculated into degrees, minutes and seconds.
Return value can be specified as 'deg', 'min' or 'sec'; default return value is a proper coordinate tuple.
"""
deg,  min,  sec = val
# pass outstanding values from right to left
min = (min or 0) + int(sec) / 60
sec = sec % 60
deg = (deg or 0) + int(min) / 60
min = min % 60
# pass decimal part from left to right
dfrac,  dint = math.modf(deg)
min = min + dfrac * 60
deg = dint
mfrac,  mint = math.modf(min)
sec = sec + mfrac * 60
min = mint
if _as:
sec = sec + min * 60 + deg * 3600
if _as == 'sec': return sec
if _as == 'min': return sec / 60
if _as == 'deg': return sec / 3600
return deg,  min,  sec

def points2distance(start,  end):
"""
Calculate distance (in kilometers) between two points given as (long, latt) pairs
based on Haversine formula (http://en.wikipedia.org/wiki/Haversine_formula).
Implementation inspired by JavaScript implementation from http://www.movable-type.co.uk/scripts/latlong.html
Accepts coordinates as tuples (deg, min, sec), but coordinates can be given in any form - e.g.
can specify only minutes:
(0, 3133.9333, 0)
is interpreted as
(52.0, 13.0, 55.998000000008687)
which, not accidentally, is the lattitude of Warsaw, Poland.
"""
d_latt = end_latt - start_latt
d_long = end_long - start_long
a = math.sin(d_latt/2)**2 + math.cos(start_latt) * math.cos(end_latt) * math.sin(d_long/2)**2
c = 2 * math.asin(math.sqrt(a))
return 6371 * c

if __name__ == '__main__':
warsaw = ((21,  0,  30),  (52, 13, 56))
cracow = ((19, 56, 18),  (50, 3, 41))
print points2distance(warsaw,  cracow)
```

### MySQL

```DELIMITER //
CREATE DEFINER=`someone`@`somehost` FUNCTION `GetDistance`(
lat1  numeric (9,6),
lon1  numeric (9,6),
lat2  numeric (9,6),
lon2  numeric (9,6)
) RETURNS decimal(10,5)
BEGIN
DECLARE  x  decimal (20,10);
DECLARE  pi  decimal (21,20);
SET  pi = 3.14159265358979323846;
SET  x = sin( lat1 * pi/180 ) * sin( lat2 * pi/180  ) + cos(
lat1 *pi/180 ) * cos( lat2 * pi/180 ) * cos(  abs( (lon2 * pi/180) -
(lon1 *pi/180) ) );
SET  x = acos( x );
RETURN  ( 1.852 * 60.0 * ((x/pi)*180) ) / 1.609344;
END //
```
```Calculate the distance between 2 points with latitude & longitude in MySQL:

DISTANCE in Kilometres:

DISTANCE in Miles:

```

### MSSQL

```CREATE FUNCTION [dbo].[GetDistance]
(
@lat1 Float(8),
@long1 Float(8),
@lat2 Float(8),
@long2 Float(8)
)
RETURNS Float(8)
AS
BEGIN
DECLARE @R Float(8);
DECLARE @dLat Float(8);
DECLARE @dLon Float(8);
DECLARE @a Float(8);
DECLARE @c Float(8);
DECLARE @d Float(8);
SET @R = 3960;
SET @dLat = RADIANS(@lat2 - @lat1);
SET @dLon = RADIANS(@long2 - @long1);
SET @a = SIN(@dLat / 2) * SIN(@dLat / 2) + COS(RADIANS(@lat1))
* COS(RADIANS(@lat2)) * SIN(@dLon / 2) * SIN(@dLon / 2);
SET @c = 2 * ASIN(MIN(SQRT(@a)));
SET @d = @R * @c;
RETURN @d;
END
GO
```

Pentultimate line of formula is junk. Is: SET @c = 2 * ASIN(MIN(SQRT(@a))); Should be: SET @c = 2 * atn2(sqrt(@a), sqrt(1-@a)); Not sure what R is here, use 6371 for approx Km differences.

### C#

```using System;
namespace HaversineFormula
{
/// <summary>
/// The distance type to return the results in.
/// </summary>
public enum DistanceType { Miles, Kilometers };
/// <summary>
/// Specifies a Latitude / Longitude point.
/// </summary>
public struct Position
{
public double Latitude;
public double Longitude;
}
class Haversine
{
/// <summary>
/// Returns the distance in miles or kilometers of any two
/// latitude / longitude points.
/// </summary>
/// <param name=”pos1″></param>
/// <param name=”pos2″></param>
/// <param name=”type”></param>
/// <returns></returns>
public double Distance(Position pos1, Position pos2, DistanceType type)
{
double R = (type == DistanceType.Miles) ? 3960 : 6371;
double dLat = this.toRadian(pos2.Latitude - pos1.Latitude);
double dLon = this.toRadian(pos2.Longitude - pos1.Longitude);
double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
double c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));
double d = R * c;
return d;
}
/// <summary>
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
{
return (Math.PI / 180) * val;
}
}
}
```

To use this code you will need 2 latitude/longitude points. I created a struct to hold the latitude/longitude points. Once we have the points, we create the Haversine class and call the Distance method, passing in the points and an enum specifying whether to return the results in Kilometers or Miles. We end up with the following:

```Position pos1 = new Position();
pos1.Latitude = 40.7486;
pos1.Longitude = -73.9864;
Position pos2 = new Position();
pos2.Latitude = 24.7486;
pos2.Longitude = -72.9864;
Haversine hv = new Haversine();
double result = hv.Distance(pos1, pos2, DistanceType.Kilometers);
```

### Excel

```=2*R*ASIN(MIN(1,SQRT(SIN((RADIANS(lat2)-RADIANS(lat1))/2)^2+SIN((RADIANS(lon2-lon1))/2)^2*COS(RADIANS(lat1))*COS(RADIANS(lat2)))))
```

### PHP

```function getDistance(\$latitude1, \$longitude1, \$latitude2, \$longitude2) {

\$a = sin(\$dLat/2) * sin(\$dLat/2) + cos(deg2rad(\$latitude1)) * cos(deg2rad(\$latitude2)) * sin(\$dLon/2) * sin(\$dLon/2);
\$c = 2 * asin(sqrt(\$a));

return \$d;
}
```

### Smalltalk

```lat1Rad := latitude * Float pi / 180.
lon1Rad := longitude * Float pi / 180.
lat2Rad := latitude2 * Float pi / 180.
lon2Rad := longitude2 * Float pi / 180.

"Haversines"
dLatSinSqrd := (dLat / 2) sin squared.
dLonSinSqrd := (dLon / 2) sin squared.
a := dLatSinSqrd + (cosLatLat * dLonSinSqrd).
c := 2 * a sqrt arcSin.

^distance
```

### Tcl

```proc deg2rad deg {expr {\$deg*atan(1)*8/360}}

proc dist {lat1 lat2 lon1 lon2} {
set R 6371
set dLat [deg2rad [expr {(\$lat2 - \$lat1)}]]
set dLon [deg2rad [expr {(\$lon2 - \$lon1)}]]
set sdlat2 [expr {sin(\$dLat/2)}]
set sdlon2 [expr {sin(\$dLon/2)}]