关于这个主题,我在这里读了几个问题+答案,但是我无法理解哪个是常见的方式(如果有一个......)找到所有的点在一个“圆圈”中有一个某个半径,以给定点为中心。
特别是我找到了两种看起来最有说服力的方法:
select id, point
from my_table
where st_Distance(point, st_PointFromText('POINT(-116.768347 33.911404)', 4326)) < 10000;
和
select id, point
from my_table
where st_Within(point, st_Buffer(st_PointFromText('POINT(-116.768347 33.911404)', 4326), 10000));
哪种查询数据库最有效?还有其他选择吗?
答案 0 :(得分:2)
创建缓冲区以找到点是一个明确的禁忌,因为(1)创建表示缓冲区的几何体的开销,以及(2)多边形点计算的效率远低于简单点距离计算。
您显然正在处理(经度,纬度)数据,因此您应该将其转换为适当的笛卡尔坐标系,该坐标系具有与10,000距离相同的度量单位。如果该距离以米为单位,那么您也可以将该点从表格转换为geography
并直接计算(长,纬度)坐标。由于您只想识别指定距离内的点,因此您可以在球体上使用ST_DWithin()
function计算增加的速度(在非常高的纬度或非常长的距离时不要这样做):
SELECT id, point
FROM my_table
WHERE ST_DWithin(point::geography,
ST_GeogFromText('POINT(-116.768347 33.911404)'),
10000, false);
答案 1 :(得分:0)
我使用了以下查询
SELECT *, ACOS(SIN(latitude) * SIN(Lat)) + COS(latitude) * COS(Lat) * COS(longitude) - (Long)) ) * 6380 AS distance FROM Table_tab WHERE ACOS( SIN(latitude) * SIN(Lat) + COS(latitude) * COS(Lat) * COS(longitude) - Long )) * 6380 < 10
在上面的查询中,纬度和经度来自数据库和纬度,long是我们要搜索的点。
工作:它将计算数据库中所有点与搜索点之间的距离(以KM为单位),并检查距离是否小于10公里。它将返回10公里内的所有坐标。
答案 2 :(得分:0)
我不知道postgis如何做到最好,但总的来说:
根据您的数据,最好先在方形的边界框(其中包含搜索区域的圆圈)中进行搜索,以消除大量候选对象,这应该非常快可以在lon / lat上使用简单的范围运算符,为此,它们应该正确地索引。 在第二步中,使用半径进行搜索。
此外,如果您的极限最大点数相对较低,并且您知道有很多候选人,那么您可以对圈子内的方框进行第一次“乐观”尝试,如果发现足够的点数就可以完成!