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 10 April 2019 10:54

zang
Participant actif
Date d'inscription: 4 Oct 2005
Messages: 55

POSTGIS - Tracer lignes communes entre des polygones

Bonjour,
J'ai 2 tables de polygones, topologiquement parfaites avec un clip réalisé pour avoir des frontières communes et aucun overlap, et j'aimerai tracer les lignes de frontières communes entre chaque polygone mitoyen. L'image jointe vous montre le résultat attendu (lignes rouges), que je n'ai pas réussi à obtenir en utilisant le SQL seul.

J'ai trouvé ce SQL sur le net pour créer des segments de ma table encaissant

Code:

SELECT ST_AsText( ST_MakeLine(sp,ep) )
FROM
   -- extract the endpoints for every 2-point line segment for each linestring
   (SELECT
      ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
      ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) as ep
    FROM
       -- extract the individual linestrings
      (SELECT (ST_Dump(ST_Boundary(geom))).geom
       FROM encaissant_v3
       ) AS linestrings
    ) AS segments;

Mais je n'arrive pas à l'insérer dans ma requête INSERT INTO ([Err] ERREUR:  erreur de syntaxe sur ou près de « FROM »
LINE 3: FROM)

Code:

INSERT INTO talus (geom)
SELECT ST_intersects(zi.geom, ((ST_AsText(ST_MakeLine(sp,ep))
FROM
   -- extract the endpoints for every 2-point line segment for each linestring
   (SELECT
      ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
      ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) as ep
    FROM
       -- extract the individual linestrings
      (SELECT (ST_Dump(ST_Boundary(geom))).geom
       FROM encaissant_v3
       ) AS linestrings
    ) AS segments)))

Comment pourrais-je combiner à la fois la commande ST_intersects et le ST_MakeLine?

Merci pour votre aide,
Bonne journée,
Franck

EDIT : je n'arrive pas à joindre l'image pour illustrer ce que je veux faire désolé...

Dernière modification par zang (Wed 10 April 2019 13:04)

Hors ligne

 

#2 Wed 10 April 2019 13:02

zang
Participant actif
Date d'inscription: 4 Oct 2005
Messages: 55

Re: POSTGIS - Tracer lignes communes entre des polygones

l'image en PJ que je n'ai pas réussi à attacher au précédent message désolé

EDIT : bon j'arrive toujours pas à attacher l'image... tant pis!

Dernière modification par zang (Wed 10 April 2019 13:07)

Hors ligne

 

#3 Wed 10 April 2019 14:28

jmarsac
Participant assidu
Lieu: NICE
Date d'inscription: 26 Oct 2005
Messages: 572
Site web

Re: POSTGIS - Tracer lignes communes entre des polygones

Bonjour,
Ce serait plutôt quelque chose comme

Code:

INSERT INTO talus (geom) 
SELECT ST_intersection(zi.geom, (SELECT ST_MakeLine(sp,ep)
FROM
   -- extract the endpoints for every 2-point line segment for each linestring
   (SELECT
      ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
      ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) as ep
    FROM
       -- extract the individual linestrings
      (SELECT (ST_Dump(ST_Boundary(geom))).geom
       FROM encaissant_v3
       ) AS linestrings
    ) AS segments)
    FROM matable zi;

NB
dans votre requête zi.geom n'est pas défini
ST_intersects renvoie un booléen  et non un type Geometry (ST_intersection)
ST_MakeLine renvoie bien un type Geometry attendu pat ST_intersects
ST_asText revoie une expression "Well Known Text" (WKT) et non un type Geometry


Jean-Marie
Azimut

Hors ligne

 

#4 Wed 10 April 2019 16:11

zang
Participant actif
Date d'inscription: 4 Oct 2005
Messages: 55

Re: POSTGIS - Tracer lignes communes entre des polygones

Merci Jean-Marie,
J'ai juste ajouté une parenthèse pour fermer le ST_Intersection.
Par contre j'ai le message suivant:
[Err] ERREUR:  plus d'une ligne renvoyée par une sous-requête utilisée comme une expression
C'est peut-être pas la meilleure manière d'opérer pour générer ces lignes frontières, si?
Merci!
Franck

Hors ligne

 

#5 Wed 10 April 2019 16:28

