Tengo una tabla de polígonos (grupos de bloques censales) en postgres. Quiero etiquetar cada grupo de bloques con la ciudad (otra tabla de polígonos) en la que reside principalmente. es posible? Estoy pensando que esencialmente necesitaría crear 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
pero esta consulta lleva una eternidad (tengo alrededor de 5,000 grupos de bloques y 375 ciudades ...). ¿Alguna sugerencia sobre cómo hacer que esta consulta funcione si es incorrecta o más rápida si es correcta?
postgis
postgresql
eirvin
fuente
fuente
Respuestas:
La forma en que lo hace funcionará, pero tomará demasiado tiempo, ya que postgis está tratando de crear la geometría de la intersección de cada combinación de "grupo de bloques vs ciudad", incluso cuando ni siquiera se tocan.
Agregue otra verificación de condición a su cláusula WHERE para verificar si las dos geometrías interceptan y póngala antes de la existente:
En SQL, si tiene una lista de condiciones en la cláusula WHERE, se prueban por el orden en que se escriben. Si se devuelve un FALSO en una de las primeras operaciones, la consulta simplemente omitirá la comprobación de otras condiciones, ya que el resultado será siempre FALSO.Además, asegúrese de tener índices espaciales en blockgroups.wkb_geometry y towns.wkb_geometry.
fuente
ST_Intersects
es la forma correcta de hacerlo aquí, pero el planificador puede o no ejecutar las condiciones en el orden en que están escritas. Vea los documentos de Postgres para más detalles sobre esto.ST_Intersects
yST_Intersection
tengo el mismo costo en mi instalación (100), así que para ser honesto, no estoy seguro de lo que está haciendo el planificador, pero siempre parece hacer lo correcto aquí.Además de la muy útil respuesta de Alexandre, si algunas de sus unidades censales pueden abarcar tres de sus ciudades (y, por lo tanto, no puede garantizar más del 50% de caídas en cualquier ciudad), puede hacer esto:
Esto básicamente protege contra la siguiente situación, en la que las áreas en azul desaparecerían:
fuente
Con st_intersects y && operator, puede usar esto: Calcolo_perc_intersez_postgis
fuente