Nous avons dit dans l’article précédent(L’analyse spatiale avec SQL:1-Introduction) que l’idée la plus répandue est que le langage SQL est un très bon outil de requête sur les tables SIG mais qu’il faut un logiciel SIG tel que QGis ou ArcGis pour réaliser les tâches d’analyse spatiale. Voyons d’où vient cette idée reçue.
La dépréciation du SQL par les logiciels SIG
Le langage SQL a été victime des carences des logiciels de SIG pendant des décades. Le format « phare » du SIG entre les années 70 et 2000, le shapefile d’ESRI, n’implémentait qu’une version réduite du standard SQL. Impossible d’utiliser des sous-requêtes faisant appel à d’autres tables, on était cantonné aux champs d’une seule table.
A cela il faut ajouter les assistants SQL mis en place par les différents logiciels, tels que le wizzard d’ArcGis:
Dans les faits, on a réduit le langage SQL à la clause WHERE en proposant une version ultra-simpliste qui était censée affranchir l’utilisateur de connaître le langage SQL.
Depuis quelques années la situation s’est nettement améliorée. Ne citons comme exemple que le Gestionnaire de bases de données de QGis:
qui permet d’utiliser toute l’étendue du SQL, de ces extensions comme Postgis, et de récupérer le résultat d’une requête et l’afficher dans la fenêtre cartographique de QGis.
Le langage SQL est compliqué et pas intuitif
Cette assertion est vraie,… seulement si vous ne connaissez pas du tout les bases du SQL!
Prenons la requête SQL de l’exemple final de l’article précédent:
SELECT sum(prix_terrain)::numeric::money, classepropriete
FROM parcelles, zones_inondables
WHERE st_intersects(parcelles.geometry,zones_inondables.geometry)
GROUP BY classepropriete;
Comme pour toutes les requêtes SQL vous avez deux lignes obligatoires:
- SELECT et une liste d’information que l’on souhaite avoir comme résultat
- FROM et une liste de tables où se trouvent les informations
Puis une ligne optionnelle
- WHERE et les conditions pour extraire les informations résultat
et finalement une ou plusieurs lignes qui mettent en forme les informations résultat (GROUP BY, ORDER BY,…)
Si vous prenez juste le temps de répondre à ces quatre questions avant de commencer à écrire une requête SQL, vous verrez que l’écriture est tout à fait intuitive:
- quelles sont les données que je veux obtenir? (->clause SELECT)
- où est-ce qu’elles sont stockées? (->clause FROM)
- quelles sont les conditions que je veux appliquer, spatiales ou pas?(->clause WHERE)
- quelle mise en forme des résultats je souhaite?(->clauses GROUP BY, ORDER BY,…)
Prenons un exemple: Je veux les adresses de toutes les parcelles limitrophes de la mienne.
Pour construire la requête je me pose la série de questions:
- quelles sont les données que je veux obtenir?: je veux l’adresse des parcelles (numéro et rue) ->clause SELECT:
SELECT num_voie ||’ ‘ || adresse
- où est-ce qu’elles sont stockées? : dans la table parcelles ->clause FROM:
FROM parcelles
- quelles sont les conditions que je veux appliquer, spatiales ou pas? sélectionner seulement les parcelles qui touchent la parcelle avec le parcel_id=1144->clause WHERE:
WHERE st_touches(parcelles.geometry, ??????)
La commande spatiale teste si deux géométries se touchent. Pour ce qui est de parcelles.geometry, cela va parcourir toute la table pour tester si chaque enregistrement touche la deuxième partie de la commande.
Cette deuxième partie on la construit en suivant la même méthode:
- quelles sont les données que je veux obtenir?: je veux la géométrie d’une parcelle ->clause SELECT:
SELECT geometry
- où est-ce qu’elles sont stockées? : dans la table parcelles ->clause FROM:
FROM parcelles
- quelles sont les conditions que je veux appliquer, spatiales ou pas? la parcelle qui a l’identifiant 1144->clause WHERE:
WHERE parcel_id=1144
Nous mettons cette deuxième partie entre parenthèses et remplaçons les ?????? dans la première partie de la requête
SELECT num_voie ||’ ‘ || adresse
FROM parcelles
WHERE st_touches(parcelles.geometry, (SELECT geometry FROM parcelles WHERE parcel_id=1144))
Si nous exécutons cette requête dans le gestionnaire de bases de données de QGis:
On obtient la liste des adresses recherchées, et si nous chargeons le résultat de la requête dans QGis on a:
La parcelle jaune est la parcelle 1144, les parcelles bleues sont celles retournées par la requête, avec leur adresse respective.
Si vous voulez être définitivement convaincu du fait que SQL est réellement intuitif et que ça vous fait gagner du temps, je vous invite à obtenir le même résultat que celui qui est affiché ici, mais en utilisant les outils classiques (non sql) de QGis ou d’ArcGis.
La suite?
Dans le prochain article nous verrons les opérateurs spatiaux de Postgis. Là aussi, on ne prendra pas le chemin habituel. En général, on commence par les opérateurs de définition des géométries, la définition des SRC, etc.
Mais de la même manière que quand on veut apprendre les opérateurs sur les nombres, en SQL, on ne démarre pas avec la transformation en nombres imaginaires, mais avec les opérateurs de base: addition, soustraction, division, multiplication… nous allons voir le petit groupe de fonctions spatiales de base. Elles ne représentent pas plus d’une dizaine parmi le millier de fonctions disponibles avec Postgis. Bien assimiler ces fonctions permet de se lancer sans problème dans l’analyse spatiale avec SQL. Et vous ferrez comme pour les fonctions sur les nombres rarement utilisées (telles que BIT_count ou MOD ou OCT), vous n’irez les chercher que quand vous en aurez vraiment besoin.
Bonjour,
Je partage votre point de vue sur la sous-utilisation de SQL dans des outils SIG comme ArcGIS, MapInfo ou autres en n’exposant que l’accès à la partie WHERE, et parfois de manière très limitée avec les shapefiles et les contraintes inhérentes au fichier DBF. C’était en tout cas vrai il y a 15 ans, car depuis cela à tout de même évolué. Pour reprendre l’exemple d’ArcGIS, depuis plus de 10 ans existe les Géodatabase Enterprise qui reposent sur des SGBDR et utilisent potentiellement tous leurs mécanismes SQL (cartouches spatiales, vues, procédures stockées, …). Depuis 6 ans maintenant, ArcGIS Desktop et ArcGIS Server permettent d’ajouter dans ses cartes des couches SQL (SQL Layers) qui font non seulement ce que vous décrivez dans votre article, mais de manière plus intelligente en intégrant la dimension temporelle ou en proposant (dans ArcGIS Pro) d’insérer des variables dans la requête ce qui permet à l’utilisateur (à l’aide de sliders ou de listes) des filtrages interactifs sur la couche.
Un paradoxe dans les outils SIG d’aujourd’hui c’est que le SQL n’a jamais été aussi bien intégré, y compris sur des bases de données in-memory et que pour autant on se tourne de plus en plus vers d’autres types d’entrepôts de données comme les bases NoSQL, les clusters de fichiers comme HDFS, … dont les « sur-couches » SQL ne pas sont forcement aussi efficace.
100% d’accord.
Tout à fait d’accord avec le contenu de l’article. L’usage du sql est tellement pratique que j’ai fait un plugin QGis pour lancer des requêtes sql contenu dans un dossier (avec variables paramétrables, listes de choix).
https://github.com/hchristol/SharedSqlQueries