mysql - 匹配最近的经度/纬度

标签 mysql geospatial latitude-longitude

使用 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/

相关文章:

java - 使用谷歌地图坐标计算欧几里德距离

java - java中如何获取 map 上的纬度和经度

mysql - 如何在update中做出select语句?

MySQL 将 UTF-8 更改为 ASCII-8BIT

php - 为什么在MySQL中存储的日期都是错误的?

python - 如何根据该地区的人口密度计算 map 搜索的动态默认半径?

R:map2SpatialPolygons 中的 ID

javascript - 我们如何将纬度和经度转换为网站中的地址?

php - 用 phpunit 模拟 PDO

javascript - 从 geojson 动态创建的 svg 路径不会渲染到 ref