Autopsie d'une dataviz [8.1] : un geojson complet et léger

Première partie d'un tuto en trois volets où l'on va voir comment réaliser de A à Z une carte choroplèthe grâce à la librairie D3js. On commence avec la création d'un geojson le plus léger possible, en utilisant notamment QGis.

J'ai réalisé il y a quelques semaines cinq cartes interactives centrées sur le FN en Alsace. Cela a été l'occasion d'un peu plus tâter de la librairie D3js, qui m'a pas mal impressionné côté géographie !

Mais ne grillons pas les étapes et commençons avec la création d'un fichier .geojson que la librairie pourra interpréter correctement. On va se servir pour cela :

On va ensuite grâce au logiciel Quantum GIS (QGis) :

  • préparer chaque fichier, avec comme impératif d'avoir un attribut commun entre eux pour permettre que les bonnes données aillent à la bonne commune
  • réaliser une jointure entre le tableur de données et les fichiers géographiques
  • simplifier ces coordonnées pour avoir un fichier le plus léger possible
  • enregistrer tout ça au bon format, le geojson dans notre cas

Préparer le shapefile

Rentrons dans le vif, et téléchargeons sur le serveur d'OSM les communes du Haut-Rhin (68) et du Bas-Rhin (67). On va ouvrir chaque .tar.gz et exporter les quatre fichiers qu'il contient (.dbf, .prj, .shp et .shx) dans un même dossier.

On a huit fichiers, mais seuls les deux .shp seront sélectionnés avec QGis. On ouvre donc le logiciel, et on clique sur l'icône "Ajouter une couche vecteur" sur la bande à gauche de l'écran :

tuto_qgis_1

Cliquez sur l'image pour l'agrandir

Une nouvelle fenêtre s'ouvre, on ne se pose pas de question et on clique sur "Parcourir" :

tuto_qgis_2

Cliquez sur l'image pour l'agrandir

De là, on navigue via l'explorateur qui vient s'ouvrir vers notre dossier, on sélectionne les deux fichiers .shp, et on clique sur "Ouvrir" pour valider la sélection :

tuto_qgis_3

Cliquez sur l'image pour l'agrandir

Retour à la fenêtre initiale où ne se pose à nouveau pas de question et où on clique sur "Ouvrir" :

tuto_qgis_4

Cliquez sur l'image pour l'agrandir

Sur l'interface de QGis, on doit maintenant voir apparaître dans le grand cadre de droite le contenu de nos deux fichiers, distingués par des couleurs différentes. Dans le gestionnaire de calques à gauche, on voit le nom de chaque fichier apparaître. C'est tout bon !

tuto_qgis_5

Cliquez sur l'image pour l'agrandir

Fusionner deux shapefiles en un

On va commencer par fusionner nos deux fichiers en un. Pour cela, se dirige vers les menus du haut et on choisit Vecteur > Outils de gestion de données > Fusionner les shapefiles en un seul... :

tuto_qgis_6

Cliquez sur l'image pour l'agrandir

Une nouvelle fenêtre s'ouvre dans laquelle il faut paramétrer le dossier où sont stockés nos fichiers d'entrée, puis celui où on veut créer le fichier de sortie.

Comme tout à l'heure, rien de bien méchant, on commence par cliquer sur le premier bouton "Parcourir", pour ensuite se diriger via l'explorateur dans le bon dossier :

tuto_qgis_7

Cliquez sur l'image pour l'agrandir

Ensuite, il ne reste plus qu'à faire de même avec le second bouton "Parcourir". Pour plus de simplicité, on va enregistrer notre nouveau shapefile, que l'on nommera "alsace", dans le même dossier que les autres. Ce qui doit nous donner dans l'explorateur :

Cliquez sur l'image pour l'agrandir

Il ne reste plus qu'à cliquer sur "Enregistrer", à laisser dans la fenêtre de départ l'option "Ajouter le résultat au canevas de la carte" cochée, et à cliquer sur "OK".

