Bergabung dengan banyak poligon kecil untuk membentuk poligon yang lebih besar menggunakan PostGIS?

47

Saya memiliki layer berikut menggunakan SRID 27700 di postgis:

masukkan deskripsi gambar di sini

Ini adalah setiap wilayah administratif di Inggris, dan (seperti yang Anda lihat dari pengelompokan warna) masing-masing memiliki bidang teks yang menentukan daerah tempat mereka berada.

Yang ingin saya lakukan adalah membuat poligon county yang lebih besar dari yang lebih kecil di county tertentu, jadi EG dalam gambar di atas semua poligon warna teal akan membentuk satu poligon besar dari cincin luar tunggal yang berisi semua polis yang warna, seperti semua ungu, coklat, merah muda, abu-abu dll semua harus membentuk satu poligon.

Saya sudah mencoba yang berikut ini:

insert into parishesmerged (geometry)
select astext(multi(ST_Union(the_geom))) as the_geom from parishes
group by county_name

Tapi itu terus menghasilkan geometri yang rusak yang kemudian saya punya masalah besar pemrosesan lebih lanjut.

Saya mencoba membuat peta tingkat kabupaten yang lebih sederhana dengan area keluaran utama di.

Solusi apa pun tidak harus ada di Postgis juga, saya memiliki tumpukan OS4Geo lengkap yang diinstal, versi terbaru QGis dan lebih banyak utilitas daripada yang bisa saya goyang.

Satu-satunya hal yang saya tidak miliki adalah anak laki-laki besar seperti ArcGis (Meskipun saya mungkin memiliki Mapinfo Lama tergeletak di suatu tempat)


Sebagai catatan, dataset yang saya coba buat adalah untuk menemani buku GIS yang sedang saya tulis yang ditujukan untuk pemrogram .NET yang ingin menulis aplikasi GIS menggunakan .NET


Setelah mencoba saran di bawah ini, salah satu yang paling berhasil adalah solusi 'Paul Ramseys'.

Saya sekarang memiliki file counties & borough sederhana yang disederhanakan yang cukup sederhana untuk buku saya, tetapi cukup kompleks untuk memungkinkan saya menunjukkan beberapa SQL geo-spasial yang menarik.

Meskipun solusi Paul pada akhirnya adalah yang bekerja untuk saya, saya juga memanfaatkan jawaban lain untuk hal-hal seperti menyederhanakan peta poligon dan mengurangi kompleksitas lebih lanjut.

Pada hal yang saya amati saat melakukan ini, sementara ST_Collect memang lebih cepat dari ST_Union, jalankan untuk menjalankan itu juga yang paling bertanggung jawab untuk geometri yang rusak. Dugaan saya adalah peningkatan kecepatan diperoleh dengan mengorbankan kurang akuratnya fungsi inti.

shawty
sumber
Proses ini dikenal sebagai "larut". Saya tidak berpengalaman dengan PostGIS, tetapi saya yakin Anda dapat menggunakan perintah ST_Union untuk melakukan pembubaran.
dmahr
Hai, terima kasih untuk klarifikasi, tidak yakin apa namanya, namun jika Anda membaca pertanyaan saya, Anda akan melihat bahwa saya sudah mencobanya :-)
shawty
Ups, maaf ... tidak melihat itu. Sudahkah Anda mencoba pernyataan pilih tanpa astext(multi())bagian? Saya hanya pergi dari apa yang saya lihat dalam contoh larut PostGIS lainnya.
dmahr
Belum, akan mencobanya sekarang. Tks. Apakah Anda memiliki tautan untuk membubarkan contoh?
shawty
Harap edit untuk mengungkapkan jika Anda ingin "cincin luar tunggal" atau tidak. (lihat jawaban saya)
Peter Krauss

Jawaban:

43

ST_Union akan berfungsi, tetapi kerja lini Anda hampir pasti tidak bersih. Jadi batas-batas benda kecil Anda tidak semuanya benar-benar disukai. Anda dapat dengan lembut memasang mereka ke kotak untuk mencoba dan meningkatkan peluang yang berbaris vertex, tapi saya yakin Anda masih akan memiliki beberapa kasus yang tidak berfungsi. Entah mereka akan melampaui toleransi atau, lebih mungkin, akan ada tempat-tempat di mana simpul tidak berpasangan, jadi ada garis di satu sisi dan sebuah simpul di sisi lain.

 CREATE TABLE merged AS
 SELECT ST_Union(ST_SnapToGrid(the_geom,0.0001)) 
 FROM parishes
 GROUP BY county_name;

Jika Anda memiliki PostGIS 2.0, membangun struktur topologi dengan toleransi dapat membuat Anda mendapatkan jawaban yang Anda cari, jika Anda beruntung.

