GeoHash是一個將地理位置映射到字符串的編碼方法,通過對地理位置經緯度的編碼可以在一定程度上實現對地理位置數據的高效存儲和查詢。而在使用GeoHash時,距離計算是其中非常重要的一個部分,主要用于比較兩個地理位置在地球上的距離,這就需要用到GeoHash距離計算的相關知識。
在PHP中實現GeoHash距離計算可以使用haversine公式或者Vicenty公式。其中haversine公式是通過求出兩點之間的“半正太角距離”來計算距離的,而Vicenty公式則通過求出經緯度之間的弧度值來計算距離。在實際應用中可以根據不同的需求進行選擇。
function get_distance($point1, $point2, $method = 'haversine') { $earth_radius = 6378137; //地球半徑,單位米 $lat1 = deg2rad($point1['lat']); $lng1 = deg2rad($point1['lng']); $lat2 = deg2rad($point2['lat']); $lng2 = deg2rad($point2['lng']); $delta_lat = $lat2 - $lat1; $delta_lng = $lng2 - $lng1; $dist = 0; if ($method == 'haversine') { $a = pow(sin($delta_lat/2), 2) + cos($lat1) * cos($lat2) * pow(sin($delta_lng/2), 2); $c = 2 * atan2(sqrt($a), sqrt(1-$a)); $dist = $earth_radius * $c; } elseif ($method == 'vicenty') { $a = $earth_radius; $b = $earth_radius * (1 - 1/298.257223563); $f = 1/298.257223563; $L = $delta_lng; $U1 = atan((1-$f) * tan($lat1)); $U2 = atan((1-$f) * tan($lat2)); $sinU1 = sin($U1); $cosU1 = cos($U1); $sinU2 = sin($U2); $cosU2 = cos($U2); $lambda = $L; $lambdaP = 2 * pi(); $iterLimit = 20; while (abs($lambda - $lambdaP) >1e-12 && $iterLimit >0) { $sinLambda = sin($lambda); $cosLambda = cos($lambda); $sinSigma = sqrt(pow($cosU2 * $sinLambda, 2) + pow($cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosLambda, 2)); if ($sinSigma == 0) { return 0; } $cosSigma = $sinU1 * $sinU2 + $cosU1 * $cosU2 * $cosLambda; $sigma = atan2($sinSigma, $cosSigma); $sinAlpha = ($cosU1 * $cosU2 * sinLambda) / ($sinSigma); $cosSqAlpha = 1 - pow($sinAlpha, 2); $cos2SigmaM = ($cosSigma - 2 * $sinU1 * $sinU2 / $cosSqAlpha); if (is_nan($cos2SigmaM)) { $cos2SigmaM = 0; } $C = $f / 16 * $cosSqAlpha * (4 + $f * (4 - 3 * $cosSqAlpha)); $lambdaP = $lambda; $lambda = $L + (1 - $C) * $f * $sinAlpha * ($sigma + $C * $sinSigma * ($cos2SigmaM + $C * $cosSigma * (-1 + 2 * pow($cos2SigmaM, 2))))); $iterLimit -= 1; } if ($iterLimit == 0) { return 0; } $uSq = $cosSqAlpha * ($a * $a - $b * $b) / ($b * $b); $A = 1 + $uSq / 16384 * (4096 + $uSq * (-768 + $uSq * (320 - 175 * $uSq))); $B = $uSq / 1024 * (256 + $uSq * (-128 + $uSq * (74 - 47 * $uSq))); $deltaSigma = $B * $sinSigma * ($cos2SigmaM + $B/4 * ($cosSigma * (-1 + 2 * pow($cos2SigmaM, 2)) - $B / 6 * $cos2SigmaM * (-3 + 4 * pow($sinSigma, 2)) * (-3 + 4 * pow($cos2SigmaM, 2)))); $dist = $b * $A * ($sigma - $deltaSigma); } return $dist; }
其中$method為計算距離的方法,可以為'haversine'或'vicenty',默認為'haversine'。$point1和$point2均為數組,分別保存著兩個地理位置的經緯度信息。
我們來舉個例子,比如說我們要獲取位于香港的Apple Store和北京的Apple Store之間的距離,這兩個地理位置的經緯度信息可以通過谷歌地圖得到:
$point1 = ['lat'=>22.298014, 'lng'=>114.171803]; //香港Apple Store $point2 = ['lat'=>39.908716, 'lng'=>116.397529]; //北京Apple Store $distance = get_distance($point1, $point2); //計算距離,默認使用'haversine'公式 echo round($distance/1000, 2).'km'; //輸出結果,單位為千米
最后我們得到的距離是2409.9km,即香港的Apple Store和北京的Apple Store之間的距離約為2409.9千米。
總結:通過上述代碼我們可以看到,在PHP中實現GeoHash距離計算非常簡單。不僅可以比較兩個地理位置之間的距離,還可以在地理位置數據的存儲和查詢中起到非常重要的作用。
上一篇python的bfs算法
下一篇php inf