Eu tenho uma tabela de polígonos (grupos de blocos de censo) no postgres. Quero marcar cada grupo de blocos com a cidade (outra tabela de polígonos) em que reside principalmente. Isso é possível? Estou pensando que precisaria essencialmente criar algo como:
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
mas essa consulta está demorando uma eternidade (eu tenho cerca de 5.000 grupos de blocos e 375 cidades ...). Alguma sugestão sobre como fazer essa consulta funcionar, se estiver incorreta ou mais rápida, se estiver correta?
postgis
postgresql
eirvin
fonte
fonte
Respostas:
A maneira como você está fazendo isso funcionará, mas levará muito tempo, pois o postgis está tentando criar a geometria da interseção de todas as combinações "grupo de blocos versus cidade", mesmo quando elas nem se tocam.
Adicione outra verificação de condição à sua cláusula WHERE para verificar se as duas geometrias interceptam e coloque-a antes da existente:
No SQL, se você tiver uma lista de condições na cláusula WHERE, elas serão testadas pela ordem em que foram gravadas. Se um FALSE for retornado em uma das operações anteriores, a consulta simplesmente ignorará a verificação de outras condições, pois o resultado será sempre FALSE.Além disso, verifique se você possui índices espaciais em blockgroups.wkb_geometry e towns.wkb_geometry.
fonte
ST_Intersects
é o caminho certo a seguir, mas o planejador pode ou não executar as condições na ordem em que foram escritas. Veja os documentos do Postgres para detalhes sobre isso.ST_Intersects
eST_Intersection
tenho o mesmo custo na minha instalação (100), portanto, para ser sincero, não tenho certeza do que o planejador está fazendo, mas sempre parece fazer a coisa certa aqui.Acrescentando a resposta muito útil de Alexandre, se algumas de suas unidades censitárias abrangerem três de suas cidades (e, portanto, você não pode garantir mais de 50% de quedas em qualquer cidade), faça o seguinte:
Isso basicamente protege contra a seguinte situação - na qual as áreas em azul desapareceriam:
fonte
Com o operador st_intersects e &&, você pode usar isto: Calcolo_perc_intersez_postgis
fonte