views:

26650

answers:

11

How do I calculate distance between two gps coordinates (lang,long)

+9  A: 

This algorithm is known as the Great Circle distance.

Greg Hewgill
A: 

I guess you want it along the curvature of the earth. Your two points and the center of the earth are on a plane. The center of the earth is the center of a circle on that plane and the two points are (roughly) on the perimeter of that circle. From that you can calculate the distance by finding out what the angle from one point to the other is.

If the points are not the same heights, or if you need to take into account that the earth is not a perfect sphere it gets a little more difficult.

Guge
+14  A: 

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

W and S locations and negative. Remember minutes and seconds are out of 60 so 31 30'S is -31.50 degrees.

Don't forget to convert degrees to radians. Many languages have this function. Or its a simply calculation:

radians = degrees * PI / 180

cletus
A: 

This Lua code is adapted from stuff found on Wikipedia and in Robert Lipe's GPSbabel tool:

local EARTH_RAD = 6378137.0 
  -- earth's radius in meters (official geoid datum, not 20,000km / pi)

local radmiles = EARTH_RAD*100.0/2.54/12.0/5280.0;
  -- earth's radius in miles

local multipliers = {
  radians = 1, miles = radmiles, mi = radmiles, feet = radmiles * 5280,
  meters = EARTH_RAD, m = EARTH_RAD, km = EARTH_RAD / 1000, 
  degrees = 360 / (2 * math.pi), min = 60 * 360 / (2 * math.pi)
}

function gcdist(pt1, pt2, units) -- return distance in radians or given units
  --- this formula works best for points close together or antipodal
  --- rounding error strikes when distance is one-quarter Earth's circumference
  --- (ref: wikipedia Great-circle distance)
  if not pt1.radians then pt1 = rad(pt1) end
  if not pt2.radians then pt2 = rad(pt2) end
  local sdlat = sin((pt1.lat - pt2.lat) / 2.0);
  local sdlon = sin((pt1.lon - pt2.lon) / 2.0);
  local res = sqrt(sdlat * sdlat + cos(pt1.lat) * cos(pt2.lat) * sdlon * sdlon);
  res = res > 1 and 1 or res < -1 and -1 or res
  res = 2 * asin(res);
  if units then return res * assert(multipliers[units])
  else return res
  end
end
Norman Ramsey
+1  A: 

I recently had to do the same thing. I found this website to be very helpful explaining spherical trig with examples that were easy to follow along with.

Twotymz
+1  A: 

It depends on how accurate you need it to be, if you need pinpoint accuracy, is best to look at an algorithm with uses an ellipsoid, rather than a sphere, such as Vincenty's algorithm, which is accurate to the mm. http://en.wikipedia.org/wiki/Vincenty%27s_algorithm

seanb
A: 

http://www.math.montana.edu/frankw/ccp/cases/Global-Positioning/spherical-coordinates/learn.htm

This page explains it very clearly.

fasih.ahmed
thanks for the link
David
+3  A: 

This is very easy to do with geography type in SQL Server 2008.

SELECT geography::Point(lat1, lon1, 4326).STDistance(geography::Point(lat2, lon2, 4326))
-- computes distance in meters using eliptical model, accurate to the mm

4326 is SRID for WGS84 elipsoidal Earth model

Marko Tintor
+2  A: 

Look for haversine with Google; here is my solution:

#include <math.h>
#include "haversine.h"

#define d2r (M_PI / 180.0)

//calculate haversine distance for linear distance
double haversine_km(double lat1, double long1, double lat2, double long2)
{
    double dlong = (long2 - long1) * d2r;
    double dlat = (lat2 - lat1) * d2r;
    double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2);
    double c = 2 * atan2(sqrt(a), sqrt(1-a));
    double d = 6367 * c;

    return d;
}

double haversine_mi(double lat1, double long1, double lat2, double long2)
{
    double dlong = (long2 - long1) * d2r;
    double dlat = (lat2 - lat1) * d2r;
    double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2);
    double c = 2 * atan2(sqrt(a), sqrt(1-a));
    double d = 3956 * c; 

    return d;
}
Peter Greis
I used haversine in my projects too.
Pascal Paradis
+2  A: 

Here it is in C# (lat and long in radians):

double CalculateGreatCircleDistance(double lat1, double long1, double lat2, double long2, double radius)
{
    return radius * Math.Acos(
        Math.Sin(lat1) * Math.Sin(lat2)
        + Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(long2 - long1));
}

If your lat and long are in degrees then divide by 180/PI to convert to radians.

Mikey Cee
A: 
Elena
this is the rest... (x2-a2)2+(y2-b2)2 <R2 where a=lat1, b=long1 and R=radius. I know that R=1km but how do I transform 1km into data that can be compared to GPS coordonates? Please help! Thank you!
Elena
and x, y are every value from a collection that are testet to see if they fit.
Elena
latitude and longitude are not eucleidian coorditates, you can't calculate this so simply. However if your latitudes and longitudes are far enough from the poles (how far is enough depends on your required precision), then you can neglect it and assume that 1 degree in longitude = (earth radius / 360) and 1 degree in latitude = (cos(longitude) * earth radius / 360).Also there's a "Ask Question" button for questions, not the "Post your answer" button.
cube
If it has to be exact, then instead of the metric from euclidean space you will have to use something like the code from Norman Ramsey's answer.
cube