Ce qui nous donne en quelques instants un nouveau fichier dans l'espace de travail :

tuto_qgis_10

Cliquez sur l'image pour l'agrandir

Cette nouvelle couche est placée tout au-dessus de la pile, et masque donc les deux autres. Comme nous n'avons plus besoin de ces dernières, nous pouvons les dégager en les sélectionnant dans le gestionnaire puis en faisant Clic droit > Supprimer :

tuto_qgis_11

Cliquez sur l'image pour l'agrandir

Garder seulement les attributs utiles

Les fichiers fournis par OpenStreetMap ont déjà quelques données attachées à chaque commune, notamment :

  • un nom (toujours utile)
  • un identifiant INSEE unique, composé du numéro de département suivi d'un code commune. Ce dernier va nous servir d'attribut commun pour réaliser la jointure avec le tableur. A conserver précieusement donc
  • des propriétés insignifiantes dans notre cadre, comme le code OSM, le code postal, etc...

Pour ne pas charger inutilement le fichier final, on va supprimer les attributs inutile pour ne garder que le nom et le code INSEE de chaque commune.

Pour ce faire, on retourne dans le gestionnaire de calque, et on fait Clic droit > Ouvrir la table d'attributs :

tuto_qgis_12

Cliquez sur l'image pour l'agrandir

Une nouvelle fenêtre s'ouvre, dans laquelle on va cliquer sur l'icône en forme de crayon en haut à gauche pour basculer en mode édition (le raccourci Ctrl+e permet également de l'activer) :

tuto_qgis_13

Cliquez sur l'image pour l'agrandir

Ensuite, on peut cliquer sur l'icône "Supprimer une colonne" ou faire un petit Ctrl+l, pour ensuite sélectionner les colonnes qu'on souhaite faire disparaître :

tuto_qgis_14

Cliquez sur l'image pour l'agrandir

Un clic sur "OK", puis sur l'icône de crayon pour confirmer la sauvegarde du shapefile, et le tour est joué !

Rassembler deux communes anciennement fusionnées

L'un des points importants des tracés communaux fournis par OSM est qu'ils datent de 2012. Or, il arrive très souvent que deux villages aient été anciennement fusionnés un temps avant de se séparer, et vice et versa.

On peut facilement régler le premier cas en fusionnant les tracés communaux les plus récents pour obtenir l'ancienne commune. Penchons-nous dans le Bas-Rhin sur Bosselshausen et Kirrwiller, anciemment Kirrwiller-Bosselshausen.

On va commencer par sélectionner nos deux communes. Le début de la manip est strictement le même que précédemment, on va donc directement se placer à l'étape du Clic droit > Ouvrir la table d'attributs, puis clic sur l'icône en forme de crayon.

On peut dès lors classer les communes par ordre alphabétique en cliquant sur le nom de colonne "COMMUNE" et chercher Bosselshausen. Un clic sur le numéro de ligne permet de sélectionner précisément la commune, qui doit apparaître en jaune dans la fenêtre d'aperçu :

tuto_qgis_15

Cliquez sur l'image pour l'agrandir

On a plus qu'à chercher et sélectionner Kirrwiller, en appuyant bien sur Ctrl pour cumuler les sélections. Si tout va bien, les deux communes doivent maintenant apparaître en jaune :

tuto_qgis_16

Cliquez sur l'image pour l'agrandir

Tout est désormais prêt pour la fusion des deux polygones. Il s'agit désormais d'aller dans Editer > Fusionner les entités sélectionnées :

tuto_qgis_17

Cliquez sur l'image pour l'agrandir

La fenêtre qui s'ouvre alors permet de paramétrer les attributs du nouveau polygone. Dans notre cas, on va juste changer "Kirrwiller" en "Kirrwiller-Bosselshausen", conserver l'identifiants INSEE et cliquer sur "OK" :

tuto_qgis_18

Cliquez sur l'image pour l'agrandir

On peut dès lors constater dans la table d'attributs l'apparition de notre polygone fusionné :

tuto_qgis_19

Cliquez sur l'image pour l'agrandir

Plus qu'à cliquer sur l'icône en forme de crayon pour enregistrer tout ça et passer (enfin) au tableur 🙂 !

Préparer le tableur

Cette partie sera bien plus courte que la précédente, la principale difficulté consistant à créer à partir de deux informations (les numéro de département et de la commune) l'attribut commun au shapefile précédent (l'identifiant INSEE).

