How to Quickly Estimate the Distance Between Two (Latitude, Longitude) Points

Calculate distance between two latitude-longitude points? (Haversine formula)

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)
}

How can I quickly estimate the distance between two (latitude, longitude) points?

The answers to Haversine Formula in Python (Bearing and Distance between two GPS points) provide Python implementations that answer your question.

Using the implementation below I performed 100,000 iterations in less than 1 second on an older laptop. I think for your purposes this should be sufficient. However, you should profile anything before you optimize for performance.

from math import radians, cos, sin, asin, sqrt
def haversine(lon1, lat1, lon2, lat2):
"""
Calculate the great circle distance between two points
on the earth (specified in decimal degrees)
"""
# convert decimal degrees to radians
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
# haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
# Radius of earth in kilometers is 6371
km = 6371* c
return km

To underestimate haversine(lat1, long1, lat2, long2) * 0.90 or whatever factor you want. I don't see how introducing error to your underestimation is useful.

Getting distance between two points based on latitude/longitude

Just as a note, if you just need a quick and easy way of finding the distance between two points, I strongly recommend using the approach described in Kurt's answer below instead of reimplementing Haversine—see his post for rationale.

This answer focuses just on answering the specific bug the OP ran into.


It's because in Python, all the trigonometry functions use radians, not degrees.

You can either convert the numbers manually to radians, or use the radians function from the math module:

from math import sin, cos, sqrt, atan2, radians

# Approximate radius of earth in km
R = 6373.0

lat1 = radians(52.2296756)
lon1 = radians(21.0122287)
lat2 = radians(52.406374)
lon2 = radians(16.9251681)

dlon = lon2 - lon1
dlat = lat2 - lat1

a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))

distance = R * c

print("Result: ", distance)
print("Should be: ", 278.546, "km")

The distance is now returning the correct value of 278.545589351 km.

Calculate distance between 2 GPS coordinates

Calculate the distance between two coordinates by latitude and longitude, including a Javascript implementation.

West and South locations are negative.
Remember minutes and seconds are out of 60 so S31 30' is -31.50 degrees.

Don't forget to convert degrees to radians. Many languages have this function. Or its a simple calculation: radians = degrees * PI / 180.

function degreesToRadians(degrees) {
return degrees * Math.PI / 180;
}

function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) {
var earthRadiusKm = 6371;

var dLat = degreesToRadians(lat2-lat1);
var dLon = degreesToRadians(lon2-lon1);

lat1 = degreesToRadians(lat1);
lat2 = degreesToRadians(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));
return earthRadiusKm * c;
}

Here are some examples of usage:

distanceInKmBetweenEarthCoordinates(0,0,0,0)  // Distance between same 
// points should be 0
0

distanceInKmBetweenEarthCoordinates(51.5, 0, 38.8, -77.1) // From London
// to Arlington
5918.185064088764

How to calculate distance between two locations using their longitude and latitude value

Here getting distance in miles (mi)

private double distance(double lat1, double lon1, double lat2, double lon2) {
double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1))
* Math.sin(deg2rad(lat2))
+ Math.cos(deg2rad(lat1))
* Math.cos(deg2rad(lat2))
* Math.cos(deg2rad(theta));
dist = Math.acos(dist);
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
return (dist);
}

private double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}

private double rad2deg(double rad) {
return (rad * 180.0 / Math.PI);
}

Approximate distance between two points (longitude / latitude) without Haversine

My original answer here was not correct; sorry. Here comes my solution, well-tested for my use case. Expecting a vector of decimal latitude values and a distance in meters, calculateProperties returns the decimal long/lat equivalent of one such distance at the location with the narrowest latitude. This means you can use these two values to filter existing long/lat points and include at least all points which are definitely within the range (i.e. making a square subset).

decimalDegreesToDMS <- function(degree){
d <- as.integer(degree)
m <- as.integer((degree - d) * 60)
s <- (degree - d - m/60) * 3600
return(
list("d"=d,"m"=m,"s"=s)
)
}

DMStoAngle <- function(d,m,s){
return( d + m/60 + s/3600 )
}

# http://formulas.tutorvista.com/math/degrees-to-radians-formula.html
angleToRadian <- function(angle){
return( angle * pi / 180 )
}

calculateProperties <- function(latitude_vector,distance){
if(abs(max(latitude_vector)) >= abs(min(latitude_vector))){
narrowest_lat <- max(latitude_vector)
} else {
narrowest_lat <- min(latitude_vector)
}

# https://gis.stackexchange.com/questions/142326/calculating-longitude-length-in-miles
dms <- decimalDegreesToDMS( narrowest_lat )
angle <- DMStoAngle( dms$d, dms$m, dms$s )
radians <- angleToRadian(angle)
x_per_lat_degree <- distance / (111.32 * 10^3)
x_per_long_degree <- distance / (40075 * 10^3 * cos( radians ) / 360)

return( list("narrowest_lat"=narrowest_lat,
"x_per_lat_degree"=x_per_lat_degree,
"x_per_long_degree"=x_per_long_degree) )
}

