3

我有一个充满地图 Locations 的数据库(Latitude, Longitude),有没有办法可以执行 SQL 查询来返回某个位置周围的所有点?

现在我基本上抓取数据库中的所有内容并循环遍历每一个并使用检查距离

Location.distanceBetween(startPoint.latitude, startPoint.longitude,endPoint.latitude,endPoint.longitude, results);

并保留在设定距离内但可能有很多点需要循环的项目。

那么有没有办法在 SQL 语句中做到这一点?

4

3 回答 3

2

我有一个充满地图位置(纬度、经度)的数据库,有没有办法可以执行 SQL 查询来返回某个位置周围的所有点?

您可以轻松检查正方形区域。

使用非常简化的纬度/经度坐标表示您在 [25.86, 57.03] 并且您想要“邻居”(+/- .05)中的所有内容,您可以使用如下查询:

SELECT * FROM Coords WHERE (latitude BETWEEN 25.81 AND 25.91) AND (longitude BETWEEN 56.98 AND 57.08);
于 2013-04-19T17:28:46.770 回答
2

您可以使用 WHERE 子句表达式过滤与原点 (x0, y0) 的角距离 r。由于 SQLite 没有平方根函数,因此您必须使用平方距离:

SELECT ... FROM ...
    WHERE (Latitude-x0)*(Latitude-x0) + (Longitude-y0)*(Longitude-y0) < r*r;

唯一不能正常工作的地方是靠近两极或本初子午线。它也是球体的平面近似,因此它仅适用于r非常小的值。最后,它平等地缩放纬度和经度,因此所选区域看起来越来越椭圆,原点离赤道越远。

您必须将线性距离(例如,“30 米内”)转换为纬度/经度差异。这是一个相当复杂的主题,因为地球不是一个完美的球体。但是,对于粗略的计算,您可以使用 1 海里 = 1852 米 = 赤道经度的 1 角分的近似值。由于随着纬度远离赤道,经线越来越靠近,因此您需要使用一些三角函数来确定r在给定纬度使用的值。有关此问题的更多信息,请参阅此线程线程,或在网上搜索“将米转换为纬度经度”

于 2013-04-19T17:35:24.030 回答
2

您还可以使用SQLite R*Tree扩展。

R-Tree 是一种特殊的索引,专为进行范围查询而设计。R-Trees 最常用于地理空间系统,其中每个条目都是一个具有最小和最大 X 和 Y 坐标的矩形。

SQLite R*Tree 模块的源代码包含在 SQLite3 合并中,但默认情况下是禁用的。要启用 R*Tree 模块,只需使用定义的 SQLITE_ENABLE_RTREE C 预处理器宏进行编译。

于 2013-04-19T17:38:22.300 回答