从给定点找到特定半径内的点的最有效方法

问题描述 投票:1回答:3

我已经在这里读了几个关于这个主题的问题+答案,但我无法理解哪个是常见的方式(如果有一个......)找到具有一定半径的“圆圈”的所有点,以给定点为中心。

特别是我找到了两种看起来最有说服力的方法:

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));

哪种查询数据库最有效?还有其他选择吗?

postgresql postgis postgresql-9.3
3个回答
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);

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

在上面的查询中,纬度和经度来自数据库和lat,long是我们想要搜索的点。

工作:它将计算数据库中所有点与搜索点之间的距离(以KM为单位),并检查距离是否小于10公里。它将返回10公里内的所有坐标。


0
投票

我不知道postgis如何做到最好,但总的来说:

根据您的数据,最好首先在方形边界框中搜索(包含搜索区域圆圈)以消除大量候选,这应该非常快,因为您可以在lon / lat上使用简单的范围运算符为此理想地索引。在第二步中使用半径搜索。

此外,如果你的极限最大分数相对较低并且你知道你有很多候选人,你可以简单地在你的圈子里用一个盒子进行第一次“乐观”尝试,如果你找到足够的分数你就完成了!

© www.soinside.com 2019 - 2024. All rights reserved.