Pages: 1
- Sujet précédent - Couper une ligne à partir de points non positionnés sur la ligne - Sujet suivant
#1 Fri 09 November 2018 08:49
- ENTECH
- Participant occasionnel
- Date d'inscription: 5 Oct 2018
- Messages: 15
Couper une ligne à partir de points non positionnés sur la ligne
Bonjour,
Sur mon projet QGis, j'ai une ligne (conduite) qui représente la distribution AEP et autour de cette conduite, j'ai plusieurs points qui symbolisent les branchements particuliers. Ces points ne sont pas sur la conduite AEP.
J'aimerais savoir s'il est possible de créer une ligne (conduite) entre tous les points de branchements et la conduite principale AEP ? Et deuxièmement si on peut couper la conduite principale et créer un point au croisement de chaque conduite.
Merci pour votre aide.
Hors ligne
#2 Fri 09 November 2018 09:28
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3175
- Site web
Re: Couper une ligne à partir de points non positionnés sur la ligne
Bonjour,
Pour créer une ligne il faut deux points.
Donc soit vos branchement particuliers sont définis par deux points donc ce que vous cherchez et l'intersection de cette ligne avec la ligne symbolisant la conduite principale, soit vos branchement particuliers sont définis uniquement par un point, donc là il vous faut définir une règle, par exemple la perpendiculaire à la conduite passant par le point "branchement particulier".
Sur un logiciel comme autocad c'est facile. Avec une base de donnée comme postgis c'est un peu plus compliqué.
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne
#3 Fri 09 November 2018 10:02
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1538
Re: Couper une ligne à partir de points non positionnés sur la ligne
Bonjour,
Pour découper rapidement des lignes avec des points, regardez du coté des fn de référencement linéaire (st_lineLocatePoint par ex)
Pour construire une ligne avec des points, ordonnez ces points et appeler st_makeLine.
Sans plus de précision, ou de schéma, pas facile de savoir votre contexte.
Nicolas
Hors ligne
#4 Fri 09 November 2018 10:11
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3175
- Site web
Re: Couper une ligne à partir de points non positionnés sur la ligne
Bonjour,
Merci Nicolas je les connaissais pas celles là.
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne
#5 Fri 09 November 2018 10:15
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1538
Re: Couper une ligne à partir de points non positionnés sur la ligne
Hello Christophe: joue un peu avec: c'est tres rapide, super précis (abscisse curviligne) et ca permet de faire du calage auto de points sur des lignes ou PG (snapping), car st_lineLocatePoint "projète" le point sur la ligne.
Nicolas
Hors ligne
#6 Fri 09 November 2018 10:25
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3175
- Site web
Re: Couper une ligne à partir de points non positionnés sur la ligne
Bonjour,
Oui et du coup cela permettrait de régler efficacement des problèmes de cohérence entre deux référentiels topologiques. (problèmes de production avec les arrondis inhérents aux logiciels utilisés pour fabriquer les couches).
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne
#7 Fri 16 November 2018 19:11
- Rlucas
- Participant occasionnel
- Date d'inscription: 20 Apr 2018
- Messages: 31
Re: Couper une ligne à partir de points non positionnés sur la ligne
Bonjour,
Je travaille actuellement sur la correction de bases de données reseau d'eau et d'assainissement. Je suis tombé sur le même type de problème et je ne résiste pas à partager mes recherches et ma requête, pour la projection des points sur la canalisation principales. Je suis parti de cette requête que j'ai adaptée :
Code:
SELECT st_line_interpolate_point(géométrie de la ligne, st_line_locate_point(géométrie de la ligne, géométrie du point)) AS géométrie projetée, FROM table des lignes JOIN table des points ON st_distance(géométrie de ligne, géométrie du point) < distance_tampon_maximum_pour_l'accrochage
Source : http://blog.martzluff.net/le-map-matchi … stgisqgis/
Pour ne prendre que la projection sur la canalisation la plus proche (et non uniquement celles prises par la distance tampon), il faut utiliser une table intermédiaire avec les fonctions de fenètrage d'agrégats Rank() Over(Partition BY) qui permettent de hiérachiser les valeurs prises par le select en fonction d'un champ (ici la distance à la canalisation).
https://docs.postgresql.fr/8.4/tutorial-window.html
http://www.bortzmeyer.org/postgresql-quantiles.html
J'y ai aussi associé une partie de requête me permettant d'exclure tous les points de piquages déjà présents sur une canalisation (j'ai une table présentant des piquages situés sur la canalisation et d'autres à côté, on ne s'en rend compte qu'en zoomant, merci les dessinateurs autocad...)
J'ai aussi du créer une table dump avec de passer mes géometries en linestring simple au lieu d'une polyline (je n'ai pas trouvé comment l'intégrer dans la requête) avec SELECT (ST_Dump(geom)).geom
Ma requête, à laquelle il faut ensuite appliquer le st_makeline comme recommandé par Nicolas Ribot (et ajuster le select).
Code:
SELECT idappareil, geom, geom_projetee FROM ( SELECT st_distance(canalisation_dump.geom, piquages.geom), st_lineinterpolatepoint(canalisation_dump.geom, st_linelocatepoint(canalisation_dump.geom, piquages.geom)) AS geom_projetee, piquages.idappareil, RANK() OVER(PARTITION BY piquages.idappareil ORDER BY st_distance(canalisation_dump.geom, piquages.geom)) as rang FROM canalisation_dump JOIN piquages ON st_distance(canalisation_dump.geom, piquages.geom) < distance_tampon WHERE piquages.idappareil IN ( SELECT piquages.idappareil FROM piquages EXCEPT SELECT piquages.idappareil FROM piquages, canalisations WHERE ST_Intersects(piquages.geom, canalisations.geom) GROUP BY piquages.idappareil) ) AS temp WHERE rang = 1 (la distance la plus courte)
Bon après la requête pourrait être mieux formulée à mon avis, mais elle marche. Bon courage!
PS : les recommendations topologiques du standard COVADIS en aep n'imposent pas le découpage des canalisations principales pour les noeuds de branchements individuels, seulements pour les autres appareillages/ouvrages)
Dernière modification par Rlucas (Fri 16 November 2018 19:15)
Hors ligne
#8 Sat 17 November 2018 17:18
- sam92
- Juste Inscrit !
- Date d'inscription: 6 Nov 2018
- Messages: 7
Re: Couper une ligne à partir de points non positionnés sur la ligne
Bonjour,
Vous pouvez utiliser la fonction ST_ClosestPoint(line.geom,point.geom) http://www.postgis.org/docs/ST_ClosestPoint.html, qui réalise la même tâche que ST_LineInterpolatePoint(line.geom,ST_LineLocatePoint(line.geom,point.geom)).
Au lieu de "ST_Distance(line.geom,point.geom) < distance_tampon", vous devriez utiliser la fonction ST_DWithin(line.geom,point.geom,distance_tampon) http://postgis.net/docs/ST_DWithin.html, elle exploite les index spatiaux, ce qui vous permettra de réduire considérablement le temps d'exécution de la requête.
Sam
Hors ligne
#9 Sat 17 November 2018 19:02
- sam92
- Juste Inscrit !
- Date d'inscription: 6 Nov 2018
- Messages: 7
Re: Couper une ligne à partir de points non positionnés sur la ligne
Rlucas, cela donnerait quelque chose comme ça :
Code:
WITH l AS (SELECT id, (st_dump(geom)).geom FROM lignes) SELECT DISTINCT ON (p.id) p.id as idpoint, st_makeline(st_geometryn(p.geom,1),st_closestpoint(l.geom,p.geom)) as geom FROM points as p JOIN l ON st_dwithin(l.geom,p.geom,distance_tampon) ORDER BY idpoint, st_distance(l.geom,p.geom);
La clause DISTINCT ON (colonnes ou ensemble de colonnes) https://www.postgresql.org/docs/9.5/sql … L-DISTINCT ne garde pour chaque colonne ou ensemble de colonnes que le premier résultat, les suivants sont retirés.
En l'occurrence, couplé à un tri sur la distance, cette clause conserve le point projeté sur la ligne le plus proche du point...
Par ailleurs, dans le cas où il existerait plusieurs lignes situées à une même distance d'un point, cette clause ne conserve tout de même qu'un résultat, à la différence de l'utilisation de la fonction de fenêtrage RANK qui en a été faite, qui aurait retourné plusieurs points projetés.
En outre, il a été intégré dans la requête le dump des lignes.
Enfin, grâce à la fonction ST_GeometryN(geom,Nième_Point) https://postgis.net/docs/ST_GeometryN.html, la requête est capable de travailler avec des Points contenus dans une table dont le type géométrique a été renseigné comme étant MultiPoint.
Pour ne pas créer de liens pour les points qui se trouvent déjà sur une ligne, la méthode la moins coûteuse en temps que j'ai pu trouver est de supprimer à la fin de la requête ces points-là :
Code:
WITH l AS (SELECT id, (st_dump(geom)).geom FROM lignes) ,proj AS (SELECT DISTINCT ON (p.id) p.id as idpoint, st_makeline(st_geometryn(p.geom,1),st_closestpoint(l.geom,p.geom)) as geom, st_distance(l.geom,p.geom) as dist FROM points as p JOIN l ON st_dwithin(l.geom,p.geom,distance_tampon) ORDER BY idpoint, st_distance(l.geom,p.geom)) SELECT idpoint, geom FROM proj WHERE dist != 0;
Sam
Hors ligne
#10 Tue 20 November 2018 06:28
- zang
- Participant actif
- Date d'inscription: 4 Oct 2005
- Messages: 55
Re: Couper une ligne à partir de points non positionnés sur la ligne
Bonjour,
Pour découper ensuite les lignes de conduite à partir des points localisés sur ces lignes, j'avais trouvé cette requête mais elle ne fonctionne pas très bien (ou bien je ne l'utilise pas très bien au choix). En effet, certaines lignes sont supprimées aléatoirement. J'ai mis ça sur le compte de la topologie des lignes qui n'étaient pas parfaite car venant d'un plan autocad mais je n'ai pas persévéré...
Code:
CREATE TABLE ln_cut AS -- premiere table des positions des points par rapport a "leurs" lignes with locus as ( -- on genere la position du debut de la ligne (index 0) pour le premier segment à découper select l.gid, 0 as l from ln l UNION ALL -- on genere la position de la fin de la ligne (index 1) pour le dernier segment à découper select l.gid, 1 as l from ln l UNION ALL -- calcul des positions des points par rapport aux lignes select l.gid, ST_LineLocatePoint(l.geom, pt.geom) as l from ln l, pt pt where st_dwithin(l.geom, pt.geom, 0.01) order by gid, l ), -- deuxieme table qui ajoute un index croissant par position croissante, pour permettre de faire la jointure plus tard sur elle-meme: loc_with_idx as ( select gid, l, rank() over (partition by gid order by l) as idx from locus ) -- decoupage final de chaque ligne avec les positions des points sur la ligne, grace a st_line_substring select l.gid, ST_LineSubstring(l.geom, loc1.l, loc2.l) as geom from loc_with_idx loc1, loc_with_idx loc2, ln l where l.gid = loc1.gid and loc1.gid = loc2.gid and loc2.idx = loc1.idx+1;
Hors ligne
Pages: 1
- Sujet précédent - Couper une ligne à partir de points non positionnés sur la ligne - Sujet suivant