从给定点开始,在特定半径范围内查找点的最有效方法

6

我在SO上读了几个关于这个主题的问题和答案,但我不明白哪种方法是常见的(如果有的话...)以找到以给定点为中心,半径为特定值的“圆”内的所有点。

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

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

什么是查询数据库的最有效方式?还有其他可考虑的选项吗?

3个回答

8
创建缓冲区以查找点是明显不可取的,因为(1)创建表示缓冲区的几何图形的开销很大,(2)点在多边形内的计算比简单距离计算效率低得多。
显然,您正在使用(经度,纬度)数据,因此应将其转换为具有与距离10,000相同的度量单位的适当笛卡尔坐标系。如果该距离以米为单位,则还可以将表中的点从geography投影并直接计算(long,lat)坐标。由于您只想识别指定距离内的点,因此可以使用ST_DWithin()函数在球形上进行计算以提高速度(当在非常高的纬度或非常长的距离时不要这样做):
SELECT id, point 
FROM my_table 
WHERE ST_DWithin(point::geography,
                 ST_GeogFromText('POINT(-116.768347 33.911404)'),
                 10000, false);

2
我使用了以下查询。
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则是我们想要搜索的点。

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


2
我不知道postgis如何最好地处理,但一般而言: 根据您的数据,首先在一个正方形的边界框内进行搜索(该边界框包含搜索区域圆),以便消除很多候选项。这应该非常快速,因为您可以对经度/纬度使用简单的范围运算符来进行索引。 第二步是使用半径进行搜索。 如果您的限制最大点数相对较低并且您知道有大量候选项,则可以在圆内部使用矩形进行第一次“乐观尝试”,如果找到足够的点则完成!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接