根據經緯度座標查詢最近的門店

expectedSelf發表於2021-06-07

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 協議》,轉載必須註明作者和本文連結
所幸無礙

相關文章