Important

La traduction est le fruit d’un effort communautaire auquel vous pouvez prendre part. Cette page est actuellement traduite à 71.24%.

16.4. Connecter et modifier des données entre couches

Ability to connect data from different layers is one of the duties of a GIS software. Such a connection can be based on the spatial relationship between the features, or on their shared attributes. QGIS provides tools to handle any of these associations, such as:

16.4.1. Joindre des entités de deux couches

Joins in QGIS allow you to associate features of the current layer to features from another loaded vector layer. Whether they are spatially enabled and the type of geometry do not matter. The join is based on an attribute that is shared by the layers, in a one-to-one relationship.

To create a join on a layer (identified below as target layer):

  1. Rendez vous dans l’onglet Propriétés ► join Jointures de la couche

  2. Cliquez sur le bouton symbologyAdd Ajouter une nouvelle jointure. La boîte de dialogue Ajouter une jointure vecteur apparaît.

  3. Sélectionnez la Couche de jointure que vous souhaitez connecter avec la couche vecteur cible

  4. Specify the Join field (from the join layer) and the Target field (from the target layer). These are the fields that are used to find matching feature in both layers hence they should have values in common.

  5. Appuyez sur OK et un résumé des paramètres sélectionnés est ajouté à l’onglet Jointure.

../../../_images/join_attributes.png

Fig. 16.101 Joindre une table attributaire à une couche vecteur existante

The steps above will create a join, where ALL the attributes of the first matching feature in the join layer is added to the target layer’s feature. The following logic is used to pair features during a join process:

  • All the features in the target layer are returned, regardless they have a match

  • If the target field contains duplicate values, these features are assigned the same feature from the join layer.

  • If the join field contains duplicate matching values, only the first fetched feature is picked.

Note

Joins in QGIS are based on a single field matching so most of the times, you would want to make sure that values in the matchable fields are unique.

QGIS provides some more options to tweak the join:

  • checkbox Mettre la couche jointe en cache dans la mémoire virtuelle : permet de mettre en cache les valeurs (sans géométrie) de la couche jointe afin d’accélérer les recherches.

  • unchecked Créer un index des attributs sur le champ de la jointure pour accélérer les recherches

  • unchecked Formulaire dynamique : aide à synchroniser les champs de jointure à la volée, selon le Champ dans la couche cible. De cette façon, les contraintes des champs de jointure sont également correctement mises à jour. Notez qu’il est désactivé par défaut car cela peut prendre beaucoup de temps si vous avez beaucoup d’entités ou une myriade de jointures.

  • Si la couche cible est modifiable, certaines icônes seront affichées dans la table attributaire à côté des champs, afin de renseigner leur statut :

    • joinNotEditable : la couche de jointure n’est pas configurée pour être modifiable. Si vous souhaitez pouvoir modifier les fonctions de jointure à partir de la table d’attributs cible, vous devez cocher l’option checkbox Couche de jointure modifiable

    • joinedLayerNotEditable : la couche de jointure est bien configurée pour être modifiable, mais son état actuel est en lecture seule.

    • joinHasNotUpsertOnEdit : la couche de jointure est modifiable, mais les mécanismes de synchronisation ne sont pas activés. Si vous souhaitez ajouter automatiquement une entité dans la couche de jointure lorsqu’une entité est créée dans la couche cible, vous devez cocher l’option checkbox Mise à jour et insertion lors de l’édition. Symétriquement, l’option checkbox Supprimer en cascade peut être activée si vous souhaitez supprimer automatiquement les entités jointes.

  • unchecked Champs joints: au lieu d’ajouter tous les champs de la couche jointe, vous pouvez spécifier un sous-ensemble.

  • unchecked Préfixe de nom de champ personnalisé pour les champs joints, afin d’éviter la collision de noms

16.4.2. Définir des relations entre plusieurs couches

Unlike joins that define a one-to-one link between features across two layers, relations help you build interconnections between multiple features across two or more layers. As such, relations are project level settings and are set in Project ► Properties ► relations Relations tab. From there, you can:

  • symbologyAdd Add relation whose type can be:

    Note

    There is no simple way yet to edit a non-polymorphic relation once it has been created. Only the name can be edited with a double-click. For any other parameters of such a relation you will have to remove and recreate it.

  • symbologyAdd Discover relations: QGIS is able to discover existing relations from supported database formats (PostgreSQL, GeoPackage, ESRI File Geodatabase, …). This can be a good way to ease the relations definition.

  • symbologyRemove Supprimer relation

