1. 引言
在空间数据处理中,矢量数据的裁剪与合并拼接是两类高频且基础的操作。裁剪通常指用一个面(如行政区边界)去切割另一个面或线,得到相交部分;合并拼接则指把多个相邻或重叠的几何对象融合成一个整体,或把分散的要素拼接为连续图层。本文以 PostGIS 为例,结合 POLYGON 等几何类型,梳理常用函数、SQL 写法和注意事项。
2. 矢量数据裁剪
矢量裁剪的核心是求两个几何对象的交集,常用函数包括 ST_Intersection、ST_ClipByBox2D 和 ST_Intersects 过滤。
2.1 ST_Intersection 裁剪
ST_Intersection 返回两个几何对象的公共部分,是最通用的裁剪方式。例如用一个矩形窗口裁剪一个多边形,得到落在窗口内的部分。
-- 用矩形窗口裁剪多边形 SELECT ST_Intersection( geom, ST_MakeEnvelope(112.66592, 26.10227, 112.75225, 26.24774, 4326) ) AS clipped_geom FROM polygon_table;2.2 ST_ClipByBox2D 快速裁剪
当裁剪窗口是轴对齐矩形时,ST_ClipByBox2D 比 ST_Intersection 更快,因为它只做矩形裁剪,不处理任意多边形相交的复杂情况。
-- 使用边界框快速裁剪 SELECT ST_ClipByBox2D( geom, ST_MakeEnvelope(112.66592, 26.10227, 112.75225, 26.24774, 4326) ) AS clipped_geom FROM polygon_table;2.3 结合 ST_Intersects 过滤
大批量裁剪时,先用 ST_Intersects 做空间索引过滤,只对真正相交的要素执行 ST_Intersection,可显著提升性能。
SELECT a.id, ST_Intersection(a.geom, b.geom) AS clipped_geom FROM target_table a JOIN clip_table b ON ST_Intersects(a.geom, b.geom);2.4 实战:按 PID 裁剪并更新数据库
实际业务中,表里往往存有多条多边形记录(一条数据就是一个多边形)。下面演示:查询 PID=2 的所有多边形,与给定矩形面做裁剪,去掉矩形内的部分,并把结果更新回数据库。
-- 1. 查询 PID=2 的所有多边形,与矩形面做差集,去掉矩形内的部分 WITH rect AS ( SELECT ST_GeomFromText( 'POLYGON((112.66592 26.24774, 112.75225 26.24774, 112.75225 26.10227, 112.66592 26.10227, 112.66592 26.24774))', 4326 ) AS geom ), clipped AS ( SELECT id, ST_Difference(p.geom, r.geom) AS new_geom FROM polygon_table p CROSS JOIN rect r WHERE p.pid = 2 ) -- 2. 更新数据库:用裁剪后的几何覆盖原几何 UPDATE polygon_table SET geom = c.new_geom FROM clipped c WHERE polygon_table.id = c.id;说明:ST_Difference 返回第一个几何减去与第二个几何相交部分后的结果,正好满足「去掉矩形内的部分」的需求。若某个多边形完全落在矩形内,裁剪后几何可能为空,更新前可用 ST_IsEmpty 判断,按业务决定是保留空几何还是删除该记录。
3. 矢量数据合并拼接
合并拼接通常指把多个几何对象融合为一个整体,或把相邻要素拼接成连续图层。常用函数包括 ST_Union、ST_Collect 和 ST_MakeValid。
3.1 ST_Union 融合
ST_Union 会把多个几何对象融合为一个,消除重叠部分并合并边界,适合把相邻多边形拼接成完整区域。
-- 把同一区域的多块多边形融合为一个整体 SELECT ST_Union(geom) AS merged_geom FROM parcels WHERE district_id = 101;3.2 ST_Collect 聚合拼接
ST_Collect 把多个几何对象收集为一个集合(MultiPolygon 或 GeometryCollection),不做边界融合,适合保留原始要素边界的拼接场景。
-- 收集多个多边形为一个 MultiPolygon SELECT ST_Collect(geom) AS collected_geom FROM parcels WHERE district_id = 101;3.3 ST_MakeValid 修复后合并
实际数据常存在自相交、重复点等拓扑错误,直接 ST_Union 可能失败。先用 ST_MakeValid 修复,再合并更稳妥。
-- 修复无效几何后再融合 SELECT ST_Union(ST_MakeValid(geom)) AS merged_geom FROM parcels WHERE district_id = 101;4. 完整示例:裁剪并拼接
下面用一个完整示例演示:先按行政区边界裁剪原始多边形,再把裁剪结果拼接为一个整体。
-- 1. 裁剪:只保留落在目标区域内的部分 WITH clipped AS ( SELECT ST_Intersection(a.geom, b.geom) AS geom FROM raw_polygon a JOIN boundary b ON ST_Intersects(a.geom, b.geom) WHERE b.name = '目标区域' ) -- 2. 拼接:把裁剪结果融合为一个整体 SELECT ST_Union(geom) AS final_geom FROM clipped;5. 注意事项
- 坐标系一致:裁剪和合并前,务必确保参与运算的几何对象使用相同坐标系(SRID),否则结果可能错位。
- 拓扑有效性:合并前建议先执行 ST_MakeValid,避免自相交、重复点等错误导致函数失败或结果异常。
- 性能优化:大批量裁剪时,先建空间索引并用 ST_Intersects 过滤,再执行 ST_Intersection,可大幅减少计算量。
- 结果验证:合并后可用 ST_IsValid 和 ST_Area 检查结果是否有效、面积是否符合预期。
6. 总结
PostGIS 中矢量数据的裁剪与合并拼接,核心是掌握 ST_Intersection、ST_ClipByBox2D、ST_Union、ST_Collect 等函数的适用场景。裁剪时优先用空间索引过滤提升性能,合并前先修复拓扑错误保证结果有效。结合坐标系统一和结果验证,可以稳妥地完成从原始多边形到目标区域的裁剪与拼接。