Corriger la géométrie d’une table Postgis

Nous avons déjà abordé le sujet de la validation des géométries dans une série d’articles:

Dans cet article nous verrons plus spécifiquement comment détecter et corriger les problèmes géométriques dans une table PostgreSQL/Postgis en utilisant des requêtes SQL.

Vérification des erreurs avec QGis.

Vous pouvez détecter rapidement les erreurs géométriques en utilisant QGis. Il suffit de charger la couche et de lancer le menu Vecteur -> Outils de géométrie -> Vérifier la validité

Vous avez le choix entre trois méthodes :

  • deux méthodes de validation : soit GEOS, soit QGIS, et
  • une méthode qui peut être imposée pour la vérification interactive lors de la création de nouvelle géométrie (Préférences → onglet numérisation).

La méthode GEOS est plus rapide mais n’indique que la première erreur rencontrée pour chaque objet. Elle renvoie un fichier ‘Sortie invalide’ qui est une couche de polygones complétée par une colonne  _errors  :


La méthode Qgis peut renvoyer plusieurs erreurs par objet. Cette méthode renvoie dans le fichier ‘Sortie invalide’ une couche de polygones complétée par une colonne _errors avec un message moins normalisé que par la méthode GEOS :

Personnellement, j’utilise cet outil pour vérifier s’il y a des erreurs ou pas. J’exécute les deux méthodes et, si elles ne renvoient aucune erreur je considère que la couche est valide.

Par contre si des erreurs existent je passe directement sur pgAdmin 4 (ou à défaut dans le gestionnaire de base de données de QGis) pour travailler en SQL.

Détection des erreurs géométriques avec Postgis

La première étape est l’identification des erreurs. Notons que PostGIS est conforme au standard OGC OpenGIS Specifications, et donc la validité est vérifiée par rapport à GEOS.

Nous allons donc réaliser une requête qui recherchera les trois types d’erreurs principaux:

  • les erreurs GEOS (voir les géométries simples et valides)
  • les géométries nulles, qui n’ont pas de sens
  • les collections de géométries, c’est à dire des objets composés par plusieurs géométries de même type ou pas. Le cas le plus fréquent ce sont des multipolygones qui sont catalogués comme FeatureCollection par erreur. Les opérateurs spatiaux habituels ne fonctionnent pas avec des collections en entrée.

Un dernier type d’erreur, en général sans conséquence, est la présence de nœuds doubles (deux points de l’entité situés exactement au même endroit). Ils ne perturbent pas les opérateurs spatiaux, mais ce n’est pas une raison pour ne pas les corriger.

Voici une requête qui vous permet de détecter les trois premiers types d’erreurs en un seul passage:

SELECT ‘non valide’ AS nb, count(*) FROM table WHERE NOT ST_IsValid(the_geom)
UNION
SELECT ‘geom nulle’ AS nb, count(*) FROM table WHERE the_geom is null
UNION
SELECT ‘collection’ AS nb, count(*) FROM table WHERE not ST_IsValid(the_geom)
AND ST_GeometryType(ST_MakeValid(the_geom))=’ST_GeometryCollection’;

Vous pouvez avoir le détail des erreurs GEOS avec la requête suivante:

SELECT id, ST_IsValidReason(the_geom) FROM table WHERE NOT ST_IsValid(the_geom);

Correction des erreurs

(Nous prenons ici le cas d’une couche de polygones, qui est le type d’entité à présenter le plus de problèmes.)

On corrige les erreurs GEOS avec la fonction St_MakeValid

UPDATE table SET the_geom = ST_MakeValid(the_geom) WHERE NOT ST_IsValid(the_geom);

Puis, on corrige les collections en les transformant en Multi_polygones. Attention à ne pas inverser les étapes. La fonction St_MakeValid peut produire des collections en sortie.

UPDATE table
SET the_geom =
ST_Multi(ST_Simplify(ST_Multi(ST_CollectionExtract(ST_ForceCollection(ST_MakeValid(the_geom)),3)),0))
WHERE ST_GeometryType(the_geom) = ‘ST_GeometryCollection’;

Troisièmement on supprime les géométries nulles (si la requête de détection des erreurs en a trouvé).

DELETE FROM table WHERE the_geom IS NULL;

Et pour finir on supprime les nœuds en double:

UPDATE table SET the_geom = ST_Multi(ST_Simplify(the_geom,0));

Cette dernière requête est une manière un peu détournée de faire l’opération. La fonction St_Simplify est une fonction de généralisation, c’est à dire une fonction qui réduit le nombre de points d’une entité, en enlevant les points qui sont à une distance inférieure du paramètre de la fonction. En mettant 0 à cette distance, la fonction ne laisse qu’un point parmi tous les points situés dans un rayon nul (les doublons).

Une fois exécutées ces requêtes, on exécute à nouveau la requête de recherche d’anomalies. Si des erreurs persistent, il faudra utiliser d’autres moyens pour les résoudre.

Une technique souvent utilisée est la création d’un buffer null:

UPDATE table SET the_geom = ST_Multi(ST_Buffer(the_geom,0)) WHERE NOT ST_IsValid(the_geom));

A ce stade, si des erreurs persistent, il faut abandonner l’idée de les corriger automatiquement, prendre son mal en patience, et les corriger manuellement.

Si cet article vous a intéressé et que vous pensez qu'il pourrait bénéficier à d'autres personnes, n'hésitez pas à le partager sur vos réseaux sociaux en utilisant les boutons ci-dessous. Votre partage est apprécié !

2 thoughts on “Corriger la géométrie d’une table Postgis

  1. Paul Bocuse nous a quitté il y a peu mais voici une belle recette de cuisine.
    Aujourd’hui je regardais différents moyens de faire une fusion de polygones (grosso-modo dissoudre/tampon positif/tampon négatif) et donc QGis, GEOS, GDAL,… : plein de moyens, mais lequel est le plus adapté ? Là vous répondez certes pas à la même question mais au comment utiliser différentes méthodes de manière efficace. Très utile. À ma question la réponse était de… ne pas faire de géo-traitement mais simplement du filtrage au niveau du style. Simple et efficace.

  2. Bonjour bonjour, petite remarque en passant pour tous les traqueurs d’erreurs, l’algorithme « Vérifier la validité » de QGis n’est absolument pas fiable, il oublie ou invente facilement des erreurs (peu importe la méthode).
    L’extension « Vérifier la topologie » elle est adaptée à un travail dans QGis, même si elle fourni moins de détail.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *