Sch*_*lle 22 sql postgresql postgis
我试图解决使用PostGIS找到n个最近邻居的问题:
初始点:
问题:在由id(geoname.geonameid)表示的表geoname中找到给定Point的n个(例如5个)最近邻居.
可能的方法:
受http://www.bostongis.com/PrinterFriendly.aspx?content_name=postgis_nearest_neighbor的启发,我尝试了以下查询:
"SELECT start.asciiname, ende.asciiname, distance_sphere(start.geom, ende.geom) as distance " +
"FROM geoname As start, geoname As ende WHERE start.geonameid = 2950159 AND start.geonameid <> ende.geonameid " +
"AND ST_DWithin(start.geom, ende.geom, 300) order by distance limit 5"
Run Code Online (Sandbox Code Playgroud)
处理时间:约60秒
还尝试了一种基于EXPAND的方法:
"SELECT start.asciiname, ende.asciiname, distance_sphere(start.geom, ende.geom) as distance " +
"FROM geoname As start, geoname As ende WHERE start.geonameid = 2950159 AND start.geonameid <> ende.geonameid AND expand(start.geom, 300) && ende.geom " +
"order by distance limit 5"
Run Code Online (Sandbox Code Playgroud)
处理时间:约120s
预期的应用程序是某种自动完成.因此,任何超过> 1s的方法都不适用.通常可以使用PostGIS实现<1s的响应时间吗?
小智 48
现在,自PostGIS 2.0以来,可以获得几何类型的KNN索引.这将为您提供最接近的5条记录,无视离"您的位置......"的距离.
SELECT *
FROM your_table
ORDER BY your_table.geom <-> "your location..."
LIMIT 5;
Run Code Online (Sandbox Code Playgroud)
请参阅PostgreSQL手册中的<->
operator .
正如我认为你在列表中回答的那样,单位是度数,因此你几乎在st_dwithin中以300度搜索整个世界.
如果您的数据集很大,那么您无法在投影的基于米的投影中工作(更快且更少CPU计算),您应该考虑使用地理数据类型.然后你可以使用st_dwithin和米.
你应该更快地创建一个新表,其中几何转换为地理.
但是要测试它你可以在飞行中投射:
SELECT start.asciiname, ende.asciiname,
ST_Distance(start.geom::geography, ende.geom::geography) as distance
FROM geoname As start, geoname As ende
WHERE start.geonameid = 2950159 AND start.geonameid <> ende.geonameid AND
ST_DWithin(start.geom::geography, ende.geom::geography, 300)
order by distance
limit 5;
Run Code Online (Sandbox Code Playgroud)
HTH尼克拉斯