../../../_images/project_relations.png

Fig. 16.102 Onglet Relations

16.4.2.1. Relation un à plusieurs (1-N)

Comme exemple, nous prendrons une couche contenant toutes les régions de l’Alaska (des polygones) qui fournit quelques attributs sur le nom, le type de région et un identifiant unique (qui jouera le rôle de clé primaire).

Nous prenons ensuite une autre couche de point ou une table contenant des informations sur les aéroports localisés dans les régions. Si vous souhaitez y accéder, depuis la couche des régions, vous devez créer une relation “un à plusieurs”, en utilisant des clés étrangères, car il y a plusieurs aéroports dans la plupart des régions.

../../../_images/regions_with_airports.png

Fig. 16.103 Les régions d’Alaska contenant des aéroports

Couches et clés

QGIS ne fait pas de distinction entre une table et une couche vecteur. Très simplement, une couche vecteur est une table associée à une géométrie. Ce qui signifie que vous pouvez ajouter votre table comme une couche vecteur. Pour démontrer la relation de 1 à n, vous pouvez charger les couches regions et airports du jeu de données. En pratique, chaque aéroport appartient à une et une seule région alors que chaque région peut avoir un nombre variable d’aéroports (une relation 1 à plusieurs).

which has a foreign key field (fk_region) to the layer regions.

In addition to the attributes describing the airports, the aiports layer has another field fk_region which acts as a foreign key (if you have a database, you will probably want to define a constraint on it). This fk_region field will always contain an id of a region. It can be seen like a pointer to the region it belongs to.

All you have to do is to tell QGIS the relation between the layers so that you can design a custom edit form for editing and QGIS takes care of the setup. It works with different providers (so you can also use it with shape and csv files).

Définir les relations 1-N

La première chose que nous allons faire est de faire connaître au logiciel QGIS les relations entre les couches. Cela se fait dans Projet ► Propriétés…. Ouvrez l’onglet Relations et cliquez sur symbologyAdd Ajout relation .

  • Nom sera utilisé comme titre. Il s’agit d’un texte lisible décrivant la relation. Ici, nous allons simplement mettre airport_relation.

  • Couche référencée (Parent) également considérée comme couche parent, est celle dont la clé primaire est pointée, donc ici c’est la couche regions. Vous devez définir la clé primaire de la couche référencée, c’est donc ID.

  • Référencement de la couche (enfant) également considérée comme la couche enfant, est celle sur laquelle se trouve le champ clé étrangère. Dans notre cas, il s’agit de la couche airports. Pour cette couche, vous devez ajouter un champ de référencement qui pointe vers l’autre couche, c’est donc la fk_region.

    Note

    Parfois, il faut plus qu’un seul champ pour identifier de manière unique les éléments d’une couche. Pour créer une relation avec une telle couche, il faut une clé composite, c’est-à-dire plus qu’une seule paire de champs correspondants. Utilisez le bouton symbologyAdd Ajouter une nouvelle paire de champ pour créer une clé composite pour ajouter autant de paires que nécessaire.

  • Id sera utilisée pour des besoins internes et doit être unique. Vous pourriez en avoir besoin pour créer des formulaires personnalisés. Si vous laissez ce champ vide, un numéro sera généré automatiquement mais vous pouvez en assigner un si vous le souhaitez.

  • Relationship strength sets the strength of the relation between the parent and the child layer. The default Association type means that the parent layer is simply linked to the child one while the Composition type allows you to duplicate also the child features when duplicating the parent ones and on deleting a feature the children are deleted as well, resulting in cascade over all levels (means children of children of… are deleted as well).

../../../_images/regions_airports_mapping.png

Fig. 16.104 Ajout d’une relation entre les couches regions et airports

Depuis l’onglet Relations, vous pouvez également appuyer sur le bouton symbologyAdd Découvrir relation pour récupérer les relations disponibles auprès des fournisseurs des couches chargées. Ceci est possible pour les couches stockées dans des fournisseurs de données comme PostgreSQL ou SpatiaLite.

