根据经纬度坐标查询最近的门店
1. 直接通过 mysql 查询
DB::table('shop')->selectRaw("id,lon,lat,
ROUND(ST_DISTANCE(point(lon,lat),point({$lon},{$lat})) /0.0111,2) distance")
->orderBy('distance')
->first();
2. 查询所有坐标,循环计算距离
/** 获取用户最近的店铺
* @param $shopList
* @param $lon
* @param $lat
* @return array
*/
function nearestShop($shopList, $lon, $lat){
$arr = [];
foreach ($shopList as $key => $shop){
$arr[$key] = getDistance($lon, $lat, $shop->lon, $shop->lat);
}
asort($arr); //按距离排序
return $shopList[array_keys($arr)[0]];
}
/** 根据坐标计算距离
* @param float $lon1
* @param float $lat1
* @param float $lon2
* @param float $lat2
* @param int $unit 单位 2是公里
* @param int $decimal 四舍五入小数点后位数
* @return float
*/
function getDistance($lon1, $lat1, $lon2, $lat2, $unit = 2, $decimal = 2){
$EARTH_RADIUS = 6371; // 地球半径系数
//将角度转为狐度
$radLng1 = deg2rad($lon1);
$radLat2 = deg2rad($lat2);
$radLat1 = deg2rad($lat1);
$radLng2 = deg2rad($lon2);
$distance = 2 * asin(sqrt(pow(sin(($radLat1-$radLat2) / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin(($radLng1-$radLng2) / 2), 2))) * $EARTH_RADIUS * 1000;
if ($unit === 2) {
$distance /= 1000;
}
return round($distance, $decimal);
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
高认可度评论:
redis GEO不香吗?
2种方法的效率有测过吗
通过当前用户的经纬度,查询附近的店铺
redis GEO不香吗?
你这每次查询都是全表扫描计算`性能有问题 我用过的2种方法来处理LBS问题
这种需求适合用geo hash 实现
0.0111 为啥用这个
曾经做过,使用 geohash 方案