Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

#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 (:smile 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

 

Pied de page des forums

Powered by FluxBB