Joh*_*ght 1 mysql geospatial latitude-longitude
使用Maxmind的GeoIP软件,我们可以在80%的时间内将IP地址的LONG/LAT缩小到25英里内的相对精度.
现在,我们不想使用MaxMind提供的任何其他信息,因为要素名称(即城市)之间存在很多差异,无法进行查找.如果其他方法无法找到某个功能,我们计划尝试这样的查找,但出于性能原因,查看浮点数比字符串快得多.
现在,我对如何找到Maxmind给我们的数据库中最接近的匹配LAT/LONG有点无能为力.问题是,与Maxmind相比,我们的数据库功能具有更高的精度,因此直接比较可能无效.如果我们在查询期间尝试将ROUND()应用于列,那显然会非常慢.
鉴于以下数据,最快的方式就是这样
LONG 79.93213 LAT 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
Run Code Online (Sandbox Code Playgroud)
任何优雅的解决方案都可以快速发展吗?我知道在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;
Run Code Online (Sandbox Code Playgroud)
编辑
这是从地理坐标计算圆距离的Haversine公式.以下是此公式在不同平台中的一些实现
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
Run Code Online (Sandbox Code Playgroud)