1.收到的参数
@param latitude 纬度
@param longitude 经度
2.将经纬度换算成范围及范围距离
/**
* @desc 根据传入的经纬度,和距离范围,返回所有在距离范围内的经纬度的取值范围
* @param $lng 坐标点经度
* @param $lat 坐标点纬度
* @param $distance 范围直径单位:km
* @return array
*/
public function location_range($lng, $lat,$distance=0){
//不传默认1km
$distance = $distance??1;
$earthRadius = 6378.137;//单位km,地球的直径
$d_lng = 2 * asin(sin($distance / (2 * $earthRadius)) / cos(deg2rad($lat)));
$d_lng = rad2deg($d_lng);
$d_lat = $distance/$earthRadius;
$d_lat = rad2deg($d_lat);
//开始跟结束不能乱,BETWEEN查询必须从小到大
return array(
'lat_start' => sprintf("%.6f",$lat - $d_lat),//纬度开始
'lat_end' => sprintf("%.6f",$lat + $d_lat),//纬度结束
'lng_start' => sprintf("%.6f",$lng - $d_lng),//纬度开始
'lng_end' => sprintf("%.6f",$lng + $d_lng),//纬度结束
'distance' => $distance*1000 //限制的距离
);
}
3.查询数据库
/**
* 获取范围内的数据列表
* @param latitude string 纬度
* @param longitude string 经度
*/
public function get_range_list($data)
{
$where = "u.status = 1";//查询条件
$param = [];//参数化条件
$scope = $this->location_range($data['longitude'],$data['latitude']);
$where .= " and (u.longitude between :lng_start and :lng_end )
and (u.latitude between :lat_start and :lat_end )";
$param['lng_start'] = $scope['lng_start'];
$param['lng_end'] = $scope['lng_end'];
$param['lat_start'] = $scope['lat_start'];
$param['lat_end'] = $scope['lat_end'];
//限制的距离(加上该条件,搜索范围才会被限制在一个圈内)
$where .= " and ROUND(6378.138 * 2 * ASIN(SQRT(POW(SIN((:latitude_1 * PI() / 180 - u.latitude * PI() / 180 ) / 2),2) + COS(:latitude_2
* PI() / 180) * COS(u.latitude * PI() / 180) * POW(SIN((:longitude_1 * PI() / 180 - u.longitude * PI() / 180) / 2),2))) * 1000) <= :distance";
$param['distance'] = $scope['distance'];
$param['latitude_1'] = $data['latitude'];
$param['latitude_2'] = $data['latitude'];
$param['longitude_1'] = $data['longitude'];
$sql = "SELECT
u.id,
ROUND(6378.138 * 2 * ASIN(SQRT(POW(SIN(({$data['latitude']} * PI() / 180 - u.latitude * PI() / 180 ) / 2),2) + COS({$data['latitude']}
* PI() / 180) * COS(u.latitude * PI() / 180) * POW(SIN(({$data['longitude']} * PI() / 180 - u.longitude * PI() / 180) / 2),2))) * 1000) AS distance
FROM
USER AS u
WHERE
{ $where }
LIMIT 0, 10";
return DB::select($sql, $param);//laravel框架的一种写法
}