ST_MakePolygon — 外殻と任意の穴リストとでポリゴンまたは曲線ポリゴンを生成します。
geometry ST_MakePolygon(geometry linestring);
geometry ST_MakePolygon(geometry outerlinestring, geometry[] interiorlinestrings);
外殻と任意の穴配列とでポリゴンまたは曲線ポリゴンを生成します。入力ジオメトリーは閉じたLINESTRING、CIRCULARSTRING、COMPOUNDCURVE、NURBSCURVEでなければなりません。いずれかのリングが曲線の場合には結果ジオメトリーはCURVEPOLYGONになります。
形式1: 一つの外側リングを受け付けます。
形式 2: 外側リングと内側リング (穴)の配列を受け付けます。ジオメトリーの配列はPostgreSQLのarray_agg()、ARRAY[]、ARRAY()のいずれかで構築できます。
|
|
|
この関数はマルチラインストリングを受け付けません。ラインストリングの生成にはST_LineMergeを使用します。また、ラインストリングを抽出するにはST_Dumpを使用します。 |
この関数は3次元に対応し、Z値を削除しません。
Enhanced: 3.7.0 - 曲線の入力リングへの対応が導入されました。
Single input variant.
2次元ラインストリングからポリゴンを生成します。
SELECT ST_MakePolygon('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 'LINESTRING(75 29,77 29,77 29,75 29)'::geometry As open_line) As foo;
3次元ラインストリングからポリゴンを生成します。
SELECT ST_MakePolygon('LINESTRING(75.15 29.53 1,77 29 1,77.6 29.5 1,75.15 29.53 1)');
POLYGON((75.15 29.53 1,77 29 1,77.6 29.5 1,75.15 29.53 1))
M値を持つラインストリングからポリゴンを生成します。
SELECT ST_MakePolygon('LINESTRINGM(75.15 29.53 1,77 29 1,77.6 29.5 2, 75.15 29.53 2)');
POLYGONM((75.15 29.53 1,77 29 1,77.6 29.5 2,75.15 29.53 2))
CURVEPOLYGONからCIRCULARSTRINGの外側リングを生成します。
SELECT ST_MakePolygon('CIRCULARSTRING(0 0,1 1,2 0,1 -1,0 0)');
CURVEPOLYGON(CIRCULARSTRING(0 0,1 1,2 0,1 -1,0 0))
Outer shell with inner holes variant.
余分な穴を持つドーナツポリゴンを生成します。
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で単一のLINESTRINGに強制します(県が二つ以上の領域を持つか島を持つ場合には、不正なポリゴンを生成します)。LEFT JOINを使って、湖の無い県を含む全ての県が返ることを保証しています。
|
|
|
NULL配列をST_MakePolygonに渡すとNULLが返るので、CASE式を使っています。 |
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 AS geom
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;