Question

I found a function in a PHP page that calculates the number of miles between 2 points, but it's faulty. It's supposed to work with google maps, but the difference in distances are ranging from 1.3 to 1.65 times further in google maps(which is more accurate).

Here's the function:

$M =  69.09 * rad2deg(acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2))));

I find it to be a bit complicated and I don't know that much about geometry to know wheter or not this is correct.

Can someone with a bit more knowhow take a look at this and see what's wrong with it?

Was it helpful?

Solution

Maybe you are comparing the 'distance as the crow flies' (direct line between two points) with driving distance?

Also, see this post for calculating distance between two points in PHP.

OTHER TIPS

You're looking for the Haversine formula to calculate distance between two points that you have longitude and latitude for.

A straightforward implementation of it in Javascript can be found here, which should be easy to convert to PHP.

There are at least three couple different methods of calculating distance on the surface of the Earth, which vary in accuracy and required computation.

  1. Spherical Law of Cosines [not very accurate, very simple to calculate]
  2. Haversine Formula [accurate except at smaller distances, still relatively simple to calculate]
  3. Vincenty Formula [highly accurate and can use several different ellipsoid models of the Earth's surface, more complicated to calculate]

The example you provided appears to be the law of cosines calculation, while Google Maps is more accurate since it uses the Vincenty Formula. (I find that the Vincenty link explains the formula in better detail than it's Wikipedia page)

Edit: I saw a comment above that the error introduced by the deviation in the Earth's surface is trivial and cannot compose the error you are seeing. I'm afraid this is only true over very large distances. At distances of a couple hundred km or less, the errors can be decidedly non-trivial.

Here is a simpler version, but not accurate for very distant locations:

    const ONE_DEGREE = 111120;

public function distance( $point ) {
    $coef = cos( $this->getLatitude() / 180 * M_PI );
    $x = $this->getLatitude() - $point->getLatitude();
    $y = ( $this->getLongitude() - $point->getLongitude() ) * $coef;
    $result = sqrt( $x * $x + $y * $y ) * self::ONE_DEGREE;
    return $result;
}

$point and $this are instances of Location class with getLatitude() and getLongitude() methods.

I don't know anything about geometry either, but google suggested this page.Maybe you will find it useful

It looks like the formula is accurate - see, for example, Wikipedia on "great circle distance". The factor of 69.09 in front is, I believe, the number of miles in one degree measured along a great circle (e.g. miles in 1 degree of longitude at the equator), so your answer will be in miles.

jonstjohn's idea that you might be incorrectly comparing straight-line distance with driving distance seems like the most likely explanation to me.

EDIT: or it could be the rounding error Wikipedia mentions, if you're working with small separations. But I would point my finger at the direct/driving distance difference first.

It looks like the calculation you're referencing uses a spherical coordinate system. The formula is almost correct. Part of what could be throwing your calculation off is the radius you're using. The 69.09 is the radius of the sphere (earth in this case). As you may know, the earth isn't really a sphere, more of an ellipsoid. I'd suggest trying the formulation below:

3963 * acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2)));

For more accurate results, you'll want to use Vincenty or Haversine calculations.

EDIT: To clarify, I'm not trying to imply that the bulk of the error you're reporting is due to using a spherical coordinate calculation. That error is much smaller than what you're seeing. The formula adjustment I supplied was intended to be a clearer version of the formula, as the 69.09 was a value of the radius of the earth adjusted to a degree system, which is less intuitive than simply using radians. Additionally, it's worth noting that for calculating very small distances, using the formula above is highly accurate (down to about 1m distances) as long as the system doing the calculation is working with enough decimal places. Using a float in modern computing gives you this accuracy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top