编程语言
首页 > 编程语言> > PHP中的等角近似

PHP中的等角近似

作者:互联网

我正在尝试使用PHP中的等角近似公式来计算两个纬度/经度坐标之间的距离,但是对于某些经度坐标,我得到的结果不同于Haversine公式(我知道这是正确的).

define('EARTH_RADIUS', 6371);

function equirectangularRad($latFrom, $lngFrom, $latTo, $lngTo) {
    $latDelta = $latTo - $latFrom;
    $lngDelta = $lngTo - $lngFrom;

    $x = $lngDelta * cos(($latFrom + $latTo) * .5);
    $radius = sqrt(($x * $x) + ($latDelta * $latDelta));

    return $radius * EARTH_RADIUS;
}

似乎总是通过本初子午线而不是最短距离来计算距离.即沿赤道从坐标(lat = 0,long = -180)到(lat = 0,long = 180),距离应为零.相反,该函数返回沿赤道的地球周长;大约40030公里.

问题似乎源于$lngDelta的计算,但是对于任何编程语言,我都能找到的所有实现都使用相同的公式.我是否缺少一些重要的细节,或者此公式确实不是可替代的haversine(忽略明显的准确性差异)?

以供参考;这是我使用的haversine实现:

function haversineRad($latFrom, $lngFrom, $latTo, $lngTo) {
    $latDelta = $latTo - $latFrom;
    $lngDelta = $lngTo - $lngFrom;              

    $latSin = sin($latDelta * .5);
    $lngSin = sin($lngDelta * .5);
    $radius = 2. * asin(sqrt(($latSin * $latSin) + cos($latFrom) * cos($latTo) * ($lngSin * $lngSin)));

    return $radius * EARTH_RADIUS;
}   

解决方法:

我不知道您的公式在哪里.下面的3个公式将计算2个坐标之间的距离.

等角矩形

function Equirectangular($lat1,$lng1,$lat2,$lng2){
$x = deg2rad($lng2-$lng1) * cos(deg2rad($lat1+$lat2)/2);
$y = deg2rad($lat1-$lat2);
$R = 6372.8; // gives d in km
$distance = sqrt($x*$x + $y*$y) * $R;
return $distance;
}

编辑
修改了Equirectangular()以考虑评论.使用php abs()函数使lng值成为绝对值.当lng2从负变为正时,它开始从Haversine漂移.

function Equirectangular($lat1,$lng1,$lat2,$lng2){
$lng1 = abs($lng1);
$lng2 = abs($lng2);
$alpha = $lng2-$lng1;
$x = deg2rad($alpha) * cos(deg2rad($lat1+$lat2)/2);
$y = deg2rad($lat1-$lat2);
$R = 6372.8; // gives d in km
$distance = sqrt($x*$x + $y*$y) * $R;
return $distance;
}

Haversine

function Haversine($lat1,$lng1,$lat2,$lng2) {
  $deltaLat = $lat2 - $lat1 ;
  $deltaLng = $lng2 - $lng1 ;
  $earthRadius = 6372.8; // 3959 in miles.
  $alpha = $deltaLat/2;
  $beta = $deltaLng/2;
  $a = sin(deg2rad($alpha)) * sin(deg2rad($alpha)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin(deg2rad($beta)) * sin(deg2rad($beta)) ;
  $c = 2 * atan2(sqrt($a), sqrt(1-$a));
  $distance = $earthRadius * $c;
  return $distance;
} 

余弦球法则

function SphericalLawOfCosines($lat1,$lng1,$lat2,$lng2) {
 $lat1 = deg2rad($lat1);
 $lat2 = deg2rad($lat2);
 $deltaLng = deg2rad($lng2-$lng1);
 $R = 6372.8; // gives d in km
$d = acos( sin($lat1)*sin($lat2) + cos($lat1)*cos($lat2) * cos($deltaLng) ) * $R;
return $d;
}

等角矩形是最简单但精度较低的.对于其他2个,要使用一个取决于所涉及的距离.请参阅此Answer.
对于短距离(大约1米或更短的距离),请使用Haversine.对于更大的距离,请使用余弦球定律.

公式结果

0,-179至0,-179等距0 km Haversine 0 km

0,-179至0,-159等距2224.526851 km Haversine 2224.526851 km

0,-179至0,-139等距4449.053703 km Haversine 4449.053703 km

0,-179至0,-119等距6673.580554 km Haversine 6673.580554 km

0,-179至0,-99等角8898.107406 km Haversine 8898.107406 km

0,-179至0,-79等距11122.634257 km Haversine 11122.634257 km

0,-179至0,-59等距13347.161109 km Haversine 13347.161109 km

0,-179至0,-39等距15571.68796 km Haversine 15571.68796 km

0,-179至0,-19等距17796.214811 km Haversine 17796.214811 km

0,-179至0.1矩形19798.288978 km Haversine 20020.741663 km

0,-179至0,21等距17573.762126 km Haversine 17796.214811 km

0,-179至0.41矩形15349.235275 km Haversine 15571.68796 km

0,-179至0.61等距13124.708423 km Haversine 13347.161109 km

0,-179至0,81等距10900.181572 km Haversine 11122.634257 km

0,-179至0,101等距8675.654721 km Haversine 8898.107406 km

0,-179至0,121等角6451.127869 km Haversine 6673.580554 km

0,-179至0,141等角矩形4226.601018 km Haversine 4449.053703 km

0,-179至0,161等角线2002.074166 km Haversine 2224.526851 km

标签:distance,geo,haversine,php
来源: https://codeday.me/bug/20191121/2048329.html