Esta es una pregunta de seguimiento a esta pregunta .
Tengo una red fluvial (multilínea) y algunos polígonos de drenaje (ver imagen a continuación). Mi objetivo es seleccionar solo los polígonos de cabecera (verde).
Con la solución de John puedo extraer fácilmente los puntos de inicio del río (estrellas). Sin embargo, puedo tener situaciones (polígono rojo) en las que tengo puntos de inicio en un polígono, pero el polígono no es un polígono de cabecera, porque el río lo vuela. Solo quiero los polígonos de cabecera.
Traté de seleccionarlos contando el número de intersección entre polígonos y ríos (justificación: un polígono de cabecera debería tener solo 1 intersección con el río)
SELECT
polyg.*
FROM
polyg, start_points, stream
WHERE
st_contains(polyg.geom, start_points.geom)
AND ST_Npoints(ST_Intersection(poly.geom, stream.geom)) = 1
, donde poylg son los polígonos, start_points de johns answer y stream es mi red fluvial.
Sin embargo, esto lleva una eternidad y no lo ejecuté:
"Nested Loop (cost=0.00..20547115.26 rows=641247 width=3075)"
" Join Filter: _st_contains(ezg.geom, start_points.geom)"
" -> Nested Loop (cost=0.00..20264906.12 rows=327276 width=3075)"
" Join Filter: (st_npoints(st_intersection(ezg.geom, rivers.geom)) = 1)"
" -> Seq Scan on ezg_2500km2_31467 ezg (cost=0.00..2161.52 rows=1648 width=3075)"
" Filter: ((st_area(geom) / 1000000::double precision) < 100::double precision)"
" -> Materialize (cost=0.00..6364.77 rows=39718 width=318)"
" -> Seq Scan on stream_typ rivers (cost=0.00..4498.18 rows=39718 width=318)"
" -> Index Scan using idx_river_starts on river_starts start_points (cost=0.00..0.60 rows=1 width=32)"
" Index Cond: (ezg.geom && geom)"
Entonces mi pregunta es: ¿cómo puedo consultar eficientemente los polígonos de cabecera?
Actualización: agregué algunos datos de muestra a mi Dropbox . Los datos son del suroeste de Alemania. Son dos archivos de forma: uno con secuencias y otro con polígonos.
polygons
esos contenga solo aquellos puntos que son fuentes de ríos (de la pregunta anterior) y excluya cualquier lugar donde se unan dos ríos. Lo sentimos, para todas las preguntas, solo quiero estar seguro.polygons
que tienen un río que pasa (el río entra y sale del polígono) y mantener a aquellos con comienzos (y los ríos solo dejan este polígono).Respuestas:
Creo que el esquema general (parcialmente probado hasta ahora) es:
Encuentre los puntos que representan las fuentes de flujo, como en esta respuesta .
Interseca con la tabla de polígonos para obtener un recuento de vértices de origen por polígono.
Use ST_DumpPoints junto con group by geometry para obtener un recuento de cada punto. La idea es contar cuántos ríos se encuentran en un punto dado.
Un ejemplo de tal consulta:
que devuelve:
Ejecute intersecciones de
3
contra la tabla de polígonos, para obtener un recuento (suma de vértices) de uniones de ríos por polígono.Une los polígonos desde
2
adelante4
, rechazando aquellos donde el recuento (suma de vértices) de puntos en una unión es mayor que la suma de las fuentes del río, obtenido al sumar las fuentes por polígono de los pasos 1 y 2. Si esta condición se cumple, significa que al menos uno de los ríos que se unen en un cruce, se originó fuera del polígono en cuestión.Todos estos se pueden combinar en una secuencia grande de CTE, a menos que se hayan creado algunas tablas a partir de los pasos que involucran puntos (e indexados).
No tengo idea de cuál será el tiempo de ejecución de esto en un conjunto de datos completo, habiendo probado solo una parte de esto en un subconjunto, pero con un índice espacial en la tabla de polígonos, habrá algo de ayuda, obviamente no es posible aplique un índice a los puntos que emergen de ST_DumpPoints, por lo que se requerirá un escaneo completo allí, aunque para entonces deberían estar en la memoria.
Esto no se publica como una respuesta completa , sino como un trabajo en progreso y una oportunidad para encontrar fallas en la lógica. Consultas de trabajo próximamente.
EDITAR 1
Esta es la consulta que se me ocurrió, que parece funcionar en un pequeño subconjunto de sus datos, pero se ejecuta durante horas en el conjunto de datos completo.
EDITAR 2 . Si bien esto parece producir respuestas correctas en un pequeño subconjunto, el tiempo de ejecución en el conjunto de datos completo es horrible , presumiblemente porque la consulta final está haciendo n ^ 2 comparaciones y no está usando un índice espacial. La solución probable sería dividir la consulta y crear tablas a partir de los puntos iniciales y el punto en consultas de polígonos, que luego se pueden indexar espacialmente antes del paso final.
fuente
En pseudocódigo, esto debería funcionar:
No estoy realmente seguro de cómo construir la consulta, y no puedo probarla sin una base de datos para probar. Es una consulta bastante loca, creo. ¡Pero debería funcionar!
fuente