#1 Tue 19 February 2013 15:08
- gaetanpru
- Participant actif
- Lieu: Limoges
- Date d'inscription: 4 Jan 2012
- Messages: 91
QGIS / Postgis: Supprimer les anneaux des polygones
Bonjour,
Je dispose actuellement de polygones ayant de très nombreux anneaux que j'aimerai faire disparaître. Je sais qu'il y a un outils sur QGIS pour faire cette manipulation mais il faut le faire un après l'autre, ce qui est trop long lorsqu'il y a des milliers d'anneaux à supprimer.
J'aimerai savoir si il n'existerai pas une autre solution plus rapide pour le faire (extension QGIS ou fonction POSTGIS) plus rapidement.
Merci d'avance
Gaëtan - Béziers
Hors ligne
#2 Tue 19 February 2013 18:12
- VianneyD
- Participant assidu
- Date d'inscription: 30 May 2011
- Messages: 153
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Bonjour,
je pense que ST_Convexhull() sur chacun des polygones doit faire l'affaire ici
Vianney Dugrain
Hors ligne
#3 Wed 20 February 2013 01:43
Re: QGIS / Postgis: Supprimer les anneaux des polygones
bonjour,
Un anneau est bien un trou pour vous?
Je doute qu'une enveloppe convexe soit dans tous les cas la solution, si le polygone est concave le résultat ne sera surement pas celui attendu.
vos pouvez utiliser un buffer de 0 éventuellement, sinon plutot une combinaison de st_exteriorring et st_makepolygon.
Dernière modification par vincentp (Wed 20 February 2013 01:44)
Hors ligne
#4 Wed 20 February 2013 09:11
- VianneyD
- Participant assidu
- Date d'inscription: 30 May 2011
- Messages: 153
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Je doute qu'une enveloppe convexe soit dans tous les cas la solution, si le polygone est concave le résultat ne sera surement pas celui attendu.
Très juste.
Vianney Dugrain
Hors ligne
#5 Wed 20 February 2013 09:47
- gaetanpru
- Participant actif
- Lieu: Limoges
- Date d'inscription: 4 Jan 2012
- Messages: 91
Re: QGIS / Postgis: Supprimer les anneaux des polygones
En effet un anneau est bien un trou, mais c'est le terme de QGIS. J'ai déjà essayé le buffer à 0 mais cela n'efface pas les "véritables anneaux" (exemple : mer intérieure, lac...). En faite j'ai une couche mondiale des bassins hydrographiques et je voudrais la simplifier au maximum (enlever les petites îles et les trous à l'intérieur des polygones)
Gaëtan - Béziers
Hors ligne
#6 Wed 20 February 2013 13:30
Re: QGIS / Postgis: Supprimer les anneaux des polygones
En effet un anneau est bien un trou, mais c'est le terme de QGIS. J'ai déjà essayé le buffer à 0 mais cela n'efface pas les "véritables anneaux" (exemple : mer intérieure, lac...). En faite j'ai une couche mondiale des bassins hydrographiques et je voudrais la simplifier au maximum (enlever les petites îles et les trous à l'intérieur des polygones)
Vous avez certainement des multipolygones, il faut suivre ces étapes :
* st_dump de la géométrie pour séparer les multis en polygones simples
* filtrer sur ceux qu'on veut enlever, par la surface mini par exemple : st_area
* enlever les trous des polygones, en reconstituant un polygone avec juste l’enveloppe extérieure : st_makepolygon(st_exteriorring(geom))
Vincent
Hors ligne
#7 Wed 20 February 2013 15:10
- gaetanpru
- Participant actif
- Lieu: Limoges
- Date d'inscription: 4 Jan 2012
- Messages: 91
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Ok, merci beaucoup je testerai cette méthode et je vous tiendrai au courant
[EDIT] Encore merci pour l'aide, ça fonctionne nickel.
Dernière modification par gaetanpru (Thu 21 February 2013 10:40)
Gaëtan - Béziers
Hors ligne
#8 Thu 28 January 2016 11:32
- Xavier Julian
- Participant assidu
- Lieu: Orange
- Date d'inscription: 19 Jan 2015
- Messages: 218
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Bonjour à tous !
Quasiment 3ans plus tard, (humhum), je me retrouve avec un problème similaire : éliminer les trous dans des polygones.
@vincentp et @gaetanpru : pouvez-vous m'expliquer comment construire la requête proposée ?
* enlever les trous des polygones, en reconstituant un polygone avec juste l’enveloppe extérieure : st_makepolygon(st_exteriorring(geom))
Quand j'essaye la requête ci-dessous, PostGIS me retourne l'erreur suivante : ERREUR: ExteriorRing: geom is not a polygon
Code:
SELECT st_makepolygon(st_exteriorring(geom)) FROM public.ma_table ;
Merci par avance !
Xavier.
Dernière modification par Xavier Julian (Thu 28 January 2016 11:33)
Hors ligne
#9 Thu 28 January 2016 14:23
- VianneyD
- Participant assidu
- Date d'inscription: 30 May 2011
- Messages: 153
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Bonjour,
Vu le message d'erreur renvoyé, je vérifierai que ton champ geom est bien de type POLYGON.
Que renvoie la requete suivante ?
Code:
SELECT ST_GeometryType(geom) FROM public.ma_table
Attention, ST_ExteriorRing ne fonctionne pas avec les MULTIPOLYGON : http://postgis.net/docs/manual-2.0/ST_ExteriorRing.html
Vianney Dugrain
Hors ligne
#10 Thu 28 January 2016 14:35
- Xavier Julian
- Participant assidu
- Lieu: Orange
- Date d'inscription: 19 Jan 2015
- Messages: 218
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Bonjour,
Cela renvoit Multipolygon ....
Pourtant j'ai bien exécuté st_dump pour séparer les multis en polygones simples.
Une autre méthode, j'ai basculé la couche dans QGIS pour exécuter la commande "morceaux multiples vers morceaux uniques" puis requestionné ma couche dans PostGis pour connaître la géométrie, idem : multipolygon.
Il doit y avoir un truc évident à côté duquel je passe ...
Hors ligne
#11 Thu 28 January 2016 16:16
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3199
- Site web
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Bonjour
Essayez sous Postgis la requête suivante
Code:
ST_GeometryType((st_dump(multigeom)).geom))
Pour vérifier que votre multi polygone est bien "explosé" en polygones.
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne
#12 Thu 28 January 2016 17:01
- VianneyD
- Participant assidu
- Date d'inscription: 30 May 2011
- Messages: 153
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Pour vérifier que tes polygones sont tous bien des entités simples, tu peux également exécuter la requête suivante :
Code:
SELECT COUNT(CASE WHEN ST_NumGeometries(geom) > 1 THEN 1 END) AS multi_geom, COUNT(geom) AS total_geom FROM ma_table;
Si elle renvoie 0 en multi_geom, tu peux exécuter la requete suivante pour transformer ta géométrie MULTI en POLYGON, sans craindre de perdre des données.
Code:
ALTER TABLE ma_table ALTER COLUMN geom TYPE geometry(POLYGON,[srid]) USING ST_GeometryN(geom, 1);
Voir cette discussion sur GisStackExchange.
Vianney Dugrain
Hors ligne
#13 Fri 29 January 2016 14:27
- Xavier Julian
- Participant assidu
- Lieu: Orange
- Date d'inscription: 19 Jan 2015
- Messages: 218
Re: QGIS / Postgis: Supprimer les anneaux des polygones
J'ai testé ta méthode Vianney,
La première requête me renvoi bien 0 : multi_geom bigint 0.
Cela signifie donc bien que je n'ai pas d'entité avec plusieurs parties.
Par contre la deuxième me retourne : La requête a été exécutée avec succès en 515 ms, mais ne renvoie aucun résultat.
En fait j'ai ré-importé ma table dans PostGIS en cochant l'option Créer des géométries simples au lieu de multiparties et ça marche.
Néanmoins, quand je retourne à mon problème initial (remplir les trous de mes polygones), cette requête ne change rien :
Code:
SELECT st_makepolygon(st_exteriorring(geom)) FROM public.ma_table ;
Dernière modification par Xavier Julian (Fri 29 January 2016 14:32)
Hors ligne
#14 Fri 29 January 2016 16:43
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Bonjour,
Il faut faire un update sur la table si vous voulez changer la géométrie, ou alors créer une nouvelle table:
Code:
create table toto as select ...
Nicolas
Hors ligne
#15 Mon 01 February 2016 08:48
- Xavier Julian
- Participant assidu
- Lieu: Orange
- Date d'inscription: 19 Jan 2015
- Messages: 218
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Voilà le truc évident à côté du quel je passais, merci !
Excusez moi, je suis autodidacte sur PostGIS, donc il me manque certains éléments basiques.
Maintenant, comment ajouter une condition pour que la création de polygone ne se fasse que sur les trous inférieurs à une certaine taille ?
(j'essaye de corriger des erreurs de topologie, mais j'ai aussi des polygones avec des anneaux que je veux garder).
Bon début de semaine à tous !
Hors ligne
#16 Mon 01 February 2016 14:56
- Xavier Julian
- Participant assidu
- Lieu: Orange
- Date d'inscription: 19 Jan 2015
- Messages: 218
Re: QGIS / Postgis: Supprimer les anneaux des polygones
J'ai essayé le code ci-dessous pour appliquer l'opération uniquement sur les polygones inférieurs à 20m2 :
Code:
CREATE TABLE public.ma_table AS SELECT st_makepolygon(st_exteriorring(ST_Area(geom)<20)) FROM public.matable_de_depart ;
Et cela me retourne l'erreur :
ERREUR: la fonction st_exteriorring(boolean) n'existe pas
LINE 2: AS SELECT st_makepolygon(st_exteriorring(ST_Area(geom)<20))
^
HINT: Aucune fonction ne correspond au nom donné et aux types d'arguments.
Vous devez ajouter des conversions explicites de type.
********** Erreur **********
ERREUR: la fonction st_exteriorring(boolean) n'existe pas
État SQL :42883
Astuce : Aucune fonction ne correspond au nom donné et aux types d'arguments.
Vous devez ajouter des conversions explicites de type.
Caractère : 54
Hors ligne
#17 Tue 02 February 2016 10:09
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3199
- Site web
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Bonjour,
Code:
st_area(geom)<20
renvoie un boolean (vrai ou faux).
il faut écrire
Code:
INSERT INTO monschema.matable SELECT st_makepolygon(stexteriorring(geom)) FROM public.matabledepart WHERE st_area(geom)<20;
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne
#18 Tue 02 February 2016 10:26
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3199
- Site web
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Ceci dit
je préfère créé la table
CREATE monschema.matable (idmatable);
Ajouter la colonne géométrie
Puis faire un insert avec une clause WITH.
Je vous conseille vivement de consulter la documentation posgresql et celle de postgis, il existe en plus de nombreux tutos sur le net.
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne
#19 Wed 03 May 2017 15:10
- Lucie D.
- Participant actif
- Date d'inscription: 21 Oct 2013
- Messages: 137
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Bonjour,
Je reviens sur ce post un an plus tard car les astuces qui y sont données m'ont beaucoup aidée mais il n'y a pas eu de suite concernant le remplissage des anneaux inférieurs à tant de m².
En effet, ChristopheV, vous nous proposez la requête suivante :
Code:
INSERT INTO monschema.matable SELECT st_makepolygon(stexteriorring(geom)) FROM public.matabledepart WHERE st_area(geom)<20;
éventuellement via un WITH.
Mais le st_area(geom)<20 ne va bien chercher que les géométries non nulles? Il faudrait donc que les anneaux soient "remplis" pour qu'on puisse connaitre leur surface?
En effet, si j'ai bien compris ce que fait le st_makepolygon(st_exteriorring((st_dump(geom)).geom)), on cherche à sélectionner le périmètre extérieur de nos polygones, périmètre qu'on remplit ensuite entièrement sans se soucier de savoir si on souhaite conserver certaines anneaux.
Pour ma part, j'ai cherché dans ma condition non pas à sélectionner les géométries de ma table de départ qui font moins de x m², mais à remplir les trous de ma couche de départ via un st_interiorringN(geom,n), à sélectionner ceux qui font moins de x m² et à redécouper ma couche remplie via st_exteriorring avec ces nouveaux polygones obtenus via st_interiorring... Le problème avec st_interiorringN(geom,n), c'est ce fameux n qui consiste à désigner quels trous on souhaite remplir. Or moi, je souhaite tous les remplir sans cette condition n!
Est-ce que je me complique la vie et, surtout, est-ce que ma méthode est applicable?
En vous remerciant par avance pour votre aide!
Bien cordialement,
Lucie D.
Dernière modification par Lucie D. (Wed 03 May 2017 15:19)
Hors ligne
#20 Tue 09 May 2017 08:12
- Ferraton
- Participant actif
- Date d'inscription: 13 Sep 2005
- Messages: 104
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Bonjour,
Je fais passer une requête parue sur notre liste interne...
select id,st_makepolygon(st_exteriorring(st_geometryn(geom,1))) as geom from _bac_a_sable.anneaux
where st_area(st_makepolygon(st_interiorringn(st_geometryn(geom,1),1))) < 20
Cordialement
Alain
Hors ligne
#21 Wed 10 May 2017 13:46
- Lucie D.
- Participant actif
- Date d'inscription: 21 Oct 2013
- Messages: 137
Re: QGIS / Postgis: Supprimer les anneaux des polygones
Bonjour,
Comme le dit Alain, la réponse a été apportée sur notre liste interne, mais il ne s'agit pas tout à fait de la requête ci-dessus (en tout cas pas pour ce que je souhaitais faire).
Voici comment je procède (merci aux personnes qui m'ont débloquée!) :
1°/ requête qui me permet d'obtenir un objet sans trous :
Code:
drop table if exists tache_sans_trous; create temp table tache_sans_trous (id bigint); SELECT AddGeometryColumn ('tache_sans_trous','geom',2154,'POLYGON',2); INSERT INTO tache_sans_trous SELECT id, st_makepolygon(st_exteriorring(st_geometryn(geom,1))) as geom FROM tache_avec_trous;
2°/ requête qui me permet de créer une couche des anneaux supérieurs à 1000 m² (correspond aux anneaux que je souhaite conserver)
Code:
DROP TABLE IF EXISTS anneaux_sup_1000; with tache_anneaux_poly as( select row_number() over () as id, st_geometryN(geom,1) AS geom from tache_avec_trous), decompte_trou as ( select id, geom, ST_NumInteriorRings(geom) as nb_trou from tache_anneaux_poly), creation_des_anneaux as ( select id, n as num_trou, st_makepolygon(st_interiorringn(geom,n)) as geom from decompte_trou CROSS JOIN generate_series(1,nb_trou) as n where nb_trou>0) select * into temp anneaux_sup_1000 from creation_des_anneaux where st_area(geom)>1000; CREATE INDEX tache_sans_trous_geom_gist ON tache_sans_trous USING gist(geom); CREATE INDEX anneaux_sup_1000_geom_gist ON anneaux_sup_1000 USING gist(geom);
3°/ découpage de la tache_sans_trous avec anneaux_sup_1000
Code:
DROP TABLE IF EXISTS tache_anneaux_sup1000; CREATE TABLE tache_anneaux_sup1000 AS SELECT st_multi(st_collectionextract(st_forcecollection(st_makevalid(st_difference((st_multi(st_collectionextract(st_forcecollection(st_makevalid(st_union(t1.geom))),3))),(st_multi(st_collectionextract(st_forcecollection(st_makevalid(st_union(t2.geom))),3)))))),3))::geometry (MultiPolygon,2154) as geom FROM tache_sans_trous as t1, anneaux_sup_1000 as t2 WHERE st_intersects(t1.geom,t2.geom);
4°/ insertion des derniers polygones qui ne sont pas concernés par le st_intersects pour obtenir l'ensemble de la tache
Code:
INSERT INTO tache_anneaux_sup1000 select st_multi(t1.geom) from tache_sans_trous as t1, tache_anneaux_sup1000 as t2 where st_intersects(t1.geom,t2.geom) IS FALSE;
Dernière modification par Lucie D. (Wed 10 May 2017 13:50)
Hors ligne