Apakah ada fungsi larut di PostGIS selain st_union?

22

Saya mencari fungsi untuk melarutkan batas bersama antara fitur poligon dalam sebuah tabel. ST_UNION () hampir melakukan apa yang saya cari, tetapi ini menciptakan multipolygon dari semua poligon di lapisan terlepas dari apakah mereka berbagi batas bersama atau tidak. Saya lebih suka hanya melarutkan batas antara poligon yang saling menyentuh. Saya pikir, harus ada beberapa cara menggunakan ST_TOUCHES () tetapi kemudian kebutuhan untuk fungsi larut tampaknya sangat umum sehingga saya akan terkejut jika tidak ada fungsi bawaan untuk mencapai ini.

Kasus penggunaannya terlihat seperti ini: Saya mengunduh data Corine Landcover untuk negara besar di Eropa dan saya ingin membubarkan batas antara berbagai jenis hutan (sekitar 75.000 poligon dalam satu tabel). Saya mencoba ST_UNION, tetapi gagal dengan kesalahan "kehabisan memori" (30.000 poligon berhasil):

create table corine00 as 
  select st_union(the_geom) as the_geom, 
         sum(area_ha) as area_ha,
         substr(code_00,1,2) as code_00
  from clc00_c31_forests
  group by substr(code_00,1,2)

Catatan: Semua kode hutan dimulai dengan '31' dan saya menggunakan PostGIS 1.4, versi GEOS: 3.2.0-CAPI-1.6.0

underdark
sumber

Jawaban:

21

ST_MemUnion () akan menjalankan proses ramah memori yang naif dan lambat. Anda dapat mencobanya, jika masalah Anda cukup kecil, mungkin selesai dalam waktu yang wajar. Anda juga bisa membagi masalah menjadi dua bagian, kemudian menjalankannya menjadi dua bagian. Karena hasilnya akan memiliki poin jauh lebih sedikit daripada input, Anda mungkin dapat memasukkan seluruh masalah ke dalam memori dengan cara itu. Atau gunakan rutin lapar memori cepat pada bagian dan rutin yang lebih lambat pada penggabungan akhir.

Paul Ramsey
sumber
4
Luar biasa untuk Anda di sini Paul, terima kasih telah membawa Anda keahlian yang tak tertandingi.
fmark
1
Terima kasih, sepertinya masalah saya tidak cukup kecil. ST_MemUnion () sekarang telah berjalan selama 24 jam. Saya akan mencoba untuk membagi masalah.
underdark
5

Saya yakin ST_Dump adalah yang Anda inginkan:

ST_Dump :

Mengembalikan satu set baris geometry_dump (geom, path), yang membentuk geometri g1 .... Misalnya, dapat digunakan untuk memperluas MULTIPOLYGON menjadi POLYGONS. ...

Jadi untuk kasus Anda:

 SELECT (ST_Dump( ST_Union( the_geom ) )).geom
 FROM clc00_c31_forests
 GROUP BY substr(code_00,1,2)

Saya tidak yakin bagaimana ini akan berinteraksi dengan pembuatan tabel yang Anda coba lakukan, tetapi itu akan memberi Anda geometri sebagai entri yang terpisah. Anda kemudian dapat melakukan gabungan spasial (menggunakan && dan ST_Contains) antara dua tabel untuk mengumpulkan data ke dalam geometri.

yhw42
sumber
2
Catatan: ini hanya akan membantu jika masalah memori ST_Union ditangani! :)
yhw42
4

Apakah PostGIS Anda dikompilasi dengan GEOS 3.1.0+? Untuk versi itu, penyatuan kaskade jauh lebih cepat diterapkan, tetapi jika tidak ditemukan akan menggunakan kode yang lebih lama yang perintah besarnya lebih lambat.

Pembaruan : sepertinya PostGIS Anda menggunakan pendekatan cascaded union, tetapi kelaparan memori itu nyata. Saya akan mencoba meningkatkan memori yang tersedia untuk contoh Postgres Anda, berikut adalah beberapa saran dari pembicaraan FOSS4G PostGIS Paul Ramsey 2007 :

  • Akses disk lambat, sehingga kinerja yang lebih tinggi dapat diperoleh dengan menggunakan lebih banyak memori untuk menyimpan data!
    • Meningkatkan shared_buffers
    • RAM Fisik - Kebutuhan OS * 75%
  • Penyortiran lebih cepat di memori
    • Meningkatkan work_mem
  • Disk clean-up lebih cepat dengan lebih banyak memori
    • Meningkatkan maintenance_work_mem
  • Dialokasikan per koneksi
  • Juga
    • Meningkatkan wal_buffers
    • Meningkatkan checkpoint_segments
    • Mengurangi random_page_cost

Dalam kasus Anda, saya akan mencoba meningkatkan shared_buffers, rekomendasi umum adalah 25% dari memori Anda yang tersedia untuk server database, tetapi cobalah meningkatkannya menjadi 3-4x nilai saat ini dan melihat apakah itu selesai.

scw
sumber
postgis_geos_version () mengembalikan: 3.2.0-CAPI-1.6.0 ... Saya rasa tidak masalah. Akan mencoba ST_Collect, terima kasih.
underdark
ST_Collect tampaknya tidak melarutkan batas apa pun dan juga menciptakan satu Multipolygon raksasa.
underdark
ya, saya salah membaca halaman untuk ST_Collect. Saya telah memperbarui jawaban saya untuk memberikan saran yang lebih spesifik untuk mengatur penggunaan memori Postgres.
scw