Annonce
Pour sa 21ème année, l’association GeoRezo a toujours besoin de vous !
10€ = 1 mois de frais bancaires ; 15€ = 12 mois de nom de domaine ; 30€ = 1 semaine de location des serveurs …
Retrouver nos membres bienfaiteurs
#1 Mon 04 April 2022 11:22
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 997
Fusion des multipolygones découpés par des routes
Salut à tous,
Un petit challenge pour un expert de SQL spatial (je sais qu'il y a des "joueurs" ici )
Est-ce que vous verriez une requête SQL qui permettrait de passer de multipolygones de type "polygone découpés par des routes" à un "polygone non découpé par les routes" ?
La capture d'écran ci-dessous montre l'idée :
[img]https://i.ibb.co/cT0N5B6/fusion.png[/img]
(sâchant que c'est un cas "simpliste", mais que dans la réalité des multipolygones, il y a aussi des polygones à trous, et que ces trous doivent être conservés au dessus d'une certaine surface.
C'est jouable en SQL ?
Sylvain M.
Hors ligne
#2 Mon 04 April 2022 11:32
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 997
Re: Fusion des multipolygones découpés par des routes
L'idée serait de définir une largeur standard de route qui serait fusionnée au polygone de sortie (par ex 30m)
Dernière modification par Sylvain M. (Mon 04 April 2022 15:28)
Sylvain M.
Hors ligne
#3 Mon 04 April 2022 11:46
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Fusion des multipolygones découpés par des routes
Bonjour,
Oui, ca doit etre faisable. Vous avez les routes qui ont servi au découpage ?
Vous auriez un dataset d'exemple ?
Nicolas
Hors ligne
#4 Mon 04 April 2022 11:48
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 997
Re: Fusion des multipolygones découpés par des routes
Non, malheureusement, je n'ai pas (de manière homogène en tout cas) les routes qui ont servi au découpage : les polygones sont digitalisés à la main de part et d'autres des emprises de route.
(MP pour le dataset de tests )
Dernière modification par Sylvain M. (Mon 04 April 2022 11:51)
Sylvain M.
Hors ligne
#5 Mon 04 April 2022 12:37
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 997
Re: Fusion des multipolygones découpés par des routes
(Nicolas, je t'ai envoyé un message via la messagerie de GeoRezo, mais j'ai un doute que celle-ci soit fonctionnelle : si tu ne l'as pas reçu, dis moi !)
Sylvain M.
Hors ligne
#6 Mon 04 April 2022 12:48
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Fusion des multipolygones découpés par des routes
non pas reçu, mais j'ai trouvé un dataset occupation du sol avec des pg découpés par des routes
Dernière modification par Nicolas Ribot (Mon 04 April 2022 12:48)
Hors ligne
#7 Mon 04 April 2022 14:23
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 997
Re: Fusion des multipolygones découpés par des routes
Je propose ici une réflexion de méthode (mais que je ne sais encore appliquer en totalité) :
1] Créer un polygone convexe du polygone (ST_ConvexHull)
2] Combler les trous de ce polygone convexe via des Polygones (ST_DumpRings je crois, mais je ne maitrise pas)
3] Pour chaque polygone de comblement, déterminer via un indice basé sur la forme, si il s'agit d'une surface à exclure de la fusion (les fameux trous à conserver), ou d'une emprise de route : caractérisée par une forme "linéaire" (mais je ne sais pas comment calculer cet indice)
4] fusion du Multipolygone source avec les petit polygones identifiés comme emprise routière
Dernière modification par Sylvain M. (Mon 04 April 2022 14:23)
Sylvain M.
Hors ligne
#8 Mon 04 April 2022 15:27
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Fusion des multipolygones découpés par des routes
Le probleme de cette approche est que st_convexhull ne fera pas le découpage route vs pg. on aura juste le "négatif" du multipolygone de départ.
Une approche pourrait etre:
Pour chaque polygone, on cherche les voisins les plus proches a x m (x = largeur qu'on veut combler)
on dump les contours des polygones en points, et pour chaque point d'un pg, on le projete sur son contour le plus proche (st_lineInterpolatePoint)
on garde ce point projeté si la distance < x m, sinon on garde le sommet initial du polygone
on reconstruit les polygones à partir de cette nouvelle liste de points.
on fait l'union des polygones ainsi reconstruits: ca fusionne les pg voisins. ca crée aussi surement des trous pour les cas ou la distance entre les contours est légèrement plus grande que la distance choisie.
On vire ces trous de la fusion (en identifiant les trous initiaux dans la couche et en ne gardant qu'eux.
Nicolas
Hors ligne
#9 Mon 04 April 2022 15:53
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 997
Re: Fusion des multipolygones découpés par des routes
Le probleme de cette approche est que st_convexhull ne fera pas le découpage route vs pg. on aura juste le "négatif" du multipolygone de départ.
En effet, je m'en suis rapidement rendu compte en faisant mes enveloppe convexes autour des multipolygones...
Pour ton approche, j'ai du boulot pour tenter de l'appliquer, mais je comprends la logique
Si jamais tu as le SQL correspondant, je veux bien
Sylvain M.
Hors ligne
#10 Mon 04 April 2022 16:43
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Fusion des multipolygones découpés par des routes
Il y a surement plus simple en passant par st_snap(geom, geom)
Il faut identifier les geom à snaper entre elles (les plus proches), puis faire l'union des geom snappées (car il y aura immanquablement des trous) et virer les trous (st_dumpRings).
avec un with recursive ... peut etre.
Pas super facile comme problématique
Nicolas
Hors ligne
#11 Mon 04 April 2022 17:28
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Fusion des multipolygones découpés par des routes
Une premiere approche en se basant sur les points des polygones proches d'un autres polygone.
On cherche ces points, on construit le buffer a x m de ces points, on fait l'union de ces buffer, puis l'union de ce buffer avec tous les polygones:
on obtient un polygone avec pas mal de trous.
On vire tous les trous de ce résultat, et on ajoute les trous présents dans les polygones initiaux.
Pb:
• certaines parties sont comblées: elles ne devraient pas l'être: il faut appliquer un critere de surface sur les trous qu'on vire.
• ca ne prend pas en compte les routes qui coupent en partie un polygone (mais la requete peut etre adaptée pour trouver ces points et les combler avec un buffer.
En SQL:
Code:
-- la table frtdmp contient le dump du multipolygone à nettoyer sous forme de polygones simples create table frtdmp as select (st_dump(geom)).path[1] as id, (st_dump(geom)).geom from frt; -- la table frtpts contient le dump des points des polygones create table frtpts as select id as idpg, (st_dumppoints(st_exteriorring(geom))).path as path, (st_dumppoints(st_exteriorring(geom))).geom from frtdmp; -- index et tout... with holes as ( -- trous des polygones select st_dumprings(geom) as dmp from frtdmp ), array_holes as ( -- on regroupe les trous dans un tableau select array_agg(st_exteriorring((dmp).geom)) as holes from holes where (dmp).path[1] > 0 ),tmp as ( -- on fait l'union des buffers des points proches des contours select st_union(st_buffer(geom2, 30)) as geom from frtpts f cross join lateral ( select f2.id, f2.idpg as idpg2, f2.geom <-> f.geom as dist, f2.geom as geom2 from frtpts f2 where f.id < f2.id and f.idpg <> f2.idpg order by f.geom <-> f2.geom limit 1 ) as t ), tmp1 as ( -- on fabrique la liste des polygones initiaux + le polygone issu des buffers des points select geom from tmp UNION ALL select geom from frtdmp ) select st_makePolygon(st_exteriorring(st_union(geom)), holes) -- on refait un polygone en ajoutant les trous initiaux from tmp1, array_holes group by holes;
Image du résultat jointe
Nicolas
Hors ligne
#12 Mon 04 April 2022 18:10
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 997
Re: Fusion des multipolygones découpés par des routes
Merci beaucoup Nicolas !!!
Bon, je dois cependant admettre que je n'ai pas encore le niveau pour tout comprendre : mais c'est bien, ça me donne matière à progresser !!!
(bon, je fais ça sur mes pauses, du coup je n'avance pas vite mais chi va piano va sano ! )
Sylvain M.
Hors ligne
#13 Tue 05 April 2022 11:16
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Fusion des multipolygones découpés par des routes
Pourquoi faire simple quand on peut faire compliqué
Un simple buffer positif puis négatif clean très bien la couche, garde les trous, traite les découpages partiels, et fait de jolis arrondis pour fermer les routes en bord de polygone et c'est très rapide
Code:
select st_buffer(st_buffer(geom, 30), -30) as geom from frt;
Nicolas
Hors ligne
#14 Tue 05 April 2022 11:58
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 997
Re: Fusion des multipolygones découpés par des routes
J'y avais pensé, mais je vais perdre la topologie des contours avec les multipolygones initiaux (ce que j'aimerais éviter).
Mais je pense qu'on peut corriger ça ensuite avec le st_snap(geom, geom) que je découvre : qu'en penses-tu ?
Sylvain M.
Hors ligne
#15 Tue 05 April 2022 13:20
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Fusion des multipolygones découpés par des routes
Oui effectivement, mais la topo est perdu puisqu'il manque une info au niveau des découpages par les routes.
La topo peut etre reconstruite s'il le faut (grass, postgis topology)
Oui snap ca peut marcher.
Nicolas
Hors ligne
#16 Tue 05 April 2022 14:38
- ppluvinet
- Participant assidu
- Lieu: VALENCE
- Date d'inscription: 6 Aug 2007
- Messages: 617
Re: Fusion des multipolygones découpés par des routes
Bonjour,
Je me lance à proposer une autre approche :
- On recrée les polygones de routes par différence entre la zone d'étude et les polygones avec un ST_DIFFERENCE.
- Pour ne conserver que les routes (=polygonne fins), on calcule la compacité en fonction de l'aire et du périmètre pour ne conserver que les polygones "fins".
- On découpe ces routes en centaines de petits polygones avec ST_SUBDIVDE
- On affecte à ces mini-polygones l'ID du polygone le + proche
- On fusionne avec ST_UNION sur l'ID.
Ceci dit, J'avais aussi pensé au buffer positif puis négatif (qui demande à connaitre un minimum la largeur maxi des routes). Puis l'utilisation de la fonction v.clean de GRASS .
Bonne continuation,
Dernière modification par ppluvinet (Tue 05 April 2022 14:39)
Pascal PLUVINET
Hors ligne
#17 Tue 05 April 2022 18:59
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 997
Re: Fusion des multipolygones découpés par des routes
Merci Pascal pour ta suggestion.
Le problème que je vois au début, c'est la "zone d'étude" qui n'existe pas.
On pourrait la créer par exemple via un bbox (ST_Envelope) sur l'emprise, ou via un polygone convexe (ST_Convexhull), mais alors les emprises de routes traversantes seraient inclues dans d'immenses polygones extérieurs au multipolygone source.
A part ça, ça pourrait marcher
Sylvain M.
Hors ligne