开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情
日常应用中我们很多时候都需要查找附近的人、与商品。最近用tp框架开发附近的人功能。具体代码如下:
一、根据经纬度和半径计算出范围,需要给定经纬度、距离半径,返回对应范围。
/**
* 根据经纬度和半径计算出范围
* @param string $lat 纬度
* @param String $lng 经度
* @param float $radius 半径
* @return Array 范围数组
* 24901*1609 地球周长*英里系数
* M_PI/180 M_PI或pi()代表圆周率
*/
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 * (M_PI/180));
$dpmLng = 1 / $mpdLng;
$radiusLng = $dpmLng*$radius;
$minLng = $lng - $radiusLng; // 最小经度
$maxLng = $lng + $radiusLng; // 最大经度
/** 返回范围数组 */
$scope = array(
'minLat' => $minLat,
'maxLat' => $maxLat,
'minLng' => $minLng,
'maxLng' => $maxLng
);
return $scope;
}
二、根据经纬度和半径查询在此范围内的所有的电站
/**
* 根据经纬度和半径查询在此范围内的所有的电站
* @param String $lat 纬度
* @param String $lng 经度
* @param float $radius 半径
* @return Array 计算出来的结果
*/
public function searchByLatAndLng($lat, $lng, $radius) {
$scope = $this->calcScope($lat, $lng, $radius); // 调用范围计算函数,获取最大最小经纬度
/** 查询经纬度在 $radius 范围内的电站的详细地址 */
$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); // 获取查询结果并返回
return $res;
}
三、获取两个经纬度之间的距离
/**
* 获取两个经纬度之间的距离
* @param string $lat1 纬一
* @param String $lng1 经一
* @param String $lat2 纬二
* @param String $lng2 经二
* @return float 返回两点之间的距离
*/
public function calcDistance($lat1, $lng1, $lat2, $lng2) {
/** 转换数据类型为 double */
$lat1 = doubleval($lat1);
$lng1 = doubleval($lng1);
$lat2 = doubleval($lat2);
$lng2 = doubleval($lng2);
/** 以下算法是 Google 出来的,与大多数经纬度计算工具结果一致 */
$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);
}
四.
1.经纬度范围的计算方法是在百度上查找的,目前尚没有找到标准的计算工具,因此该算法无法求证,但大多数帖子基本上采用的这种计算方式。
2.经纬度距离的计算方式是在 Google 上查找的,计算结果与大多数计算工具结果相近。之所以在 Google 中查找,是因为我曾在百度上查找过多种计算方式,结果都不尽人意。
3.通过半径和经纬度计算范围时,半径的单位是m;计算距离时,得到的结果是km。因此,要注意单位变化。