Formulaires pour les relations de 1 à n

Maintenant que QGIS a bien généré la relation, le formulaire d’édition va être amélioré. Nous n’avons pas modifié le formulaire d’édition par défaut (généré automatiquement), une nouvelle zone va simplement être ajoutée au formulaire. Sélectionnez la couche de régions dans la légende et utilisez l’outil d’identification. Selon vos préférences, le formulaire s’ouvre directement ou vous devez le faire via la zone d’identification qui s’affiche.

../../../_images/airport_relation_dataview.png

Fig. 16.105 Formulaire de la couche des régions affichant la relation avec les aéroports

Comme vous pouvez le voir, les aéroports liés à cette région en particulier sont tous visibles dans la table. Il y a également quelques boutons disponibles ; passons-les en revue rapidement :

  • Le bouton toggleEditing permet de passer en mode édition. Soyez conscients qu’il active le mode édition de la couche des aéroports bien qu’il soit situé dans le formulaire de la couche des régions. La table affiche bien les entités de la couche des aéroports.

  • The saveEdits button is for saving all the edits in the child layer (airport).

  • The capturePoint button lets you digitize the airport geometry in the map canvas and assigns the new feature to the current region by default. Note that the icon will change according to the geometry type.

  • The newTableRow button adds a new record to the airport layer attribute table and assigns the new feature to the current region by default. The geometry can be drawn later with the Add part digitizing tool.

  • The duplicateFeature button allows you to copy and paste one or more child features within the child layer. They can later be assigned to a different parent feature or have their attributes modified.

  • The deleteSelectedFeatures button deletes the selected airport(s) permanently.

  • The link symbol opens a new dialog where you can select any existing airport which will then be assigned to the current region. This may be handy if you created the airport on the wrong region by accident.

  • The unlink symbol unlinks the selected airport(s) from the current region, leaving them unassigned (the foreign key is set to NULL) effectively.

  • Avec le bouton zoomToSelected vous pouvez zoomer sur les entités enfant sélectionnées.

  • The two buttons formView and openTable to the right switch between the table view and form view of the related child features.

If you use the Drag and Drop Designer for the regions feature, you can select which tools are available. You can even decide whether to open a new form when a new feature is added using Force hide form on add feature option. Be aware that this option implies that not null attributes must take a valid default value to work correctly.

../../../_images/airport_relation_formproperties.png

Fig. 16.106 Drag and Drop Designer for configure regions-airports relation tools

Dans l’exemple ci-dessus, la couche référence à des géométries (ce n’est pas seulement une table alphanumérique) ce qui implique que les étapes citées créeront une entrée dans la table d’attribut qui n’aura pas de géométrie correspondante. Pour ajouter une géométrie :

  1. Choisir openTable Ouvrir la table d’attributs pour la couche référence.

  2. Sélectionner l’enregistrement ajouté précédemment dans le formulaire d’entité de la couche référence .

  3. Utiliser l’outil de numérisation addPart Ajouter une partie pour attacher une géométrie à l’entité sélectionnée dans la table attributaire.

Si vous travaillez dans la table d’attributs des aéroports, le widget Relation de référence sera automatiquement réglé sur le champ fk_region (celui utilisée pour créer la relation); voir le Widget de Relation de référence.

Dans le formulaire des aéroports, vous voyez le bouton formView à droite du champ fk_region : si vous cliquez sur le bouton, le formulaire de la couche région s’ouvrira. Ce widget vous permet d’ouvrir et modifier rapidement les formulaires des entités parent liées.

../../../_images/airport_attributes.png

Fig. 16.107 Formulaire d’identification d’un aéroport et de sa région associée

Le widget de Relation de référence a également une option pour incruster le formulaire de la couche parent dans celui de la couche enfant. Il est disponible depuis le menu Propriétés ► Formulaire d’attributs de la couche des aéroports : sélectionner le champ fk_region et cocher l’option Montrer le formulaire incrusté

Vous devriez ainsi voir que le formulaire de la région est inclus dans celui d’un aéroport et il vous permet via une liste déroulante de modifier la région assignée à l’aéroport.

