我使用的是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
答案 0 :(得分:4)
这里给出了如何在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;
其中newLon newLat是查询点坐标。
此查询将利用gist索引(http://workshops.boundlessgeo.com/postgis-intro/knn.html)的kNN功能。
返回的距离仍然是度数,而不是米(投影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/
EDIT。这涵盖了一点的必要步骤。对于一组点:
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;