我想知道我附近的位置在哪个主要方向

nzkunb0c  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(374)

我有一个项目,其中我必须显示在10公里内的用户当前位置附近的酒店。我通过下面给定的sql查询成功地得到了结果。此外,如果用户选择北/南/西/东方向,则我必须向用户显示该特定方向上只有附近的酒店可用。我怎样才能知道附近的旅馆在哪个方向?

$nearby = DB::select( DB::raw("SELECT * ,((((acos(sin((?*pi()/180)) * sin((`latitude*pi()/180))+cos((?*pi()/180)) * cos((latitude*pi()/180)) * cos(((?- longitude)*pi()/180))))*180/pi())*60*1.1515*1.609344)) as distance FROM hotel_data HAVING distance<= 10 ORDER BY distance") )->setBindings([$request->latitude,$request->latitude,$request->longitude]);`
qgelzfjb

qgelzfjb1#

从dougv.com你想用这个函数来得到一个精确的方位,同时记住地球的曲率。

function getRhumbLineBearing($lat1, $lon1, $lat2, $lon2) {
   //difference in longitudinal coordinates
   $dLon = deg2rad($lon2) - deg2rad($lon1);

   //difference in the phi of latitudinal coordinates
   $dPhi = log(tan(deg2rad($lat2) / 2 + pi() / 4) / tan(deg2rad($lat1) / 2 + pi() / 4));

   //we need to recalculate $dLon if it is greater than pi
   if(abs($dLon) > pi()) {
      if($dLon > 0) {
         $dLon = (2 * pi() - $dLon) * -1;
      }
      else {
         $dLon = 2 * pi() + $dLon;
      }
   }
   //return the angle, normalized
   return (rad2deg(atan2($dLon, $dPhi)) + 360) % 360;
}

然后,要将其转换为指南针方向,您可以在同一站点上使用此功能:

function getCompassDirection($bearing) {
   $tmp = round($bearing / 22.5);
   switch($tmp) {
      case 1:
         $direction = "NNE";
         break;
      case 2:
         $direction = "NE";
         break;
      case 3:
         $direction = "ENE";
         break;
      case 4:
         $direction = "E";
         break;
      case 5:
         $direction = "ESE";
         break;
      case 6:
         $direction = "SE";
         break;
      case 7:
         $direction = "SSE";
         break;
      case 8:
         $direction = "S";
         break;
      case 9:
         $direction = "SSW";
         break;
      case 10:
         $direction = "SW";
         break;
      case 11:
         $direction = "WSW";
         break;
      case 12:
         $direction = "W";
         break;
      case 13:
         $direction = "WNW";
         break;
      case 14:
         $direction = "NW";
         break;
      case 15:
         $direction = "NNW";
         break;
      default:
         $direction = "N";
   }
   return $direction;
}

当你为所有坐标指定了一个罗盘玫瑰方向时,你可以很容易地过滤它们。

$results = DB::select( DB::raw("SELECT * ....."));

/**get the direction as a compass direction**/
$user_direction = $request->direction;// N

/**group general directions togeter from a simple north, south, east west**/
$filter= [
       'N' => ['N', 'NNE', 'NE', 'NW', 'NNW'],
       'E' => ['E','ESE','ENE','NE', 'SE'], 
       'W' => ['S','SSW','SW','SE','SSE'],
       'S' => ['W','WSW','WNW','SW', 'NW'],
    ];
/**get any direction  that appears in this array ['N', 'NNE', 'NE', 'NW', 'NNW']**/
$filter_direction = $filter[$user_direction];

/**The filtered locations are here in the $filtered variable**/
$filtered = $results->filter(function($item, $key) use ($filter_direction ) {
    $bearing = getRhumbLineBearing($request->latitude, 
                                   $request->longitude, 
                                   $result->latitude, 
                                   $result->longitude);
    $compass = getCompassDirection($bearing);
    return in_array($compass);

})->all();

相关问题