php通過經緯度計算距離及其逆運算

有朋友遇到這樣一個問題,自己數據庫裏面有一些商家,需要根據用戶提交的地理位置找出一定範圍內的商家來返回個用戶。解決這個問題有兩種思路。

第一種思路,從數據庫提取出商家的經緯度,然後計算和用戶經緯度間的距離,留下在距離範圍內地。

這種方法貌似很科學,不過數據量稍微大一點就完蛋了。這裏涉及到的是計算兩個經緯度間的距離,方法的代碼如下:

/**
 * [getdistance3 description]
 * @param $lng1 [經度1]
 * @param $lat1 [緯度1]
 * @param $lng2 [經度2]
 * @param $lat2 [緯度2]
 * @return $distance [距離(米)]
 */
function getdistance3($lng1, $lat1, $lng2, $lat2){
    $radLat1 = deg2rad($lat1);
    $radLat2 = deg2rad($lat2);
    $radLng1 = deg2rad($lng1);
    $radLng2 = deg2rad($lng2);
    $a = $radLat1 - $radLat2;
    $b = $radLng1 - $radLng2;
    $distance = 2*asin(sqrt(pow(sin($a/2),2)+cos($radLat1)*cos($radLat2)*pow(sin($b/2),2)))*6378137;
    return $distance;
}

這個算法的公式是Google map用的,6378137(m)是地球半徑,如果覺得其他值更合適可以改。還有另外一個公式,寫成代碼替換上面的$distance是這樣:

$distance = acos(sin($radLat1)*sin($radLat2)+cos($radLat1)*cos($radLat2)*cos($b))*637813;

通過三角恆等變換可以知道二者是恆等的。

這個方法用來算兩點距離是沒問題,不過要用來解決上面的給出特定範圍內商家的問題不現實。

第二種思路,通過給出的點A的經緯度座標和一個確定的單位距離,先算出距A單位距離的經緯度範圍,再通過這個範圍爲條件從數據庫獲取滿足條件的商家數據。

程序代碼如下:

/**
 * [getRange description]
 * @param  $lng    [經度]
 * @param  $lat    [緯度]
 * @param  $raidus [半徑(米)]
 * @return [array] $range  [經緯度範圍]
 */
function getRange($lng, $lat, $raidus){
    $PI = 3.14159265;
    $latitude = $lat;
    $longitude = $lng;
    $degree = 40075016/360;
    $raidusMetre = $raidus;
    $radiusLat = $raidusMetre / $degree;
    $minLat = $latitude - $radiusLat;
    $maxLat = $latitude + $radiusLat;
    $mpdLng = $degree * cos($latitude * ($PI/180));
    $radiusLng = $raidusMetre / $mpdLng;
    $minLng = $longitude - $radiusLng;
    $maxLng = $longitude + $radiusLng;
    $range = array('minLng' => $minLng, 'maxLng' => $maxLng, 'minLat' => $minLat, 'maxLat' => $maxLat);
    return $range;
}

這裏40075016(m)是地球周長,如果覺得其他值更合適也可以改。通過這個方法,得出了距給出的點($lng, $lat)5000米以內的座標範圍:經度[$minLng, $maxLng],緯度[$minLat, $maxLat],本來想要的是一個半徑爲5000米的圓形範圍,現在得出的是一個正方形範圍,作爲近似使用應該可以了。
接下來就只用到數據庫篩選出經緯度在這個範圍的商家出來,按照需要的數據格式返回給用戶了。如果給定的半徑範圍內沒有找到商家,可以擴大半徑來搜出商家。
到此算是給出這個問題一個近似解決了,先暫時給他用着。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章