問題設定
任意のPolygonについて外周の線分集合がほしいこと、あると思います。
少なくとも僕はありました。
どういうことかというと、例えば次の図1のような(0.0, 0.0), (1.0, 0.0), (0.5, 1.0)からなる正三角形があったときに、それぞれの辺に分解したいということです。
図1 正三角形
使う関数
こういう関数があるもの思い込んでいましたが、リファレンスを見渡してもどうも見当たりません。
で、下記関数の組み合わせでなんとかなるようです。
- ST_ExteriorRing
- ST_PointN
- ST_NPoints
- ST_MakeLine
クエリ例
正三角形を用意します。
CREATE TABLE triangle AS
SELECT ST_GeomFromText('POLYGON((0.0 0.0,1.0 0.0,0.5 1.0,0.0 0.0))') AS geom;
で次のようなクエリで3つのLINESTRINGに分解できます。
SELECT ST_MakeLine(sp, ep)
FROM (
SELECT
ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) AS sp,
ST_PointN(geom, generate_series(2, ST_NPoints(geom))) AS ep
FROM (
SELECT
ST_ExteriorRing(geom) AS geom
FROM
triangle
) AS lines
) AS spep;
解説
内側のクエリから。
ST_ExteriorRing(geom) AS geom
まぁ外環のLINESTRING取ってきてるだけですね。
で、
ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) AS sp,
ST_PointN(geom, generate_series(2, ST_NPoints(geom))) AS ep
ここがミソ。generate_seriesで1〜最後尾1個手前のポイント
と2〜最後尾のポイント
を作っています。
各レコードは
(1st Point, 2nd Point)
(2nd Point, 3rd Point)
(3rd Point, 4th Point)
みたいな形になります。
これを最後に
ST_MakeLine(sp, ep)
でそれぞれ線分にする。
出力
上記クエリの出力をST_AsText
に食わせるとこうなります
"LINESTRING(0 0,1 0)"
"LINESTRING(1 0,0.5 1)"
"LINESTRING(0.5 1,0 0)"
やったー!
参考
ほぼこちらのママです。
https://www.mail-archive.com/postgis-users@postgis.refractions.net/msg02883.html