【发布时间】:2011-01-06 23:19:31
【问题描述】:
我需要在我的应用程序中实现地理邻近搜索,但我对要使用的正确公式感到非常困惑。在网络和 StackOverflow 中进行了一些搜索后,我发现解决方案是:
- 使用 Haversine 公式
使用大圆距离公式- 在数据库中使用空间搜索引擎
选项#3 对我的 ATM 来说真的不是一个选项。现在我有点困惑,因为我一直认为Great-Circle Distance Formula 和Haversine Formula 是同义词,但显然我错了?
上面的屏幕截图取自很棒的 Geo (proximity) Search with MySQL 论文,并使用了以下函数:
ASIN, SQRT, POWER, SIN, PI, COS
我还看到了相同公式 (Spherical Law of Cosines)的变体,例如:
(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
我不是数学专家,但这些公式是否相同?我遇到了一些更多变体和公式(例如 Spherical Law of Cosines 和 Vincenty'sformulae - 这似乎是最准确的),这让我更加困惑......
我需要选择一个好的通用公式在 PHP/MySQL 中实现。谁能解释一下我上面提到的公式之间的区别?
- 哪个计算速度最快?
- 哪一个提供的结果最准确?
- 就结果的速度/准确性而言,哪一个最好?
感谢您对这些问题的见解。
根据theonlytheory 的回答,我测试了以下大圆距离公式:
- 文森提公式
- Haversine 公式
- 余弦球定律
Vincenty 公式非常缓慢,但 它非常准确(低至 0.5 毫米)。
Haversine 公式 比 Vincenty 公式快得多,我能够在大约 6 秒内运行 100 万次计算,这对于我的需求来说几乎是可以接受的。
余弦公式的球面定律显示几乎是Haversine公式的两倍,并且对于大多数情况精度差异是忽略不计用例。
以下是一些测试地点:
-
Google 总部(
37.422045、-122.084347) -
加利福尼亚州旧金山(
37.77493,-122.419416) -
法国埃菲尔铁塔 (
48.8582,2.294407) -
悉尼歌剧院 (
-33.856553,151.214696)
Google 总部 - 加利福尼亚州旧金山:
- 文森蒂公式:
49 087.066 meters - Haversine 公式:
49 103.006 meters - 球面余弦定律:
49 103.006 meters
Google 总部 - 法国埃菲尔铁塔:
- 文森蒂公式:
8 989 724.399 meters - Haversine 公式:
8 967 042.917 meters - 球面余弦定律:
8 967 042.917 meters
Google 总部 - 悉尼歌剧院:
- 文森蒂公式:
11 939 773.640 meters - Haversine 公式:
11 952 717.240 meters - 球面余弦定律:
11 952 717.240 meters
如您所见,Haversine 公式和余弦球定律之间没有明显差异,但是与Vincenty 公式,因为它使用地球的椭球近似值而不是球形近似值。
【问题讨论】:
-
我很久以前遇到过类似的问题,在一个我从未开始的项目中..在我的笔记中我发现了这个公式:
AB=sqrt(pow(($Xb-$Xa),2)+pow(($Yb-$Ya),2)));,我从来不明白它到底是做什么的..希望可以帮助你;) -
@DaNieL:检查 theonlytheory 答案,他解释了何时应该使用您提供的公式。 =)
-
FWIW:对于那些对以英里为单位的地球半径“3956”感到困惑的人,但是根据维基百科,如果您希望使用以公里为单位的距离,这应该近似为 3959 en.wikipedia.org/wiki/Earth_radius那将是 6371。我不确定这是否会影响您的答案@Alix,但取决于您使用的单位可能会关闭,而应该以英里为单位。
-
如果您的“搜索范围”足够小(
-
顺便说一句:
orig.lat - dest.lat的坐标[-180, 180]不是有问题吗?如果orig.lat = -170和dest.lat = 170会发生什么?距离是340度?不,实际上只有 20 个。如果您使用实际的地球(地图集)坐标,您将如何解决这个问题?
标签: php mysql math geospatial geo