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/36886Jawaban:
Saya tidak tahan untuk berpikir bahwa contoh Anda sebenarnya adalah raster dan meskipun Anda menyebutkan bahwa Anda ingin menggabungkan berdasarkan "kriteria tertentu (bisa ukuran)" Saya ingin mencobanya dengan konversi raster.
Untuk contoh spesifik Anda ini akan berfungsi:
Apa yang terjadi adalah karena poligon Anda adalah sel-sel yang disejajarkan dengan sempurna, poligon akan dikonversi dengan baik menjadi raster (10x20 sel ukuran). The dumpaspolygons membantu Anda di sini dengan menggabungkan semua sel yang berdekatan menjadi satu dan dengan membandingkan dengan poligon asli Anda bahkan akan bisa mendapatkan id kembali untuk poli yang tidak bergabung.
Setelah menjelaskan ini, saya sangat ingin tahu bagaimana ini akan skala dan seberapa besar dataset Anda: D
sumber
Berikut adalah contoh bagaimana melakukan ini dalam gaya prosedural dengan beberapa lintasan di bawah kap.
Anda harus dapat membawa lebih banyak kolom dan menerapkan kriteria tambahan untuk bergabung dengan memodifikasi cara kerja
LIMIT 1
pilih di bawah ini:Jalankan hal itu:
Serikat pekerja yang tepat, tidak ada multipoligon:
sumber
Berikut ini adalah strategi (tidak berfungsi) untuk referensi (yang saya tidak bisa mengecualikan kasus titik sentuh tunggal). Itu harus lebih cepat daripada jawaban saya yang lain karena hanya membutuhkan 'satu lulus'.
(merasa bebas untuk mengubah dan memposting jawaban lain jika ada yang bisa mendapatkan id = 5 geometri di grup sendiri)
Untuk mendapatkan kembali daftar id dll. Anda harus menggunakan
st_contains
untuk bergabung kembali di tabel testpoly sebagaimana dirinci dalam jawaban berikut: /programming//a/37486732/6691 tapi saya tidak bisa menggunakannya untuk bekerja untuk poligon karena alasan tertentu.sumber
Berikut adalah langkah cepat menggunakan permintaan asli Anda yang sedikit disesuaikan:
Referensi: https://postgis.net/docs/using_postgis_dbmanagement.html#DE-9IM
sumber