On va commencer par télécharger le tableur original sur data.gouv.fr, pour ensuite l'ouvrir avec Libre Calc.

Dès que c'est fait, on va préparer un nouveau tableur grâce à un petit Ctrl+n, et copier/coller la première ligne du gros tableur.

Une fois ceci fait, on revient dans le gros tableur à la rechercher de la ligne correspondant à la première commune du Bas-Rhin (il s'agit de la ligne 27 497). On clique alors sur le numéro de ligne pour la sélectionner, on scrolle rapido vers la dernière ligne du Haut-Rhin (numéro 28 399) en restant bien appuyé sur Shift pour signifier qu'on prend tout l'intervalle.

Plus qu'à faire un petit Ctrl+c puis Ctrl+v dans notre nouveau fichier, et nous voilà avec un fichier uniquement centré sur les résultats de l'Alsace qui doit faire en tout 904 lignes. On peut fermer l'original et se concentrer sur notre nouveau fichier.

Comme pour le shapefile, on ne va retenir que les colonnes qui nous intéressent pour ne pas alourdir le fichier final. On ne gardera que :

  • les codes du département et de la commune
  • le nom de la commune
  • le nombre d'inscrits
  • le pourcentage d'abstention
  • le nombre d'électeurs FN
  • le pourcentage d'exprimés en faveur du FN

Pour rappel, la sélection d'une colonne entière se fait en cliquant sur la lettre correspondante, puis Clic droit > Supprimer.

Voici une proposition de fichiers, avec colonnes renommées pour plus de clarté :

tuto_qgis_20

Cliquez sur l'image pour l'agrandir

Concaténer deux colonnes pour avoir un attribut unique

On va dès lors procéder en deux étapes :

  • préparer une colonne d'identifiants de communes qui seront  formatés en trois chiffres (au lieu de 1, on aura 001, au lieu de 10, 010, etc...). L'objectif est que chaque identifiant fasse cinq chiffres, pas un de moins
  • concaténer cette colonne avec celle de l'identifiant de département

On se place sur la colonne C, puis Clic droit > Insérer. Cette manip' va créer une nouvelle colonne à gauche de celle que l'on a sélectionnée :

tuto_qgis_21

Cliquez sur l'image pour l'agrandir

On va appeler cette colonne "code_com" pour la distinguer de l'autre, et immédiatement faire un Clic droit > Formater les cellules :

tuto_qgis_22

Cliquez sur l'image pour l'agrandir

On va alors choisir un format "Texte", pour éviter que 001 soit automatiquement transformé en 1 :

tuto_qgis_23

Cliquez sur l'image pour l'agrandir

On peut alors se placer sur la première cellule vide de la colonne "code_com" pour y écrire 001. Si le format est bien du texte, le 001 se plaquera à gauche de la cellule.

Ensuite, plus qu'à cliquer glisser à partir du bord inférieur droit de la cellule déjà remplie pour que Calc complète les cellules suivantes en ajoutant 1 à chaque fois :

tuto_qgis_24

Cliquez sur l'image pour l'agrandir

Attention à ne pas y aller comme un bourrin : il arrive qu'un numéro de commune soit manquant (dans notre cas, le 7 n'existe pas), et si on va trop vite, toutes les communes vont se retrouver décalées d'une unité. Ce qui au final donnera des résultats électoraux faux.

On réécrit dans la cellule 008 et on clique/glisse depuis le bord inférieur droit pour créer le reste, en étant bien vigilant aux éventuels trous dans la suite (il y en a quand même quelques-uns).

