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

Rencontres QGIS 2025

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

#1 Wed 04 October 2017 15:22

fassa222
Participant occasionnel
Date d'inscription: 18 Jan 2012
Messages: 36

découper une seule ligne en plusieurs

Bonjour,

J'ai une couche ligne qui est composée d'une seule entité (comme en faisant un st_union de plusieurs lignes pour en former une seule) et une couche points qui est composée de plusieurs entités. Mon objectif est de découper cette une seule ligne en plusieurs tout en se basant sur la couche point. Au final je souhaite avoir plusieurs lignes dont leur extrémités sont en intersection avec les entités de la couche point. C'est à dire que chaque ligne découpée doit être compris entre deux points de la couche point.

Merci de votre aide
CDT.

Hors ligne

 

#2 Wed 04 October 2017 15:35

meonais
Participant occasionnel
Date d'inscription: 17 Jan 2017
Messages: 35

Re: découper une seule ligne en plusieurs

Bonjour,

J'ai résolu le même type de problématique (probablement pas vraiment optimisé mais ça fonctionne) ici : https://georezo.net/forum/viewtopic.php?id=104853, post n°7

A bientôt

Hors ligne

 

#3 Wed 04 October 2017 16:23

fassa222
Participant occasionnel
Date d'inscription: 18 Jan 2012
Messages: 36

Re: découper une seule ligne en plusieurs

meonais a écrit:

Bonjour,

J'ai résolu le même type de problématique (probablement pas vraiment optimisé mais ça fonctionne) ici : https://georezo.net/forum/viewtopic.php?id=104853, post n°7

A bientôt


Bonjour Meonais,

J'ai essayé votre solution mais aparement ça marche que pour les lignes ayant plusieurs entités alors que moi je pars du principe que ma couche ligne est composée d'une seule entité. J'essaiyé de partir à une couche d'une seule entité mais j'ai un problème de validé de la couche ligne avec cette erreur "line_locate_point: 1st arg isn't a line" que j'ai essaiyé de corrigé avec un st_linemerge mais çà fonction pas

Hors ligne

 

#4 Wed 04 October 2017 16:30

fassa222
Participant occasionnel
Date d'inscription: 18 Jan 2012
Messages: 36

Re: découper une seule ligne en plusieurs

Bonjour Meonais,

J'ai essayé votre solution mais aparement ça marche que pour les lignes ayant plusieurs entités alors que moi je pars du principe que ma couche ligne est composée d'une seule entité. J'essaiyé de partir à une couche d'une seule entité mais j'ai un problème de validé de la couche ligne avec cette erreur "line_locate_point: 1st arg isn't a line" que j'ai essaiyé de corrigé avec un st_linemerge mais çà fonction pas

Hors ligne

 

#5 Wed 04 October 2017 16:36

meonais
Participant occasionnel
Date d'inscription: 17 Jan 2017
Messages: 35

Re: découper une seule ligne en plusieurs

Bonjour,

De mémoire il faut que ce soit des linestring et pas des multilignes
Ça vient peut être de là ?

Mes lignes ont plusieurs entités mais je les regroupe (si je ne me suis pas trompée) en une seule, justement parce que j'avais besoin de délimiter les tronçons résultants par les points (ou les extrémités de lignes), et ne pas avoir plusieurs tronçons entre deux points.

Hors ligne

 

#6 Wed 04 October 2017 17:28

fassa222
Participant occasionnel
Date d'inscription: 18 Jan 2012
Messages: 36

Re: découper une seule ligne en plusieurs

ma couche ligne est en linestring et c'est une seule entité, donc j'ai appliqué le code mais il y a un problème au niveau du calcul des positions

Hors ligne

 

#7 Wed 04 October 2017 17:40

meonais
Participant occasionnel
Date d'inscription: 17 Jan 2017
Messages: 35

Re: découper une seule ligne en plusieurs

Désolée, mais de mémoire et d'après votre message d'erreur, c'est la fonction st_linelocatepoint() qui ne trouve pas les éléments "à manger correctement ou suffisamment bons" ;-)

Sans plus d'infos sur vos données que je pourrais essayer de comparer aux miennes, je ne vois pas ce que ça peut être d'autre

Je ne vois pas non plus pourquoi cette requête ne fonctionnerait pas sur une seule ligne si elle fonctionne sur plusieurs :
si j'ai bien suivi le code, elle identifie
- la position du début de la ligne (== crée un point avec la valeur 0 pour la position du point sur la ligne),
-celle de la fin (== crée un autre point avec la valeur 1 pour la position du point sur la ligne = le max possible)
- chaque position de chaque point de votre couche de points sur votre ligne (entre 0 et 1)
et réunie le tout dans une seule table de points
puis elle les ordonne pour pouvoir appliquer la fonction st_linesubstring() entre les bons couples de points et générer ainsi les tronçons.

