用于计算地理邻近性的公式
我需要在我的应用程序中实现地理位置邻近搜索,但我对要使用的正确公式感到非常困惑。在Web和StackOverflow中进行了一些搜索后,我发现解决方案是:
- 使用哈弗正因公式
使用大圆距离公式- 在数据库中使用空间搜索引擎
选项#3对我来说真的不是一个选择。现在我有点困惑,因为我总是认为大圆距离公式和哈弗正弦公式是同义词,但显然我错了?
上面的屏幕截图取自令人敬畏的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.8582
2.294407
) -
悉尼歌剧院 (,
-33.856553
151.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公里,因为它使用地球的椭圆体近似而不是球形近似。