# subset existing points by meter distance
points <-data.frame("longitude"=c(8.678180,8.678459,8.618162,8.610878,7.208705),
"latitude"=c(50.114390,50.114124,50.226831,50.230530,50.799290))
cp <- calculateProperties(points[,"latitude"],1000)
x_per_long_degree <- cp[["x_per_long_degree"]]
x_per_lat_degree <- cp[["x_per_lat_degree"]]
square_subset <- subset(points, longitude < points[1,"longitude"]+x_per_long_degree
& longitude > points[1,"longitude"]-x_per_long_degree
& latitude < points[1,"latitude"]+x_per_lat_degree
& latitude > points[1,"latitude"]-x_per_lat_degree)

(Please note that this does not cover the original question completely, but it is easy to solve the equation for distance.)

How to find distance from the latitude and longitude of two locations?

The Haversine formula assumes a spherical earth. However, the shape of the earh is more complex. An oblate spheroid model will give better results.

If such accuracy is needed, you should better use Vincenty inverse formula.
See http://en.wikipedia.org/wiki/Vincenty's_formulae for details. Using it, you can get a 0.5mm accuracy for the spheroid model.

There is no perfect formula, since the real shape of the earth is too complex to be expressed by a formula. Moreover, the shape of earth changes due to climate events (see http://www.nasa.gov/centers/goddard/earthandsun/earthshape.html), and also changes over time due to the rotation of the earth.

You should also note that the method above does not take altitudes into account, and assumes a sea-level oblate spheroid.

Edit 10-Jul-2010: I found out that there are rare situations for which Vincenty inverse formula does not converge to the declared accuracy. A better idea is to use GeographicLib (see http://sourceforge.net/projects/geographiclib/) which is also more accurate.

Find distance between two points using latitude and longitude in mysql

I think your question says you have the city values for the two cities between which you wish to compute the distance.

This query will do the job for you, yielding the distance in km. It uses the spherical cosine law formula.

Notice that you join the table to itself so you can retrieve two coordinate pairs for the computation.

SELECT a.city AS from_city, b.city AS to_city, 
111.111 *
DEGREES(ACOS(LEAST(1.0, COS(RADIANS(a.Latitude))
* COS(RADIANS(b.Latitude))
* COS(RADIANS(a.Longitude - b.Longitude))
+ SIN(RADIANS(a.Latitude))
* SIN(RADIANS(b.Latitude))))) AS distance_in_km
FROM city AS a
JOIN city AS b ON a.id <> b.id
WHERE a.city = 3 AND b.city = 7

Notice that the constant 111.1111 is the number of kilometres per degree of latitude, based on the old Napoleonic definition of the metre as one ten-thousandth of the distance from the equator to the pole. That definition is close enough for location-finder work.

If you want statute miles instead of kilometres, use 69.0 instead.

http://sqlfiddle.com/#!9/21e06/412/0

If you're looking for nearby points you may be tempted to use a clause something like this:

   HAVING distance_in_km < 10.0    /* slow ! */
ORDER BY distance_in_km DESC

That is (as we say near Boston MA USA) wicked slow.

In that case you need to use a bounding box computation. See this writeup about how to do that. http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/

The formula contains a LEAST() function. Why? Because the ACOS() function throws an error if its argument is even slightly greater than 1. When the two points in question are very close together, the expression with the COS() and SIN() computations can sometimes yield a value slightly greater than 1 due to floating-point epsilon (inaccuracy). The LEAST(1.0, dirty-great-expression) call copes with that problem.

There's a better way, a formula by Thaddeus Vincenty. It uses ATAN2() rather than ACOS() so it's less susceptible to epsilon problems.


Edit 2022 (by Alexio Vay):
As of today the modern solution should be the following short code:

   select ST_Distance_Sphere(
point(-87.6770458, 41.9631174),
point(-73.9898293, 40.7628267))

Please check out the answer of Naresh Kumar.

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

CLLocation *location1 = [[CLLocation alloc] initWithLatitude:lat1 longitude:long1];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:lat2 longitude:long2];
NSLog(@"Distance i meters: %f", [location1 distanceFromLocation:location2]);
[location1 release];
[location2 release];

You also need to add CoreLocation.framework to your project, and add the import statement:

#import <CoreLocation/CoreLocation.h>


Related Topics



Leave a reply



Submit