Autopsie d'une dataviz [5.2] : des MBTiles pour éviter les tuiles

Comment faire pour afficher proprement et sans lenteur une carte choroplèthe contenant des milliers de zones ? Réponse dans cette seconde partie d'une trilogie cartographique !

Dans l'épisode précédent :

Un cartographe amateur s'est lancé dans un projet un peu fou. Il souhaite créer des cartes interactives contenant des milliers d'informations, et est déjà parvenu, au prix d'efforts harassants, à obtenir un fichier .shp réutilisable. Reste plus qu'à le transformer en carte...

Première difficulté : notre .shp pèse environ 60 Mo... Erf, ça s'annonce dur pour l'afficher convenablement dans un service de cartographie numérique !

Même en passant par Mapshaper pour simplifier tout ça, ce ragoût de données fera ramer à coup sûr Google Fusion Tables sur n'importe quelle machine...

Les MBTiles à la rescousse

Les tarés de MapBox ont heureusement une solution à proposer : les MapBox Tiles (aujour'hui transformées en Vector Tiles).

Le principe, pour ce que j'en ai compris, est grosso modo le suivant :

  • en utilisant l'excellent logiciel de cartographie TileMill, on choisit d'exporter sa carte en MBTiles
  • TileMill va ensuite, selon les options choisies (profondeur de zoom, grandeur de la zone à afficher), découper la carte en plusieurs tuiles
  • ces différentes tuiles permettront d'afficher uniquement les zones utiles en fonction du zoom et de la zone considérés.

Plus de ramage, plus de plantage, et en prime de l'interactivité et un poids réduit (dans notre cas environ 11 Mo). Que demande le peuple 🙂 ?

Première choroplèthe avec TileMill

En ouvrant un nouveau projet sur TileMill, on obtient un écran similaire au suivant :

tuto_choro_tm

Cliquez sur l'image pour l'agrandir

Par défaut, TileMill fournit un fichier de l'ensemble des nations mondiales, avec leurs frontières respectives. En bas à gauche, on voit le seul calque pour l'instant présent, #countries.

En haut à droite, on distingue le code CartoCSS qui permet de colorer le fond de carte, les frontières et les pays :

Map {
  background-color: #b8dee6;
}

#countries {
  ::outline {
    line-color: #85c5d3;
    line-width: 2;
    line-join: round;
  }
  polygon-fill: #fff;
}

A la base, on définit la couleur du fond de carte qui, en-dessous des pays affichés en blanc, correspondra effectivement aux mers et océans. Du coup, en changeant simplement trois couleurs, on obtient le fond de carte suivant :

tuto_choro_tm_2

Cliquez sur l'image pour l'agrandir

Pour l'instant, rien de vraiment bien méchant, on a simplement changé le code comme suit :

Map {
  background-color: #fff;
}

#countries {
  ::outline {
    line-color: #f0f0f0;
    line-width: 2;
    line-join: round;
  }
  polygon-fill: #000;
}

On va maintenant charger le .shp obtenu précédemment. Pour cela, il faut le copier dans Mes Documents, ou en tout cas ailleurs que sur un disque dur externe.

Ensuite, on clique sur l'icône de calque tout en bas à gauche, puis sur "Add layer".

tuto_choro_tm_3

De là, on va cliquer sur "Browse" à côté du champ "Datasource" pour sélectionner le .shp avec toutes les données, puis cliquer sur "Save". Si le shapefile est correct, on se retrouve avec un nouveau calque au-dessus du précédent.

tuto_choro_tm_4

Si l'on clique sur l'icône en forme de tableur juste à côté du calque #europeennes2009geabs, voici ce que l'on peut observer :

tuto_choro_tm_5

Cliquez sur l'image pour l'agrandir

Pour rapidement résumer :

  • l'un des champs nombres (ABS_INS) va servir de base pour la choroplèthe
  • quatre champs, celui des communes et les trois champs nombre, vont servir à remplir la fenêtre d'information qui s'affichera au survol de chaque ville

Les données rattachées au calque ont l'air propres, mais on peut tout de même vérifier le bon affichage des zones contenus dans ce .shp en ajoutant ces quelques lignes au CartoCSS :

#europeennes2009geabs{
  polygon-fill: #fff;
}

Après avoir cliqué sur "Save" en haut à droite et zoomé un tantinet, voici ce que l'on obtient dans notre cas :

tuto_choro_tm_6

Cliquez sur l'image pour l'agrandir

Sacré morceau, n'est-ce pas ? Reste plus qu'à programmer la fameuse choroplèthe 🙂 !

Le diable est dans les détails

Ce mantra, vous le lirez très souvent sur les tutoriels de ce blog, et pour cause : le diable est toujours dans les détails !

Dans le cas des choroplèthes, on peut par exemple hésiter entre un un éventail de couleurs séquentiel ou divergent.

Et les deux ne donneront pas du tout la même lisibilité, comme le montre l'exemple suivant (cliquez sur les calques en icônes pour changer de type de cartes) :

Etonnant, non ? Et comme il faut rendre à César ce qui est à César, un grand merci  à Thierry Labro pour m'avoir conseillé le premier d'utiliser ce type de choroplèthe alors que j'étais parti sur une séquentielle.

La traduction en CartoCSS, obtenue à partir de la colonne ABS_INS et d'un éventail pioché sur colorbrewer, se trouve ci-après :

