使用postgis数据库进行多边形裁切线

背景:有一份polyline的基础数据,有一个多边形,求出多边形内的所有polyline

PostGIS参考手册: http://postgis.net/docs/reference.html

1、polyline数据表、qgis可视化


2、polygon数据表、qgis可视化


3、使用ST_Covers,求出所有完全包含在面内的线,有一部分线是被多边形穿过了,此部分线是没有在covers里的

sql 复制代码
SELECT f.geom FROM "freeway" f LEFT JOIN area r ON 1 = 1 WHERE ST_Covers (r.geom, f.geom) = 't'

4、获取多边形边界(ST_Boundary)和polyline的相交的线(ST_Intersects),并用边界分割(ST_Split)这些线,此时结果为GEOMETRYCOLLECTION,需要提取(ST_Dump)几何图形组件的集合(GEOMETRYCOLLECTION)中的图形,涉及到的函数如下:

ST_Boundary(geometry geomA)
ST_Intersects(geometry geomA , geometry geomB )
ST_Split(geometry input , geometry blade)
ST_Dump(geometry geom)

sql 复制代码
SELECT
  (ST_Dump (ST_Split (l.geom, ST_Boundary (rr.geom)))).geom 
FROM
  (
    SELECT
      f.geom 
    FROM
      "freeway" f
      LEFT JOIN area r ON 1 = 1 
    WHERE
  ST_Intersects (ST_Boundary (r.geom), f.geom) = 't') l
  LEFT JOIN area rr ON 1 =1

5、第4步骤分割完成后,一部分线在面内,一部分线在面外,此时:

面内的线与面还有交点,所以ST_Covers不可用

面外的线与面还有交点,所以ST_Intersects不可用

思路为:判断所有线的中心点,中心点在面内,则线段被面完全包含

sql 复制代码
SELECT f.geom FROM res_3 f LEFT JOIN area r ON 1 = 1 WHERE
ST_Covers (r.geom, ST_Centroid (f.geom)) = 't';

6、把1的查询结果和5的结果union一下,最终结果如下