ST_MakePolygon — 从外壳和可选的孔列表创建多边形。
geometry ST_MakePolygon(
geometry 线串)
;
geometry ST_MakePolygon(
geometry 外线串, geometry[] 内部线串)
;
根据给定的外壳和可选的孔数组创建多边形。输入的几何图形必须是闭合的线串(环)。
变体 1: 接受一个外壳线串。
变体 2: 接受一个外壳线串和一个内部(孔)线串数组。可以使用 PostgreSQL 的 array_agg()、ARRAY[] 或 ARRAY() 构造函数构造几何数组。
此函数不接受 MultiLineStrings。 使用 ST_LineMerge 生成 LineString,或使用 ST_Dump 提取 LineStrings。 |
此函数支持 3d,不会删除 z 索引。
从 2D 线串创建多边形。
SELECT ST_MakePolygon( ST_GeomFromText('LINESTRING(75 29,77 29,77 29, 75 29)'));
从开放的线串创建多边形,使用 ST_StartPoint 和 ST_AddPoint 来闭合它。
SELECT ST_MakePolygon( ST_AddPoint(foo.open_line, ST_StartPoint(foo.open_line)) ) FROM ( SELECT ST_GeomFromText('LINESTRING(75 29,77 29,77 29, 75 29)') As open_line) As foo;
从 3D 线串创建多边形
SELECT ST_AsEWKT( ST_MakePolygon( 'LINESTRING(75.15 29.53 1,77 29 1,77.6 29.5 1, 75.15 29.53 1)')); st_asewkt ----------- POLYGON((75.15 29.53 1,77 29 1,77.6 29.5 1,75.15 29.53 1))
从带度量的线串创建多边形
SELECT ST_AsEWKT( ST_MakePolygon( 'LINESTRINGM(75.15 29.53 1,77 29 1,77.6 29.5 2, 75.15 29.53 2)' )); st_asewkt ---------- POLYGONM((75.15 29.53 1,77 29 1,77.6 29.5 2,75.15 29.53 2))
创建一个带有额外孔的甜甜圈多边形
SELECT ST_MakePolygon( ST_ExteriorRing( ST_Buffer(ring.line,10)), ARRAY[ ST_Translate(ring.line, 1, 1), ST_ExteriorRing(ST_Buffer(ST_Point(20,20),1)) ] ) FROM (SELECT ST_ExteriorRing( ST_Buffer(ST_Point(10,10),10,10)) AS line ) AS ring;
创建一组省界,其中孔代表湖泊。输入是一个省多边形/多多边形表和一个水线串表。构成湖泊的线是通过使用 ST_IsClosed 确定的。省线是通过使用 ST_Boundary 提取的。根据 ST_MakePolygon
的要求,边界通过使用 ST_LineMerge 被强制为一个单一的线串。(然而,请注意,如果一个省有多个区域或有岛屿,这将产生一个无效的多边形。)使用 LEFT JOIN 确保包含所有省份,即使它们没有湖泊。
使用 CASE 构造是因为将 null 数组传递给 ST_MakePolygon 会导致返回 NULL 值。 |
SELECT p.gid, p.province_name, CASE WHEN array_agg(w.geom) IS NULL THEN p.geom ELSE ST_MakePolygon( ST_LineMerge(ST_Boundary(p.geom)), array_agg(w.geom)) END FROM provinces p LEFT JOIN waterlines w ON (ST_Within(w.geom, p.geom) AND ST_IsClosed(w.geom)) GROUP BY p.gid, p.province_name, p.geom;
另一种技术是利用相关子查询和 ARRAY() 构造函数,该构造函数将行集转换为数组。
SELECT p.gid, p.province_name, CASE WHEN EXISTS( SELECT w.geom FROM waterlines w WHERE ST_Within(w.geom, p.geom) AND ST_IsClosed(w.geom)) THEN ST_MakePolygon( ST_LineMerge(ST_Boundary(p.geom)), ARRAY( SELECT w.geom FROM waterlines w WHERE ST_Within(w.geom, p.geom) AND ST_IsClosed(w.geom))) ELSE p.geom END AS geom FROM provinces p;