../../../_images/airport_attributes_expanded.png

De plus, si vous basculez la couche aéroport en mode édition, le champ fk_region aura également une fonctionnalité d’autocomplétion. De ce fait, tout en complétant le champ, vous verrez toutes les valeurs du champ id de la couche des régions. Si vous activez l’option Autoriser l'ajout de nouvelles entités disponible dans le menu Propriétés ► Formulaire d’attributs de la couche des aéroports, il est également possible de numériser un nouveau polygone pour la couche région en utilisant le bouton symbologyAdd.

La couche enfant peut également être utilisée dans l’outil Sélectionner des Entités par Valeur afin de sélectionner les entités de la couche parent en fonction des attributs de leurs enfants.

Dans Fig. 16.108, toutes les régions où l’altitude moyenne des aéroports est supérieure à 500 mètres au-dessus du niveau de la mer sont sélectionnées.

Vous constaterez que de nombreuses fonctions d’agrégation différentes sont disponibles dans le formulaire.

../../../_images/relation_select_by_value.png

Fig. 16.108 Sélectionner les entités des parents avec les valeurs des enfants

16.4.2.2. Relations plusieurs à plusieurs (N-M)

Les relations de n à n sont des relations de plusieurs à plusieurs entre deux tables. Par exemple, les couches airports et airlines: un aéroport reçoit plusieurs compagnies aériennes et une compagnie aérienne utilise plusieurs aéroports.

Ce code SQL crée les trois tables dont nous avons besoin pour une relation de n à n dans un schéma PostgreSQL/PostGIS nommé locations. Vous pouvez lancer le code en utilisant Base de données ► DB Manager… pour PostGIS ou des outils extérieurs tels que pgAdmin. La table des aéroports stocke la couche airports et la table airlines stocke des lignes aériennes. Dans les deux tables, il y a peu de champs, pour faire simple. La partie délicate est la table airports_airlines. Il faut qu’elle compile toutes les lignes aériennes pour tous les aéroports (et vice versa). Ce genre de table s’appelle une table pivot. Les contraintes de cette table ne rendent possible l’association d’un aéroport avec une ligne que si les deux existent déjà dans leurs couches.

CREATE SCHEMA locations;

CREATE TABLE locations.airports
(
   id serial NOT NULL,
   geom geometry(Point, 4326) NOT NULL,
   airport_name text NOT NULL,
   CONSTRAINT airports_pkey PRIMARY KEY (id)
);

CREATE INDEX airports_geom_idx ON locations.airports USING gist (geom);

CREATE TABLE locations.airlines
(
   id serial NOT NULL,
   geom geometry(Point, 4326) NOT NULL,
   airline_name text NOT NULL,
   CONSTRAINT airlines_pkey PRIMARY KEY (id)
);

CREATE INDEX airlines_geom_idx ON locations.airlines USING gist (geom);

CREATE TABLE locations.airports_airlines
(
   id serial NOT NULL,
   airport_fk integer NOT NULL,
   airline_fk integer NOT NULL,
   CONSTRAINT airports_airlines_pkey PRIMARY KEY (id),
   CONSTRAINT airports_airlines_airport_fk_fkey FOREIGN KEY (airport_fk)
      REFERENCES locations.airports (id)
      ON DELETE CASCADE
      ON UPDATE CASCADE
      DEFERRABLE INITIALLY DEFERRED,
   CONSTRAINT airports_airlines_airline_fk_fkey FOREIGN KEY (airline_fk)
      REFERENCES locations.airlines (id)
      ON DELETE CASCADE
      ON UPDATE CASCADE
      DEFERRABLE INITIALLY DEFERRED
 );

Au lieu de PostgreSQL, vous pouvez utiliser GeoPackage. Dans ce cas, les trois tables sont créées manuellement avec le menu Base de données ► DB Manager…. Dans GeoPackage, il n’y a pas de schémas, donc le préfixe locations n’est pas requis.

