1

Why does the Haversine formula return HUGE distances ? From the values that I'm passing, the distance should not be more than 1 or 2 kms. But it returns 8,104 kms.

I'm aware this is a recurrent problem with PHP.

Courtesy of the code snippet here :

function haversineGreatCircleDistance(
  $latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371)
{
  // convert from degrees to radians
  $latFrom = deg2rad($latitudeFrom);
  $lonFrom = deg2rad($longitudeFrom);
  $latTo = deg2rad($latitudeTo);
  $lonTo = deg2rad($longitudeTo);

  $latDelta = $latTo - $latFrom;
  $lonDelta = $lonTo - $lonFrom;

  $angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
    cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
  return $angle * $earthRadius;
}
Community
  • 1
  • 1
Abhishek
  • 743
  • 1
  • 15
  • 28

1 Answers1

9
function haversineGreatCircleDistance(
  $latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthMeanRadius = 6371)
{
    $deltaLatitude = deg2rad($latitudeTo - $latitudeFrom);
    $deltaLongitude = deg2rad($longitudeTo - $longitudeFrom);
    $a = sin($deltaLatitude / 2) * sin($deltaLatitude / 2) +
         cos(deg2rad($latitudeFrom)) * cos(deg2rad($latitudeTo)) *
         sin($deltaLongitude / 2) * sin($deltaLongitude / 2);
    $c = 2 * atan2(sqrt($a), sqrt(1-$a));
    return $earthMeanRadius * $c;
}

A value of 6371 for the $earthMeanRadius argument (which is the default) is the earth mean radius in kilometres, which means that the returned result will be in kilometres.... if you want miles instead, then call it with an $earthMeanRadius argument value of 3,958; if you want nautical miles, change it to 3440, etc.

Mark Baker
  • 209,507
  • 32
  • 346
  • 385
  • Hi Mark Baker. Thanks for that, but I'm afraid your implementation too returns a very large value. Is there a modulo or something ? – Abhishek Sep 16 '14 at 12:53
  • 2
    That is a tested and correct version of the Haversine formula.... if that doesn't work, check your inputs – Mark Baker Sep 16 '14 at 12:55
  • Thanks Mark Baker for pointing that out. My input was indeed wrong. – Abhishek Sep 16 '14 at 13:18
  • And how to convert the value in Miles ? In what unit is the returned value??? Please clarify ! – Pratik Joshi Jul 22 '15 at 08:03
  • @PratikCJoshi - EARTH MEAN RADIUS.... A value of 6371 for the $earthMeanRadius argument (the default) is the earth mean radius in kilometres, which means that the returned result will be in kilometres.... if you want miles instead, then call it with an $earthMeanRadius argument value of 3,958; if you want nautical miles, change it to 3440 – Mark Baker Jul 22 '15 at 08:12
  • @MarkBaker , Thanks Mark. But i see when i calculate distance , Google map difference(http://maps.google.com/) shows `0.069` miles where as when i use our algorithm it says `0.0601` . Is this difference ok(acceptable) ? Will this slight difference exist between what Google map says and what our code says ? – Pratik Joshi Jul 22 '15 at 08:53
  • @MarkBaker , no issue sir I was using 3440 INSTEAD of 3958. 3958 gives me proper result – Pratik Joshi Jul 22 '15 at 08:59
  • I've just realised for the first time right now that its terrible even at 100 metre resolution!!! I have pictures to prove it calculating distances along a roadway. I'm actually shocked by this. I'd like to know how postgis is calculating: ST_Length(geom,true) which is the spheroid version. – Eamonn Kenny Nov 03 '17 at 10:09
  • @EamonnKenny - If you need a more accurate formula, then I'd recommend Vincenty rather than Haversine.... the algorithm is more intensive to calculate, but it is more accurate – Mark Baker Nov 03 '17 at 10:11