LoginSignup
3
3

More than 5 years have passed since last update.

POLYGONの外環となるLINESTRINGを線分に分解する

Last updated at Posted at 2016-08-10

問題設定

任意のPolygonについて外周の線分集合がほしいこと、あると思います。
少なくとも僕はありました。
どういうことかというと、例えば次の図1のような(0.0, 0.0), (1.0, 0.0), (0.5, 1.0)からなる正三角形があったときに、それぞれの辺に分解したいということです。
図1 正三角形
図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

3
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3