Saya menghadapi tantangan dengan PostGIS yang sepertinya tidak bisa saya lindungi. Saya tahu saya bisa menyelesaikan ini menggunakan bahasa pemrograman (dan itu adalah rencana cadangan saya), tapi saya benar-benar ingin menyelesaikan ini di PostGIS. Saya sudah mencoba mencari, tetapi tidak dapat menemukan jawaban yang cocok dengan masalah saya, ini mungkin karena saya tidak yakin tentang istilah pencarian saya, jadi tolong permisi dan arahkan saya ke arah yang benar karena memang ada jawaban.
Masalah saya adalah ini:
- Saya punya meja dengan Polygons / MultiPolygons campuran
- Setiap poligon (multi) memiliki atribut yang memeringkatnya (prioritas)
- Setiap poligon juga memiliki nilai yang ingin saya ketahui
- Saya memiliki area pencarian (poligon)
- Untuk area kueri saya, saya ingin menemukan area yang dicakup oleh setiap nilai poligon
Contoh:
Katakanlah saya memiliki tiga poligon yang digambarkan merah, hijau, dan nila di sini:
Dan bahwa, persegi panjang biru yang lebih kecil adalah kueri poligon saya
Selain itu, atributnya adalah
geom | rank | value
-------|------|----
red | 3 | 0.1
green | 1 | 0.2
indigo | 2 | 0.2
Apa yang saya inginkan adalah memilih geometri ini, sehingga peringkat tertinggi (hijau) mengisi semua area yang ia dapat (yaitu persimpangan antara geom kueri dan geom itu), lalu tertinggi berikutnya (nila) mengisi persimpangan antara geom kueri dan geom MINUS yang sudah dibahas) dll.
Saya menemukan pertanyaan ini: Menggunakan ST_Difference untuk menghapus fitur yang tumpang tindih? tetapi tampaknya tidak melakukan apa yang saya inginkan.
Saya sendiri dapat mengetahui cara menghitung area dan semacamnya, jadi pertanyaan yang memberi saya tiga geometri seperti yang digambarkan dalam gambar kedua baik-baik saja!
Info tambahan: - Ini bukan tabel besar (~ 2000 baris) - mungkin ada nol atau beberapa tumpang tindih (bukan hanya tiga) - mungkin tidak ada poligon di area kueri saya (atau hanya sebagian saja) - i ' m menjalankan postgis 2.3 di postgres 9.6.6
Solusi fallback saya adalah melakukan kueri seperti ini:
SELECT
ST_Intersection(geom, querygeom) as intersection, rank, value
FROM mytable
WHERE ST_Intersects(geom, querygeom)
ORDER by rank asc
Dan secara iteratif "potong" bagian geometri dalam kode. Tetapi, seperti yang saya katakan, saya benar-benar ingin melakukan ini di PostGIS
WITH RECURSIVE ...
CTE ( dokumen dan tutorial umum )Jawaban:
Saya pikir ini berhasil.
Ini adalah fungsi windowing, mendapatkan perbedaan antara persimpangan setiap persimpangan geometri dengan kotak kueri dan penyatuan geometri sebelumnya.
Koalesensi diperlukan karena penyatuan geometri sebelumnya untuk geometri pertama adalah nol yang memberikan hasil nol, bukan apa yang diinginkan.
Saya tidak yakin bagaimana kinerjanya. Tetapi karena ST_Union dan ST_Intersection ditandai tidak berubah, mungkin tidak terlalu buruk.
sumber
Sedikit pendekatan yang berbeda untuk ini. Ada peringatan bahwa saya tidak tahu bagaimana hal itu akan meningkatkan kinerja, tetapi pada tabel yang diindeks seharusnya ok. Kerjanya hampir sama dengan permintaan Nicklas (sedikit lebih lambat?), Tetapi pengukuran pada sampel sekecil itu penuh.
Itu terlihat jauh lebih jelek daripada permintaan Nicklas, tetapi ia menghindari rekursi dalam kueri.
sumber
Karena saya mengoceh tentang saya
WITH RECURSIVE
akan menambahkan jawaban cepat dan kotor menggunakannya.Ini berkinerja sebaik solusi @ NicklasAvén pada tiga Poligon, tidak bisa menguji ketika ditingkatkan.
Karena kedua solusi berdiri, yang satu ini memiliki satu manfaat kecil di atas yang lain: jika, misalnya, Poligon dengan peringkat = 2 terkandung oleh peringkat = 1 ,
...WHERE GeometryType = 'POLYGON'
filter yang keluar sementara jika tidak akan adaGEOMETRYCOLLECTION EMPTY
(saya mengubah geometri). dari masing-masing Poligon dalam solusi saya sesuai untuk memberikan contoh; ini juga berlaku untuk kasus lain ketika tidak ada persimpangan dengan perbedaan yang ditemukan). Ini mudah dimasukkan dalam solusi lain, dan mungkin bahkan tidak menjadi perhatian.sumber