У меня есть таблица полигонов (групп блоков переписи) в 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 городов ...). Любые предложения о том, как заставить этот запрос работать вообще, если он неправильный, или быстрее, если он правильный?
postgis
postgresql
eirvin
источник
источник
Ответы:
То, как вы это делаете, будет работать, но это займет слишком много времени, так как Postgis пытается создать геометрию пересечения каждой комбинации «блок-группа против города», даже если они даже не касаются.
Добавьте еще одну проверку условия в ваше предложение WHERE, чтобы проверить, пересекаются ли две геометрии, и поместите ее перед существующей:
В SQL, если у вас есть список условий в предложении WHERE, они проверяются в порядке их написания. Если FALSE возвращается в одной из ранних операций, запрос просто пропустит проверку остальных условий, поскольку результатом всегда будет FALSE.Также убедитесь, что у вас есть пространственные индексы для blockgroups.wkb_geometry и towns.wkb_geometry.
источник
ST_Intersects
- правильный путь, но планировщик может выполнять или не выполнять условия в том порядке, в котором они написаны. См. Документацию Postgres для подробностей об этом.ST_Intersects
иST_Intersection
имеют одинаковую стоимость на мою установку (100), поэтому, если честно, я не уверен, что делает планировщик, но здесь, кажется, всегда поступают правильно.В дополнение к очень полезному ответу Александра, если некоторые из ваших переписных единиц могут охватывать три ваших города (и, следовательно, вы не можете гарантировать более 50% падений в любом городе), вы можете сделать это:
Это в основном защищает от следующей ситуации - в которой исчезают синие области:
источник
С st_intersects и оператором && вы можете использовать это: Calcolo_perc_intersez_postgis
источник