Les contraintes de clé étrangère dans la table airports_airlines ne peuvent être créées en utilisant Table ► Créer une Table… ou Table ► Modifier une table…. Elles doivent donc être créées en sélectionnant Base de données ► Fenêtre SQL…. GeoPackage n’accepte pas les déclarations ADD CONSTRAINT ce qui fait que la table airports_airlines doit être créée en deux étapes :

  1. Créer la table avec seulement le champ id en utilisant Table ► Créer une Table…

  2. Avec Base de données ► Fenêtre SQL…, copier et exécuter ce code SQL :

    ALTER TABLE airports_airlines
       ADD COLUMN airport_fk INTEGER
       REFERENCES airports (id)
       ON DELETE CASCADE
       ON UPDATE CASCADE
       DEFERRABLE INITIALLY DEFERRED;
    
    ALTER TABLE airports_airlines
       ADD COLUMN airline_fk INTEGER
       REFERENCES airlines (id)
       ON DELETE CASCADE
       ON UPDATE CASCADE
       DEFERRABLE INITIALLY DEFERRED;
    

Puis dans QGIS, vous devez établir deux relations « un à plusieurs » comme expliqué au-dessus :

  • une relation entre la table airlines et la table pivot ;

  • et une seconde entre la table airports et la table pivot.

Une façon plus simple de faire cela (seulement pour PostgreSQL) est d’utiliser Découvrir des relations dans Projet ► Propriétés ► Relations. QGIS lit automatiquement toutes les relations de votre base de données et vous n’avez qu’à sélectionner les deux dont vous avez besoin. Pensez à charger les trois tables dans le projet QGIS d’abord.

../../../_images/airports_airlines_relation.png

Fig. 16.109 Relations et découverte automatique

Si vous souhaitez supprimer un airport ou une airline, QGIS ne supprimera pas la ou les entité(s) associée(s) dans la table airports_airlines. Cette tâche sera effectuée par la base de données si nous lui fournissons les bonnes contraintes lors de la création de la table pivot comme dans l’exemple actuel.

Note

Combiner des relations de n à n avec un groupe de transaction automatique

Vous devez activer le mode de transaction dans Propriétés du projet ► Sources de données ► quand vous travaillez dans de tels contextes. QGIS doit pouvoir ajouter ou mettre à jour un ou plusieurs champs dans toutes les tables (lignes aériennes, aéroports et les tables pivot).

Finally we have to select the right cardinality in the Layer Properties ► Attributes Form for the airports and airlines layers. For the first one we should choose the airlines (id) option and for the second one the airports (id) option.

../../../_images/airports_airlines_relation_formproperties.png

Fig. 16.110 Régler la relation de cardinalité

Vous pouvez maintenant associer un aéroport avec une ligne aérienne (ou une ligne aérienne avec un aéroport) en utilisant Ajouter une entité enfant ou Lier à une entité enfant existante dans les sous-formulaires. Un enregistrement sera automatiquement inséré dans la table airports_airlines.

../../../_images/add_airport_airline.png

Fig. 16.111 relation de n à n entre aéroports et lignes aériennes

Note

Utiliser la cardinalité Relation de n à 1

Il n’est parfois pas souhaitable de cacher la table pivot dans une relation de n à n. Principalement parce qu’il y a des attributs dans cette relation qui ne peuvent avoir de valeurs que lorsque la relation est établie. Si vos tables sont des couches (qui ont un champ géométrie), il peut être intéressant d’activer l’option Identification sur la carte (Propriétés de la couche ► Formulaire d’attributs ► Outils disponibles ► Champs) pour les champs de clé étrangère dans la table pivot.

Note

Clé primaire de la table pivot

Évitez d’utiliser des champs multiples dans la clé primaire de la table pivot. QGIS attend une clé primaire unique donc une contrainte comme constraint airports_airlines_pkey primary key (airport_fk, airline_fk) ne fonctionnera pas.

16.4.2.3. Les relations polymorphiques

L’objectif

Polymorphic relations are special case of 1-N relations, where a single referencing (document) layer contains the features for multiple referenced layers. This differs from normal relations which require different referencing layer for each referenced layer. A single referencing (document) layer is achieved by adding an adiditonal layer_field column in the referencing (document) layer that stores information to identify the referenced layer. In its most simple form, the referencing (document) layer will just insert the layer name of the referenced layer into this field.

