使用 Maxmind 的 GeoIP 软件,我们可以在大约 80% 的时间内将 IP 地址的 LONG/LAT 缩小到 25 英里范围内的相对精度。
现在,我们不想使用 MaxMind 提供的任何其他信息,因为特征名称(即城市)之间存在很多差异来执行查找。如果其他方法无法找到某个特征,我们计划尝试进行此类查找,但出于性能原因,查找 float 比查找字符串快得多。
现在,我对如何找到 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 中有一些新的空间存储类型,也许任何人都可以提供超出我似乎对自己提出的盲点的解决方案。
最佳答案
执行此操作的优雅(更准确)方式(但速度不快)
// 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
关于mysql - 匹配最近的经度/纬度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4982125/