Esta é uma pergunta de acompanhamento para esta pergunta .
Eu tenho uma rede fluvial (multilinha) e alguns polígonos de drenagem (veja a figura abaixo). Meu objetivo é selecionar apenas os polígonos da cabeceira (verde).
Com a solução de John, posso extrair facilmente os pontos de partida do rio (estrelas). No entanto, eu posso ter situações (polígono vermelho) em que tenho pontos de partida em um polígono, mas o polígono não é um polígono de cabeceira, porque é levado pelo rio. Eu só quero os polígonos da cabeceira.
Tentei selecioná-los contando o número de interseções entre polígonos e rios (justificativa: um polígono de cabeceira deveria ter apenas 1 interseção com o rio)
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
, onde poylg são os poylgons, start_points de johns respondem e stream é minha rede fluvial.
No entanto, isso leva uma eternidade e eu não o executei:
"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)"
Portanto, minha pergunta é: como posso consultar com eficiência polígonos de cabeceira?
Atualização: adicionei alguns dados de amostra à minha caixa de depósito . Os dados são do sudoeste da Alemanha. São dois arquivos de forma - um com fluxos e outro com polígonos.
polygons
contenha apenas os pontos que são fontes de rios (da pergunta anterior) e exclua os locais onde dois rios se encontram. Desculpe, por todas as perguntas, só quero ter certeza.polygons
que têm um rio que passa (o rio entra e sai do polígono) e os mantém com início (e os rios deixam apenas esse polígono).Respostas:
Acredito que o esquema geral (parcialmente testado até agora) é:
Encontre os pontos que representam as fontes de fluxo, como nesta resposta .
Interseção com a tabela de polígonos para obter uma contagem dos vértices de origem por polígono.
Use ST_DumpPoints em conjunto com o grupo por geometria para obter uma contagem de cada ponto. A idéia é contar quantos rios se encontram em um determinado ponto.
Um exemplo dessa consulta:
que retorna:
Execute uma interseção
3
contra a tabela de polígonos, para obter uma contagem (soma dos vértices) de junções de rio por polígono.Una os polígonos a partir
2
de então4
, rejeitando aqueles em que a contagem (soma dos vértices) dos pontos em uma junção é maior que a soma das fontes do rio, obtida pela soma das fontes por polígono das etapas 1 e 2. Se essa condição for válida, significa que pelo menos um dos rios que se encontra em uma junção teve origem fora do polígono em questão.Todos eles podem ser combinados em uma seqüência ampla de CTEs, a menos que algumas tabelas tenham sido criadas a partir das etapas que envolvem pontos (e indexadas).
Não tenho idéia de qual será o tempo de execução disso em um conjunto de dados completo, tendo testado apenas parte disso em um subconjunto, mas com um índice espacial na tabela de polígonos, haverá alguma assistência - obviamente não é possível aplique um índice aos pontos que emergem de ST_DumpPoints, para que uma verificação completa seja necessária lá, embora eles devam estar na memória até então.
Isso não está sendo publicado como uma resposta completa , mas como um trabalho em andamento e como uma chance de encontrar falhas na lógica. Consultas de trabalho em breve.
EDIT 1
Essa é a consulta que eu criei, que parece funcionar em um pequeno subconjunto de seus dados, mas é executada por horas no conjunto de dados completo.
EDIT 2 . Embora isso pareça produzir respostas corretas em um pequeno subconjunto, o tempo de execução no conjunto de dados completo é horrível , presumivelmente porque a consulta final está fazendo comparações n ^ 2 e não está usando um índice espacial. A solução provável seria quebrar a consulta e criar tabelas a partir dos pontos iniciais e das consultas dos polígonos, que podem ser indexadas espacialmente antes da etapa final.
fonte
No pseudo-código, isso deve funcionar:
Não tenho muita certeza de como criar a consulta e não posso testá-la sem um banco de dados para testar. É uma pergunta bem louca, eu acho. Mas deve funcionar!
fonte