Jean David

QGIS : Représenter plusieurs symboles sur un même point (déplacement en grille)

Introduction & constat

Un aspect fréquent de la représentation cartographique est la capacité à représenter plusieurs symboles contenus dans un même point.

Particulièrement utilisée dans les cartes urbaines, cette méthode sémiologique permet de présenter une information complexe au lecteur, en préservant la lisibilité de la carte.

Variation cartographiques sur le même thème de différentes sémiologies centralisées sur un même point. Notons que cet artéfact, souvent utilisé pour des cartes urbaines - et donc très denses - est également particulièrement présent dans les cartes historiques.

A ma surprise, QGIS ne permet pas de gérer ces sémiologies nativement. L'option de QGIS qui s'en rapproche le plus semble être la symbologie en déplacement de point, avec une méthode de déplacement en grille. Pourtant, sauf erreur, cette méthode est très limitée en terme de personnalisation, et ne permet pas une gestion adéquate du nombre d'éléments représentés. Dans mon cas, je cherchais à figurer mes symboles dans une ligne en dessous de mon étiquette.

Pour cela, la méthode que j'ai conçue consiste à attribuer à chacun de mes points un id, puis d'utiliser cet id comme base pour mon placement dans QGIS.

Entité Symbole id
Entité A Symbole 1 1
Entité A Symbole 2 2
Entité A Symbole 3 3
Entité A Symbole 4 4
Entité B Symbole XYZ 1
Entité B Symbole ABC 2
Entité C Symbole #&@ 1
Entité C Symbole %$§ 2

Implémentation en python

La difficulté ici étant de générer automatiquement la liste des id dans le cas où ma table serait vouée à changer régulièrement. Idéalement, pour faciliter mon intégration dans QGIS, je vais également créer une colonne correspondant à l'id maximum de chaque entité, ainsi que la valeur échelonnée de l'id par rapport au milieu du groupe (Utile dans le cas où ma représentation serait en ligne plutôt qu'en grille). C'est à dire :

$$ id = 1 + ∑_{j=1}^{i} I(ENTITY_j = ENTITY_i) $$

Soit en python :

df['id'] = df.groupby('entity').cumcount() + 1
df['id_max'] = df.groupby('entity')['id'].transform('max')
df['id_x'] = ((df['id']-1)-((df['id_max']-1)/2))*4

Dans le cas d'une grille de symbole, je peux attribuer un id à chaque ligne correspondant à sa position x et y dans une grille :

grid_base = 5
df['pos_y'], df['pos_x'] = divmod(df['id']-1, grid_base)
df['pos_y'], df['pos_x'] = df['pos_y']+1, df['pos_x']+1

Implémentation dans QGIS

Une fois dans QGIS, nous pouvons utiliser les chiffres calculés pour la représentation avec respectivement :

-- Dans le cas d'une grille
    concat("pos_x"*5-3,',',"pos_y"*5-3)
    -- Dans le cas d'une ligne
    to_string("id_x"*0.75)+',0'

Soit en l'utilisant dans QGIS :

Le réseau des services Judiciaires, Ministère de la Justice, Direction des services judiciaires, Pôle de l'évaluation et de la prospective, Jean David, 2024.