数学相关PHP问题+;纬度

数学相关PHP问题+;纬度,php,google-maps,geolocation,distance,Php,Google Maps,Geolocation,Distance,我在一个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页面中找到了一个计算两点之间英里数的函数,但它有错误。它应该可以与谷歌地图一起使用,但是距离的差异在谷歌地图的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中计算两点之间的距离。

我也不知道几何,但谷歌建议。也许你会发现它很有用。

你正在寻找计算经度和纬度的两点之间距离的方法


一个简单的Javascript实现,应该很容易转换为PHP。

您所引用的计算似乎使用了球面坐标系。这个公式几乎是正确的。可能会使您的计算偏离的一部分是您使用的半径。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的距离)。在现代计算中使用浮点运算可以提供这种精度。

看起来公式是精确的-例如,请参阅。前面69.09的系数是,我相信,沿着一个大圆测量的一度中的英里数(例如,赤道经度为1度时的英里数),所以你的答案是英里

jonstjohn的观点是,你可能错误地将直线距离与行驶距离相比较,这似乎是我最可能的解释


编辑:也可能是维基百科提到的舍入错误,如果你使用的是小的分隔。但我首先要指出的是直接/行驶距离的差异。

计算地球表面距离的方法至少有三种,其精度和计算要求各不相同

  • 不太好 精确,计算起来非常简单]
  • [精确,但距离较小,计算起来仍然相对简单]
  • [高精度,可使用多种不同的地球表面椭球模型,计算更复杂]
  • 您提供的示例似乎是余弦计算定律,而Google Maps则更精确,因为它使用了Vincety公式。(我发现Vincety链接比维基百科页面更详细地解释了这个公式)


    编辑:我在上面看到一条评论,说地球表面的偏差引起的误差是微不足道的,不能构成你所看到的误差。恐怕这只适用于非常长的距离。在距离小于等于几百公里的情况下,误差肯定是不小的。

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

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

    你知道这和OP里的公式是一样的吗?此外,地球的非球形引入的误差很小,当然远不足以解释沃德勒提到的1.3-1.65因子。是的,这是相同的公式,但半径已经修正,可读性更强。我也没有试图暗示地球的elipsoid性质引入了误差(正如你所说的,误差要小得多),但主要是他有一个不准确的半径。实际上半径是准确的,因为OP的公式在相乘之前转换成度。这引入了一个180/pi的额外因子,180/pi*69.09非常接近3963…在最后一条评论之前我没有读过你的编辑。我同意,3963更直观。如果你说的是我的答案:地球表面椭圆度引入的误差在小距离上可以忽略不计,因为球体和椭球体在小尺度上都是平的。你可能想到了余弦定律计算中的舍入误差。在小距离(1-10km)上,我想起了一些结果,其中余弦定律使文森特公式产生的距离加倍(至少加倍)。由于懒得重新检查这些:D,我在我周围的一些点上运行了haversine和vincenty,在250公里的距离上得到了1公里的误差。这对我来说并非微不足道:)仔细考虑一下,我不知道余弦定律能带来多少舍入误差,但这似乎是一个合理的答案。