Расчет процента площади пересечения в где пункт


15

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

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 или Places), то, вероятно, нет необходимости рассчитывать процент перекрытия.
dbaston

Ответы:


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 возвращается в одной из ранних операций, запрос просто пропустит проверку остальных условий, поскольку результатом всегда будет FALSE.

Также убедитесь, что у вас есть пространственные индексы для blockgroups.wkb_geometry и towns.wkb_geometry.


1
Добавление ST_Intersects- правильный путь, но планировщик может выполнять или не выполнять условия в том порядке, в котором они написаны. См. Документацию Postgres для подробностей об этом. ST_Intersectsи ST_Intersectionимеют одинаковую стоимость на мою установку (100), поэтому, если честно, я не уверен, что делает планировщик, но здесь, кажется, всегда поступают правильно.
dbaston

Ааа ... Я предполагал, что условия будут проверены, как на других языках. Но я думаю, это даст планировщику еще один вариант.
Александр Нето

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
Я абсолютно обожаю это, когда самая первая проблема, с которой я сталкиваюсь с ответом SO, будет решена с помощью следующего ответа. Ура, @RobinL!
wfgeo

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.