nerede cümlede kesişme yüzdesinin hesaplanması


15

Postgres bir çokgen tablosu (sayım blok grupları) var. Her blok grubunu esas olarak içinde bulunan kasaba (başka bir çokgen tablo) ile etiketlemek istiyorum. Mümkün mü? Aslında şöyle bir şey yaratmam gerektiğini düşünüyorum:

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  

ama bu sorgu sonsuza kadar sürüyor (yaklaşık 5.000 blok grubu ve 375 kasabam var ...). Bu sorgunun yanlış olması durumunda nasıl çalıştığına dair herhangi bir öneriniz mi yoksa doğru ise daha hızlı mı?


Blok gruplarını maksimum çakışmaya göre etiketlemek mi istiyorsunuz? Eğer öyleyse, bu cevaba bakınız . 'Kasabalarınız' da Sayım coğrafyalarıysa (MCD'ler veya Yerler, örneğin) örtüşme yüzdesini hesaplamaya gerek yoktur.
dbaston

Yanıtlar:


23

Yaptığınız yol işe yarayacak ama çok zaman alacak, çünkü postgis dokunmadığı zamanlarda bile her "blok grubu vs kasaba" kombinasyonunun kesişim geometrisini yaratmaya çalışıyor.

İki geometrinin kesişip kesilmediğini kontrol etmek için WHERE yan tümcesinize başka bir koşul denetimi ekleyin ve mevcut geometrinin önüne koyun:

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

SQL'de WHERE yan tümcesinde koşulların bir listesi varsa, bunlar yazıldıkları sıraya göre test edilir. İlk işlemlerden birinde YANLIŞ döndürülürse, sorgu her zaman YANLIŞ olacağından diğer koşulların denetimini atlayacaktır.

Ayrıca, blockgroups.wkb_geometry ve towns.wkb_geometry'de boşluk dizinleri bulunduğundan emin olun.


1
Ekleme ST_Intersectsburaya gitmek için doğru yoldur, ancak planlayıcı koşulları yazıldıkları sırayla yürütebilir veya yürütebilir. Bununla ilgili ayrıntılar için Postgres belgelerine bakın . ST_Intersectsve ST_Intersectionkurulumumda aynı maliyete sahip (100), bu yüzden dürüst olmak gerekirse planlayıcının ne yaptığından emin değilim, ama her zaman burada doğru olanı yapıyor gibi görünüyor.
dbaston

Ahh ... Bu koşulların diğer dillerde olduğu gibi kontrol edileceğini varsaydım. Ama planlayıcıya başka bir seçenek verdiğini tahmin ediyorum.
Alexandre Neto

10

Alexandre'ın çok yararlı cevabına ek olarak, sayım birimlerinizden bazıları kasabalarınızdan üçünü kapsayabiliyorsa (ve bu nedenle herhangi bir kasabada% 50'den fazla düşüşü garanti edemezseniz) bunu yapabilirsiniz:

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;

Bu temel olarak aşağıdaki durumlara karşı korur - mavi alanların kaybolacağı: resim açıklamasını buraya girin


1
Bir SO cevabıyla karşılaştığım ilk sorun bir sonraki cevapla çözüldüğünde kesinlikle tapıyorum. Şerefe, @RobinL!
wfgeo

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.