在PostGIS中,如何找到多边形内的所有点?

19
我正在使用带有GIS扩展的PostgreSQL来存储地图数据,结合OpenLayers、GeoServer等工具。给定一个多边形(例如一个街区),我需要查找某个表中存储的所有在该多边形内部的LAT/LONG点(例如信号灯、餐厅);或者,给定一组多边形,我想要找到每个多边形内的点集(类似于GROUP BY查询,而不是遍历每个多边形)。
这些功能是否需要我进行编程,还是可以使用可用的功能(作为扩展SQL)?请详细说明。
此外,对于我所拥有的简单2D数据,我是否真正需要GIS扩展(GPL许可证存在限制),还是只需使用PostgreSQL即可?
谢谢!
3个回答

14
在PostGIS中,您可以使用边界框运算符查找候选项,这非常高效,因为它使用GiST索引。然后,如果需要严格匹配,请使用包含运算符。
类似以下内容:
SELECT 
     points,neighborhood_name from points_table,neighborhood 
WHERE 
     neighborhood_poly && points /* Uses GiST index with the polygon's bounding box */
AND 
    ST_Contains(neighborhood_poly,points); /* Uses exact matching */

关于是否需要这个,取决于您的需求。要使上述工作正常,您必须安装PostGIS和GEOS。但是,如果仅需要边界框匹配,则可以在SQL中简单编写代码而不需要PostGIS。

如果需要精确匹配,则包含算法是公开可用的,但要有效地实现它们需要编写一个库,并从SQL调用它(就像GEOS一样)。


4
“neighborhood_poly && points”检查现在已经变得多余。ST_Contains现在会自动使用索引。我不确定这个改变是从哪个版本开始的,但我认为这可能是从1.3.0版本开始(“为关系函数(除了ST_Disjoint)添加内联索引支持”)。 - jpmc26

4
我相信ST_Contains会自动重写查询以使用GiST索引的边界框,因为它指出:
“此函数调用将自动包括一个边界框比较,该比较将利用几何图形上可用的任何索引。要避免使用索引,请使用函数_ST_Contains。”

http://postgis.refractions.net/docs/ST_Contains.html


这更像是一条评论而不是一个答案。 - RickyA
1
这是根据SO常见问题解答提供的一个答案。 - IamIC
它不会“重写”。ST_Contains被重新定义为普通的SQL函数,调用SQL geomA && geomB AND _ST_Contains(geomA, geomB),其中_ST_Contains映射到编译的二进制函数,执行实际的包含检查。大多数其他关系函数也被类似地重新定义。 - jpmc26

2

ST_Contains可以解决您的问题。

SELECT  
polygon.gid, points.x, points.y
FROM
  polygons LEFT JOIN points
ON st_contains(polygon.geom, points.geom)
WHERE
  polygon.gid=your_id

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