使用最近的纬度和经度坐标与SQLITE进行排序

Nul*_*ion 6 java sqlite android latitude-longitude

在给定初始位置的情况下,我必须获得一个SQLite SQL Sentence,用于按最近的纬度和经度坐标进行排序.

这是sqlite数据库中我的表的示例句子:

SELECT id, name, lat, lng FROM items

EXAMPLE RESULT: 1, Museu, 41375310.0, 2175970.0
Run Code Online (Sandbox Code Playgroud)

我必须使用SQLite和该表来实现这一点.我不能使用其他技术,因为这是一个我无法改变的存在SQlite数据库.

Android和SQlite是否有办法实现这一目标?我检查了很多stackoverflow帖子,我没有找到实现这一目标的方法

谢谢

Dar*_*ter 20

SELECT * AS distance FROM items ORDER BY ABS(location_lat - lat) + ABS(location_lng - lng) ASC
Run Code Online (Sandbox Code Playgroud)

这应该粗略地对MySQL中的距离项进行排序,并且应该在SQLite中工作.
如果你需要对它们进行排序,你可以尝试使用毕达哥拉斯定理(a ^ 2 + b ^ 2 = c ^ 2)来得到精确的距离.


chr*_*ris 19

Darkwater的答案几乎是正确的.要正确,您需要使用差异的平方.由于方形函数在SqLite上不可用,您需要自己乘以差值.无需计算平方根.

SELECT * AS distance FROM items ORDER BY ((location_lat-lat)*(location_lat-lat)) + ((location_lng - lng)*(location_lng - lng)) ASC
Run Code Online (Sandbox Code Playgroud)


Jes*_*más 10

克里斯提出的解决方案:

SELECT*AS FROM FROM items ORDER BY((location_lat-lat)*(location_lat-lat))+((location_lng - lng)*(location_lng - lng))ASC

当我们接近赤道时是正确的.为了让它在其他纬度上正常工作,我建议:

SELECT*AS FROM FROM items ORDER BY((location_lat-lat)*(location_lat-lat))+((location_lng - lng)*(location_lng - lng)*cos_lat_2)ASC

我们必须预先计算的地方:

cos_lat_2 = cos(location_lat * PI / 180) ^ 2
Run Code Online (Sandbox Code Playgroud)

问题:

如果我们在赤道并且我们在经度(东或西)移动一度,我们在40,000公里的圆周上移动,表示距离为40.000/360.如果我们在纬度(北或南)移动一度,我们在一个穿过两极的圆上这样做,这也涉及到40.000/360的距离(考虑到地球是一个球体).

但是,如果我们在英格兰南部,纬度为50°,我们在经度(东或西)移动一度,我们在第50个平行线上进行,其周长小于赤道.的距离是perimeter_parallel_50/360计算这个周长很简单:perimeter_parallel_50 = COS(50)*2*PI*EARHT_RADIUS = 0.64*40000公里.如果我们向南或向北移动一度,则不会看到距离的减少.我们移动的周长仍然是40,000公里的周长.

解:

由于location_lat是预先已知的值,就可以预先计算的余弦(location_lat)的值,以便它可以因此在经度和纬度的位移是相等的被用作缩放因子.而且,我们预先设定它以避免必须将它乘以两次.

注意:

这仍然是一个近似值,当移动大距离时会产生错误的结果,特别是在极点附近和穿过第180个子午线时.


Dan*_*lFo 5

如果您知道,1 度纬度约为 111111 米,1 度经度约为 111111*cos(纬度) 米,那么您可以轻松获取特定正方形内的所有地点。

SELECT * FROM items WHERE latitude BETWEEN %f AND %f AND longitude BETWEEN %f AND %f
Run Code Online (Sandbox Code Playgroud)

即使有数百万行,该查询也非常快。但不要忘记为纬度和经度创建索引:

CREATE INDEX position ON items (latitude, longitude)
Run Code Online (Sandbox Code Playgroud)

我在 Objective-C 中使用它来获取当前位置周围 3 公里范围内的所有名胜古迹:

double latDist = 1.0 / 111111.0 * 3.0;
double lonDist = 1.0 / ABS(111111.0*cos(location.coordinate.latitude)) * 3.0;

FMResultSet *results = [database executeQueryWithFormat:@"SELECT * FROM items WHERE latitude BETWEEN %f AND %f AND longitude BETWEEN %f AND %f", location.coordinate.latitude - latDist, location.coordinate.latitude + latDist, location.coordinate.longitude - lonDist, location.coordinate.longitude + lonDist];
Run Code Online (Sandbox Code Playgroud)

您现在可以计算准确的距离并对结果进行排序...