banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Rencontres QGIS 2025

L'appel à participation est ouvert jusqu'au 19 janvier 2025!

#1 Mon 24 March 2014 15:20

jeffm
Juste Inscrit !
Date d'inscription: 22 Sep 2005
Messages: 4

Réseau d'eau potable et requêtes spécifiques avec postgis

Bonjour,
Je démarre actuellement un projet de SIG pour la gestion d'un réseau d'eau potable, basé sur QGIS et Postgis.
J'ai récupéré le réseau existant et je m’interroge sur le modèle à adopter en vues des requêtes spécifiques à ce type de réseau. Je recherche donc des expériences sur ce type de réseau.
Par exemple, une des requêtes les plus courantes en la matière est la recherche des vannes à fermer pour isoler un secteur.
Comment procéder pour de telle requêtes? Faut-il utiliser les fonctions de parcours de réseau de postgis ou de pgrouting?
En vous remerciant!

Jeff

Dernière modification par jeffm (Mon 24 March 2014 15:20)

Hors ligne

 

#2 Tue 25 March 2014 11:41

jeffm
Juste Inscrit !
Date d'inscription: 22 Sep 2005
Messages: 4

Re: Réseau d'eau potable et requêtes spécifiques avec postgis

Bon, ma demande est sans doute un peu vague, je vais préciser.
J'ai un réseau, composé de tronçons et de vannes. L'idée est de pouvoir identifier l'ensemble des vannes permettant d'isoler un secteur, c'est à dire un ensemble de tronçons compris entre ces vannes.
J'ai une piste qui consisterait à fusionner tous les tronçon en un seul objet, puis à les découper au niveau des vannes. Ainsi en sélectionnant graphiquement un troncon, je pourrais par une intersection identifier les vannes à fermer.
Mais je souhaiterais savoir s'il n'y aurait pas dans les fonction de parcours de graphe une solution plus propre permettant de remonter chacune des branches d'un ensemble de tronçons pour identifier les vannes qui permettent de l'isoler.
Auriez-vous quelques pistes à me soumettre?
Merci!

Hors ligne

 

#3 Tue 25 March 2014 12:52

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: Réseau d'eau potable et requêtes spécifiques avec postgis

Bonjour,

Pour ce genre de parcours de graphe, l'utilisation de pgRouting peut etre utile, ou plus simplement, suivant le modele des données, la construction:
WITH RECURSIVE ...
qui permet une itération en SQL et donc de parcourir des elements connectés entre eux.

Vous auriez un exemple plus précis des données et de la notion "isoler un secteur" ?

Nicolas

Hors ligne

 

#4 Tue 25 March 2014 13:21

jeffm
Juste Inscrit !
Date d'inscription: 22 Sep 2005
Messages: 4

Re: Réseau d'eau potable et requêtes spécifiques avec postgis

Bonjour Nicolas,
Comme tu peux le voir, je n'ai sans doute pas assez pratiquer Postgis depuis que tu m'as formé!
En tout cas, merci de m'apporter tes lumière.
Je met en pièce jointe un extrait du réseau pour illustrer ce que je cherche à faire.
Pour le moment, mon réseau est en shape. Je ne l'ai pas intégré dans postgis. J'ai donc simplement 2 shapes, un avec les tronçons, et 1 avec les vannes. Je me suis assuré de la validité de la topologie, et j'ai découpé les troncons au niveau des vannes. Celle-ci sont donc sur les extremités des troncons qu'elles peuvent séparer. J'attendais d'avoir des pistes quand à ma problématique avant d'intégrer mon réseau dans postgis en utilisant un modèle permettant d'effectuer la requête souhaitée.

Merci de ton aide!

Jeff


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

Hors ligne

 

#5 Tue 25 March 2014 19:31

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: Réseau d'eau potable et requêtes spécifiques avec postgis

Salut,

Alors il est temps de refaire une formation smile

