Last active
July 15, 2020 15:10
-
-
Save jakebathman/883a447f9eca970b0bc1 to your computer and use it in GitHub Desktop.
Lat/Lon Distance Calculator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Calculate the distance between two points on a sphere | |
* | |
* Implements the Haversine formula: http://en.wikipedia.org/wiki/Haversine_formula | |
* | |
* More advanced calculation (good for antipodal points) can be used by using | |
* FALSE for $boolUseHaversine. This will use another solution to the Great-circle | |
* ditance problem (http://en.wikipedia.org/wiki/Great-circle_distance), implementing | |
* the Vincenty formula (http://en.wikipedia.org/wiki/Vincenty%27s_formulae#Nearly_antipodal_points). | |
* This matches the calculation from Google's Geometry Library's computeDistanceBetween() function, | |
* assuming the Mercator projection value of Earth's radius of 6378137.0 meters | |
* | |
* $lat1 (string) decimal latitude for point 1 | |
* $lng1 (string) decimal longitude for point 1 | |
* $lat2 (string) decimal latitude for point 2 | |
* $lng2 (string) decimal longitude for point 2 | |
* $unit (string) OPTIONAL unit of measure, either M (miles, the default), K (kilometers), or N (nautical miles) | |
* $boolUseHaversine (boolean) OPTIONAL formula to use for the calculation. Haversine is good for shorter distances (<10,000 km), | |
* see above for more information on Haversine | |
* | |
* @return Returns a decimal distance in the $unit of choice | |
* | |
*/ | |
function geoDistance($lat1, $lng1, $lat2, $lng2, $unit = "M", $boolUseHaversine = true) | |
{ | |
if ($boolUseHaversine === true) { | |
$theta = $lng1 - $lng2; | |
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); | |
$dist = acos($dist); | |
$dist = rad2deg($dist); | |
$totalDist = $dist * 60 * 1.1515; | |
$unit = strtoupper($unit); | |
if ($unit == "K") { | |
return ($totalDist * 1.609344); | |
} elseif ($unit == "N") { | |
return ($totalDist * 0.8684); | |
} else { | |
return $totalDist; | |
} | |
} else { | |
// Vincenty formula implementation from martinstoeckli on Stack Overflow: http://stackoverflow.com/a/10054282/1026279 | |
$earthRadius = 6378137.0; // in meters | |
// convert from degrees to radians | |
$latFrom = deg2rad($lat1); | |
$lonFrom = deg2rad($lng1); | |
$latTo = deg2rad($lat2); | |
$lonTo = deg2rad($lng2); | |
$lonDelta = $lonTo - $lonFrom; | |
$a = pow(cos($latTo) * sin($lonDelta), 2) + | |
pow(cos($latFrom) * sin($latTo) - sin($latFrom) * cos($latTo) * cos($lonDelta), 2); | |
$b = sin($latFrom) * sin($latTo) + cos($latFrom) * cos($latTo) * cos($lonDelta); | |
$angle = atan2(sqrt($a), $b); | |
$totalDist = $angle * $earthRadius; | |
return $totalDist / 1000; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment