我有一个每个点都有纬度和经度的机场数据库。我想运行一个PHP脚本来查找特定机场附近的所有机场,以及它们的距离和相对方向。
即。机场KLDJ(40-37-02.810N 074-14-40.539W)
附近的机场
KJFK - 约翰肯尼迪机场(21.2 nm NE)(40-38-23.104N 073-46-44.132W)
我使用了来自http://www.movable-type.co.uk/scripts/latlong.html的代码来查找距离,并试图用它来查找方位,这可能不对。
//BEARING RHUMB LINE
$phi = log(tan($lat2/2+pi/4)/tan($lat1/2+pi/4));
$distance['bearing'] = (rad2deg(atan2($theta, $phi)) +180) % 360;
我基本上想通过这个脚本运行所有点并找到我已经拥有的距离,然后是方向。 (即N,S,W,E,NW,SW,NE,SE)
答案 0 :(得分:6)
大量借鉴here技巧并使用here中的数据,我把这个例子放在一起
<?php
$chicago = array(
'lat' => 41.9
, 'lng' => 87.65
);
$dallas = array(
'lat' => 32.73
, 'lng' => 96.97
);
$ftworth = array(
'lat' => 32.82
, 'lng' => 97.35
);
$bearing = getBearingBetweenPoints( $dallas, $chicago );
echo "Bearing: $bearing°<br>";
echo "Direction: " . getCompassDirection( $bearing );
function getBearingBetweenPoints( $point1, $point2 )
{
return getRhumbLineBearing( $point1['lat'], $point2['lng'], $point2['lat'], $point1['lng'] );
}
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 )
{
static $cardinals = array( 'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N' );
return $cardinals[round( $bearing / 45 )];
}
答案 1 :(得分:1)
如果位置B的纬度大于或小于位置A的纬度,您可以检查它是在东部还是在西部。北方和南方的经度也是如此。最后,您需要一个阈值来检测,在这种情况下,漂移大到足以切换到中间方向。
答案 2 :(得分:1)
查看another page from the same website:
$lat = 0; // latitude of centre of bounding circle in degrees
$lon = 0; // longitude of centre of bounding circle in degrees
$rad = 0; // radius of bounding circle in chosen units
// Choose your unit of measure...
$r = 6371; // earth's radius in km
$r = 3959; // earth's radius in miles
// or
$r = 3440; // earth's radius in nautical miles
// convert point of origin to radians
$lat = deg2rad($lat);
$lon = deg2rad($lon);
// first-cut bounding box (in radians)
$maxLat = $lat + $rad / $r;
$minLat = $lat - $rad / $r;
// compensate for longitude getting smaller with increasing latitude
$maxLon = ( $lon + $rad / $r ) / cos( $lat );
$minLon = ( $lon - $rad / $r ) / cos( $lat );
结合查询:
$query = 'SELECT
id
, lat
, lon
, ACOS(SIN('.$lat.') * SIN(RADIANS(lat)) + COS('.$lat.') * COS(RADIANS(lat)) * COS(RADIANS(lon) - '. $lon.')) * '.$r.' AS distance
FROM (
SELECT
id
, lat
, lon
FROM MyTable
WHERE
RADIANS(lat) > $minLat AND RADIANS(lat) < '.$maxLat.'
AND
RADIANS(lon) > $minLon AND RADIANS(lon) < '.$maxLon.'
) AS FirstCut
WHERE ACOS(SIN('.$lat.') * SIN(RADIANS(lat)) + COS('.$lat.') * COS(RADIANS(lat)) * COS(RADIANS(lon) - '. $lon.')) * '.$r.' < '.$rad;
选择您指定的边界圆内的位置列表(以及它们与圆的原点的距离)。
剩下要做的唯一事情是计算返回位置的方位。这可以用你的直线公式来完成。
以上假设您的数据库中填充了以度为单位的坐标。
如果您将位置存储为几何对象,则可以使用MySQL's inbuilt spatial functions。虽然我非常确定MySQL只包含边界矩形。