Avec une connexion des vannes en debut ou fin de tronçon, il est possible de répondre à la problématique avec une construction WITH RECURSIVE:
Le principe serait alors de parcourir le graphe a partir d'un tronçon donné (ou plusieurs) et de ne s'arrêter que lorsque 2 tronçons sont concernés par une vanne:

La table des tronçons (gid, geom)
La table des vannes (gid, geom)

Pour plus de facilité dans la requête qui va suivre, on ajoute une colonne à la table tronçon qui dit si le tronçon est concerné par une vanne (qu'il y en ait une ou deux, peu importe: une vanne permet de fermer ce tronçon)

Code:

alter table tronçon add column vanne boolean;
-- mise à jour de la colonne
update troncon set vanne = false;
update troncon t set vanne = true
from vanne v
where st_dwithin(v.geom, t.geom, 0.001);

Ensuite on parcourt cette table de façon itérative, en comparant un tronçon et son tronçon connecté (utilisation de st_dwithin pour trouver un tronçon connecté: plus rapide et souvent plus robuste que st_intersects entre une ligne et un point):
si les deux possèdent une vanne, alors il faut fermer cette vanne: on arrete la récursion pour cette branche.
Si les deux tronçons n'ont pas chacun une vanne, on continue a chercher le tronçon connecté suivant.

Dans la requête suivante, je liste les infos du tronçon précédent et tronçon suivant (prev_ et next_):
pour la partie non récursive de la requête, le tronçon précédent n'existe pas: valeurs vides ou nulles.
La liste des tronçons parcourus est stockée dans un tableau: c'est une des conditions d'arrêt de l'itération: on ne recherche pas des tronçons déjà cherchés.

La deuxième condition d'arrêt de l'itération est lorsque un tronçon et son suivant ont chacun une vanne sur le tronçon.

La requête itérative liste les identifiants de tronçons concernés par des vannes à fermer.
Pour retrouver les vannes les plus proches du tronçon de départ, on trouve toutes les vannes rattachés aux tronçons élus et on calcule la distance entre ces vannes et le tronçon de départ.
On ne garde alors que les vannes les plus proches (distinct on de la requête finale):

Code:

with recursive toclose(prev_geom, next_geom, prev_gid, next_gid, prev_vanne, next_vanne, stop, tgids, depth) as (
    -- partie non recursive
    select 'LINESTRING EMPTY'::geometry, t.geom, -1, t.gid, false, t.vanne, false, ARRAY[t.gid], 1 as a
    from troncon t
    where t.gid = 30

    UNION ALL
    -- partie recursive
    select o.next_geom, t.geom, o.next_gid, t.gid, o.next_vanne, t.vanne, (o.next_vanne AND t.vanne), o.tgids || t.gid, o.depth + 1
    from troncon t, toclose o
    where 
    -- connection entre troncons
    st_dwithin(t.geom, o.next_geom, 0.001)
    -- connexion entre deux troncon sans vanne
    and not stop
    -- troncon pas parcouru
    and not (t.gid = any(tgids))
), -- les troncons concernés par les vannes a fermer
tr as ( 
    select distinct prev_gid as gid, prev_geom as geom
    from toclose
    where stop
), -- les vannes les plus proches du troncon de ref appartenant a ces troncons
vannes as (
    select v.gid as vanne_gid, tr.gid as troncon_gid, st_distance(v.geom, t.geom), v.geom
    from vanne v, tr, troncon t
    where t.gid = 30
    and st_dwithin(v.geom, tr.geom, 0.001)
    order by 1, 2
) select distinct on (1) vanne_gid, troncon_gid, geom
from vannes;

L'image montre le résultat de la requête pour le tronçon #27

Nico


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

Hors ligne

 

#6 Tue 25 March 2014 20:53

vincentp
Participant actif
Lieu: Drôme
Date d'inscription: 18 Jul 2006
Messages: 128
Site web

Re: Réseau d'eau potable et requêtes spécifiques avec postgis

Salut,

Nicolas Ribot a écrit:

Salut,

Alors il est temps de refaire une formation smile

Avec une connexion des vannes en debut ou fin de tronçon, il est possible de répondre à la problématique avec une construction WITH RECURSIVE:
Le principe serait alors de parcourir le graphe a partir d'un tronçon donné (ou plusieurs) et de ne s'arrêter que lorsque 2 tronçons sont concernés par une vanne:

La table des tronçons (gid, geom)
La table des vannes (gid, geom)

Pour plus de facilité dans la requête qui va suivre, on ajoute une colonne à la table tronçon qui dit si le tronçon est concerné par une vanne (qu'il y en ait une ou deux, peu importe: une vanne permet de fermer ce tronçon)

Code:

alter table tronçon add column vanne boolean;
-- mise à jour de la colonne
update troncon set vanne = false;
update troncon t set vanne = true
from vanne v
where st_dwithin(v.geom, t.geom, 0.001);

Ensuite on parcourt cette table de façon itérative, en comparant un tronçon et son tronçon connecté (utilisation de st_dwithin pour trouver un tronçon connecté: plus rapide et souvent plus robuste que st_intersects entre une ligne et un point):
si les deux possèdent une vanne, alors il faut fermer cette vanne: on arrete la récursion pour cette branche.
Si les deux tronçons n'ont pas chacun une vanne, on continue a chercher le tronçon connecté suivant.

Dans la requête suivante, je liste les infos du tronçon précédent et tronçon suivant (prev_ et next_):
pour la partie non récursive de la requête, le tronçon précédent n'existe pas: valeurs vides ou nulles.
La liste des tronçons parcourus est stockée dans un tableau: c'est une des conditions d'arrêt de l'itération: on ne recherche pas des tronçons déjà cherchés.

La deuxième condition d'arrêt de l'itération est lorsque un tronçon et son suivant ont chacun une vanne sur le tronçon.

La requête itérative liste les identifiants de tronçons concernés par des vannes à fermer.
Pour retrouver les vannes les plus proches du tronçon de départ, on trouve toutes les vannes rattachés aux tronçons élus et on calcule la distance entre ces vannes et le tronçon de départ.
On ne garde alors que les vannes les plus proches (distinct on de la requête finale):

Code:

with recursive toclose(prev_geom, next_geom, prev_gid, next_gid, prev_vanne, next_vanne, stop, tgids, depth) as (
    -- partie non recursive
    select 'LINESTRING EMPTY'::geometry, t.geom, -1, t.gid, false, t.vanne, false, ARRAY[t.gid], 1 as a
    from troncon t
    where t.gid = 30

    UNION ALL
    -- partie recursive
    select o.next_geom, t.geom, o.next_gid, t.gid, o.next_vanne, t.vanne, (o.next_vanne AND t.vanne), o.tgids || t.gid, o.depth + 1
    from troncon t, toclose o
    where 
    -- connection entre troncons
    st_dwithin(t.geom, o.next_geom, 0.001)
    -- connexion entre deux troncon sans vanne
    and not stop
    -- troncon pas parcouru
    and not (t.gid = any(tgids))
), -- les troncons concernés par les vannes a fermer
tr as ( 
    select distinct prev_gid as gid, prev_geom as geom
    from toclose
    where stop
), -- les vannes les plus proches du troncon de ref appartenant a ces troncons
vannes as (
    select v.gid as vanne_gid, tr.gid as troncon_gid, st_distance(v.geom, t.geom), v.geom
    from vanne v, tr, troncon t
    where t.gid = 30
    and st_dwithin(v.geom, tr.geom, 0.001)
    order by 1, 2
) select distinct on (1) vanne_gid, troncon_gid, geom
from vannes;

L'image montre le résultat de la requête pour le tronçon #27

Nico


Nicolas a été plus vite que moi, j'allais envoyer une requete with récursive également.

Par contre pour tout ce qui est travail sur les réseaux, il est important de noter que c'est la topologie qui est primordiale : savoir qu'est ce qui est connecté à quoi.
Donc en général on fait les choses en deux temps :
1/ construction de la topologie de données à partir des informations géométriques
2/ interrogation sur cette topologie

On ne fait cette opération de construction qu'une seule fois ou bien quand le réseau change. Ça permet de détecter de façon initiale les erreurs géométriques sur le réseau également, ce qui évite des ennuis car ce n'est pas forcément facile de le vérifier par la suite lors des lancements d'algos.
On représente en général un réseau par des noeuds et des arêtes, la construction de topologie consistant alors à remplir un champ noeud_debut et un champ noeud_fin pour chaque arête.

Ensuite on peut interroger la topologie, en se basant sur des relations basées sur des correspondances d'ids plutot que des relations spatiales. On gagne aussi en rapidité de la requête.

On peut également pour cela utiliser la topologie PostGIS, et faire tourner les requêtes récursives dessus.
Il y a des exemples dans la présentation du pgconf Europe 2012 ici :
http://oslandia.github.io/presentations/

La problématique ensuite dans la gestion de réseau est de garder cette correspondance topologie/géométrie correcte. On peut utiliser des triggers pour le faire automatiquement, ou mettre des contraintes, ou s'assurer que l'applicatif est fait pour.

Une fois qu'on a une topologie correcte, l'avantage est de pouvoir ensuite faire tourner d'autres types d'applications qui fonctionnent sur des graphes, comme par exemple pgrouting, ou bien EPANET pour de la simulation (et ça tombe bien on vient de sortir un plugin qgis : http://www.oslandia.com/qgis-plugin-for … nt-en.html )

Vincent

Hors ligne

 

#7 Thu 27 March 2014 09:42

jeffm
Juste Inscrit !
Date d'inscription: 22 Sep 2005
Messages: 4

Re: Réseau d'eau potable et requêtes spécifiques avec postgis

Bonjour, et merci pour vos réponses!
Ça fonctionne parfaitement. Effectivement, il va falloir que je me remette à niveau! C'est le problème de peu pratiquer....
Tu es dans quelle structure aujourd'hui Nicolas? Tu fais toujours des formations?

Merci également à Vincent. Le plugin qgis de connexion à EPANET m'intéresse particulièrement. Le service AEP pour lequel je travaille est en train de s'équiper et les outils de modélisation font partie de leurs problématiques.

Merci encore.

Jeff

Hors ligne

 

#8 Fri 28 March 2014 15:27

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: Réseau d'eau potable et requêtes spécifiques avec postgis

Bonjour,

Cool que ca marche en l'etat, mais comme le dit Vincent, la problématique est assez riche et potentiellement complexe pour bien préparer le modèle et les données avant leur exploitation.

Je suis désormais à mon compte et oui, je donne toujours des formations.

A bientot

Nicolas

Hors ligne

 

#9 Wed 06 September 2017 07:54

poterezer
Juste Inscrit !
Date d'inscription: 5 Sep 2017
Messages: 2

Re: Réseau d'eau potable et requêtes spécifiques avec postgis

Bonjour, j
Je me permets de relancer le sujet. L'approche est très intéressante, moi, j'ai eu à travailler sur Qgis en utilisant les index spatiaux, même si c'est légèrement plus lent je pense que sur postgis, ca tient le coup sur 15 000 tronçons ( le cas de ma ville).
Cependant, l'approche présentée est limitée. Il ne suffit pas juste de s'arrêter quand on trouve des vannes. En effet, il faudrait tenir compte aussi de la topologie du réseau de distribution.
Imaginez un peu dans un réseau le cas des retours d'eau, on a des tronçons secondaires connectés à un principal qui desservent des zones élevées en altitude.
En cas d'incident, l'eau continuera à venir de la source mais il y aura aussi  un retour d'eau qu'il faut arrêter pour gagner sur le plan économique, surtout quand les zones sont forte altitude par rapport à la conduite touchée, il faudrait donc tenir compte de ces cas pour avoir un outil optimisé pour prendre les bonnes décisions. J'ai travaillé dessus mais ce n'est pas abouti, en effet les retours d'eau sont dans certains cas complexes à saisir.

Hors ligne

 

Pied de page des forums

Powered by FluxBB