#1 Thu 15 November 2018 14:33
- dhaulagiri
- Participant occasionnel
- Lieu: Nîmes, Gard
- Date d'inscription: 1 Dec 2006
- Messages: 46
- Site web
Gérer les modifications de géométrie dans une requête
Bonjour,
Je cherche à faire une requête globale pour enchaîner plusieurs traitements avec des tables PostGIS. Chaque traitement est assez basique: buffers, intersections, différences, unions... Il s'agit d'obtenir une zone théoriquement favorable à l'implantation d'un équipement.
Comme je n'arrivais pas à afficher la couche obtenue dans QGIS, j'ai jeté un oeil à sa géométrie: c'était une GeometryCollection alors que toutes les données utilisées au cours du traitement étaient des multipolygon. J'ai repris chaque étape en générant à chaque fois une table pour voir ce qu'il se passait. Dans mon cas, la fonction st_union ne modifie jamais la géométrie des couches en entrée, contrairement à st_buffer, st_intersection et st_difference. Avec ces trois dernières fonctions, la table obtenue se traduit systématiquement par les entrées suivantes dans la vue geometry_columns: type de géométrie = GEOMETRY, srid = 0 (les données en entrée ont le srid 2154).
Pour m'en sortir, j'ai dû modifier les tables concernées a posteriori avec la commande:
Code:
alter table maTable alter column geom type geometry (multipolygon, 2154)
Pour le dernier traitement (intersection de zones favorables intermédiaires), j'ai même dû utiliser la fonction st_collectionextract pour obtenir des multipolygon à la place d'un GeometryCollection (alors que les deux tables en entrée sont des multipolygon).
Au-delà du fait de ne pas bien comprendre pourquoi les géométries sont modifiées (de nombreux messages sur le sujet existent pourtant dans les forums), je me demande surtout comment faire pour intégrer la modification de géométrie que je fais en post-traitement dans ma requête globale où je ne crée aucune table intermédiaire.
Je vous remercie pour votre aide,
Nicolas
Dernière modification par dhaulagiri (Thu 15 November 2018 14:35)
Salutations, Nicolas.
Hors ligne
#2 Thu 15 November 2018 16:00
- tumasgiu
- Membre
- Lieu: Ajaccio
- Date d'inscription: 5 Jul 2010
- Messages: 1144
Re: Gérer les modifications de géométrie dans une requête
Salut,
pour ce qui est de le changement des géométries après traitement :
pour le type :
les traitement sont susceptibles de produire des géométries de type différents
de ceux des arguments, mêmes quand tout les arguments partagent le même type.
Exemple :
Deux lignes dont la différence serait un point unique :
ici chaque caractère - représente un point
différence de:
______________________
|geometrie | type |
|_________|____________|
|----- | (LINESTRING)|
|---- | (LINESTRING)|
|= | |
| - | (POINT) |
|_________|____________|
Il se peut également que le traitement produise plusieurs types de géométrie en sortie,
pour cela Postgis englobe tout cela dans une GeometryCollection.
pour le SRID:
La colonne SRID de geometry_columns est un SRID de contrainte,
ou 0 signifie pas de contrainte.
Si vous créez une table à partir d'une requête, PostgreSQL ne peut pas savoir
à l'avance si les résultat de la requête auront toujours le même type de geometry
et le même SRID, donc il se borne à dire que la colonne est de type géométrie "libre".
Pour contraindre, vous pouvez créer la table en amont en spécifiant les contraintes,
ou spécifier le type voulu du résultat d'un traitement en le castant .
Exemple
Code:
CREATE TABLE satan_estate AS SELECT st_difference(poly1.geom, poly2.geom)::geometry(POLYGON, 666) FROM poly1,poly2;
La requête ci-dessus produira une erreur si un des résultat n'est pas du type POLYGON localisé en enfer.
Dernière modification par tumasgiu (Thu 15 November 2018 16:56)
Hors ligne
#3 Thu 15 November 2018 16:47
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1538
Re: Gérer les modifications de géométrie dans une requête
Bonsoir,
Comme le dit tumasgiu, les opérations intersection, union, différence, etc. peuvent (et le font très souvent) renvoyer des geometryCollection.
Vous avez donc bien fait, et je vous invite a le faire systématiquement, d'utiliser st_collectionExtract pour englober ces opérations geo.
En tant que géomaticien écrivant la requête, vous seul savez si le traitement que vous faites concerne des surfaces (=> st_collectionExtract(geom, 3), des lignes, des points.
Qd on traite des données qui peuvent être polygones ou mutlipolygones, on rajoute souvent st_multi devant le tout, histoire d'avoir des geom de même type dans la colonne:
st_multi(st_collectionExtract(geom,3))
Nicolas
Dernière modification par Nicolas Ribot (Thu 15 November 2018 16:48)
Hors ligne
#4 Fri 16 November 2018 18:33
- Rlucas
- Participant occasionnel
- Date d'inscription: 20 Apr 2018
- Messages: 31
Re: Gérer les modifications de géométrie dans une requête
Bonjour,
Pour continuer sur le sujet, et malgré un peu de pratique, j'ai aussi énormément de mal à comprendre comment gérer les types géométriques dans les fonctions spatiales. Bien que la documentation soit claire sur les types pris en entrée dans les fonctions, elle l'est beaucoup moins sur les fonction permettant de convertir les types. Notemment lors de l'écriture de requêtes uniques, sans tables intermédiaires (ou à la rigueur avec des CTE).
Autant pour les multigéométries, St_Multi, St_Linemerge ou autre permet le plus souvent de passer en multigeometrie, autant l'inverse est complexe : ST_Dump produit une double geométrie qui peut entrer en conflit avec les contraintes geometry_columns, et la formulation avec les :: est aléatoire dans ses résultats.
Par ailleurs je n'ai trouvé aucun tuto clair sur ce sujet (passage de geometries simples à multi) et les nouvelles requêtes demandent de longs tatonnements.
Est-ce que que quelqu'un aurait de la documentation à ce sujet? Comment utiliser correctement les fonctions et les assignations de type (: sans risquer de futurs conflits d'interprétation?
Hors ligne
#5 Tue 20 November 2018 15:28
- dhaulagiri
- Participant occasionnel
- Lieu: Nîmes, Gard
- Date d'inscription: 1 Dec 2006
- Messages: 46
- Site web
Re: Gérer les modifications de géométrie dans une requête
Bonjour,
Je vous remercie pour vos explications. Je ferai un retour si je trouve une solution satisfaisante.
Sinon, je suis assez d'accord avec Rlucas. J'imagine qu'il doit y avoir de quoi lire sur le site de l'OGC mais j'ai besoin d'une seconde vie pour le faire...
Salutations, Nicolas.
Hors ligne
#6 Thu 29 November 2018 19:25
- Rlucas
- Participant occasionnel
- Date d'inscription: 20 Apr 2018
- Messages: 31
Re: Gérer les modifications de géométrie dans une requête
Bonjour,
Pour résumer sur les passages d'une multi-géométrie à une géométrie simple :
1. Vérifier le type geométrique des tables :
select st_geometrytype(geom) FROM table
2. Vérifier si les geometries ont plus d'une partie :
SELECT COUNT(CASE WHEN ST_NumGeometries(geom) > 1 THEN 1 END) AS multi_geom,
COUNT(geom) AS total_geom FROM table;
3.1. Si oui : Passage de multigeom à geom avec la fonction st_dump. Créer d'abord une cope de la table a modifier avec
CREATE TABLE table_simple AS SELECT * FROM table_multi
WITH dump_temp AS
(SELECT (ST_Dump(geom)).geom as geom, id FROM table_multi)
UPDATE table_simple SET geom = dump_temp.geom
FROM dump_temp WHERE table_simple.idcana = dump_temp.idcana
Les multigéometries seront bien sûr éclatées par la fonction dump. Noter la formulation pour le ST_DUMP pour ne séléctionner que la géométrie qui nous intéresse (cf. documentation).
3.2 Si non : Changer le type (la contrainte) d'une colonne de geometrie sur une table :
Ici passage de multilinestring à string simple : spécifier dans la fonction geometry le type et le SRID en premier et second argument puis avec ST_GeometryN spécifier le nom de la colonne portant les géometries et la dimension de celle-ci - cf. doc postgis) :
ALTER TABLE table
ALTER COLUMN geom TYPE geometry(linestring,2972) USING ST_GeometryN(geom, 1);
Hors ligne