【问题标题】:Matching closest longitude/latitude匹配最近的经度/纬度
【发布时间】:2011-02-13 02:49:07
【问题描述】:

使用 Maxmind 的 GeoIP 软件,我们可以在大约 80% 的时间内将 IP 地址的 LONG/LAT 缩小到 25 英里内的相对准确度。

现在,我们不想使用 MaxMind 提供的任何其他信息,因为功能名称(即城市)之间存在很多差异来执行查找。如果其他方法无法定位特征,我们计划尝试这样的查找,但出于性能原因,在浮点数上查找比字符串快得多。

现在,我对如何找到 Maxmind 提供的与我们的数据库最匹配的 LAT/LONG 有点一头雾水。问题是,与 Maxmind 相比,我们的数据库功能具有更高的精度,因此直接比较可能无效。如果我们尝试在查询期间对列应用 ROUND(),那显然会很慢。

给定以下数据,最快的方法是不是像

长 79.93213 纬度 39.13111

SELECT `feature_name` FROM `geo_features`
WHERE long BETWEEN 79.93 AND 79.79.94
AND lat BETWEEN 39.13 AND 39.14

任何人都可以快速获得优雅的解决方案吗?我知道在 MySQL 5 中有一些新的空间存储类型,也许任何人都可以提供一个解决方案,而不是我似乎给自己戴上的眼罩。

【问题讨论】:

  • mysql 网站上的 This post 可能会有所帮助(特别提到纬度/经度坐标)。

标签: mysql geospatial latitude-longitude


【解决方案1】:

这样做的优雅(更准确)方式(但不是很快

// Closest within radius of 25 Miles
// 37, -122 are your current coordinates
// To search by kilometers instead of miles, replace 3959 with 6371
SELECT feature_name, 
 ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) 
  * cos( radians( long ) - radians(-122) ) + sin( radians(37) ) 
  * sin( radians( lat ) ) ) ) AS distance 
FROM geo_features HAVING distance < 25 
ORDER BY distance LIMIT 1;

编辑

这是Haversine formula,用于计算与地理坐标的圆形距离。这是different platforms中这个公式的一些实现@

R = earth’s radius (mean radius = 6,371km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c
// Note that angles need to be in radians to pass to Trigonometric functions

【讨论】:

  • 我们已经实现了一个解决方案,类似于我已经发布的内容,但使用了我们 2.5M 特性数据库的一个子集,使其更易于管理。但是,由于这是我所要求的,如果您能解释一下您使用的常量,我会接受您的回答。谢谢。
  • 另外,似乎很多这些值可以预先计算。你这样做是有原因的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-10
相关资源
最近更新 更多