#europeennes2009geabs::fill[zoom>=0] {
  [ABS_INS > 75]{polygon-fill:#d7191c;}
  [ABS_INS > 65.0][ABS_INS <= 75.0]{ polygon-fill:#fc8d59; }
  [ABS_INS > 55.0][ABS_INS <= 65.0]{ polygon-fill:#fee08b; }
  [ABS_INS > 45.0][ABS_INS <= 55.0]{ polygon-fill:#ffffbf; }
  [ABS_INS > 35.0][ABS_INS <= 45.0]{ polygon-fill:#d9ef8b; }
  [ABS_INS > 25.0][ABS_INS <= 35.0]{ polygon-fill:#91cf60; }
  [ABS_INS <= 25]{polygon-fill:#1a9850;}
}

Les plus observateurs auront également remarqué plus-haut les contours des départements. Ils sont obtenus après avoir créé sur QGis un fichier des départements en fusionnant toutes les villes de chacun d'entre eux.

Il ne reste ensuite plus qu'à charger ce calque, et à n'afficher que ses contours comme ceci :

#deptsge {
  ::outline {
    line-color: #000;
    line-width: 1;
    line-join: round;
  }
}

La choroplèthe a déjà pas mal de gueule, mais ce serait encore mieux si on ajoutait une légende et de l'interaction. Ça tombe bien, on peut faire tout ça depuis TileMill 🙂 !

Légende et fenêtre interactive

Passons maintenant à l'étape suivante avec la mise en place d'une légende sur notre belle carte. On va directement s'inspirer d'un des exemples fournis par l'équipe de MapBox pour la réaliser.

Ce code, on va tout simplement le placer dans une zone prévue à cet effet. Pour l'atteindre, il suffit de cliquer sur l'icône en forme de main, en bas à gauche de l'interface :

tuto_choro_tm_7

Cliquez sur l'image pour l'agrandir

Et voici le code qui anime tout ça :

<div class='my-legend'>
<div class='legend-title'>L'abstention aux européennes de 2009<br/> (circonscription Grand-Est)</div>
<div class='legend-scale'>
  <ul class='legend-labels'>
    <li><span style='background:#d7191c;'></span>plus de 75%</li>
    <li><span style='background:#fc8d59;'></span>entre 65% et 75%</li>
    <li><span style='background:#fee08b;'></span>entre 55% et 65%</li>
    <li><span style='background:#ffffbf;'></span>entre 45% et 55%</li>
    <li><span style='background:#d9ef8b;'></span>entre 35% et 45%</li>
    <li><span style='background:#91cf60;'></span>entre 25% et 35%</li>
    <li><span style='background:#1a9850;'></span>moins de 25%</li>
  </ul>
</div>
<div class='legend-source'>Source: <a href="http://www.data.gouv.fr/" target="_blank">Data.gouv</a></div>
</div>

<style type='text/css'>
  .my-legend .legend-title {
    text-align: left;
    margin-bottom: 5px;
    font-weight: bold;
    font-size: 90%;
    }
  .my-legend .legend-scale ul {
    margin: 0;
    margin-bottom: 5px;
    padding: 0;
    float: left;
    list-style: none;
    }
  .my-legend .legend-scale ul li {
    font-size: 80%;
    list-style: none;
    margin-left: 0;
    line-height: 18px;
    margin-bottom: 2px;
    }
  .my-legend ul.legend-labels li span {
    display: block;
    float: left;
    height: 16px;
    width: 30px;
    margin-right: 5px;
    margin-left: 0;
    border: 1px solid #999;
    }
  .my-legend .legend-source {
    font-size: 70%;
    color: #999;
    clear: both;
    }
  .my-legend a {
    color: #777;
    }
</style>

La magie opère immédiatement après avoir sauvegardé :

tuto_choro_tm_8

Cliquez sur l'image pour l'agrandir

Pourquoi s'arrêter en si bon chemin ? Installer des fenêtres interactives au survol de chaque commune n'a rien de bien méchant.

Il suffit encore une fois de se rendre dans la zone spécifique en cliquant de nouveau sur l'icône en forme de main, mais en se rendant cette fois-ci dans le menu "Teaser".

tuto_choro_tm_9

Cliquez sur l'image pour l'agrandir

Il suffit, dans le menu déroulant en bas à gauche, de choisir le calque qui contient les données à afficher. TileMill affiche chaque colonne entre trois {}. On a plus qu'à coder intuitivement notre div comme ceci :

<div>
<strong>{{{COMMUNE}}}</strong><br>
Inscrits : {{{INSCRITS}}} <br>
Abstentions : {{{ABSTENTION}}}<br>
Abstention : {{{ABS_INS}}} % des inscrits
</div>

Et après avoir, sauvegardé, on a enfin un résultat final plus que chouette :

tuto_choro_tm_10

Cliquez sur l'image pour l'agrandir

Bref, tout est prêt pour l'export 🙂 !

Quelques astuces pour un MBTiles léger

Il est temps de préparer un fichier MBTiles que l'on hébergera ensuite sur MapBox ou un serveur perso. Pour cela, on clique sur "Export" tout en haut à droite, et on choisit "MBTiles".

Voici deux trucs pour ne pas avoir un fichier trop lourd à l'arrivée :

  • donnez de l'air à votre carte en choisissant des bords finaux assez éloignés de votre zone. C'est surtout pratique pour que la légende ne masque pas ensuite trop de zones à afficher
  • choisissez un éventail de zoom le plus restreint possible. Qui dit grosse profondeur de zoom dit aussi plus de tuiles à calculer, et donc un fichier plus lourd à l'arrivée

Dans notre cas, un export optimal serait le suivant :

tuto_choro_tm_11

Cliquez sur l'image pour l'agrandir

Une fois le fichier chargé dans la file d'attente, plus qu'à cliquer sur "Save" pour le voir immédiatement débarquer par défaut dans "Mes Documents".

A suivre

Au menu de la troisième et dernière partie de ce tutoriel : utiliser la librairie mapbox.js pour installer un switcher qui conserve l'interactivité des fameux MBTiles.