搜索附近的人PHP實現(xiàn)代碼
本文實例為大家分享了PHP實現(xiàn)搜索附近的人具體代碼,供大家參考,具體內(nèi)容如下
實現(xiàn)思路:
首先,我們應(yīng)該這樣想: 既然我們知道了用戶當前位置的經(jīng)緯度,又知道我們將要搜索的范圍,我們可不可以計算出一個范圍 ?也就是說,根據(jù)一個中心點和半徑,計算出符合條件的經(jīng)緯度的最大值和最小值 。
具體實現(xiàn):
那么到此,想要獨立思考完成的小伙伴可以不要繼續(xù)往下看了。
上面我們提到該功能的一個實現(xiàn)原理,接下來我們就講解一下具體的實現(xiàn)步驟。
我們先聲明一個函數(shù),用作計算經(jīng)緯度的范圍:
/**
* 根據(jù)經(jīng)緯度和半徑計算出范圍
* @param string $lat 緯度
* @param String $lng 經(jīng)度
* @param float $radius 半徑
* @return Array 范圍數(shù)組
*/
private function calcScope($lat, $lng, $radius) {
$degree = (24901*1609)/360.0;
$dpmLat = 1/$degree;
$radiusLat = $dpmLat*$radius;
$minLat = $lat - $radiusLat; // 最小緯度
$maxLat = $lat + $radiusLat; // 最大緯度
$mpdLng = $degree*cos($lat * (PI/180));
$dpmLng = 1 / $mpdLng;
$radiusLng = $dpmLng*$radius;
$minLng = $lng - $radiusLng; // 最小經(jīng)度
$maxLng = $lng + $radiusLng; // 最大經(jīng)度
/** 返回范圍數(shù)組 */
$scope = array(
'minLat' => $minLat,
'maxLat' => $maxLat,
'minLng' => $minLng,
'maxLng' => $maxLng
);
return $scope;
}
返回的數(shù)組中包含了在 $radius 范圍內(nèi),符合條件的最大最小經(jīng)緯度。
既然我們已經(jīng)獲取到了范圍,那么我們就可以開始從數(shù)據(jù)庫中查找所有在這個經(jīng)緯度范圍內(nèi)符合條件的記錄:
/**
* 根據(jù)經(jīng)緯度和半徑查詢在此范圍內(nèi)的所有的電站
* @param String $lat 緯度
* @param String $lng 經(jīng)度
* @param float $radius 半徑
* @return Array 計算出來的結(jié)果
*/
public function searchByLatAndLng($lat, $lng, $radius) {
$scope = $this->calcScope($lat, $lng, $radius); // 調(diào)用范圍計算函數(shù),獲取最大最小經(jīng)緯度
/** 查詢經(jīng)緯度在 $radius 范圍內(nèi)的電站的詳細地址 */
$sql = 'SELECT `字段` FROM `表名` WHERE `Latitude` < '.$scope['maxLat'].' and `Latitude` > '.$scope['minLat'].' and `Longitude` < '.$scope['maxLng'].' and `Longitude` > '.$scope['minLng'];
$stmt = self::$db->query($sql);
$res = $stmt->fetchAll(PDO::FETCH_ASSOC); // 獲取查詢結(jié)果并返回
return $res;
}
擴展:
直到現(xiàn)在,我們已經(jīng)知道了如何計算出附近的人,但在實際需求中,我們往往需要計算出每一個人與當前中心點的實際距離。
接著,我們再來看一個方法:
/**
* 獲取兩個經(jīng)緯度之間的距離
* @param string $lat1 緯一
* @param String $lng1 經(jīng)一
* @param String $lat2 緯二
* @param String $lng2 經(jīng)二
* @return float 返回兩點之間的距離
*/
public function calcDistance($lat1, $lng1, $lat2, $lng2) {
/** 轉(zhuǎn)換數(shù)據(jù)類型為 double */
$lat1 = doubleval($lat1);
$lng1 = doubleval($lng1);
$lat2 = doubleval($lat2);
$lng2 = doubleval($lng2);
/** 以下算法是 Google 出來的,與大多數(shù)經(jīng)緯度計算工具結(jié)果一致 */
$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);
$miles = $dist * 60 * 1.1515;
return ($miles * 1.609344);
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
php實現(xiàn)對短信驗證碼發(fā)送次數(shù)的限制實例講解
這篇文章主要介紹了php實現(xiàn)對短信驗證碼發(fā)送次數(shù)的限制實例講解,案例中列舉了具體代碼實現(xiàn),有感興趣的同學可以學習下2021-03-03
詳解PHP中instanceof關(guān)鍵字及instanceof關(guān)鍵字有什么作用
這篇文章主要介紹了PHP中instanceof關(guān)鍵字詳解及instanceof關(guān)鍵字有什么作用的相關(guān)資料,需要的朋友可以參考下2015-11-11
Laravel中任務(wù)調(diào)度console使用方法小結(jié)
這篇文章主要給大家簡單介紹了Laravel中任務(wù)調(diào)度console使用方法,并附上一個簡單的示例,希望對大家學習使用console能夠有所幫助2017-05-05
php 從一個數(shù)組中隨機的取出若干個不同的數(shù)實例
本文章向碼農(nóng)介紹php從一個不重復的數(shù)組中隨機的取出若干個不同的元素,難點是防止在取數(shù)的時候出現(xiàn)已經(jīng)取到過的情況(特別是取到最后),需要盡可能的降低碰撞,需要的朋友可以參考下2016-12-12
dedecms 批量提取第一張圖片最為縮略圖的代碼(文章+軟件)
用了dedecms自帶的縮略圖批量獲取,因為代碼好像是只適用于文字,對于軟件就不能了,或兩者都不能。從網(wǎng)站看到了這段代碼,對于dedecms 5.1是沒問題的。2009-10-10
Laravel5.5 數(shù)據(jù)庫遷移:創(chuàng)建表與修改表示例
今天小編就為大家分享一篇Laravel5.5 數(shù)據(jù)庫遷移:創(chuàng)建表與修改表示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10

