从
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();