不久前,我写了一个haversine公式的示例,并将其发布在我的网站上:
function haversineGreatCircleDistance( $latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371000){ // 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;}➽请注意,返回的距离与使用参数传入时所用的单位相同
$earthRadius。默认值为6371000米,因此结果也将以[m]为单位。要获得以英里为单位的结果,您可以例如传递3959英里,
$earthRadius结果将以[mi]为单位。我认为,如果没有特殊原因,坚持SI单位是个好习惯。
编辑:
正如TreyA正确指出的那样,由于舍入误差,Haversine公式在对映点上具有弱点(尽管对于短距离而言
是 稳定的)。要绕过它们,可以改用Vincenty公式。
public static function vincentyGreatCircleDistance( $latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371000){ // convert from degrees to radians $latFrom = deg2rad($latitudeFrom); $lonFrom = deg2rad($longitudeFrom); $latTo = deg2rad($latitudeTo); $lonTo = deg2rad($longitudeTo); $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); return $angle * $earthRadius;}