A partir du numéro 100, on peut recopier directement les nombres de la colonne "code_co", avant de recommencer la manip' pour les communes du Haut-Rhin.

Il ne nous reste plus qu'à concaténer le contenu des colonnes "code_dpt" et "code_com". Pour cela, on va insérer une colonne "code_insee" et  utiliser la fonction CONCATENER(cellule_1;cellule_2;...;cellule_n) :

tuto_qgis_26

Cliquez sur l'image pour l'agrandir

Attention : il faut bien veiller à séparer chaque attribut avec des points-virgules et la fonction ne marche pas lorsque l'on manipule un .csv (par contre avec un fichier pas encore enregistré, tout roule) !

Plus qu'à cliquer/glisser à partir du bord inférieur droit de la première cellule pour répéter la fonction, ce qui doit nous donner au final quelque chose qui ressemble à ceci :

tuto_qgis_27

Cliquez sur l'image pour l'agrandir

Pour être sûr que tout se passe sans accroc au moment de la jointure sur QGis, on ne va conserver que le résultat de notre formule, et pas la formule elle-même. Pour ce faire, on sélectionner toute la colonne en cliquant sur la lettre au-dessus de la première cellule, on copie, et on fait un Clic droit > sur la première cellule d'une nouvelle colonne :

tuto_qgis_28

Cliquez sur l'image pour l'agrandir

A partir de là, on peut virer les quatre première colonnes (département, codes communes en chiffres, codes communes en caractères, et formules de concaténation) et transformer la colonne "code_insee" restante en nombre.

