PostGIS:如何找到离给定点集最近的N个点集?

6
我正在使用PostGIS/Rails,有一组带有地理位置的点。
class DataSet < ActiveRecord::Base  # these are the sets containing the points
  has_many :raw_data
  # attributes: id , name
end

class RawData < ActiveRecord::Base  # these are the data points
  belongs_to :data_set
  # attributes: id, location which is "Point(lon,lat)"
end

对于给定的点集,我需要找到N个最接近的点集和它们之间的距离;
或者:
对于给定的最大距离和点集,我需要找到N个最接近的点集。
使用PostGIS,最好的方法是什么?
我的版本是PostgreSQL 9.3.4和PostGIS 2.1.2。

我相信我可以回答这个问题,但是你能否进一步解释一下你所说的“一组点”的含义——在问题的背景下,这些点是如何定义的? - John Powell
see comments in the code - Tilo
好的,进一步澄清,在你对 Alexandros 的评论中,你说要在两组中找到最近的点,然而在原始问题中你说要找到离一个点最近的 N 个组。很抱歉提了这么多问题,但在 Postgis 中有各种做这些事情的方法,但性能也不同。 - John Powell
1
PostgreSQL的版本是多少? - Jakub Kania
PostgerSQL 9.3.4带有PostGIS 2.1.2 - Tilo
我正在处理“点集”,例如包含点的多个数据库记录,每个记录都有一个set_id,表示成员资格。有不同的方法来制定此查询。我猜这个查询也可以工作: “找到N个最接近的点,其中set_id与我的参考点不同。”=>唯一的set-id - Tilo
1个回答

7

如何在PostGIS中找到N个最近邻居的答案在这里给出:

Postgis SQL for nearest neighbors

总结答案如下:

您需要为您的点创建一个几何对象。如果您使用纬度,经度,则需要使用4326。

UPDATE season SET geom = ST_PointFromText ('POINT(' || longitude || ' ' || latitude || ')' , 4326 ) ;

然后你需要在geom字段上创建一个索引。
CREATE INDEX [indexname] ON [tablename] USING GIST ( [geometryfield] ); 

然后你会得到kNN邻居:
SELECT *,ST_Distance(geom,'SRID=4326;POINT(newLon newLat)'::geometry) 
FROM yourDbTable
ORDER BY
yourDbTable.geom <->'SRID=4326;POINT(newLon newLat)'::geometry
LIMIT 10;

新经度和新纬度是查询点的坐标。

此查询将利用gist索引的kNN功能(http://workshops.boundlessgeo.com/postgis-intro/knn.html)。

然而,返回的距离将以度为单位,而不是米(投影4326使用度)。

要修复这个问题:

SELECT *,ST_Distance(geography(geom),ST_GeographyFromText('POINT(newLon newLat)') 
FROM yourDbTable
ORDER BY
yourDbTable.geom <->'SRID=4326;POINT(newLon newLat)'::geometry
LIMIT 10;

当您计算ST_distance时,请使用地理类型。这里的距离始终以米为单位:http://workshops.boundlessgeo.com/postgis-intro/geography.html。所有这些功能可能需要较新的Postgis版本(2.0+)。不过我不确定。请参考https://gis.stackexchange.com/questions/91765/improve-speed-of-postgis-nearest-neighbor-query/。编辑。这涵盖了一个点所需的必要步骤。对于一组点:
SELECT n1.*,n2.*, ST_Distance(n1.geom,n2.geom) 
FROM yourDbTable n1, yourDbTable n2
WHERE n1.setId=1 AND n1.setId=2 //your condition here for the separate sets
AND n1.id<>n2.id // in case the same object belong to 2 sets
ORDER BY n1.geom <->n2.geom
LIMIT 20;

1
谢谢!我已经在我的PostGIS数据库中有几何对象了。 你列出的SQL查询是在比较点,而不是点集 - 我想知道是否有一种查询可以找到两个集合中最近的点。 - Tilo

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