3
votes

SELECT postcode, lat, lng, truncate( (degrees(acos (sin(radians(lat)) * sin( radians('.$latitude.')) + cos(radians(lat)) * cos( radians('.$latitude.')) * cos( radians(lng - ('.$longitude.'))) ) ) * 69.172), 2) as distance FROM myData
This query calculates distance (in miles). But when I check distance for same lat and longitude at google maps my result doesnt match. If the distance is around 10 miles then my result is a bit accurate, but over that it gets wrong (for example, my result showed 13 miles and google showed 22 miles for same post code values)

I got this query from http://forums.mysql.com/read.php?23,3868,3868#msg-3868

How can I get it accurate. Any ideas? Thanks for help.

UPDATE

I tried @Blixt code in PHP. Picked up 2 sample postcodes and their lats longs

//B28 9ET
$lat1 = 52.418819;
$long1 = -1.8481053;

//CV5 8BX
$lat2 = 52.4125573;
$long2 = -1.5407743;

$dtr = M_PI / 180;
$latA = $lat1 * $dtr;
$lonA = $long1 * $dtr;
$latB = $lat2 * $dtr;
$lonB = $long2 * $dtr;
$EarthRadius = 3958.76; //miles
echo $distance = $EarthRadius * acos(cos($latA) * cos($latB) * cos($lonB - $lonA) + sin($latA) * sin($latB));

Results:

My app - 12.95 miles

Google - 17.8 miles

Any ideas how to get it right?

1
Are you sure Google doesn't take stuff like roads into account when calculating distances? - 0scar
hmm .. may be because of this. I checked using Get directions on google maps. Is there any formula to get something similiar to Googles? - TigerTiger
There is no formula to take roads into account, other than some kind of average bird distance/drive distance ratio that will be wrong 99% of the time. You'll need to use an API that lets you get the road distance in that case. Have a look at the Google Maps API: code.google.com/apis/maps - Blixt

1 Answers

2
votes

Have a look at this source code. When I tested it against various other measurement services it seemed to get the same results. It's C# but the math should be easy enough to convert.

Here are the relevant pieces:

public const double EarthRadius = 6371.0072; // Kilometers
//public const double EarthRadius = 3958.76; // Miles

/* ... */

const double dtr = Math.PI / 180;
double latA = this.Latitude * dtr;
double lonA = this.Longitude * dtr;
double latB = other.Latitude * dtr;
double lonB = other.Longitude * dtr;

return GpsLocation.EarthRadius * Math.Acos(Math.Cos(latA) * Math.Cos(latB) * Math.Cos(lonB - lonA) + Math.Sin(latA) * Math.Sin(latB));

Note: The Earth is not perfectly spherical, so the constants used may differ. There is no easy way to make the measurements truly exact. See Wikipedia.