#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
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
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!
C'est en panne et ce sera fixé.
Hors ligne
#6 Thu 11 April 2019 08:14
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
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: 1160
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: 1160
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: 1160
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: 1160
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 )
mais la requête précédente devrait fonctionner de manière équivalente.
Hors ligne