数学相关的PHP问题+纬度
-
21-08-2019 - |
题
我在 PHP 页面中发现一个函数可以计算两点之间的英里数,但它是错误的。它应该可以与谷歌地图一起使用,但谷歌地图中的距离差异为 1.3 到 1.65 倍(更准确)。
这是函数:
$M = 69.09 * rad2deg(acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2))));
我发现它有点复杂,而且我对几何了解不多,无法知道这是否正确。
有更多专业知识的人可以看一下这个并找出问题所在吗?
解决方案
也许您在“为直线距离的距离”(两个点之间的直接线)与行驶距离比较?
此外,看到此信息获得两点之间的距离计算在PHP。
其他提示
您正在寻找的 haversine公式你有两个点之间的距离计算经度和纬度为
在Javascript中的直接实现它可以此处发现,这应该是很容易转换为PHP。
至少有三种不同的方法来计算地球表面的距离,它们的精度和所需的计算量各不相同。
- 余弦球面定律 [not very accurate, very simple to calculate]
- 半正矢公式 [除了距离较近外都很准确,计算起来仍然相对简单]
- 文森特公式 【精度高,可以使用地球表面的几种不同的椭球模型,计算比较复杂】
您提供的示例似乎是余弦计算定律,而谷歌地图更准确,因为它使用文森蒂公式。(我发现 Vincenty 链接比维基百科页面更详细地解释了该公式)
编辑:我看到上面的评论说,地球表面偏差引入的误差是微不足道的,不能构成你所看到的误差。恐怕这只有在很远的距离上才是正确的。在几百公里或更短的距离上,误差绝对是不小的。
下面是一个简单的版本,但不是准确的很远的地方:
const ONE_DEGREE = 111120;
public function distance( $point ) {
$coef = cos( $this->getLatitude() / 180 * M_PI );
$x = $this->getLatitude() - $point->getLatitude();
$y = ( $this->getLongitude() - $point->getLongitude() ) * $coef;
$result = sqrt( $x * $x + $y * $y ) * self::ONE_DEGREE;
return $result;
}
$点和$这是与getLatitude()和getLongitude()方法地点类的实例。
我不知道什么几何要么,但谷歌建议此页一>。也许你会发现它有用
它看起来像公式是准确的 - 参见,例如,维基百科上的“大圆距离“。的69.09前面的因素是,我相信,英里的一个程度(在赤道在1度经度的例如英里)沿一个大圆测定的数,所以你的答案将是英里。
你可能会错误地与行驶距离与直线距离jonstjohn的想法似乎是最可能的解释给我。
修改的:或者它可能是舍入误差维基百科中提到,如果你有小的分离工作。不过,我想在直接/行驶距离差首先指出了我的手指。
它看起来像你引用的计算采用的是球面坐标系。其计算公式为几乎是正确的。什么可以扔你计算过的部分是你正在使用的半径。的69.09是球体(土在这种情况下)的半径。正如你可能知道,地球是不是一个真正的球,更多的椭球。我建议尝试下面的配方:
3963 * acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2)));
有关更精确的结果,你会希望使用Vincenty或半正矢计算。
编辑:为了澄清,我不是想暗示你要举报错误的大部分是由于使用球面坐标计算。该错误比你看到的要小得多。我提供的公式调整意欲是下式的更清晰的版本,作为69.09是地球的调节在一定程度上系统的半径,这是比单纯使用弧度不太直观的值。此外,值得注意的是,计算非常小的距离,使用上述公式是非常准确的(下降到1m左右的距离),只要系统做计算工作有足够的小数位。利用现代计算的浮动给你这样的精度。