我在 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。

至少有三种不同的方法来计算地球表面的距离,它们的精度和所需的计算量各不相同。

  1. 余弦球面定律 [not very accurate, very simple to calculate]
  2. 半正矢公式 [除了距离较近外都很准确,计算起来仍然相对简单]
  3. 文森特公式 【精度高,可以使用地球表面的几种不同的椭球模型,计算比较复杂】

您提供的示例似乎是余弦计算定律,而谷歌地图更准确,因为它使用文森蒂公式。(我发现 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左右的距离),只要系统做计算工作有足够的小数位。利用现代计算的浮动给你这样的精度。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top