обчислення відсотка площі перетину, де застереження


15

У мене є таблиця полігонів (групи блоків перепису) у постгресах. Я хочу позначити кожну групу блоків містечком (іншою таблицею багатокутників), в якій вона знаходиться в основному. Чи можливо це? Я думаю, що мені потрібно створити щось на кшталт:

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  

але цей запит бере назавжди (у мене близько 5000 блокових груп та 375 містечок ...). Будь-які пропозиції, як змусити цей запит працювати або взагалі, якщо він неправильний, або швидше, якщо він правильний?


Здається, що ви хочете позначити групи блоків на основі максимального перекриття? Якщо так, дивіться цю відповідь . Якщо у ваших "містах" також є переписні географії (скажімо, MCD або Місця), певно, не потрібно обчислювати відсотки перекриття.
дбастон

Відповіді:


23

Те, як ви це робите, буде працювати, але це займе занадто багато часу, оскільки postgis намагається створити геометрію перетину кожної комбінації «блок-група проти міста», навіть коли вони навіть не торкаються.

Додайте ще одну перевірку умови до свого пункту WHERE, щоб перевірити, чи перетинаються дві геометрії, і поставте її перед наявною:

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, якщо у вас є перелік умов у пункті WHERE, вони перевіряються у порядку, в якому вони записані. Якщо FALSE буде повернуто в одній із ранніх операцій, querie просто пропустить інші умови перевірки, оскільки результат завжди буде ЛІЖНИМ.

Також переконайтеся, що у вас є просторові індекси на blockgroups.wkb_geometry та town.wkb_geometry.


1
Додавання ST_Intersects- це правильний спосіб перейти сюди, але планувальник може виконати або не виконати умови в тому порядку, про який вони написали. Докладніше про це див. У документах Postgres . ST_Intersectsі ST_Intersectionмаю однакову вартість моєї установки (100), тому, якщо чесно, я не впевнений, що планувальник робить, але завжди здається, що це робить правильно.
дбастон

Ааа ... я припускав, що умови перевірятимуться, як і в інших мовах. Але я думаю, це дає планувальникові ще один варіант.
Олександр Нето

10

Додавши до Олександра дуже корисну відповідь, якщо деякі з ваших переписних одиниць можуть охоплювати три ваші міста (а значить, ви не можете гарантувати більше 50% падінь у будь-якому місті), ви можете зробити це:

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;

Це в основному захищає від наступної ситуації - в якій сині області зникнуть: введіть тут опис зображення


1
Я абсолютно обожнюю його, коли найперше питання, з яким я стикаюсь з відповіддю на відповідь, вирішується вже наступною відповіддю. Привіт, @RobinL!
wfgeo

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.