Ini adalah pertanyaan lanjutan untuk pertanyaan ini .
Saya memiliki jaringan sungai (multiline) dan beberapa poligon drainase (lihat gambar di bawah). Tujuan saya adalah untuk memilih hanya poligon headwater (hijau).
Dengan solusi John, saya dapat dengan mudah mengekstraksi titik awal sungai (bintang). Namun, saya dapat memiliki situasi (poligon merah) di mana saya memiliki titik awal dalam poligon, tetapi poligon itu bukan poligon hulu, karena diterbangkan melalui sungai. Saya hanya ingin poligon hulu.
Saya mencoba memilihnya dengan menghitung jumlah persimpangan antara poligon dan sungai (dasar pemikiran: poligon hulu hanya memiliki 1 persimpangan dengan sungai)
SELECT
polyg.*
FROM
polyg, start_points, stream
WHERE
st_contains(polyg.geom, start_points.geom)
AND ST_Npoints(ST_Intersection(poly.geom, stream.geom)) = 1
, di mana poylg adalah poylgons, start_points dari johns answer and stream adalah jaringan sungai saya.
Namun, ini berlangsung selamanya dan saya tidak menjalankannya:
"Nested Loop (cost=0.00..20547115.26 rows=641247 width=3075)"
" Join Filter: _st_contains(ezg.geom, start_points.geom)"
" -> Nested Loop (cost=0.00..20264906.12 rows=327276 width=3075)"
" Join Filter: (st_npoints(st_intersection(ezg.geom, rivers.geom)) = 1)"
" -> Seq Scan on ezg_2500km2_31467 ezg (cost=0.00..2161.52 rows=1648 width=3075)"
" Filter: ((st_area(geom) / 1000000::double precision) < 100::double precision)"
" -> Materialize (cost=0.00..6364.77 rows=39718 width=318)"
" -> Seq Scan on stream_typ rivers (cost=0.00..4498.18 rows=39718 width=318)"
" -> Index Scan using idx_river_starts on river_starts start_points (cost=0.00..0.60 rows=1 width=32)"
" Index Cond: (ezg.geom && geom)"
Jadi pertanyaan saya adalah: Bagaimana saya bisa meminta kuota hulu secara efisien?
Pembaruan: Saya menambahkan beberapa data sampel ke dropbox saya . Data berasal dari Jerman barat daya. Ini dua file bentuk - satu dengan aliran dan satu dengan poligon.
polygons
yang hanya berisi titik-titik yang merupakan sumber sungai (dari pertanyaan sebelumnya) dan untuk mengecualikan di mana dua sungai bertemu. Maaf, untuk semua pertanyaan, hanya ingin memastikan.polygons
yang memiliki sungai yang lewat (sungai masuk dan meninggalkan poligon) dan menjaga mereka yang mulai (dan sungai hanya menyisakan poligon ini).Jawaban:
Saya percaya garis besar umum (sebagian diuji sejauh ini) adalah:
Temukan titik yang mewakili sumber aliran, seperti dalam jawaban ini .
Berpotongan dengan tabel poligon untuk mendapatkan hitungan simpul sumber dengan poligon.
Gunakan ST_DumpPoints dalam hubungannya dengan grup dengan geometri untuk mendapatkan hitungan setiap titik. Idenya adalah untuk menghitung berapa banyak sungai yang bertemu pada titik tertentu.
Contoh permintaan seperti itu:
yang mengembalikan:
Jalankan perpotongan
3
terhadap tabel poligon, untuk mendapatkan hitungan (jumlah simpul) persimpangan sungai per poligon.Bergabung dengan poligon dari
2
pada4
, menolak titik-titik di mana jumlah (jumlah simpul) titik di persimpangan lebih besar dari jumlah sumber sungai, diperoleh dengan menjumlahkan sumber dengan poligon dari langkah 1 dan 2. Jika kondisi ini berlaku, itu berarti bahwa setidaknya satu dari sungai bertemu di persimpangan, berasal dari luar poligon yang dimaksud.Ini semua dapat digabungkan bersama dalam urutan CTE yang besar, kecuali beberapa tabel dibuat dari langkah-langkah yang melibatkan poin (dan diindeks).
Saya tidak tahu apa runtime ini pada set data lengkap, hanya menguji bagian ini pada subset, tetapi dengan indeks spasial pada tabel poligon, akan ada beberapa bantuan - jelas tidak mungkin untuk menerapkan indeks ke titik-titik yang muncul dari ST_DumpPoints, sehingga pemindaian penuh akan diperlukan di sana, meskipun mereka harus ada dalam memori saat itu.
Ini tidak diposting sebagai jawaban penuh , tetapi sebagai pekerjaan yang sedang berjalan, dan kesempatan untuk menemukan kekurangan dalam logika. Permintaan kerja segera hadir.
EDIT 1
Ini adalah pertanyaan yang saya buat, yang tampaknya berfungsi pada sebagian kecil dari data Anda, tetapi berjalan selama berjam-jam pada dataset lengkap.
EDIT 2 . Sementara ini tampaknya menghasilkan jawaban yang benar pada subset kecil, waktu berjalan pada dataset lengkap mengerikan , mungkin karena permintaan terakhir melakukan perbandingan n ^ 2 dan tidak menggunakan indeks spasial. Solusi yang mungkin adalah memecah kueri dan membuat tabel dari titik awal dan titik dalam kueri poligon, yang kemudian dapat diindeks secara spasial sebelum langkah terakhir.
sumber
Dalam kode semu, ini harus bekerja:
Saya tidak begitu yakin bagaimana cara membangun kueri, dan saya tidak dapat mengujinya tanpa database untuk diuji. Itu pertanyaan yang cukup gila, saya pikir. Tapi itu seharusnya berhasil!
sumber