Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
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

Suite à un problème technique intervenu entre le 22 et le 23 mars, nous avons du procéder dans la soirée du 25 mars, à la restauration de la base de données du 24 mars (matinée).

En clair, nous avons perdu vos contributions et inscriptions du dimanche 24 et du lundi 25 mars.
Nous vous prions de nous excuser.

#1 Mon 04 July 2016 14:41

Razorbak
Participant assidu
Lieu: Clermont Ferrand
Date d'inscription: 7 Oct 2007
Messages: 505

[PostGis] Découper une ligne par des points non snappés sur la ligne

Bonjour,

Je suis déjà tombé sur des sujets ressemblant à mon problème mais sans jamais trouver de solution réelle.
Voici ce que je cherche à faire :
- je dispose d'une couche de ligne : des cours d'eau
- je dispose d'une couche de points : des ponts, non positionnés directement sur la ligne (topologiquement parlant)
- je souhaiterai découper ma ligne à chaque fois que l'on rencontre un point

J'ai donc commencé par "snapper" mes points sur les lignes en faisant cette requête :

Code:

SELECT a.id_point, b.code_cdo, ST_ClosestPoint(b.geom, a.geom) as geom_newpoint, ST_AsText(ST_ClosestPoint(b.geom, a.geom))
            FROM points as a, cdo as b
            WHERE b.code_cdo = 'toto' AND ST_Distance(a.geom, b.geom) < 200

Elle fonctionne bien. Pour l'instant, j'ai juste sélectionné un seul cours d'eau "toto" et uniquement les points situés à moins de 200m de la ligne.

Maintenant, j'aimerai donc couper cette ligne en fonction de ces points. Et c'est là que ça ne fonctionne pas. Je n'arrive pas à récupérer une table avec cette ligne "toto" découpée.
Voici ma requête complète :

Code:

WITH newpoint as (SELECT a.id_point, b.code_cdo, ST_ClosestPoint(b.geom, a.geom) as geom_newpoint, ST_AsText(ST_ClosestPoint(b.geom, a.geom))
            FROM points as a, cdo as b
            WHERE b.code_cdo = 'toto' AND ST_Distance(a.geom, b.geom) < 200)

SELECT row_number() over() as id, b.cdo, ST_Split(a.geom, b.geom_newpoint) as geom, ST_AsText((ST_Split(a.geom, b.geom_newpoint))) as text
FROM cdo as a, newpoint as b
WHERE a.cdo = 'toto'

Quelqu'un pourrait-il m'aiguiller un peu SVP ?
Merci

Hors ligne

 

#2 Mon 04 July 2016 14:54

ppluvinet
Participant assidu
Lieu: LYON
Date d'inscription: 6 Aug 2007
Messages: 606

Re: [PostGis] Découper une ligne par des points non snappés sur la ligne

Bonjour,

La communauté m'avait bien aidé à l'époque pour faire un travail un peu similaire
http://georezo.net/forum/viewtopic.php?id=84911
Est-ce que ca peut également  t'aider ?

Bon courage,


Pascal PLUVINET

Hors ligne

 

#3 Mon 04 July 2016 15:15

Razorbak
Participant assidu
Lieu: Clermont Ferrand
Date d'inscription: 7 Oct 2007
Messages: 505

Re: [PostGis] Découper une ligne par des points non snappés sur la ligne

Bonjour Pascal,

Merci ! J'ai appliqué la formule de Nicolas Granier et ça fonctionne.

Mais pour info, ça ne pouvait pas fonctionner en complétant ce que j'avais déjà fait ? Avec le ST_Split ?

Bonne journée

Hors ligne

 

#4 Tue 21 March 2017 10:17

nideux
Juste Inscrit !
Lieu: Alès
Date d'inscription: 11 May 2006
Messages: 1
Site web

Re: [PostGis] Découper une ligne par des points non snappés sur la ligne

Bonjour,

J'essaie de reprendre le code de Nicolas Granier mais je ne comprends pas à quoi correspond le "point" dans
ST_SNAP((ST_DUMP(st_difference(couche_de_ligne.the_geom,point))).geom,all_point,0.1) as the_geom

Quelqu'un peut-il m'aider?

Merci d'avance,