To be more precise, a polymorphic relation is a set of normal relations having the same referencing layer but having the referenced layer dynamically defined. The polymorphic setting of the layer is solved by using an expression which has to match some properties of the referenced layer like the table name, layer id, layer name.

Imagine we are going to the park and want to take pictures of different species of plants and animals we see there. Each plant or animal has multiple pictures associated with it, so if we use the normal 1:N relations to store pictures, we would need two separate tables, animal_images and plant_images. This might not be a problem for 2 tables, but imagine if we want to take separate pictures for mushrooms, birds etc.

Polymorphic relations solve this problem as all the referencing features are stored in the same table documents. For each feature the referenced layer is stored in the referenced_layer field and the referenced feature id in the referenced_fk field.

Définir les relations polymorphiques

First, let QGIS know about the polymorphic relations between the layers. This is done in Project ► Properties…. Open the Relations tab and click on the little down arrow next to the symbologyAdd Add Relation button, so you can select the Add Polymorphic Relation option from the newly appeared dropdown.

../../../_images/polymorphic_relation_properties.png

Fig. 16.112 Adding a polymorphic relation using documents layer as referencing and animals and plants as referenced layers.

  • Id sera utilisée pour des besoins internes et doit être unique. Vous pourriez en avoir besoin pour créer des formulaires personnalisés. Si vous laissez ce champ vide, un numéro sera généré automatiquement mais vous pouvez en assigner un si vous le souhaitez.

  • Referencing Layer (Child) also considered as child layer, is the one with the foreign key field on it. In our case, this is the documents layer. For this layer you need to add a referencing field which points to the other layer, so this is referenced_fk.

    Note

    Parfois, il faut plus qu’un seul champ pour identifier de manière unique les éléments d’une couche. Pour créer une relation avec une telle couche, il faut une clé composite, c’est-à-dire plus qu’une seule paire de champs correspondants. Utilisez le bouton symbologyAdd Ajouter une nouvelle paire de champ pour créer une clé composite pour ajouter autant de paires que nécessaire.

  • Layer Field is the field in the referencing table that stores the result of the evaluated layer expression which is the referencing table that this feature belongs to. In our example, this would be the referenced_layer field.

  • Layer expression evaluates to a unique identifier of the layer. This can be the layer name @layer_name, the layer id @layer_id, the layer’s table name decode_uri(@layer, 'table') or anything that can uniquely identifies a layer.

  • Relationship strength sets the strength of the generated relations between the parent and the child layer. The default Association type means that the parent layer is simply linked to the child one while the Composition type allows you to duplicate also the child features when duplicating the parent ones and on deleting a feature the children are deleted as well, resulting in cascade over all levels (means children of children of… are deleted as well).

  • Referenced Layers also considered as parent layers, are those with the primary key, pointed to, so here they would be plants and animals layers. You need to define the primary key of the referenced layers from the dropdown, so it is fid. Note that the definition of a valid primary key requires all the referenced layers to have a field with that name. If there is no such field you cannot save a polymorphic relation.

Once added, the polymorphic relation can be edited via the Edit Polymorphic Relation menu entry.

../../../_images/polymorphic_relations.png

Fig. 16.113 Preview of the newly created polymorphic relation and its child relations for animals and plants.

L’exemple ci-dessus utilise le schéma de base de données suivant :

CREATE SCHEMA park;

CREATE TABLE park.animals
(
   fid serial NOT NULL,
   geom geometry(Point, 4326) NOT NULL,
   animal_species text NOT NULL,
   CONSTRAINT animals_pkey PRIMARY KEY (fid)
);

CREATE INDEX animals_geom_idx ON park.animals USING gist (geom);

CREATE TABLE park.plants
(
   fid serial NOT NULL,
   geom geometry(Point, 4326) NOT NULL,
   plant_species text NOT NULL,
   CONSTRAINT plants_pkey PRIMARY KEY (fid)
);

CREATE INDEX plants_geom_idx ON park.plants USING gist (geom);

CREATE TABLE park.documents
(
   fid serial NOT NULL,
   referenced_layer text NOT NULL,
   referenced_fk integer NOT NULL,
   image_filename text NOT NULL,
   CONSTRAINT documents_pkey PRIMARY KEY (fid)
);