パーセル(ポリゴン)レイヤーで隣接関係のテストを行い、特定の基準(サイズなど)に適合する場合はそれらをマージします。次の図では、ポリゴン1、2、3、4をマージしますが、 5はマージしません。
私には2つの問題があります:
ST_TOUCHES
線分ではなく、角だけが接触している場合にTRUEを返します。共有ラインセグメントをチェックするには、ST_RELATEが必要だと思います。- 理想的には、隣接するすべてのポリゴンを1つにマージしたいと思いますが、1ラウンドで1、2、3、4(および実際のデータでさらに)をマージするなど、2つを超えてスケーリングする方法がわかりません。
私が今持っている構造は自己結合に基づいていST_TOUCHES
ます。
玩具データ
CREATE TABLE testpoly AS
SELECT
1 AS id, ST_PolyFromText('POLYGON ((0 0, 10 0, 10 20, 00 20, 0 0 ))') AS geom UNION SELECT
2 AS id, ST_PolyFromText('POLYGON ((10 0, 20 0, 20 20, 10 20, 10 0 ))') AS geom UNION SELECT
3 AS id, ST_PolyFromText('POLYGON ((10 -20, 20 -20, 20 0, 10 0, 10 -20 ))') AS geom UNION SELECT
4 AS id, ST_PolyFromText('POLYGON ((20 -20, 30 -20, 30 0, 20 0, 20 -20 ))') AS geom UNION SELECT
5 AS id, ST_PolyFromText('POLYGON ((30 0, 40 0, 40 20, 30 20, 30 0 ))') AS geom ;
選択
SELECT
gid, adj_gid,
st_AStext(st_union(l2.g1,l2.g2)) AS geo_combo
from (
--level 2
SELECT
t1.id AS gid,
t1.geom AS g1,
t2.id AS adj_gid,
t2.geom AS g2
from
testpoly t1,
testpoly t2
where
ST_Touches( t1.geom, t2.geom )
AND t1.geom && t2.geom
)
l2
出力は次のとおりです。
+-----+---------+-------------------------------------------------------------------------------+
| gid | adj_gid | geo_combo |
+-----+---------+-------------------------------------------------------------------------------+
| 1 | 2 | POLYGON((10 0,0 0,0 20,10 20,20 20,20 0,10 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 1 | 3 | MULTIPOLYGON(((10 0,0 0,0 20,10 20,10 0)),((10 0,20 0,20 -20,10 -20,10 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 2 | 1 | POLYGON((10 20,20 20,20 0,10 0,0 0,0 20,10 20)) |
+-----+---------+-------------------------------------------------------------------------------+
| 2 | 3 | POLYGON((10 0,10 20,20 20,20 0,20 -20,10 -20,10 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 2 | 4 | MULTIPOLYGON(((20 0,10 0,10 20,20 20,20 0)),((20 0,30 0,30 -20,20 -20,20 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 3 | 1 | MULTIPOLYGON(((10 0,20 0,20 -20,10 -20,10 0)),((10 0,0 0,0 20,10 20,10 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 3 | 2 | POLYGON((20 0,20 -20,10 -20,10 0,10 20,20 20,20 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 3 | 4 | POLYGON((20 -20,10 -20,10 0,20 0,30 0,30 -20,20 -20)) |
+-----+---------+-------------------------------------------------------------------------------+
| 4 | 2 | MULTIPOLYGON(((20 0,30 0,30 -20,20 -20,20 0)),((20 0,10 0,10 20,20 20,20 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 4 | 3 | POLYGON((20 0,30 0,30 -20,20 -20,10 -20,10 0,20 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 4 | 5 | MULTIPOLYGON(((30 0,30 -20,20 -20,20 0,30 0)),((30 0,30 20,40 20,40 0,30 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 5 | 4 | MULTIPOLYGON(((30 0,30 20,40 20,40 0,30 0)),((30 0,30 -20,20 -20,20 0,30 0))) |
+-----+---------+-------------------------------------------------------------------------------+
ポリゴンid = 3はid = 1とポイントを共有するため、肯定的な結果として返されることに注意してください。WHERE句をに変更すると、ST_Touches( t1.geom, t2.geom ) AND t1.geom && t2.geom AND ST_Relate(t1.geom, t2.geom ,'T*T***T**');
レコードがまったく取得されません。
だから、最初に、どのように私は確信して線分を共有するだけで小包が考慮されていることを確認するためにST_Relateを指定してください。
それから、ポリゴン1、2、3、4を1ラウンドでマージし、上記の呼び出しの結果を折り畳みながら、隣接関係1から2が逆と同じであることを認識しますか?
更新
これをwhere
句に追加すると、明らかにポリゴンのみが取得され、マルチポリゴンは取得されないため、誤検知を取り除くために、コーナータッチは無視されます。
GeometryType(st_union(t1.geom,t2.geom)) != 'MULTIPOLYGON'
これは理想的ではありませんが(ST_RELATE
より一般的な解決策としてトポロジチェックを使用したい)、これは将来の方法です。その後、これらの重複排除と結合の問題が残ります。おそらく、タッチしているポリゴンのみのシーケンスを生成できれば、それを結合できます。
アップデートII
これは、ラインを共有するポリゴン(コーナーではない)を選択するために機能するようで、上記のMULTIPOLYGON
テストよりも一般的なソリューションです。私のwhere句は次のようになります。
WHERE
ST_Touches( t1.geom, t2.geom )
AND t1.geom && t2.geom
-- 'overlap' relation
AND ST_Relate(t1.geom, t2.geom)='FF2F11212') t2
残っているのは、ポリゴンのペアだけでなく、基準に適合する任意の数のマージを一度に行う方法です。