0

我在一个 PHP 页面中找到了一个计算 2 点之间的英里数的函数,但它有问题。它应该适用于谷歌地图,但距离差异在谷歌地图中的范围是 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))));

我发现它有点复杂,而且我对几何学了解不多,不知道这是否正确。

有更多专业知识的人可以看看这个,看看有什么问题吗?

4

7 回答 7

5

也许您正在将“乌鸦飞行的距离”(两点之间的直线)与行驶距离进行比较?

另外,请参阅这篇文章以计算 PHP 中两点之间的距离。

于 2009-03-19T20:19:35.140 回答
2

您正在寻找Haversine 公式来计算具有经度和纬度的两点之间的距离。

可以在这里找到它在 Javascript 中的直接实现,它应该很容易转换为 PHP。

于 2009-03-19T20:27:47.117 回答
2

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

  1. 球面余弦定律[不是很精确,计算很简单]
  2. Haversine 公式[除了在较小的距离处准确,计算仍然相对简单]
  3. 文森特公式[精度高,可以使用地球表面的几种不同椭球模型,计算更复杂]

您提供的示例似乎是余弦计算定律,而谷歌地图更准确,因为它使用文森蒂公式。(我发现 Vincenty 链接比维基百科页面更详细地解释了公式)

编辑:我在上面看到一条评论,地球表面偏差引入的错误是微不足道的,不能构成您所看到的错误。恐怕这仅在很远的距离上才是正确的。在几百公里或更短的距离内,错误绝对是不小的。

于 2009-03-19T20:38:27.403 回答
1

这是一个更简单的版本,但对于非常遥远的位置并不准确:

    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;
}

$point 和 $this 是具有 getLatitude() 和 getLongitude() 方法的 Location 类的实例。

于 2009-03-20T05:04:04.070 回答
0

我对几何也一无所知,但谷歌推荐了这个页面。也许你会发现它很有用

于 2009-03-19T20:19:59.150 回答
0

看起来您引用的计算使用球坐标系。这个公式几乎是正确的。可能导致您的计算失败的部分原因是您正在使用的半径。69.09 是球体的半径(在本例中为地球)。您可能知道,地球实际上并不是一个球体,更像是一个椭球体。我建议尝试以下公式:

3963 * acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2)));

要获得更准确的结果,您需要使用 Vincenty 或 Haversine 计算。

编辑:澄清一下,我并不是要暗示您报告的大部分错误是由于使用球坐标计算造成的。该错误比您看到的要小得多。我提供的公式调整旨在成为公式的更清晰版本,因为 69.09 是调整为度数系统的地球半径值,这比简单地使用弧度更不直观。此外,值得注意的是,对于计算非常小的距离,只要进行计算的系统使用足够的小数位,使用上面的公式就非常准确(低至大约 1m 的距离)。在现代计算中使用浮点数可为您提供这种准确性。

于 2009-03-19T20:28:11.920 回答
0

看起来该公式是准确的 - 例如,请参见Wikipedia on "great circle distance"。我相信前面的 69.09 是沿大圆测量的 1 度的英里数(例如,赤道 1 度经度的英里),所以你的答案将以英里为单位。

jonstjohn 认为您可能错误地将直线距离与行驶距离进行了比较,这对我来说似乎是最有可能的解释。

编辑:或者它可能是维基百科提到的舍入错误,如果你正在处理小分离。但我会首先指出直接/行驶距离的差异。

于 2009-03-19T20:28:18.863 回答