用于计算地理邻近性的公式

2022-08-30 08:48:54

我需要在我的应用程序中实现地理位置邻近搜索,但我对要使用的正确公式感到非常困惑。在Web和StackOverflow中进行了一些搜索后,我发现解决方案是:

  1. 使用哈弗正因公式
  2. 使用大圆距离公式
  3. 数据库中使用空间搜索引擎

选项#3对我来说真的不是一个选择。现在我有点困惑,因为我总是认为大圆距离公式哈弗正弦公式同义词,但显然我错了?

Haversine Formula

上面的屏幕截图取自令人敬畏的Geo(接近)搜索与MySQL论文,并使用以下功能:

ASIN, SQRT, POWER, SIN, PI, COS

我也看到了来自同一公式余弦球面定律)的变化,比如这个:

(3956 * ACOS(COS(RADIANS(o_lat)) * COS(RADIANS(d_lat)) * COS(RADIANS(d_lon) - RADIANS(o_lon)) + SIN(RADIANS(o_lat)) * SIN(RADIANS(d_lat))))

它使用以下函数:

ACOS, COS, RADIANS, SIN

我不是数学专家,但这些公式是一样的吗?我遇到了更多的变体和公式(例如余弦的球面定律Vincenty公式 - 这似乎是最准确的),这让我更加困惑......

我需要选择一个好的通用公式在PHP / MySQL中实现。任何人都可以解释我上面提到的公式之间的差异吗?

  • 哪一个是计算最快的?
  • 哪一个提供最准确的结果?
  • 在结果的速度/准确性方面,哪一个是最好的?

我感谢您对这些问题的见解。


根据唯一的理论答案,我测试了以下大圆距离公式:

  • 文森特公式
  • 哈弗辛配方
  • 余弦球面定律

Vincenty公式非常慢,但它非常准确(低至0.5毫米)。

Haversine公式比Vincenty公式快得多,我能够在大约6秒内运行100万次计算,这对于我的需求来说几乎是可以接受的。

余弦公式的球面定律显示几乎是哈弗正弦公式的两倍,并且对于大多数用例,精度差异是忽略的


以下是一些测试位置:

  • 谷歌总部 (,37.422045-122.084347)
  • 旧金山, 加利福尼亚州 (,37.77493-122.419416)
  • 埃菲尔铁塔, 法国 (,48.85822.294407)
  • 悉尼歌剧院 (,-33.856553151.214696)

谷歌总部 - 加利福尼亚州旧金山:

  • 文森特公式:49 087.066 meters
  • 哈弗辛公式:49 103.006 meters
  • 余弦球面定律:49 103.006 meters

谷歌总部 - 埃菲尔铁塔,法国:

  • 文森特公式:8 989 724.399 meters
  • 哈弗辛公式:8 967 042.917 meters
  • 余弦球面定律:8 967 042.917 meters

谷歌总部 - 悉尼歌剧院:

  • 文森特公式:11 939 773.640 meters
  • 哈弗辛公式:11 952 717.240 meters
  • 余弦球面定律:11 952 717.240 meters

如您所见,哈弗正弦公式和余弦球面定律之间没有明显的区别,但是与Vincenty公式相比,两者的距离偏移高达22公里,因为它使用地球的椭圆体近似而不是球形近似。


答案 1

余弦定律和哈弗正弦公式将给出相同的结果,假设机器具有无限的精度。哈弗正弦公式对浮点误差更为鲁棒。但是,今天的机器具有15个有效数字的双精度,余弦定律可能适合您。这两个公式都假设球形地球,而Vicenty的迭代解(最准确)假设椭圆体地球(实际上地球甚至不是椭球体 - 它是大地水准面)。一些参考:http://www.movable-type.co.uk/scripts/gis-faq-5.1.html

它变得更好:请注意余弦定律中使用的纬度,以及Haversine是地心纬度,这与大地纬度不同。对于球体,这两者是相同的。

哪一个计算速度最快?

从最快到最慢的顺序是:余弦定律(5个三角调用)-> haversine(涉及sqrt)->Vicenty(必须在for循环中迭代解决这个问题)

哪一个最准确?

维森蒂。

当速度和准确性都考虑在内时,哪一个是最好的?

如果你的问题域是这样的,对于你试图计算的距离,地球可以被认为是平坦的,那么你可以计算出一个公式(我不打算给出细节)x = kx *经度差,y = ky *纬度差。然后距离 = sqrt(dxdx + dydy)。如果你的问题域可以用距离平方来解决,那么你就不必取sqrt,这个公式将尽可能快。它具有额外的优点,您可以计算矢量距离 - x是东向的距离,y是北向的距离。否则,请尝试使用3,并选择最适合您情况的方法。


答案 2

因此,您希望:

  • 按距 p0 的距离对记录进行排序
  • 仅选择与 p0 的距离小于 r 的记录

诀窍是,您不需要为此计算大圆距离!您可以使用从一对点到实际值的任何函数,该实值严格地随着点之间的大圆距离而增长。有许多这样的函数,有些函数的计算速度比精确大圆距离的各种公式快得多。其中一个函数是 3D 中的欧氏距离。将纬度和经度转换为球体上的 3D 点不涉及反三角函数。

一旦你有了x,Y,Z,你就可以意识到你实际上并不需要从p0到你的点的距离,因为你也可以使用p0处的切平面的距离。该距离也严格地随着大圆距离的增长而增长,并且从X,Y,Z作为线性组合计算 - 甚至不需要平方根。您只需要预先计算系数和对应于所需大圆距离的截止距离。


推荐