名前

ST_ConcaveHull — 凹包は、集合の範囲内におけるすべてのジオメトリーを囲む、できる限り凹となるジオメトリを表現するものです。収縮包装とみることができます。

概要

geometry ST_ConcaveHull(geometry geomA, float target_percent, boolean allow_holes=false);

説明

凹包は、集合の範囲内におけるすべてのジオメトリーを囲む、できる限り凹となるジオメトリを表現するものです。ポリゴンの穴を認めるのはデフォルトではfalseです。結果はシングルポリゴンより高くなることはありません。

target_percentは、凸包からPostGISがあきらめるか終了するまでに接近を試みる、凸包に対する目標割合です。凹包はジオメトリの集合を真空パックしたジオメトリと考えることができます。target_percentが1の場合には、凸包と同じ答えになります。target_parcetが0から0.99までの間では、凸包より小さい面積が得られます。これが、ジオメトリ集合を輪ゴムで囲うのに似ている凸包との違いです。

通常はMULTI系とジオメトリコレクションに使われます。 集計関数ではないのですが、ST_CollectやST_Unionと併用して、ポイント/ラインストリング/ポリゴンの凹包を得ることができます。"ST_ConcaveHull(ST_Collect(somepointfield), 0.80)"といったようにします。

凸包の計算よりも非常に遅いですが、よりよくジオメトリを囲みますし、画像認識にも使用されます。

GEOSモジュールで実現しています。

[注記]

ご注意 - ポイント、ラインストリング、ジオメトリコレクションで使用する場合には、ST_Collectを使用して下さい。ポリゴンで使用する場合には、不正なジオメトリで失敗する可能性があるため、ST_Unionを使用して下さい。

[注記]

ご注意 - 目標割合を小さくすると、凹包処理が長くなり、トポロジ例外が発生しやすくなります。蓄積される浮動小数点数とポイントの数もまた多くなります。最初に0.99で実行してみて下さい。普通は非常に速く、時々凸包と同じ速さです。99%縮小ではほとんどの場合行き過ぎになるので、通常は99%縮小より良い結果になります。次に0.98で実行すると、2乗のオーダーで遅くなります。ST_ConcaveHull実行後に、精度と浮動小数点数を減らすために、ST_SimplifyPreserveTopologyST_SnapToGridを使用します。ST_SnapToGridは少し早くなりますが、不正なジオメトリが得られることがあります。ST_SimplifyPreserveTopologyは常にジオメトリの妥当性を確保します。

現実世界の例と技術面でのしっかりした説明は、http://www.bostongis.com/postgis_concavehull.snippetにあります。

Oracle 11G R2で導入された凹包のデモンストレーションに関するSimon Greenerさんの記事も見てください。http://www.spatialdbadvisor.com/oracle_spatial_tips_tricks/172/concave-hull-geometries-in-oracle-11gr2にあります。凸包に対する目標割合を0.75にした際の形状がSimonさんOracleのSDO_CONCAVEHULL_BOUNDARYで得た形状と似ています。

初出: 2.0.0

-- 観察ポイントを基に感染域の見積もりを得ます
SELECT d.disease_type,
        ST_ConcaveHull(ST_Collect(d.pnt_geom), 0.99) As geom
        FROM disease_obs As d
        GROUP BY d.disease_type;

縮小目標割合100%にした場合の2ポリゴンのST_ConcaveHull

-- 縮小目標割合100%の凹包(凸包と同じとなり縮小しません)
-- で覆われるジオメトリ
SELECT 
        ST_ConcaveHull(
                ST_Union(ST_GeomFromText('POLYGON((175 150, 20 40, 
                        50 60, 125 100, 175 150))'),
                ST_Buffer(ST_GeomFromText('POINT(110 170)'), 20)
                ), 1)  
         As convexhull;
                                

凸包に対する縮小目標割合を90%にした凹包で覆われるジオメトリ

-- 縮小目標割合90%の凹包で覆われるジオメトリ
SELECT 
        ST_ConcaveHull(
                ST_Union(ST_GeomFromText('POLYGON((175 150, 20 40, 
                        50 60, 125 100, 175 150))'),
                ST_Buffer(ST_GeomFromText('POINT(110 170)'), 20)
                ), 0.9)  
         As target_90;
                                

凸包で覆われたL字型のポイント群

-- 42ポイントでL字型を形成するテーブルを生成
SELECT (ST_DumpPoints(ST_GeomFromText(
'MULTIPOINT(14 14,34 14,54 14,74 14,94 14,114 14,134 14,
150 14,154 14,154 6,134 6,114 6,94 6,74 6,54 6,34 6,
14 6,10 6,8 6,7 7,6 8,6 10,6 30,6 50,6 70,6 90,6 110,6 130,
6 150,6 170,6 190,6 194,14 194,14 174,14 154,14 134,14 114,
14 94,14 74,14 54,14 34,14 14)'))).geom 
        INTO TABLE l_shape;

SELECT ST_ConvexHull(ST_Collect(geom))
FROM l_shape;
                                

凸包に対する縮小目標割合を99%としたL字型のポイント群の凹包

SELECT ST_ConcaveHull(ST_Collect(geom), 0.99)
        FROM l_shape;
                                

凸包に対する縮小目標割合を80%としたL字型のポイント群の凹包

        -- 凸包に対する縮小目標割合を80%としたL字型のポイント群の凹包
        SELECT ST_ConcaveHull(ST_Collect(geom), 0.80)
        FROM l_shape;
        

凸包に覆われたマルチラインストリング

凸包に対する縮小目標割合を99%(第1段階)とした凹包に覆われたマルチラインストリング

SELECT ST_ConcaveHull(ST_GeomFromText('MULTILINESTRING((106 164,30 112,74 70,82 112,130 94,
        130 62,122 40,156 32,162 76,172 88),
(132 178,134 148,128 136,96 128,132 108,150 130,
170 142,174 110,156 96,158 90,158 88),
(22 64,66 28,94 38,94 68,114 76,112 30,
132 10,168 18,178 34,186 52,184 74,190 100,
190 122,182 148,178 170,176 184,156 164,146 178,
132 186,92 182,56 158,36 150,62 150,76 128,88 118))'),0.99)
        

関連情報

ST_Collect, ST_ConvexHull, ST_SimplifyPreserveTopology, ST_SnapToGrid