Hors ligne

 

#5 Tue 21 March 2017 23:21

Nicolas Granier
Participant assidu
Date d'inscription: 19 Apr 2007
Messages: 271

Re: [PostGis] Découper une ligne par des points non snappés sur la ligne

Bonsoir,
Je dois pouvoir vous aider wink
Dans la requete que vous citez (il en manque un morceau dans votre citation), le terme "point" designe en realité un agglomérat de buffer carré autour de tous les points assemblés en une seule géométrie. Le terme point provient de la sous requete suivante passée dans le from

Code:

(select ST_Multi(ST_Union(st_expand(couche_de_point.the_geom, 0.05))) as point from couche_de_point ) as t1

Pourquoi un buffer ? car topologiquement parlant, pour utiliser vos termes si votre pont n'est pas sur la ligne celle ci ne pourra jamais être coupée. On fait donc un buffer dont la distance correspond à la réponse à la question " Dans mes données, jusqu'à quelle distance dois-je considérer qu'un pont enjambe un cours d'eau ? 1mm, 1m, 100m ?" Si je décide de faire un buffer de 1m pour faire un carre de 1m, les polygones vont pouvoir intersecter le cours d'eau distant de moins d'un mètre.

Pourquoi un buffer carré ? Là je dois dire que je ne m'en souviens plus mais il doit y avoir une histoire non négligeable de vitesse de calcul, sur un buffer carré vous n'avez toujours que 4 points qui constituent le polygone d'enveloppe, sur un rond vous en avez une multitude donc derrière en vitesse de calcul vous êtes cuits avec vos ronds.

Pourquoi un agglomérat de petits carrés ?

Ce qu'il faut garder en tete lors d'une requete SQL c'est que les opérations que vous lancez se font pour chaque enregistrement (chaque ligne de la table), et si vous faites une opération de type st_intersects entre deux tables les résultats en sortie s'en trouvent multipliés ce qui donne au final quelque chose comme ça :

Code:

ligne 1 table 1 intersects ligne 1 table 2
ligne 1 table 1 intersects ligne 2 table 2
ligne 1 table 1 intersects ligne 3 table 2
ligne 2 table 1 intersects ligne 1 table 2
ligne 2 table 1 intersects ligne 2 table 2

Tout ca pour dire que la requete fait apparaitre le terme st_multi(st_union ...) afin de n'avoir qu'une seule ligne de geométrie de point face à chaque ligne géométrique

si l'on décompose maintenant  la requete de découpage elle même :
st_difference (geométrie d'une ligne, géométrie de tous les carrés/buffers autour des points)
Admettons que sur un cours d'eau se trouvent deux ponts. Vous avez donc votre ligne qui se retrouve superposée avec deux petits carrés  distants mais géométriquement ne représentant qu'un seul objet géométrique. L'outil St_différence va effacer les morceaux de ligne qu'il y a sous les carrés. Vous avez donc à la fin de cette étape une ligne avec deux trous dedans mais stockée dans une seule géométrie multiligne.

st_dump(...).geom permet d'éclater la multiligne en 3 lignes (comme on a fait deux trous dedans, il y a donc 3 morceaux). Sans cette opération vous auriez autant de ligne dans la table d'arrivée que dans la table de départ.

enfin
ST_SNAP(mes morceaux de ligne, tous mes points, distance) permet de recoller les morceaux entre eux. Je m'explique. Pour l'instant vous avez bien des lignes mais elles ne sont pas jointives car vous avez fait un buffer sur les ponts et effacé la ligne sous le buffer. Si vous avez fait un buffer de 1 m, vous avez donc des trous dans vos cours d'eau d'environ 1m. L'outil St Snap permet de venir coller une géométrie sur une autre. On vient donc coller l'extrémité de nos cours d'eau sur nos ponts. Là encore on se retrouve avec le cas de 2 tables qui vont discuter ensemble, il faut donc faire un agglomérat des ponts pour n'avoir qu'une seule géométrie de ponts mais sans réaliser de buffer cette fois.

A+
Nicolas GRANIER

Dernière modification par Nicolas Granier (Tue 21 March 2017 23:29)

Hors ligne

 

Pied de page des forums

Powered by FluxBB