Jointures 1-n dans QGis: les couches virtuelles

Une des techniques les plus répandues en SIG pour pouvoir traiter des données non spatiales est celle de la jointure. On utilise une couche géographique, possédant des géométries, comme support d’une autre couche ne possédant pas de données de localisation. Pour faire cela, on utilise un champ commun aux deux tables, qui permet de « joindre » les enregistrements de la table géographique à ceux de la table non géographique. On créé ainsi une nouvelle table virtuelle ou les attributs de la table non géographique peuvent être utilisés pour être cartographiés avec la géométrie de la première table. Pour que cette jointure marche il faut que pour un enregistrement de la table géographique on retrouve un enregistrement dans la table non géographique, ou qu’on n’en trouve pas. Car si l’on trouve plus d’un, la jointure ne peut pas marcher. On parle alors de « relation » entre les tables et non de « jointure ».

Pendant longtemps, les logiciels SIG n’ont permis que de travailler avec des jointures. Les relations ne supportaient pas la plupart des opérateurs spatiaux applicables aux jointures.

Une des raisons de cette limitation était le sous-ensemble restreint du langage SQL applicable aux couches géographiques. Que ce soit sur les fichiers shapefile, ou autres, les requêtes applicables se limitaient à une clause préformatée  de type « SELECT * FROM la_table WHERE » et où on pouvait construire la fin de la requête, c’est à dire la clause WHERE.

Pour pouvoir créer une table virtuelle avec plusieurs enregistrements de la table B correspondants à un enregistrement de la table A (cardinalité de type 1,n) il faut utiliser la capacité de jointure de tables du SQL et donc, utiliser deux tables dans la requête. Ceci est possible dans QGis aujourd’hui (ça n’a pas toujours été le cas), en utilisant les « couches virtuelles ». Elles sont apparues sous forme de plugin dans la version 2.10, et intégrées aux corps de QGis dans la version 2.14 .

Les couches virtuelles de QGis

Fonctionnalités des couches virtuelles

•Vous pouvez créer une nouvelle couche virtuelle avec le bouton « New virtual layer »:
•Une couche virtuelle peut être créée à partir d’une sélection de couche (clic droit dans la fenêtre couche)

•Si vous voulez filtrer une couche avec une jointure, Qgis proposera de créer une couche virtuelle

•Dans DBMANAGER, il y a une nouvelle entrée « Virtual Layers » où vous pouvez utiliser la Fenêtre SQL pour créer une couche virtuelle

La génération des couches virtuelles est sauvegardée dans le fichier projet. La couche virtuelle se comporte comme une table native, notamment avec les champs issus d’une jointure.

Utilisation des couches virtuelles

Prenons un exemple:

Nous disposons d’un fichier Excel contenant les différentes aires communales (campings, grandes surfaces,naturelles, stationnements,…). Ce tableau a une colonne INSEE où l’on trouve le code Insee de la commune sur laquelle se trouve l’aire.

Nous disposons d’un shapefile des communes sous forme de polygones, dans lequel nous trouvons un attribut INSEE_COM avec le code Insee de la commune.

Ce que nous souhaitons c’est d’avoir une couche où chaque aire soit représentée par le polygone de la commune correspondante. Au lieu d’avoir les X polygones de la couche communes nous voulons avoir les Y polygones correspondants aux Y lignes de la table Excel des aires communales.

Nous chargeons la couche Communes dans QGis, ainsi que la table Excel CCAires. Pour charger la table Excel vous devez activer et utiliser le plugin Spreadsheet Layers.

Pour créer la couche virtuelle, on clique sur le bouton Ajouter/Editer couche virtuelle

Nous utilisons le bouton Importer pour ajouter les deux couches dans la liste des Couches intégrées.

Dans la fenêtre Requête, on rentre la commande SQL suivante:

SELECT * FROM communes29, CCAires  where INSEE_COM = INSEE

Vous pouvez (et devez) tester la syntaxe de votre requête SQL avec le bouton Tester

On clique sur OK et la couche virtuelle est ajoutée à la carte.

Remarquez les deux communes absentes, car elles n’ont pas d’aire communale dans le fichier Excel.

Si on affiche la table attributaire de la couche virtuelle:

On peut voir que plusieurs enregistrements correspondent à une même commune, et que le nombre d’enregistrements (419) correspond au nombre de lignes du tableau Excel et non au nombre des communes du shapefile (283).

On peut aller plus loin et ajouter une clause WHERE pour ne sélectionner qu’une partie des aires communales, par exemple les campings

On obtient seulement 148 enregistrements, correspondant au nombre de campings présents dans le tableau Excel.

7 réflexions sur « Jointures 1-n dans QGis: les couches virtuelles »

  1. Toujours aussi didactique, c’est un plaisir à lire.
    Concernant la cardinalité de type 1-n, autant écrire 1, n ou (1, n), on a ainsi moins tendance à lire « un moins n ».

  2. Bonjour, c’est effectivement très clair mais je n’y arrive pas 🙁

    Voici ma requête sql :

    select * from limites-communales, test where COMMUNE=nom

    Et j’ai ce message d’erreur : Query execution error on DROP TABLE IF EXISTS « test »; CREATE VIRTUAL TABLE « test » USING QgsVLayer(‘ogr’,’C:/Users/Etude/Downloads/carto/test.csv.vrt’,UTF-8): 1 – near « . »: syntax error

    Limites-communales est un shp avec mes limites de communes
    il est dans C:\Users\Etude\Downloads\carto\limites-communales.shp

    test est un fichier csv avec parfois plusieurs enregistrements pour une même commune :
    il est dans C:/Users/Etude/Downloads/carto/test.csv.vrt

    (pourquoi il y a il des « slash » dans un cas et des « antislashs » dans l’autre ? )

    Merci d’avance si vous voyez une solution…

  3. J’ai trouvé !!!! (mais ca peut servir à d’autres). J’essayais de relier mes 2 tables à l’aide de champ texte. En utilisant 2 champs de nobres entier ca marche parfaitement.
    Quelle serait la syntaxe à utiliser pour relier avec des champs textes ?
    merci….

    1. C’est aussi mon problème: est-ce un problème de syntaxe, ou est-il simplement impossible de faire une telle jointure sur une colonne de type « char »?

      1. Il y a effectivement un bug sur la jointure de deux champs texte, seulement s’ils sont de type NOT NULL
        Si le champ est character varying ou text mais il n’est pas de type NOT NULL, ça fonctionne. Dans le cas contraire, la table virtuelle résultante apparaît vide.
        Il faut donc, soit enlever le NOT NULL, soit créer un nouveau champ texte.

Laisser un commentaire

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