Pour cela, deux possibilités :

  • on sélectionne toute la colonne, puis Clic droit > Formater les cellules > Nombre
  • soit, si la cellule renvoie quelque chose comme '67001 au lieu de 67001, un petit copier/coller de toute la colonne dans le bloc-note pour virer les apostrophes, puis copier/coller du bloc-notes au tableur (un peu une technique de galérien, mais qui a fait ses preuves)
  • On enregistre tout ça dans un .csv nommé "fn_alsace_1995", en spécifiant bien à l'enregistrement que les valeurs doivent être séparées par des virgules, et on passe à la suite !

    Réaliser la jointure d'un shapefile et d'un csv

    Nous voilà enfin au clou du spectacle. On va reprendre QGis qui dormait gentiment pendant tout ce temps, et simplement glisser/déposer le csv fraîchement créé dans le gestionnaire de couches.

    Le fichier doit alors apparaître tout en haut de la pile, comme ceci :

    tuto_qgis_29

    On double clique ensuite sur le calque géographique, celui nommé "alsace". Dans la nouvelle fenêtre qui s'ouvre, il faut ensuite choisir "Jointure" dans le menu de gauche puis cliquer sur l'icône en forme de flèche verte :

    tuto_qgis_29

    Cliquez sur l'image pour l'agrandir

    Nouvelle fenêtre, nouveaux choix. Comme il n'y a qu'un fichier autre que la couche, il n'y a pas besoin de se préoccuper de la première liste déroulante.

    La seconde permet de choisir le champ de notre tableur qui contient l'identifiant commun au fichier géographique. Dans notre cas, c'est la toute première colonne "code_insee", et on ne touche donc encore à rien.

    Arrive enfin les champs de notre fichier géographique. On utilise cette fois-ci la liste déroulante pour choisir "REF_INSEE".

    On peut également choisir de joindre tous les champs sauf "code_insee" et "commune", puisqu'ils existent déjà dans le shapefile. Ce qui nous donne :

    tuto_qgis_30

    Cliquez sur l'image pour l'agrandir

    On clique sur "OK" et on peut voir apparaître notre jointure dans la fenêtre précédente. On peut fermer cette dernière et très vite faire un Clic droit > Ouvrir la table d'attributs.

    Plus qu'à cliquer sur l'icône en forme de crayon avant de cliquer sur celle en forme de boulier (ou Ctrl+i) pour ouvrir la calculatrice de champs.

    Elle va nous permettre d'intégrer directement les champs joints à notre shapefile d'origine (pour que la jointure soit définitive, il faudrait enregistrer un nouveau fichier), et de convertir les valeurs qui seraient encore des lettres en nombres. Cela peut notamment se produire quand le tableur utilise la virgule pour les décimales alors que QGis ne comprend que le point.

    Une fois la calculatrice ouverte, on ne coche surtout pas la case "Créer un champ virtuel", puis on lui donne un  nom, et on laisse le type sur "Nombre entiers (entier)".

    Une liste de fonctions nous permet de choisir celle qui nous intéressé, mais on va griller cette étape en tapant directement dans le champ de saisie tout en bas :

    toint(fn_alsace_1995_inscrits)

    S'il n'y pas d'erreur dans le nom de formule et le nom de colonnes, un aperçu du résultat doit s'afficher en-dessous du champ avec la première valeur bien convertie :

    Cliquez sur l'image pour l'agrandir

    On peut alors cliquer sur "OK" et passer à la suite.

    Attention au moment de la conversion de champs décimaux : il faut bien changer le type en "Nombre décimal (réel)" et définir une précision de 2 pour avoir deux chiffres après la virgule (et évidemment utiliser la fonction toreal()) :

    Cliquez sur l'image pour l'agrandir

    Une fois tous les champs convertis, on peut cliquer sur le crayon magique pour enregistrer tout ça et supprimer la jointure (c'est comme précédemment, sauf qu'on clique sur le trait rouge au lieu de la croix verte dans le menu "Jointure").

    Il ne nous reste plus qu'à simplifier le shapefile et ensuite le convertir en geojson.

    Simplifier les polygones d'un shapefile

    On pourrait déjà convertir notre shapefile en geojson. Le hic, c'est que le fichier obtenu pèserait un peu plus de 11 Mo, ce qui donnerait à l'arrivée de très longs temps de chargement. Impensables pour les lecteurs qui ont une mauvaise connexion ou qui utilisent un smartphone.

    La simplification permet d'alléger de façon optimale les polygones décrits dans le fichier, en utilisant un algorithme comme celui de Douglas-Peucker.

    Comme on ne prévoit aucun zoom sur la carte finale et qu'on restera sur une vision à l'échelle régionale, on peut se permettre de simplifier suffisamment les polygones pour que le procédé ne soit pas visible. Aucune perte de qualité mais à l'arrivée une taille de fichier d'un peu plus de 1 Mo contre 11 Mo initialement.

    Dans QGis, la manip' est ultra simple, il suffit d'aller dans le menu du haut Vecteur > Outils de géométrie > Simplifier la géométrie.

    Sur la fenêtre suivante, on va augmenter la tolérance de 0,0001 à 0,001 (un 0 en moins) et cocher la case "Enregistrer un nouveau fichier". On va appeler ce dernier "alsace_fn_1995". La fenêtre doit alors ressembler à ça :

    tuto_qgis_34

    Cliquez sur l'image pour l'agrandir

    Une fois le bouton "OK" cliqué et le tout simplifié, une pop confirme le passage de plus de 265 000 traits à moins de 25 000. A l'échelle régionale, départementale et cantonale, absolument aucune différence à l’œil nu.

    En fait, il faut zoomer quasiment à l'échelle communale pour distinguer les imperfections :

    tuto_qgis_34

    A ce stade, il ne reste plus qu'à :

  • se positionner sur la couche qui correspond au fichier simplifié
  • faire depuis le gestionnaire de couches un Clic droit > Sauvegarder sous
  • choisir le format GeoJSON, l'emplacement dudit fichier, garder le SCR de la couche (ce doit être absolument du WGS 84) et emballer le tout
  • Au menu la prochaine fois : préparer les seuils de sa carte choroplèthe en utilisant la fonction CENTILE() !