微信lbs开发 php,【LBS】基于地理位置的搜索之微信 附近的人 简单实现
緣由
本周技術群有一個同學說我們該怎么實現 由近到遠的基于地理位置的搜索,我創業做電商的系統做過類似這樣的服務,我把我們以前的操作給大家分享下
什么是LBS
LBS 全稱是 Location ?Based Service ,基于位置的服務。我們可以使用到這種服務,真是由于我國移動設備的大量增加,讓我們加速進入了 移動互聯網的時代。
由近到遠的基于地理位置的搜索 ?其實就是 通過當前使用用戶的經緯度,然后從我們自己的數據庫中查出指定范圍內(例如5km)的數據,按照由近到遠的順序 進行展示。
這句話中有四個條件
用戶的經緯度,我們定義 用戶維度為:$lat 、經度:$lng
指定范圍,定義范圍:distince
數據庫中商家的經緯度字段,定義 維度為:lat,經度:lng
計算 用戶經緯度 與 數據庫中商家的經緯度 距離,由遠及近進行排序
接下來,我們一起來用兩種方案實現
實現方案一:
這種方案會比較挫,
理想模型計算閥值點
計算某個經緯度的周圍某段距離的正方形的四個點
為什么這么計算,我給大家舉個例子,如果我們把我們的地球儀中國區域直接摁平,是不是地球儀就滅有弧度了 ,我們理想方式就是在一定距離上這么計算的。計算代碼如下
/**
*?php代碼
*計算某個經緯度的周圍某段距離的正方形的四個點
*@param?float?$lng??經度
*@param?float?$lat??緯度
*@param?float?$distance??該點所在圓的半徑,該圓與此正方形內切,默認值為5千米
*@return?array?正方形的四個點的經緯度坐標
*/
function?squarePoint($lat,?$lng,$distance?=?5.0){
$earth_radius?=?6371;//地球半徑
$dlng?=??2?*?asin(sin($distance?/?(2?*?$earth_radius))?/?cos(deg2rad($lat)));
$dlng?=?rad2deg($dlng);
$dlat?=?$distance/$earth_radius;
$dlat?=?rad2deg($dlat);
return?[
'left-top'????=>['lat'=>$lat?+?$dlat,?'lng'=>$lng?-?$dlng],
'right-top'???=>['lat'=>$lat?+?$dlat,?'lng'=>$lng?+?$dlng],
'left-bottom'?=>['lat'=>$lat?-?$dlat,?'lng'=>$lng?-?$dlng],
'right-bottom'=>['lat'=>$lat?-?$dlat,?'lng'=>$lng?+?$dlng],
];
}
取出用戶指定距離的數據
根據上面的方法,我們計算出來了4個點,接下來我們直接從數據庫取出符合條件的數據
$geo_data?=?squarePoint($lat,$lng,$distance);
$left_bottom?=??$geo_data['left-bottom'];
$right_top?=?$geo_data['right-top'];
$lat_min?=?$left_bottom['lat'];
$lat_max?=?$right_top['lat'];
$lng_min?=?$left_bottom['lng'];
$lng_max?=?$right_top['lng'];
$sql?=?"SELECT?*?FROM?table_name
WHERE?lat?>?{$lat_min}?lat??{$lng_min}?and?lng?
按照距離遠近排序
這個將 上面的符合條件的結果集取出來,在代碼中排序,計算 兩個經緯度之間距離的方法如下
/**
*
*?根據經緯度計算距離?單位(公里)
*?@param??$lng1 float?經度1
*?@param??$lat1 float?緯度2
*?@param??$lng2 float?經度1
*?@param??$lat2 float?緯度2
*?@return?float
*/
function?getdistance($lng1,$lat1,$lng2,$lat2)
{
$dx?=?$lng1?-?$lng2;?//?經度差值
$dy?=?$lat1?-?$lat2;?//?緯度差值
$b?=?($lat1?+?$lat2)?/?2.0;?//?平均緯度
$Lx?=?deg2rad($dx)?*?cos(deg2rad($b));?//?東西距離
$Ly?=?deg2rad($dy);?//?南北距離
return?round(6371*sqrt($Lx?*?$Lx?+?$Ly?*?$Ly),4);??//?用平面的矩形對角距離公式計算總距離
}
按照方法一計算出來,基本問題不大,但是在數據量大(第二步結果集)到一定程度了是有很嚴重的效率問題的。這里給出一個衍生版本,直接計算距離
SELECT?*,SQRT(?POWER(?$lat?-?lat,?2)?+?POWER($lng??-?lng,?2)?)?AS?d
FROM?table_name
WHERE?(lat?BETWEEN?$lat_min?AND?$lat_max?)?AND?(lng?BETWEEN?$lng_min?AND?$lng_max?)?AND?d?
ORDER?BY?d?ASC?LIMIT?10;
實現方案二
這個方法很快,直接可以SQL實現,由于數據庫本身也支持很多函數的,我們直接在數據庫本身計算就可以了。具體計算代碼如下:
/**
*?$lat:用戶維度
*?$lng:用戶精度
*?$as_name:查詢出來的SQL字段名稱
*/
get_distance_sql($lat,$lng,$as_name='distance')
{
return?sprintf('round(6371*sqrt(?pow((PI()*(abs(`lat`-%f))/180)?*?cos(PI()*(`lat`+%f)/360),2)
+?pow((PI()*abs(`lng`-%f)/180),2)),4)?as?%s',$lat,$lat,$lng,$as_name);
}
具體SQL如下:
/**
*?shop_id?商家id
*/
$sql?=?"SELECT?shop_id,lat,lng,".get_distance_sql(?$lat,$lng)."?FROM?table_name
WHERE?distance
這樣就可以直接查出結果并排序了
結論
以上兩種方案中,第二個是我我們當時使用的,我們當時數據庫幾十萬,效率還可以。上百萬乃至更高的需要大家去實現了
總結
以上是生活随笔為你收集整理的微信lbs开发 php,【LBS】基于地理位置的搜索之微信 附近的人 简单实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kubernetes集群(概念篇)
- 下一篇: 如果备份还原SecureCRT、Xshe