#1 Tue 25 June 2013 22:04
- SANTANNA
- Moderateur
- Lieu: Angers
- Date d'inscription: 18 Jan 2008
- Messages: 3943
Equivalent "fusionner les entités" dans Postgis
Bonjour,
QGis, comme d'autres logiciels, permet de fusionner des entités d'une même table, créant une nouvelle entité en lieu et place des précédentes.
Sous Postgis, la commande
Code:
insert into matable (geom) select st_union (geom)
ajoute en effet une nouvelle ligne correspondant à la fusion des géométries de mes précédentes entités mais celles-ci sont toujours conservées dans ma table; il faut donc penser à les supprimer si on veut avoir le même effet que "fusionner les entités".
D'où ma question, existe-t-il sous qgis une fonction qui génère l'entité fusionnée et supprime les entités en entrée?
Hors ligne
#2 Wed 26 June 2013 11:03
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Equivalent "fusionner les entités" dans Postgis
Bonjour,
Sous Postgis, vous vouliez dire ?
Non. Postgis n'offre pas ce genre de fonctions haut niveau. Ca n'est pas trop son but: un enchainement de commandes SQL permet de faire cela.
En général, on crée une nouvelle table lors de ce genre d'opération de fusion:
Dans votre exemple, vous n'insérez qu'une géométrie dans la table: que valent les autres colonnes pour cette ligne ?
En terme de modélisation, avoir dans la même table des objets géo ET ces objets fusionnés n'est pas très pratique.
Nicolas
Hors ligne
#3 Wed 26 June 2013 12:25
- Razorbak
- Participant assidu
- Lieu: Clermont Ferrand
- Date d'inscription: 7 Oct 2007
- Messages: 505
Re: Equivalent "fusionner les entités" dans Postgis
Bonjour,
Je rejoins le sujet car je pense avoir le même souci. En effet, j'essaie de fusionner des entités selon un attribut présent dans ma table (l'équivalent de l'outil "Fusionner" d'ArcGis par exemple) et j'obtiens le même nombre d'enregistrements qu'au départ.
Est-ce que le problème pourrait venir des erreurs topologiques entre les entités que j'essaie de fusionner ? Selon moi, non, car il me ferait finalement une entité multiparties dans ce cas...?
Du coup, il faut faire un CREATE TABLE incluant la commande ST_Union ?
Merci. Bonne journée
Hors ligne
#4 Wed 26 June 2013 14:12
- ppluvinet
- Participant assidu
- Lieu: VALENCE
- Date d'inscription: 6 Aug 2007
- Messages: 617
Re: Equivalent "fusionner les entités" dans Postgis
Bonjour, Quelle est ta requette exactement?
As-tu essayé une requête du genre :
Code:
create table matablefus as select champ1, st_union(geom) as geom from matable group by champ1;
A bientôt,
Dernière modification par ppluvinet (Wed 26 June 2013 14:12)
Pascal PLUVINET
Hors ligne
#5 Wed 26 June 2013 14:17
- Razorbak
- Participant assidu
- Lieu: Clermont Ferrand
- Date d'inscription: 7 Oct 2007
- Messages: 505
Re: Equivalent "fusionner les entités" dans Postgis
Bonjour Pascal,
Oui, j'avais fait une requête comme celle-ci mais en fait j'ai couplé avec la commande ST_LineMerge et cette fois ça marche.
Code:
SELECT champ1, champ2, champ3, champ4, St_linemerge(ST_Union(geom)) as geom FROM matable GROUP BY champ1, champ2, champ3, champ4)
Merci
Dernière modification par Razorbak (Wed 26 June 2013 14:17)
Hors ligne
#6 Wed 26 June 2013 15:06
- SANTANNA
- Moderateur
- Lieu: Angers
- Date d'inscription: 18 Jan 2008
- Messages: 3943
Re: Equivalent "fusionner les entités" dans Postgis
Bonjour,
Nicolas, je suis d'accord; ma requête est partielle. Il ne s'agit pas de faire cohabiter dans une même table entités d'origine et entité fusionnée. ma question était plus dans l'absolu : existe-t-il une commande dans Postgis qui fait fusionne et supprime les entités source ou faut-il une succession de commandes? Apparemment, c'est la succession des commandes qui est envisageable.
Pour préciser le contexte toutefois, il m'arrive de numériser sous QGis des périmètres regroupant plusieurs parcelles cadastrales. Et, pour ne pas avoir à dessiner chacune des limites extérieures du polygone, je procède par copie des parcelles dans ma table, remodelage éventuel de quelques points puis fusion de l'ensemble et renseignement des attributs. C'est beaucoup plus rapide que la numérisation point par point.
Et parfois, pour des raisons que je ne comprends pas bien (surement lié à ce post http://georezo.net/forum/viewtopic.php?id=82150 ou celui-ci http://www.forumsig.org/showthread.php/ … ne+postgis) QGIS refuse de fusionner ou plutôt d'enregistrer la fusion de mes entités (conflit polygone/multipolygone).
Je contourne donc en passant par st_union de postgis puis delete des entités d'origine.
D'où ma question : existe-t-il une commande deux en un?
Dernière modification par SANTANNA (Wed 26 June 2013 15:06)
Hors ligne
#7 Thu 27 June 2013 10:20
- sigdu80
- Participant actif
- Date d'inscription: 2 Sep 2010
- Messages: 112
Re: Equivalent "fusionner les entités" dans Postgis
Bonjour à tous,
comme dit Nicolas, je ne pense pas qu'une commande fasse ces 2 actions en même temps.
Il faudrait que tu le fasses toi-même.
QGIS refuse de fusionner ou plutôt d'enregistrer la fusion de mes entités (conflit polygone/multipolygone).
Peux-tu afficher les contraintes SQL de ta table à l'heure actuelle (tu sembles en parler dans le sujet de forumsig, mais tu as dû retoucher ta table depuis) ?
Tu penses que le type de données compris par QGis en ajoutant ta couche Postgis est le problème ? C'est à dire qu'il n'accepte qu'un seul type de donnée et non plusieurs (toi, tu souhaites polygon et multipolygon) ?
Dernière modification par sigdu80 (Thu 27 June 2013 10:21)
Hors ligne
#8 Thu 27 June 2013 16:26
- SANTANNA
- Moderateur
- Lieu: Angers
- Date d'inscription: 18 Jan 2008
- Messages: 3943
Re: Equivalent "fusionner les entités" dans Postgis
Bonjour,
je me suis pris la tête effectivement à une époque avec ça et n'en ayant pas compris le fin mot, ai laissé la quasi totalité de mes tables en multipolygon (pour uniformiser, et ce d'autant que certaines tables étaient appelées à accueillir des entités multiparties). Je fais désormais attention à ne pas "dessiner" mes entités et n'opère que par copier coller, remodeler. Mais je ne suis pas seul à utiliser la base et c'est parfois pénible de ne pas pouvoir "dessiner" un petit polygone ici ou là.
Ma table de production est de la forme
Code:
create table matable ( gid serial not null, insee character varying (5), identifiant integer, code_statut integer, geom (multipolygon, 2154), constraint matable_pkey PRIMARY KEY (gid), constraint enforce_geotype_geom CHECK ((geometrytype(geom)=any(array['MULTYPOLYGON'::text, 'POLYGON'::text])) or geom is null) )
Avec ou sans la contrainte, si mes objets proviennent de tables multipolygon, je peux les enregistrer, enregistrer la résultante de leur fusion. Le drame survient si jamais j'ai dessiné avec les outils de QGIS une entité. Elle ne peut pas être enregistrée et si j'ai eu l'imprudence de le fusionner auparavant avec des objets existants dans la table, je les perds tous : message d'impossibilité de valider les changements dans PostGIS (==> obligation de sortir du mode édition sans enregistrer) finissant par
Code:
Erreur du prestataire:= Erreur Postgis lors de l'ajout de l'entité : ERREUR : Geometry type (Polygon) does not match column type (multipolygon)
)
J'ai essayé avec une table en polygon, mes entités créées par numérisation sont enregistrées, celles provenant de copies de multipolygon, non (message d'erreur précédente mais dans le sens inverse). Même avec la contrainte (ne serait-elle pas bonne?). Mais lorsque je copie colle des entités multipolygones et les fusionne en une entité d'un seul tenant, pas de problème pour enregistrer ces modifications.
Je fais référence à QGIS car c'est l'outil graphique que j'utilise mais sous PGAdmin, un
Code:
insert into ma_table_multipolygon_avec_contrainte select * from ma_table_polygon;
débouche sur un message d'erreur : Geometry type (Polygon) does not match column type (Multipolygon), comme si ma contrainte check n'existait pas.
Désolé pour le "roman". Mais même si je me suis fait une raison, résoudre ce problème m'arrangerait beaucoup. Donc si t'as des pistes, sigdu80 ou quelqu'un d'autre, je veux bien me pencher à nouveau dessus.
Dernière modification par SANTANNA (Thu 27 June 2013 16:27)
Hors ligne
#9 Thu 27 June 2013 18:12
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Equivalent "fusionner les entités" dans Postgis
Bonsoir,
Peut etre quelques pistes:
Dans la définition de la table, vous utilisez un typemod pour définir la colonne géometrique:
geom (multipolygon, 2154)
La colonne est ainsi fixée a un type multipolygon, de SRID 2154 et les contraintes définies plus tard ne sont pas utilisées, d'ou les messages d'erreur a l'insertion d'un objet de mauvais type (PG)
Pour que ces contraintes soient prises en compte, définissez la colonne geom de type geometry sans préciser de sous-type et de SRID, puis ajoutez les contraintes sur le sous-type et sur le SRID.
Attention a la fausse "souplesse" de pouvoir stocker à la fois des PG et des MultiPG dans la meme table: Beaucoup de fonctions de postgis ne marchent que sur un type particulier et ne pourront donc pas etre lancées sur tous les objets de la table, a moins de forcer le type MULTI lors de la requete (select st_multi(geom)...).
Une autre solution pour faire en sorte que le stockage soit possible quelque soit le type d'objet envoyé par un client comme QGis (PG et MultiPG) est de définir la colonne geom de type MULTI (comme dans votre définition de table) et d'ajouter un trigger BEFORE INSERT OR UPDATE sur la table.
Ce trigger encapsule toute géometrie a insérer ou mettre à jour sous la forme d'un MULTI, en appelant st_multi(geom) dans la fonction du trigger.
Ainsi:
• La table ne contient que des MULTIPG: plus simple a gérer
• L'insertion de PG et de MULTIPG est possible depuis les clients
Nicolas
Hors ligne
#10 Thu 27 June 2013 20:19
- Georgie
- Participant assidu
- Date d'inscription: 28 May 2011
- Messages: 232
Re: Equivalent "fusionner les entités" dans Postgis
Je dis peut-être des bêtises, mais j'ai souvenir d'avoir un jour fait un copier-coller entre deux tables postgis (à vérifier)...
Hors ligne
#11 Mon 01 July 2013 10:54
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Equivalent "fusionner les entités" dans Postgis
Je dis peut-être des bêtises, mais j'ai souvenir d'avoir un jour fait un copier-coller entre deux tables postgis (à vérifier)...
Depuis QGis ?
Hors ligne
#12 Thu 18 July 2013 15:45
- Yaëlle F
- Participant actif
- Date d'inscription: 27 Sep 2012
- Messages: 87
Re: Equivalent "fusionner les entités" dans Postgis
Bonjour à tous,
Je me permets de "rebondir" sur votre fil de conversation car j'ai besoin de fusionner des entités d'une table en fonction d'attribut.
Je vous explique rapidement, je travaille sur de l'automatisation de données avec spatialite (qui ressemble grandement à postgis). J'ai une couche avec les tronçons de cours d'eau d'une zone d'étude. Cependant, le nombre d'objet me bloque pour la suite de mon travail. Il me faudrait regrouper les entités en fonction d'une colonne spécifique afin de ne passer qu'à 5 objets au final.
Pour cela j'ai utilisé la fonction ST_union avec un order by, comme suit :
CREATE TABLE TRONCON_COURS_EAU_ZE AS SELECT id, rugosite, ST_UNION(geometry) AS geometry FROM COURS_EAU_ZE ORDER BY 'rugosite';
Cependant, la table créée ne possède plus qu'un seul objet. Je ne comprends pas à quoi cela est du.
A savoir que la colonne rugosité prend des valeurs aussi bien négatives que positives, cela viendrait-il de là ??
En espérant qui vous puissiez m'aider,
Yaëlle
Hors ligne
#13 Thu 18 July 2013 16:35
- SANTANNA
- Moderateur
- Lieu: Angers
- Date d'inscription: 18 Jan 2008
- Messages: 3943
Re: Equivalent "fusionner les entités" dans Postgis
Bonjour,
votre requête n'indique pas quel champ devrait servir d'élément discriminant. Si c'est rugosite, je pense que votre requête devrait plutôt être
Code:
CREATE TABLE TRONCON_COURS_EAU_ZE AS SELECT id, rugosite, ST_UNION(geometry) AS geometry FROM COURS_EAU_ZE GROUP BY rugosite ORDER BY rugosite;
le group by permet de regrouper les entités selon la valeur du champ.
Hors ligne
#14 Thu 18 July 2013 17:03
- SANTANNA
- Moderateur
- Lieu: Angers
- Date d'inscription: 18 Jan 2008
- Messages: 3943
Re: Equivalent "fusionner les entités" dans Postgis
Pour ma part, je reviens sur l'échange concernant l'impossibilité de créer des entités depuis QGIS dans mes tables Postgis.
Merci Nicolas, J'avais pas cerné toute la substance de ma définition de table, pensant que Postgis se chargerait après avoir checké que mon entité est PG ou MULTIPG de l'intégrer mais en le convertissant en MULTIPG (étant donné le typemod de la colonne geom).
C'est d'autant plus étonnant que ce genre de définition de table est très présente sur le web...
Et oui, je préférerais avoir une table avec un seul type de géométrie.
Face à mes soucis, j'avais aussi essayé de rajouter dans ma fonction trigger une commande qui se chargerait de passer en multi l'entité mais je n'ai jamais trouvé la syntaxe exacte. Un coup de pouce, svp?
Par contre, je viens de découvrir un truc incompréhensible.
Mon serveur postgre est du 9.2, Postgis 2, qgis 1.8 via osgeo4w sous windows 7. Mes tables ont des soucis d'écriture via qgis, comme déjà indiqué.
Sur un autre ordi en windows 8 mais avec les mêmes postgre, postgis, qgis, j'ai découvert que je pouvais dessiner mes entités dans QGIS sans problème (sur les mêmes tables que celles du serveur, qu'elles aient une contrainte ou pas) et un
Code:
select geometrytype (geom) from matable
indique que les entités sont en MULTIPG. Bref, le comportement que je cherchais depuis le début.
J'en déduis donc qu'il y a peut-être une embrouille avec ma première installation de PostgreSQL. Mais quoi (à part que ce fut ma première fois et qu'elle a essuyé les plâtres)? Je ne sais pas du tout sur quoi intervenir, d'autant qu'il est en production.
Hors ligne
#15 Thu 18 July 2013 17:41
- VianneyD
- Participant assidu
- Date d'inscription: 30 May 2011
- Messages: 153
Re: Equivalent "fusionner les entités" dans Postgis
Bonjour,
Face à mes soucis, j'avais aussi essayé de rajouter dans ma fonction trigger une commande qui se chargerait de passer en multi l'entité mais je n'ai jamais trouvé la syntaxe exacte. Un coup de pouce, svp?
As-tu essayé avec ST_Multi ?
Vianney Dugrain
Hors ligne
#16 Thu 18 July 2013 18:37
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Equivalent "fusionner les entités" dans Postgis
Bonsoir,
Oui st_multi() permet de garantir que toute géométrie est transformée en un MULTI objet.
Pour le faire avec un trigger, il faut d'abord definir la fonction que va utiliser le trigger, puis créer le trigger sur la table:
Code:
-------- La fonction du trigger create or replace function forceMulti() returns trigger as $$ DECLARE BEGIN NEW.geom := st_Multi(NEW.the_geom); RETURN NEW; END; $$ LANGUAGE PLPGSQL; --------- puis la creation du trigger drop trigger if exists forceMulti_trigger on matable; create trigger forceMulti_trigger BEFORE UPDATE OR INSERT ON matable FOR EACH ROW EXECUTE PROCEDURE forceMulti();
Cela peut aussi etre fait avec les RULES, qui remplissent un peu le meme role que les triggers.
Concernant les differences de comportement entre les deux serveurs, je regarderais:
• Si les versions de QGis sont exactement les mêmes (versions, plugins, etc.)
• Les définitions complètes des tables dans les deux serveurs, avec pgAdmin ou psql (\dt+ matable)
• les logs des deux serveurs PG après avoir activé le log des requêtes, pour voir quelles requêtes sont reçues par les serveurs en provenance de QGis.
Il doit y avoir une explication
Nicolas
Hors ligne
#17 Wed 24 July 2013 21:54
- David Delhorbe
- Invité
Re: Equivalent "fusionner les entités" dans Postgis
Bonjour,
pour regrouper des objets en SQL avec des fonctions d'agrégations, il
faut utiliser la clause GROUP BY et mettre le nom du champs entre
guillemets (double quotte) et non simple quotte. Le ORDER BY n'est pas
très utile ici, c'est surtout pour du SELECT
Cdlt,
David D.