Hors ligne

 

#8 Wed 04 October 2017 18:03

fassa222
Participant occasionnel
Date d'inscription: 18 Jan 2012
Messages: 36

Re: découper une seule ligne en plusieurs

Bonjour,

je vous joins mes deux couches ainsi que le code sql afin que vous pouvez faire unecomparaison, pour que ca marche pour moi. Des fois j'ai un résultat mais le découpage n'est exact.

CDT


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

Hors ligne

 

#9 Wed 04 October 2017 19:11

meonais
Participant occasionnel
Date d'inscription: 17 Jan 2017
Messages: 35

Re: découper une seule ligne en plusieurs

Je n'arrive pas à charger vos couches dans Postgesql

pourquoi avoir rajouté un round() ?
et enlevé la condition

Code:

AND st_linelocatepoint(l.geom, p.geom) NOT IN (0,1)

?
ce sont les différences que je vois entre mon script que je fais tourner plusieurs fois par jours en ce moment et le votre

Hors ligne

 

#10 Wed 04 October 2017 19:18

meonais
Participant occasionnel
Date d'inscription: 17 Jan 2017
Messages: 35

Re: découper une seule ligne en plusieurs

Je viens de réussir à charger vos couches
J'ai décomposé votre code
Je m'arrête aux deux premières étapes car vous générez des GEOMETRY au lieu de LINESTRING ou POINT (d'après la table geometry_columns)
Je débute en Postgres/postgis mais je crois bien que ce n'est pas bon pour ensuite faire tourner les différentes fonctions st() de la suite.

Code:

DROP TABLE IF EXISTS lignes_dumped CASCADE;
CREATE TABLE lignes_dumped as (

SELECT row_number() over() as gid , (ST_Dump(geom)).geom as geom ---(ST_Dump(geom)).geom
FROM public.lignes l -- multilinestring
);
-->>> ca donne une couche GEOMETRY

---Création de la couche de points, snappés sur les lignes
CREATE TABLE ptsnapAS as (
SELECT o.gid as id, ST_Closestpoint(ST_Collect(r.geom), o.geom) AS geom
FROM public."noeud" o
INNER JOIN public."lignes" r
ON ST_Dwithin(r.geom, o.geom, 50)
GROUP BY o.gid, o.geom) ;
-->>> ca donne une couche GEOMETRY

locus as (
-- premiere table des positions des points par rapport a "leurs" lignes
---DROP TABLE IF EXISTS locus CASCADE;

        -- on genere la position du debut de la ligne (index 0)  pour le premier segment à découper
    select l.gid, 0 as l
    from lignes_dumped 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 lignes_dumped l

    UNION ALL

        -- calcul des positions des points par rapport aux lignes
    select l.gid, round(st_linelocatepoint((l.geom), p.geom)) as  l -- il faut LINESTRING
    from lignes_dumped l, ptsnapAS p
    where st_dwithin(l.geom, p.geom, 0.01)
    GROUP BY l.gid, l
    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:
---DROP  TABLE IF EXISTS loc_with_idx CASCADE;
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--

---DROP TABLE IF EXISTS splitang CASCADE;
splitang AS (

select l.gid, st_linesubstring(l.geom, loc1.l, loc2.l) as geom 
from loc_with_idx loc1, loc_with_idx loc2, lignes_dumped l
where l.gid = loc1.gid
and loc1.gid = loc2.gid
and loc2.idx = loc1.idx+1
GROUP BY l.gid, l.geom, loc1.l, loc2.l  ) select * from splitang

Hors ligne

 

#11 Thu 05 October 2017 12:26

fassa222
Participant occasionnel
Date d'inscription: 18 Jan 2012
Messages: 36

Re: découper une seule ligne en plusieurs

meonais a écrit:

Je n'arrive pas à charger vos couches dans Postgesql

pourquoi avoir rajouté un round() ?
et enlevé la condition

Code:

AND st_linelocatepoint(l.geom, p.geom) NOT IN (0,1)

?
ce sont les différences que je vois entre mon script que je fais tourner plusieurs fois par jours en ce moment et le votre


Bonjour Meonais,

Le round il sert à arrondir nos positions, puisse que des fois on a des valeurs décimales. Exemple 0.1111111 qui devient 0 ou 0.9999999 qui devient 1

Hors ligne

 

#12 Thu 05 October 2017 12:29

fassa222
Participant occasionnel
Date d'inscription: 18 Jan 2012
Messages: 36

Re: découper une seule ligne en plusieurs

meonais a écrit:

Je viens de réussir à charger vos couches
J'ai décomposé votre code
Je m'arrête aux deux premières étapes car vous générez des GEOMETRY au lieu de LINESTRING ou POINT (d'après la table geometry_columns)
Je débute en Postgres/postgis mais je crois bien que ce n'est pas bon pour ensuite faire tourner les différentes fonctions st() de la suite.

