menghitung persen area persimpangan di mana klausa

15

Saya memiliki tabel poligon (kelompok blok sensus) di postgres. Saya ingin memberi tag pada masing-masing grup blok dengan kota (tabel poligon lain) yang sebagian besar ada di dalamnya. Apakah ini mungkin? Saya pikir saya pada dasarnya perlu membuat sesuatu seperti:

select b.*,t.name  
from blockgroups b, towns t  
where (st_area(st_intersection(b.wkb_geometry, t.wkb_geometry))/st_area(b.wkb_geometry)) > .5  

tetapi kueri ini berlangsung selamanya (saya punya sekitar 5.000 grup blok dan 375 kota ...). Adakah saran tentang cara membuat kueri ini berfungsi baik jika itu salah, atau lebih cepat jika itu benar?

eirvin
sumber
Kedengarannya Anda ingin memberi tag pada grup blokir berdasarkan pada tumpang tindih maksimum? Jika demikian, lihat jawaban ini . Jika 'kota' Anda juga merupakan Sensus geografi (MCD atau Tempat, katakanlah) mungkin tidak perlu menghitung persen yang tumpang tindih.
dbaston

Jawaban:

23

Cara Anda melakukannya akan berhasil tetapi itu akan memakan waktu terlalu banyak, karena postgis berusaha membuat geometri persimpangan setiap kombinasi "blockgroup vs kota", bahkan ketika mereka bahkan tidak menyentuh.

Tambahkan cek kondisi lain ke klausa WHERE Anda untuk memeriksa apakah kedua geometri mencegat, dan letakkan sebelum yang ada:

select b.*,t.name
from blockgroups b, towns t
where st_intersects(b.wkb_geometry, t.wkb_geometry) and    
    (st_area(st_intersection(b.wkb_geometry, t.wkb_geometry))/st_area(b.wkb_geometry)) > .5

Dalam SQL jika Anda memiliki daftar kondisi di klausa WHERE, mereka diuji oleh urutan mereka ditulis. Jika FALSE dikembalikan dalam salah satu operasi awal, queri hanya akan melewati pemeriksaan kondisi lainnya, karena hasilnya akan selalu FALSE.

Juga, pastikan Anda memiliki indeks spasial di blockgroups.wkb_geometry dan towns.wkb_geometry.

Alexandre Neto
sumber
1
Menambahkan ST_Intersectsadalah cara yang tepat untuk pergi ke sini, tetapi perencana mungkin atau tidak dapat menjalankan kondisi dalam urutan yang mereka tulis. Lihat dokumen Postgres untuk detailnya. ST_Intersectsdan ST_Intersectionmemiliki biaya yang sama pada instalasi saya (100), jadi jujur ​​saja saya tidak yakin apa yang perencana lakukan, tetapi sepertinya selalu melakukan hal yang benar di sini.
dbaston
Ahh ... Saya berasumsi bahwa kondisi akan diperiksa seperti dalam bahasa lain. Tapi saya kira itu memberi perencana opsi lain.
Alexandre Neto
10

Menambahkan ke jawaban Alexandre yang sangat berguna, jika beberapa unit sensus Anda dapat menjangkau tiga kota Anda (dan karenanya Anda tidak dapat menjamin lebih dari 50% jatuh di kota mana pun) Anda dapat melakukan ini:

select distinct on (b.id)
b.*,t.name,
(st_area(st_intersection(b.wkb_geometry, t.wkb_geometry))/st_area(b.wkb_geometry)) as proportion
from blockgroups b, towns t
where st_intersects(b.wkb_geometry, t.wkb_geometry) 
order by b.id, proportion desc;

Ini pada dasarnya melindungi terhadap situasi berikut - di mana area berwarna biru akan hilang: masukkan deskripsi gambar di sini

RobinL
sumber
1
Saya benar-benar memujanya ketika masalah pertama yang saya temui dengan jawaban SO diselesaikan dengan jawaban berikutnya. Cheers, @RobinL!
wfgeo