Paul Ramsey
sumber
Petunjuk bagus untuk koreksi geometri, tetapi tentang "... satu poligon besar dari cincin luar tunggal yang berisi semua polys ..."?
Peter Krauss
Saya tidak tahu tentang 'SnapTo', saya akan mencobanya :-) Tks. Sayangnya, tidak, tidak menggunakan PG 2 dulu, upgrade masih dalam jalur.
shawty
Tidak yakin sintaks Anda benar. Per postgis.net/docs/ST_Union.html , tidak ada tanda tangan yang menerima angka di parameter ke-2.
Aren Cambre
Anda benar, tanda kurung berada di tempat yang salah. Diedit.
Paul Ramsey
apakah ada mysql yang setara dengan ini? saya terus mendapatkan Incorrect parameter count in the call to native function 'ST_Union'dan saya tidak tahu apakah itu batasan mysql.
Jayen
7

Anda mengatakan bahwa perlu "... membentuk satu poligon besar dari cincin luar tunggal yang berisi semua polys ...". ST_ExteriorRing melakukan ini,

SELECT ST_MakePolygon(ST_ExteriorRing(ST_Union(GEOM)))
FROM GEOMTABLE GROUP BY ATTRCOLUMN

Anda dapat menggunakan ST_Union (), seperti yang disarankan, atau tes dengan ST_Collection ().


CATATAN: untuk menghindari sedikit lengkungan atau "geometri patah" Anda dapat menggunakan st_convexhull dan / atau ST_Sederhana untuk setiap geom,

SELECT ST_MakePolygon(ST_ExteriorRing(ST_union(ST_Simplify(GEOM,0.5))))
FROM GEOMTABLE GROUP BY ATTRCOLUMN

dan periksa geometri Anda,

SELECT * FROM (
   SELECT gid, ST_IsValid(geom) as valid, ST_IsSimple(geom) as simple 
   FROM GEOMTABLE) AS t  
WHERE NOT(valid AND simple); 
Peter Krauss
sumber
Maaf atas kebingungan: Apa yang saya maksud dengan uraian saya adalah satu poligon yang lebih besar dibuat dari yang lebih kecil, saya menyadari bahwa tergantung pada konteks 'Cincin Luar' dapat berarti hal yang berbeda untuk orang yang berbeda, maksud saya adalah untuk menggambarkan satu poligon yang dibuat dari batas hadir di sekitar setiap kelompok poligon.
shawty
7

Fungsi ST_Collect adalah fungsi "agregat" dalam terminologi PostgreSQL

" SELECT ST_Collect(GEOM) FROM GEOMTABLE GROUP BY ATTRCOLUMN" akan mengembalikan GEOMETRYCOLLECTION terpisah untuk setiap nilai ATTRCOLUM yang berbeda

http://postgis.net/docs/ST_Collect.html

Catatan: ST_Collect jauh lebih cepat daripada ST_Union

Mapperz
sumber
3
Saya mencobanya dan mendapatkan hasil yang sedikit berbeda, namun apakah koleksi geometri yang saya butuhkan? Saya pada dasarnya mencoba untuk membuat satu poligon besar, opsional dengan lubang di dalamnya (Khususnya di Derbyshire & nottinghamshire di mana kedua derby & Nottingham membentuk distrik terpisah tepat di tengah. Saya memang mengamati perbedaan kecepatan, jadi itulah kewl.
shawty
2

Saya berasumsi dari pertanyaan Anda bahwa Anda menggunakan produk Boundary-Line dari Ordnance Survey. Jika demikian, maka sudah termasuk kumpulan data tingkat Kabupaten sehingga tidak perlu mencoba untuk menghasilkan sendiri dari daerah paroki tingkat bawah.

Jika Anda tidak menggunakan Boundary-Line maka saya sarankan Anda melakukannya karena gratis di bawah lisensi OpenData OS dan memiliki tingkat County sebagai file bentuk yang dapat Anda muat langsung ke PostGIS.

Chenderson
sumber
2
Bagaimana dengan menyediakan tautan untuk mereka yang tidak mengetahuinya? Terima kasih.
Jonatr
1
Hai CHEnderson Anda sebenarnya benar, ya saya menggunakan lapisan data batas set dari OS Opendata, sayangnya batas-batas county tidak lengkap, file bentuk County yang sebenarnya hanya mencakup orang-orang yang disebut sebagai kabupaten, London borough berisi area sekitar London, dan file-file lain semuanya memiliki beberapa bagian, beberapa level lebih rendah dan lebih kecil daripada yang lain. Satu-satunya file yang memiliki seluruh garis besar Inggris, dan kemudian setiap kesempatan untuk mengekstraksi semua kabupaten tingkat atas dan batas kota dalam satu lapisan adalah lapisan paroki, maka dari itu mengapa saya berusaha untuk melakukannya.
shawty
Bagi mereka yang tertarik, Anda dapat mengunduh batas-batas county dan banyak lagi, di sini: ordnancesurvey.co.uk/oswebsite/products/os-opendata.html
shawty