Saya ingin melakukan tes adjacency pada layer parcel (poligon) dan menggabungkan mereka jika mereka memenuhi kriteria tertentu (bisa ukuran). Per gambar di bawah ini, saya ingin menggabungkan poligon 1,2,3 dan 4, tetapi tidak 5.
Saya punya dua masalah:
ST_TOUCHES
mengembalikan TRUE jika hanya sudut sentuh dan bukan segmen garis. Saya rasa saya perlu ST_RELATE untuk memeriksa segmen garis yang dibagikan.- Idealnya, saya ingin menggabungkan SEMUA poligon yang berdekatan menjadi satu, tetapi saya tidak yakin bagaimana skala melampaui dua - seperti dalam, menggabungkan 1,2,3 dan 4 (dan mungkin lebih pada data aktual) dalam satu putaran.
Struktur yang saya miliki sekarang didasarkan pada self join ST_TOUCHES
.
Data mainan
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 ;
Pilihan
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
Berikut hasilnya:
+-----+---------+-------------------------------------------------------------------------------+
| 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))) |
+-----+---------+-------------------------------------------------------------------------------+
Perhatikan bahwa id poligon = 3 berbagi titik dengan id = 1 dan karenanya dikembalikan sebagai hasil positif. Jika saya mengubah klausa WHERE menjadi ST_Touches( t1.geom, t2.geom ) AND t1.geom && t2.geom AND ST_Relate(t1.geom, t2.geom ,'T*T***T**');
saya tidak mendapatkan catatan sama sekali.
Jadi pertama-tama , bagaimana cara menentukan ST_Relate untuk memastikan hanya paket yang berbagi segmen baris yang dipertimbangkan.
Dan kemudian, bagaimana saya menggabungkan poligon 1,2,3,4 dalam satu putaran, meruntuhkan hasil dari panggilan di atas, sementara itu mengakui bahwa kedekatan 1 ke 2 sama dengan kebalikannya?
Memperbarui
Jika saya menambahkan ini ke where
klausa saya jelas hanya mendapatkan poligon dan bukan multipoligon, sehingga menyingkirkan positif palsu untuk tujuan saya - sentuhan sudut akan diabaikan.
GeometryType(st_union(t1.geom,t2.geom)) != 'MULTIPOLYGON'
Meskipun ini tidak ideal (saya lebih suka menggunakan pemeriksaan topologi dengan ST_RELATE
sebagai solusi yang lebih umum), ini adalah jalan ke depan. Kemudian tetap tinggal masalah de-duping dan penyatuan ini. Mungkin, jika saya bisa menghasilkan urutan hanya untuk menyentuh poligon, saya bisa menyatukan itu.
Pembaruan II
Yang ini tampaknya bekerja untuk memilih jalur berbagi poligon (tetapi bukan sudut) dan dengan demikian merupakan solusi yang lebih umum daripada MULTIPOLYGON
tes di atas . Klausa tempat saya sekarang terlihat seperti ini:
WHERE
ST_Touches( t1.geom, t2.geom )
AND t1.geom && t2.geom
-- 'overlap' relation
AND ST_Relate(t1.geom, t2.geom)='FF2F11212') t2
Sekarang yang masih tersisa adalah bagaimana melakukan penggabungan untuk lebih dari sekadar sepasang poligon, tetapi untuk angka arbitrer yang memenuhi kriteria, dalam sekali jalan.
ST_IntersectionArray
[fungsi] [1] agar berfungsi dengan ST_Union [1]: gis.stackexchange.com/a/60295/36886