PA
Membre
Lieu: Paris
Date d'inscription: 5 Sep 2005
Messages: 3259
Site web

Re: POSTGIS - Tracer lignes communes entre des polygones

zang a écrit:

l'image en PJ que je n'ai pas réussi à attacher au précédent message désolé

EDIT : bon j'arrive toujours pas à attacher l'image... tant pis!


C'est en panne et ce sera fixé.


Pierre-André Le Ny
Modérateur QGIS, Données, Coin de l'OpenSource
Aidez l'association GeoRezo !

Hors ligne

 

#6 Thu 11 April 2019 08:14

jmarsac
Participant assidu
Lieu: NICE
Date d'inscription: 26 Oct 2005
Messages: 572
Site web

Re: POSTGIS - Tracer lignes communes entre des polygones

zang a écrit:

Merci Jean-Marie,
J'ai juste ajouté une parenthèse pour fermer le ST_Intersection.
Par contre j'ai le message suivant:
[Err] ERREUR:  plus d'une ligne renvoyée par une sous-requête utilisée comme une expression
Franck


Bonjour Franck,
Il faut rajouter une clause WHERE dans la sous-requete afin que ST_intersection ne "reçoive" qu'une seule geometrie


Jean-Marie
Azimut

Hors ligne

 

#7 Thu 11 April 2019 09:41

zang
Participant actif
Date d'inscription: 4 Oct 2005
Messages: 55

Re: POSTGIS - Tracer lignes communes entre des polygones

Bonjour,
Merci Jean-Marie pour le suivi.
J'ai inséré une clause WHERE dans la sous-requête de l'intersection mais j'ai toujours plus d'une ligne renvoyée. Normal quand on y pense... Il faudrait que la commande traite segment par segment dans une boucle mais mes connaissances sont limitées aux requêtes basiques en SQL...
Encore une fois s'il y a une autre façon de faire je suis preneur!
Merci,
Bonne journée,
Franck


Code:

INSERT INTO talus (geom) 
SELECT ST_intersection(zi.geom, (SELECT ST_MakeLine(sp,ep)
FROM
   -- extract the endpoints for every 2-point line segment for each linestring
   (SELECT
      ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
      ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) as ep
    FROM
       -- extract the individual linestrings
      (SELECT (ST_Dump(ST_Boundary(geom))).geom
       FROM encaissant_v3
       ) AS linestrings
    ) AS segments
WHERE ST_Dwithin(encaissant_v3.geom, zi.geom, 0.01)))
    FROM zi, encaissant_v3

Hors ligne

 

#8 Thu 11 April 2019 10:01

tumasgiu
Membre
Lieu: Ajaccio
Date d'inscription: 5 Jul 2010
Messages: 1159

Re: POSTGIS - Tracer lignes communes entre des polygones

En isolant la segmentisation d'encaissant_v3
dans une CTE ou une sous requête,
je pense que ca devrait passer :

Code:

with segments as (
    SELECT
        DISTINCT
                St_makeline(
                  ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)),
                  ST_PointN(geom, generate_series(2, ST_NPoints(geom) ))
                    ) line
    FROM
        (SELECT 
            (ST_Dump(ST_Boundary(geom))).geom
        FROM 
            encaissant_v3
        ) AS linestrings 
    )

INSERT INTO matable
SELECT 
    DISTINCT inter 
FROM 
    (SELECT 
        st_intersection(geom, line) inter 
    FROM 
        segments
    JOIN
        matable ON geom && line
    ) foo 
WHERE
    not st_isempty(inter)

Dernière modification par tumasgiu (Thu 11 April 2019 10:04)

Hors ligne

 

#9 Thu 11 April 2019 10:48

zang
Participant actif
Date d'inscription: 4 Oct 2005
Messages: 55

Re: POSTGIS - Tracer lignes communes entre des polygones

Bonjour,
Merci Tumasgiu,
Votre requête me dépasse un peu mais je compte bien me mettre à niveau prochainement ;o)
Je l'ai modifiée en précisant noms de table et champs à actualiser mais j'ai encore un message d'erreur :

[Err] ERREUR:  les fonctions et opérateurs peuvent prendre au plus un argument d'ensemble

Code:

with segments as (
    SELECT
        DISTINCT
                St_makeline(
                  ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)),
                  ST_PointN(geom, generate_series(2, ST_NPoints(geom) ))
                    ) line
    FROM
        (SELECT 
            (ST_Dump(ST_Boundary(geom))).geom
        FROM 
            encaissant_v3
        ) AS linestrings 
    )

INSERT INTO talus (geom)
SELECT 
    DISTINCT inter 
FROM 
    (SELECT 
        st_intersection(geom, line) inter 
    FROM 
        segments
    JOIN
        talus ON geom && line
    ) foo 
WHERE
    not st_isempty(inter)

Dernière modification par zang (Thu 11 April 2019 10:49)

Hors ligne

 

#10 Thu 11 April 2019 11:22

tumasgiu
Membre
Lieu: Ajaccio
Date d'inscription: 5 Jul 2010
Messages: 1159

Re: POSTGIS - Tracer lignes communes entre des polygones

Quelle version de PostgreSQL utilisez vous ?

j'ai l'impression que c'est

Code:

                St_makeline(
                  ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)),
                  ST_PointN(geom, generate_series(2, ST_NPoints(geom) ))
                    ) line

qui coince.

La requête est tres simple :
le bloc WITH est une autre manière d'écrire des sous-requêtes,
en les écrivant en préambule.
Pour la requête en elle même, plutot que d'utiliser une sous requête
pour générer le second argument de st_intersection,
on croise une sous requête qui est l'ensemble des segments,
avec l'ensemble des polygones, on génère toutes les intersections probables,
on ecarte les intersections nulles et les doublons.

Hors ligne

 

#11 Thu 11 April 2019 11:55

zang
Participant actif
Date d'inscription: 4 Oct 2005
Messages: 55

Re: POSTGIS - Tracer lignes communes entre des polygones

J'utilise PostgreSQL 9.6

Pour la requête, je n'ai pas encore suffisamment pratiqué le WITH, et je ne connaissais pas le &&
Mais c'est en pratiquant qu'on apprend!

Merci encore

Hors ligne

 

#12 Fri 12 April 2019 16:30

tumasgiu
Membre
Lieu: Ajaccio
Date d'inscription: 5 Jul 2010
Messages: 1159

Re: POSTGIS - Tracer lignes communes entre des polygones

Il faudrait que vous utilisez Postgres >= 10 (je crois)
pour que cette syntaxe fonctionne.
Ce qui coince ce sont les deux appels à generate_series
comme arguments d'une même fonction.
Ceux ci sont censés générer tout les couples d'indices
(Exemple pour un polygone à 4 coté, donc composé de 5 points: (0, 1), (1, 2), (2, 3) , (3, 4) )
pour récupérer les points grâce à la fonction st_pointn.

En déplaçant la création de cet indice dans une requête LATERAL (ou corrélée),
çà devrait fonctionner :

Code:

with segments as (
    SELECT
        DISTINCT
                St_makeline(
                  ST_PointN(geom, sp),
                  ST_PointN(geom, sp + 1)
                    ) line
    FROM
        (SELECT 
            (ST_Dump(ST_Boundary(geom))).geom
        FROM 
            encaissant_v3
        ) AS linestrings,
    LATERAL generate_series(1, st_npoint(geom) - 1) sp
    )

INSERT INTO talus (geom)
SELECT 
    DISTINCT inter 
FROM 
    (SELECT 
        st_intersection(geom, line) inter 
    FROM 
        segments
    JOIN
        talus ON geom && line
    ) foo 
WHERE
    not st_isempty(inter)

Hors ligne

 

#13 Mon 15 April 2019 15:11

zang
Participant actif
Date d'inscription: 4 Oct 2005
Messages: 55

Re: POSTGIS - Tracer lignes communes entre des polygones

Bonjour,
Merci, je vais installer la version 10 et essayer.
Je vous tiens au courant,
Bonne journée,
Franck

Hors ligne

 

#14 Mon 15 April 2019 16:48

tumasgiu
Membre
Lieu: Ajaccio
Date d'inscription: 5 Jul 2010
Messages: 1159

Re: POSTGIS - Tracer lignes communes entre des polygones

Si vous voulez faire la MAJ, c'est une très bonne chose
(dans ce cas là, essayez directement la 11 smile )
mais la requête précédente devrait fonctionner de manière équivalente.

Hors ligne

 

Pied de page des forums

Powered by FluxBB