Code:

DROP TABLE IF EXISTS lignes_dumped CASCADE;
CREATE TABLE lignes_dumped as (

SELECT row_number() over() as gid , (ST_Dump(geom)).geom as geom ---(ST_Dump(geom)).geom
FROM public.lignes l -- multilinestring
);
-->>> ca donne une couche GEOMETRY

---Création de la couche de points, snappés sur les lignes
CREATE TABLE ptsnapAS as (
SELECT o.gid as id, ST_Closestpoint(ST_Collect(r.geom), o.geom) AS geom
FROM public."noeud" o
INNER JOIN public."lignes" r
ON ST_Dwithin(r.geom, o.geom, 50)
GROUP BY o.gid, o.geom) ;
-->>> ca donne une couche GEOMETRY

locus as (
-- premiere table des positions des points par rapport a "leurs" lignes
---DROP TABLE IF EXISTS locus CASCADE;

        -- on genere la position du debut de la ligne (index 0)  pour le premier segment à découper
    select l.gid, 0 as l
    from lignes_dumped 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 lignes_dumped l

    UNION ALL

        -- calcul des positions des points par rapport aux lignes
    select l.gid, round(st_linelocatepoint((l.geom), p.geom)) as  l -- il faut LINESTRING
    from lignes_dumped l, ptsnapAS p
    where st_dwithin(l.geom, p.geom, 0.01)
    GROUP BY l.gid, l
    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:
---DROP  TABLE IF EXISTS loc_with_idx CASCADE;
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--

---DROP TABLE IF EXISTS splitang CASCADE;
splitang AS (

select l.gid, st_linesubstring(l.geom, loc1.l, loc2.l) as geom 
from loc_with_idx loc1, loc_with_idx loc2, lignes_dumped l
where l.gid = loc1.gid
and loc1.gid = loc2.gid
and loc2.idx = loc1.idx+1
GROUP BY l.gid, l.geom, loc1.l, loc2.l  ) select * from splitang


Mes couches sont bien en linestring, donc forcement ils doivent etre appropriées à la catégorie geometry

Hors ligne

 

#13 Thu 05 October 2017 14:14

meonais
Participant occasionnel
Date d'inscription: 17 Jan 2017
Messages: 35

Re: découper une seule ligne en plusieurs

Bonjour,

Pour le Round() je ne pense pas que ce soit optimal puisque justement l'idée de st_linelocatepoint() est de donner une valeur de position entre zéro (début de la ligne) et 1 (fin de la ligne) pour chaque point
Donc le début de la ligne = 0 ; le premier point = 0.2 (par exemple), le deuxième = 0.3345, le quatrième = 0.5658 etc. jusqu'au dernier = 1 (fin de la ligne)

Pour la géométrie des couches utilisées, en décomposant votre requête, pour moi vous créez des tables de format GEOMETRY (multi collection je suppose) et non LINESTRING. Voici ce que j'obtiens dans la table geometry_columns en appliquant juste vos deux sous requêtes lines_dumped et ptsnapAS :

Code:

[i]-- vos deux couches en entrée de sous-requête [/i]
"lignes";"geom";2;0;"MULTILINESTRING"
"noeud";"geom";2;0;"POINT"

[i]-- vos deux couches en sortie de sous-requête[/i]
"lignes_dumped";"geom";2;0;[b]"GEOMETRY"[/b]
"ptsnapas";"geom";2;0;[b]"GEOMETRY"[/b]

Pour moi, la couche ligne doit être en linestring pour pouvoir l'incorporer dans le reste de la requête (locus, loc_with_idx, et split) :

Code:

-- format de ma couche que je découpe
"selectcdotrhydromerge";"geom";2;2154;[b]"LINESTRING"[/b]

peut-être utiliser un st_collectionextract() pour ne récupérer que les linestring ?

Hors ligne

 

Pied de page des forums

Powered by FluxBB