根据经纬度坐标查询最近的门店

Laravel框架
362
0
0
2022-04-20

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);
}