Il s'agit d'une question complémentaire à cette question .
J'ai un réseau fluvial (multiligne) et quelques polygones de drainage (voir photo ci-dessous). Mon objectif est de ne sélectionner que les polygones d'amont (vert).
Avec la solution de John, je peux facilement extraire les points de départ de la rivière (étoiles). Cependant, je peux avoir des situations (polygone rouge) où j'ai des points de départ dans un polygone, mais le polygone n'est pas un polygone d'amont, car il est survolé par la rivière. Je veux seulement les polygones d'amont.
J'ai essayé de les sélectionner en comptant le nombre d'intersection entre les polygones et les rivières (justification: un polygone d'amont ne devrait avoir qu'une seule intersection avec la rivière)
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
, où poylg sont les poylgons, start_points de johns answer et stream est mon réseau fluvial.
Cependant, cela prend une éternité et je ne l'ai pas exécuté:
"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)"
Ma question est donc la suivante: comment puis-je interroger efficacement les polygones d'amont?
Mise à jour: j'ai ajouté des exemples de données à ma boîte de dépôt . Les données proviennent du sud-ouest de l'Allemagne. Il s'agit de deux fichiers de formes - un avec des flux et un avec des polygones.
polygons
ceux-ci ne contienne que les points qui sont des sources fluviales (de la question précédente) et exclure tout point de rencontre de deux fleuves. Désolé, pour toutes les questions, je veux juste être sûr.polygons
qui ont une rivière qui passe (la rivière entre et sort du polygone) et garder ceux avec des départs (et les rivières ne quittent que ce polygone).Réponses:
Je pense que le schéma général (partiellement testé jusqu'à présent) est le suivant:
Trouvez les points représentant les sources de flux, comme dans cette réponse .
Intersection avec la table des polygones pour obtenir un nombre de sommets source par polygone.
Utilisez ST_DumpPoints conjointement avec le regroupement par géométrie pour obtenir un décompte de chaque point. L'idée étant de compter le nombre de rivières qui se rencontrent à un point donné.
Un exemple d'une telle requête:
qui renvoie:
Exécutez une intersection de
3
contre la table des polygones, pour obtenir un compte (somme des sommets) des jonctions de rivière par polygone.Joignez les polygones à partir
2
de4
, en rejetant ceux où le nombre (somme de sommets) de points à une jonction est supérieur à la somme des sources de la rivière, obtenu en sommant les sources par polygone des étapes 1 et 2. Si cette condition est vérifiée, elle signifie qu'au moins une des rivières se rencontrant à une jonction, provient de l'extérieur du polygone en question.Ceux-ci peuvent tous être combinés ensemble dans une séquence étendue de CTE, à moins que certaines tables aient été créées à partir des étapes impliquant des points (et indexées).
Je n'ai aucune idée de ce que sera l'exécution de cela sur un ensemble de données complet, n'ayant testé qu'une partie de cela sur un sous-ensemble, mais avec un index spatial sur la table des polygones, il y aura une aide - il n'est évidemment pas possible de appliquer un index aux points qui émergent de ST_DumpPoints, donc une analyse complète y sera requise, bien qu'ils devraient être en mémoire d'ici là.
Ce n'est pas affiché comme une réponse complète , mais comme un travail en cours et une chance de trouver des failles dans la logique. Requêtes de travail à venir.
EDIT 1
C'est la requête que j'ai trouvée, qui semble fonctionner sur un petit sous-ensemble de vos données, mais qui s'exécute pendant des heures sur l'ensemble de données complet.
MODIFIER 2 . Bien que cela semble produire des réponses correctes sur un petit sous-ensemble, le temps d'exécution sur l'ensemble de données complet est horrible , probablement parce que la requête finale effectue n ^ 2 comparaisons et n'utilise pas d'index spatial. La solution probable serait de décomposer la requête et de créer des tables à partir des points initiaux et des points dans les requêtes polygonales, qui peuvent ensuite être indexées spatialement avant l'étape finale.
la source
En pseudo code, cela devrait fonctionner:
Je ne sais pas vraiment comment créer la requête, et je ne peux pas la tester sans base de données sur laquelle tester. C'est une question assez folle, je pense. Mais ça devrait marcher!
la source