Postgis, GeoJSON et approximations

Chez Karnott, nous usons et abusons de Postgis, cette extension PostgreSQL qui permet de stocker de nouveaux types géographiques et ajoute beaucoup de fonctions bien pratiques pour requêter en SQL dessus.

Pour bien comprendre, rien de mieux que leur exemple sur leur page d’accueil :

SELECT superhero.name
FROM city, superhero
WHERE ST_Contains(city.geom, superhero.geom)
AND city.name = 'Gotham';

On comprend tout de suite qu’une ville a une entité géométrique geom, qu’un superhero a une position, et qu’il est possible de requêter tous les superhero de Gotham.

L’une de nos dernières fonctionnalités avec Postgis, c’est d’avoir importé l’intégralité du parcellaire français (anonymisé) pour faciliter la vie de nos agriculteurs lors de la saisie de leur parcellaire chez Karnott. Ils n’ont plus qu’à faire clic clic dans l’interface, les parcelles étant déjà dessinées pour eux.

Mais côté technique, comment cela se déroule ? Comment représenter une parcelle agricole à travers une API ? Il y a beaucoup de formats et de standards pour représenter des polygones. Par homogénéité avec le reste de notre API, nous avons naturellement choisi de représenter tous nos objets géographiques en GeoJSON (RFC 7946) . Et pour cela, Postgis est plus que pratique !

SELECT ST_AsGeoJSON(field.geom) from field limit 1;

Par défaut, nous allons avoir quelque chose du genre :

{
    "coordinates": [
        [
            [
                0.584523334321845,
                42.9562400255637
            ],
            [
                0.585194166712806,
                42.9565556385987
            ],
            [
                0.586094811603247,
                42.9566130759021
            ],
            [
                0.586148521684631,
                42.9564425054839
            ],
            [
                0.584523334321845,
                42.9562400255637
            ]
        ]
    ],
    "type": "Polygon"
}

Vous remarquerez que les coordonnées sont fournies en Degrés Décimaux, et non en Degrés Minutes Secondes. Pourquoi pas. Cela dit, si l’API doit retourner une centaine de parcelles comme sur l’écran vu précédemment, la taille du JSON associé est trop conséquente. (Une parcelle contient rarement 4 points comme dans mon exemple, mais plutôt une 20aine!)

Se pose alors une question : Quel intéret d’avoir 15 décimales après la virgule ?

Nombre de chiffres après la virgule Equivalent en mètres
0 111.32 km
1 11.132 km
2 1.1132 km
3 111.32 m
4 11.132 m
5 1.1132 m
6 111.32 mm
7 11.132 mm
8 1.1132 mm

8 chiffres après la virgule : 1mm. Autant dire que 15 chiffres, ça n’a aucun sens!

Heureusement, Postgis vient encore à la rescousse. Pour 6 décimales, il suffit de demander…

SELECT ST_AsGeoJSON(field.geom,6) from field limit 1;
=>
{
    "coordinates": [
        [
            [
                0.584523,
                42.956240
            ],
            [
                0.585194,
                42.956555
            ],
            [
                0.586094,
                42.956613
            ],
            [
                0.586148,
                42.956442
            ],
            [
                0.584523,
                42.956240
            ]
        ]
    ],
    "type": "Polygon"
}

 

Et voilà une API qui a divisé sa taille par 2!

En Conclusion

Postgis est vraiment un outil puissant et pratique. En contrepartie, Postgis embarque avec lui toute la complexité du monde de la GeoData, avec son système de projection, ses transformations et ses approximations. Si nous avions un retour d’expérience à faire, c’est de bien lire la documentation de chaque fonction, et de ne jamais se fier aux valeurs par défaut.

Laisser un commentaire

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

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.