微信小程序通过经纬度计算两地距离并且按照由近到远排序
根据两点间的经纬度计算距离
/**
* @desc 根据两点间的经纬度计算距离
* @param float $lat 纬度值
* @param float $lng 经度值
* @param $status true KM,M显示;false 只返回M
*/
function getDistance($lat1, $lng1, $lat2, $lng2, $status = true, $single = true)
{
$earthRadius = 6367000;
//approximate radius of earth in meters
$lat1 = (floatval($lat1) * pi()) / 180;
$lng1 = (floatval($lng1) * pi()) / 180;
$lat2 = (floatval($lat2) * pi()) / 180;
$lng2 = (floatval($lng2) * pi()) / 180;
$calcLongitude = $lng2 - $lng1;
$calcLatitude = $lat2 - $lat1;
$stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
$stepTwo = 2 * asin(min(1, sqrt($stepOne)));
$calculatedDistance = $earthRadius * $stepTwo;
if (!$single) {
return round($calculatedDistance);
exit;
}
//把大于1000米的转换成km
if ($status) {
$m = round($calculatedDistance) / 1000;
return $m > 1 ? round($m, 1) . "km" : ($m * 1000) . "m";
//return round($m,2); //这个是我在程序中用的,以为排序比较方便,大家根据需求选用
} else {
return round($calculatedDistance) . "m";
}
}
通过距离排序
/**
* @param Request $request
* @return array
* 获取分类商店,并按距离排序
*/
public function getShop(Request $request){
$c_id = $request->get('c_id');
$lat1 = $request->get('lat');
$lng1 = $request->get('lng');
$lat1U = floatval($lat1)+0.01;
$lat1D = floatval($lat1)-0.01;
$lng1U = floatval($lng1)+0.01;
$lng1D = floatval($lng1)-0.01;
$data = DB::table('hunqing_shop')
->where('c_id',$c_id)
->where('lat','<',$lat1U) //获取周围经纬度差0.01的商家距离
->where('lat','>',$lat1D)
->where('lng','<',$lng1U)
->where('lng','>',$lng1D)
->get();
$res = json_encode($data);
$arr1 = json_decode($res,true);
$arr = [];
foreach ($arr1 as $k=>$v){
$res = $this -> getDistance($lat1,$lng1,$v['lat'],$v['lng']);
$arr1[$k]['km'] = $res.'km';
$arr[$k] = $res;
}
asort($arr);
$arr2 = [];
foreach($arr as $k=>$v){
$arr2[] = $arr1[$k];
}
return $arr2;
}
以上是通过程序代码来实现的,下面我再附加一条sql语句来实现的,具体哪种比较快,有感兴趣的可以自己测试一下,记得留言哦!!!
SELECT
id,
lat,
lng,
ROUND(
6378.138 * 2 * ASIN(
SQRT(
POW(
SIN(
(
$lat * PI() / 180 - lat * PI() / 180
) / 2
),
2
) + COS($lat * PI() / 180) * COS(lat * PI() / 180) * POW(
SIN(
(
$lng * PI() / 180 - lng * PI() / 180
) / 2
),
2
)
)
) * 1000
) AS distance
FROM
image_hunqing_shop
ORDER BY
distance asc
本作品采用《CC 协议》,转载必须注明作者和本文链接