如何使用PostGIS提取多面体内的内环(孔洞)?
提取PostGIS中带孔洞MultiPolygon的外环与内环
问题背景
我数据库中的土壤数据由带孔洞的MultiPolygon类型构成,已通过以下SQL筛选出纽约周边区域的相关多边形,但尝试用ST_Dump、ST_DumpRings、ST_InteriorRingN提取内外环时失败,需要正确的提取方法。
原筛选查询:
WITH point AS ( SELECT ST_SetSRID(ST_MakePoint(-74.0060, 40.7128), 4326) AS geom ), buffered_point AS ( SELECT ST_Buffer(geom, 1.0) AS geom FROM point ) SELECT s.geom AS geom FROM soil s JOIN buffered_point bp ON ST_Intersects(s.geom, bp.geom);
核心问题分析
直接在MultiPolygon上调用ST_DumpRings会失败,因为该函数仅支持单个Polygon类型。必须先将MultiPolygon拆解为独立的Polygon,再提取每个多边形的环。
完整解决方案代码
WITH point AS ( SELECT ST_SetSRID(ST_MakePoint(-74.0060, 40.7128), 4326) AS geom ), buffered_point AS ( SELECT ST_Buffer(geom, 1.0) AS geom FROM point ), -- 第一步:将MultiPolygon拆解为单个Polygon dumped_polygons AS ( SELECT (ST_Dump(s.geom)).geom AS poly_geom FROM soil s JOIN buffered_point bp ON ST_Intersects(s.geom, bp.geom) ), -- 第二步:提取每个Polygon的所有环(外环+内环) dumped_rings AS ( SELECT (ST_DumpRings(poly_geom)).path AS ring_path, (ST_DumpRings(poly_geom)).geom AS ring_geom FROM dumped_polygons ) -- 筛选并区分外环与内环 SELECT CASE WHEN ring_path[2] = 0 THEN '外环' ELSE '内环' || ring_path[2]::TEXT END AS ring_type, ring_geom FROM dumped_rings;
代码说明
- ST_Dump:将
MultiPolygon拆分为多个独立的Polygon,返回的geom为单个多边形要素。 - ST_DumpRings:对每个
Polygon提取所有环,返回的path数组含义:path[1]:原MultiPolygon中对应多边形的索引(从1开始)path[2]:对应多边形中环的索引(0为外环,1、2...依次为内环)
- 环类型区分:通过
path[2]的值快速识别外环/内环,方便后续业务处理。
简化:仅提取内环
如果只需要所有内环,可在最后一步添加过滤条件:
SELECT ring_geom AS interior_ring FROM dumped_rings WHERE ring_path[2] > 0;
内容的提问来源于stack exchange,提问作者IvoRum
相关产品推荐
相关产品推荐

