【问题标题】:math related PHP question + latitude数学相关的 PHP 问题 + 纬度
【发布时间】:2009-03-20 13:04:04
【问题描述】:

我在一个 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))));

我觉得它有点复杂,我对几何学了解不多,不知道这是否正确。

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

【问题讨论】:

    标签: php google-maps geolocation distance


    【解决方案1】:

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

    另外,see this post 用于在 PHP 中计算两点之间的距离。

    【讨论】:

      【解决方案2】:

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

      在 Javascript can be found here 中直接实现它,应该很容易转换为 PHP。

      【讨论】:

        【解决方案3】:

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

        1. Spherical Law of Cosines [不是很 准确,计算非常简单]
        2. Haversine Formula [准确,除了在较小的距离,仍然相对简单的计算]
        3. Vincenty Formula[精度高,可以使用几种不同的地球表面椭球模型,计算比较复杂]

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

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

        【讨论】:

        • 如果您在谈论我的答案:地球表面的椭圆率引入的误差在小距离内可以忽略不计/微不足道,因为球体和椭圆体在小尺度上都是平坦的。您可能正在考虑余弦计算定律中的舍入误差。
        • 在小距离(1-10 公里)上,我记得余弦定律使 vincenty 公式产生的距离(至少)加倍的一些结果。懒得重新检查那些:D,我在我周围的一些点上运行了 hasrsine 和 vincenty,并且在 250 公里的距离上出现了 1 公里的错误。对我来说不是微不足道的:)
        • 再想一想,我不知道余弦定律可以输入多少舍入误差,但这似乎是一个合理的答案。
        【解决方案4】:

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

            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 类的实例。

        【讨论】:

          【解决方案5】:

          我对几何也一无所知,但谷歌建议this page。也许你会发现它很有用

          【讨论】:

            【解决方案6】:

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

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

            编辑:或者它可能是 Wikipedia 提到的舍入错误,如果您使用的是小分隔符。但我会首先指出直接/行驶距离的差异。

            【讨论】:

              【解决方案7】:

              您引用的计算似乎使用了球坐标系。公式几乎是正确的。可能导致您的计算失败的部分原因是您正在使用的半径。 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 的距离)。在现代计算中使用浮点数可为您提供这种准确性。

              【讨论】:

              • 您知道这与 OP 中的公式相同吗?此外,地球的非球形所带来的误差很小,肯定远不足以解释 Vordreller 提到的 1.3-1.65 因子。
              • 是的,它是相同的公式,但半径已被修正,并且更具可读性。我也没有试图暗示地球的椭球性质导致了误差(正如你所说,误差要小得多),但主要是他的半径不准确。
              • 实际上半径是准确的,因为 OP 的公式在相乘之前转换为度数。这引入了 180/pi 的额外因子,而 180/pi*69.09 非常接近 3963。
              • ...在最后一条评论之前我没有阅读您的编辑。我同意,3963 更直观。
              猜你喜欢
              • 2011-09-05
              • 1970-01-01
              • 2019-05-19
              • 2013-10-23
              • 2011-08-20
              • 1970-01-01
              • 1970-01-01
              • 2011-10-01
              • 2020-02-22
              相关资源
              最近更新 更多