😀

ST_Buffer()を使ってジオメトリコレクションからポリゴン要素だけを抜き出す

2020/10/27に公開

はじめに

ST_Buffer(geom, 0.0)とすると、なぜかポリゴンだけが残るというネタです。

ジオメトリコレクションに対するバッファは、要素ごとにバッファを施したジオメトリを生成して、妥当なジオメトリだけ残すようにフィルタリングして、結果をまとめて返す、というようなことをしていると思われます。
0.0でバッファを施すと、ラインストリング要素とポイント要素は面積がゼロになるポリゴンになり、これらは不正ジオメトリとなります。
フィルタリングで消されるのだと思います。

まずはジオメトリコレクションを用意します。

db=# WITH t1 AS (
  SELECT ST_Collect(ARRAY[
    'POINT(1 1)'::GEOMETRY,
    'LINESTRING(1 1, 2 2)'::GEOMETRY,
    'POLYGON((1 1, 2 2, 2 1, 1 1))'::GEOMETRY
  ]) AS geom
)
SELECT ST_AsText(geom) FROM t1;

                                   st_astext                                   
-------------------------------------------------------------------------------
 GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(1 1,2 2),POLYGON((1 1,2 2,2 1,1 1)))
(1)

ここからポリゴンだけを出してみましょう。

db=# WITH t1 AS (
  SELECT ST_Collect(ARRAY[
    'POINT(1 1)'::GEOMETRY,
    'LINESTRING(1 1, 2 2)'::GEOMETRY,
    'POLYGON((1 1, 2 2, 2 1, 1 1))'::GEOMETRY
  ]) AS geom
)
SELECT ST_AsText(
  ST_Buffer(geom, 0.0)
) FROM t1;

         st_astext          
----------------------------
 POLYGON((1 1,2 2,2 1,1 1))
(1)

複数個のポリゴンがあるとマルチポリゴンになります。

db=# WITH t1 AS (
  SELECT ST_Collect(ARRAY[
    'POINT(1 1)'::GEOMETRY,
    'LINESTRING(1 1, 2 2)'::GEOMETRY,
    'POLYGON((1 1, 2 2, 2 1, 1 1))'::GEOMETRY,
    'POLYGON((2 2, 3 3, 3 2, 2 2))'::GEOMETRY
  ]) AS geom
)
SELECT ST_AsText(
  ST_Buffer(geom, 0.0)
) FROM t1;

                       st_astext                       
-------------------------------------------------------
 MULTIPOLYGON(((1 1,2 2,2 1,1 1)),((2 2,3 3,3 2,2 2)))
(1)

マルチポリゴンが混じっている場合には、シングルポリゴンにダンプしたあと全部でマルチポリゴンにまとめられたかんじになります。

WITH t1 AS (
  SELECT ST_Collect(ARRAY[
    'POINT(1 1)'::GEOMETRY,
    'LINESTRING(1 1, 2 2)'::GEOMETRY,
    'POLYGON((1 1, 2 2, 2 1, 1 1))'::GEOMETRY,
    'MULTIPOLYGON(((2 2, 3 3, 3 2, 2 2)),((3 3, 4 4, 4 3, 3 3)))'::GEOMETRY
  ]) AS geom
)
SELECT ST_AsText(
  ST_Buffer(geom, 0.0)
) FROM t1;

                                 st_astext                                 
---------------------------------------------------------------------------
 MULTIPOLYGON(((1 1,2 2,2 1,1 1)),((2 2,3 3,3 2,2 2)),((3 3,4 4,4 3,3 3)))
(1)

本記事のライセンス

クリエイティブ・コモンズ・ライセンス
この記事は クリエイティブ・コモンズ 表示 4.0 国際 ライセンス の下に提供されています。

Discussion