mysql - 动态确定/创建地理围栏/边界框
问题描述
我有一个纬度/经度的 MySQL 表(想想学校校园或购物中心)。
每个位置(学校/商场)可以在表中存储数十个 GPS 位置。所有位置都是使用移动应用程序捕获的,这些位置可以代表从入口到特定房间(会议)到易于识别的位置(如电梯)的所有位置。
用户提交了一个请求(即,6 号岛的看门人清理),我需要确保提交的请求(清理)在通过找到该位置彼此相距最远的 4 个点而建立的地理围栏内。
目前我们正在使用 Haversine 搜索,但我们希望将其转换为封闭系统。我们不能做的是建立一个单独的地理围栏表。
我用谷歌搜索并没有找到任何东西(我可能没有使用正确的术语)。如何构建该查询?
解决方案
在近似的第一级,您可以扫描边界框。
假设您有一个包含, ,列的loc
表格。并说你的候选点有位置,。loc_id
lat
lng
@ptLat
@ptLng
计算每个位置的边界框。这适用于纬度和经度,除非您在北极或南极几度范围内或接近 180° 经度。
SELECT loc_id, MAX(lat) north, MAX(lng) east, MIN(lat) south, MIN(lng) west
FROM loc
GROUP BY loc_id
如果你有一个索引,这很快(loc_id, lat, lng)
。它也很快,因为您可以避免大圆计算中的所有三角函数。
一旦你有了边界框,你就可以决定你的候选点是否在它里面。
然后你可以做
SELECT loc_id
FROM (
SELECT loc_id, MAX(lat) north, MAX(lng) east, MIN(lat) south, MIN(lng) west
FROM loc
GROUP BY loc_id
) box
JOIN ( SELECT @ptLat ptLat, @ptLon, ptLon ) pt
ON ptLat <= north
AND ptLat >= south
AND ptLon <= east
AHD ptLon >= west
这将为您提供与候选点匹配的 loc_id 值的结果集。
如果您的 lat,lng 数据很混乱——如果它有很多异常点——这将不会很好地工作。它对错误很敏感。例如,如果冰岛的某个位置附近有很多点,但格陵兰岛的一个点编码错误,则边界框将大得离谱。
如果它对您来说不够准确,您应该研究凸包算法。但这很可能会将您带到纯 SQL 之外。
推荐阅读
- ios - RealmSwift 线性迁移
- ios - swift - 对来自 API 的 tableview 数据进行分页
- matlab - MatLab 静默安装激活网络许可证失败
- scipy - 有没有办法将 scipy.optimize.fsolve 与 jit_integrand_function 和 scipy.integrate.quad 一起使用?
- ruby - 将字符串转换为整数列表
- python - 使用 Python 的 Firefox/TOR 浏览器自动化和带宽测量?
- flutter - Flutter / Dart List 将条目加倍“uid=10099((com.example.test) 1.ui 相同的 8 行”
- javascript - 是否可以映射包含在 useState 中的数组,然后使用 setter 函数更新状态 - 反应清单
- javascript - 如何在 pdf 中保存图形而不在 div 中显示?-谷歌图表
- python - 如何在 WSL Ubuntu 上的 venv 中使用 pip3,而不会出现 errno 18 问题