我需要在我的应用程序中实现地理邻近搜索,但我对要使用的正确公式感到非常困惑。在 Web 和 StackOverflow 中进行一些搜索后,我发现解决方案是:
- 使用Haversine 公式
使用大圆距离公式- 在数据库中使用空间搜索引擎
选项#3 对我的 ATM 来说真的不是一个选项。现在我有点困惑,因为我一直认为大圆距离公式和哈弗辛公式是同义词,但显然我错了?
上面的屏幕截图取自很棒的Geo (proximity) Search with 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
我不是数学专家,但这些公式是否相同?我遇到了更多的变体和公式(例如余弦的球面定律和文森蒂的公式 -这似乎是最准确的),这让我更加困惑......
我需要选择一个好的通用公式在 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
)
Google 总部 - 加利福尼亚州旧金山:
- 文森特公式:
49 087.066 meters
- 哈弗辛公式:
49 103.006 meters
- 球面余弦定律:
49 103.006 meters
Google 总部 - 法国埃菲尔铁塔:
- 文森特公式:
8 989 724.399 meters
- 哈弗辛公式:
8 967 042.917 meters
- 球面余弦定律:
8 967 042.917 meters
Google 总部 - 悉尼歌剧院:
- 文森特公式:
11 939 773.640 meters
- 哈弗辛公式:
11 952 717.240 meters
- 球面余弦定律:
11 952 717.240 meters
正如您所看到的,Haversine 公式和余弦球面定律之间没有明显的区别,但是与 Vincenty 公式相比,两者的距离偏移量高达 22 公里,因为它使用地球的椭球近似而不是球形近似。