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Ă© ?

#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: 579
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
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: 579
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: 1226

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: 1226

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: 1226

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: 1226

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

Copyright Association GeoRezo