Saya mencoba menghitung statistik raster (min, maks, rata-rata) untuk setiap poligon dalam lapisan vektor menggunakan PostgreSQL / PostGIS.
Jawaban GIS.SE ini menjelaskan cara melakukan ini, dengan menghitung persimpangan antara poligon dan raster, lalu menghitung rata-rata tertimbang: https://gis.stackexchange.com/a/19858/12420
Saya menggunakan kueri berikut (di mana dem
raster saya, topo_area_su_region
adalah vektor saya, dan toid
merupakan ID unik:
SELECT toid, Min((gv).val) As MinElevation, Max((gv).val) As MaxElevation, Sum(ST_Area((gv).geom) * (gv).val) / Sum(ST_Area((gv).geom)) as MeanElevation FROM (SELECT toid, ST_Intersection(rast, geom) AS gv FROM topo_area_su_region,dem WHERE ST_Intersects(rast, geom)) foo GROUP BY toid ORDER BY toid;
Ini berfungsi, tetapi terlalu lambat. Layer vektor saya memiliki fitur 2489k, dengan masing-masing membutuhkan sekitar 90 ms untuk diproses - akan butuh berhari - hari untuk memproses seluruh layer. Kecepatan perhitungan tampaknya tidak meningkat secara signifikan jika saya hanya menghitung min dan maks (yang menghindari panggilan ke ST_Area).
Jika saya melakukan perhitungan yang sama menggunakan Python (GDAL, NumPy dan PIL) saya dapat secara signifikan mengurangi jumlah waktu yang dibutuhkan untuk memproses data, jika alih-alih membuat vektor raster (menggunakan ST_Intersection) saya rasterize vektor. Lihat kode di sini: https://gist.github.com/snorfalorpagus/7320167
Saya tidak benar-benar membutuhkan rata-rata tertimbang - pendekatan "jika menyentuh, berarti" cukup baik - dan saya cukup yakin inilah yang memperlambat segalanya.
Pertanyaan : Apakah ada cara agar PostGIS berperilaku seperti ini? yaitu untuk mengembalikan nilai semua sel dari raster yang disentuh poligon, daripada persimpangan yang tepat.
Saya sangat baru di PostgreSQL / PostGIS, jadi mungkin ada hal lain yang tidak saya lakukan dengan benar. Saya menjalankan PostgreSQL 9.3.1 dan PostGIS 2.1 pada Windows 7 (2.9GHz i7, 8GB RAM) dan telah mengubah konfigurasi database seperti yang disarankan di sini: http://postgis.net/workshops/postgis-intro/tuning.html
sumber
Jawaban:
Anda benar, menggunakan
ST_Intersection
memperlambat permintaan Anda terlihat.Alih-alih menggunakannya
ST_Intersection
lebih baik untuk memotong (ST_Clip
) raster Anda dengan poligon (bidang Anda) dan membuang hasilnya sebagai poligon (ST_DumpAsPolygons
). Jadi setiap sel raster akan dikonversi menjadi persegi panjang poligon kecil dengan nilai yang berbeda.Untuk menerima min, maks atau berarti dari kesedihan Anda dapat menggunakan pernyataan yang sama.
Kueri ini harus melakukan trik:
Dalam pernyataan yang
ST_Clip
Anda tentukan raster, band raster (= 1), poligon dan jika krop harus TRUE atau FALSE.Selain itu Anda dapat menggunakan
avg((gv).val)
untuk menghitung nilai rata-rata.EDIT
Hasil pendekatan Anda lebih tepat, tetapi lebih lambat. Hasil kombinasi
ST_Clip
danST_DumpAsPolygons
mengabaikan sel raster yang berpotongan dengan kurang dari 50% (atau 51%) dari ukurannya.Dua tangkapan layar ini dari persimpangan CORINE Land Use menunjukkan perbedaan. Gambar pertama dengan
ST_Intersection
, gambar kedua denganST_Clip
danST_DumpAsPolygons
.sumber