;
Fév
23
2014

Autopsie d'une dataviz [5.3] : des switchers sur mapbox.js

Troisième et dernier volet d'une trilogie "dataïste" et cartographique avec la méthode pour obtenir des switchers efficaces sur mapbox.js.

Résumé des épisodes précédents : un cartographe amateur a, après une préparation d'un gros .shp sur QGis, réussi à obtenir une choroplèthe interactive sur TileMill. Reste plus qu'à animer tout ça sur mapbox.js...

Et autant le dire tout de suite : ça n'a pas été une partie de plaisir. Mon Javascript était déjà bien rouillé à la base, mais les développeurs de MapBox ont aussi une manière particulière d'appréhender les calques sur leur app'.

Mais avec beaucoup de pugnacité de mon côté et de patience du leur, je peux maintenant dresser une feuille de route pour ceux qui voudraient programmer un switcher simple et fonctionnel sur mapbox.js.

Un bel exemple obsolète

Tout d'abord, une brève présentation de mapbox.js. Cette librairie est basée essentiellement sur leaflet.js, une librairie de cartographie open source créée par Vladimir Agafonkin.

Outre sa licence, cette librairie a l'atout majeur d'être très bien optimisée pour les OS mobiles, ce qui est plutôt intéressant à une époque où beaucoup de consommateurs d'info s'exportent sur smartphones et tablettes.

Le défi pour enfin terminer ma cartographie électorale du Grand-Est était le suivant : programmer une carte interactive avec un switcher qui permettrait de naviguer entre plusieurs années de scrutin.

En furetant un peu sur la Toile, je suis tombé sur ce boulot titanesque de Bjørn Sandvik avec la Nouvelle-Zélande.

Il avait exactement créé ce que je cherchais à faire, et détaillé par le menu toutes les étapes de son travail sur son blog.

J'ai donc d'abord commencé à essayer d'adapter son exemple avec mes propres cartes.

Voici le résultat, publié premièrement sur Rue89Strasbourg :

D'un point de vue fonctionnel, la carte fait bien le job sur ordinateur, mais j'ai très vite trouvé quelques défauts :

  • la police d'écriture des fenêtres interactives n'était pas exactement la même que mes autres cartes. A la limite, pas super grave
  • je n'avais pas réussi à afficher mes légendes. A la limite, pas super grave non plus
  • sur mobile, un zoom faisait automatiquement planter la carte. Ça, c'était en revanche assez moyen.

Tout ceci venait malheureusement du code, devenu complètement obsolète après la version 1.0.0 de l'application :

Sauf que depuis la 1.0.0, l'intégration de Leaflet était devenue encore plus importante, et cette syntaxe ne permettait pas d'afficher une carte correcte sur OS mobile.

Il fallait donc arriver à une mise à jour sur une version actuelle de l'app'.

Bien distinguer les types de calques

La déclaration d'une carte avec un calque unique sur mapbox.js est ultra simple :

Ce qui nous donne concrètement avec un MBTile préparé convenable sur TileMill :

En affectant quelques options à une div map, on se retrouve avec une carte qui :

  • est bien interactive
  • a une légende rattachée au fichier MBTiles d'origine
  • on peut zoomer sur OS mobile sans souci

On pourrait facilement imaginer que, pour obtenir un switcher opérationnel, il suffirait de réaffecter de nouvelles options à la div map, comme ceci :

 Sauf que ça ne marche pas. Mince...

En réalité, la meilleure méthode est de considérer le remplissage de la div 'map' comme un simple fond de carte, sur lequel on va appliquer ensuite des transformations.

Pour cela, il faut bien distinguer :

  • les tileLayers, qui correspondent grossièrement aux tuiles "brutes" d'un calque
  • les gridLayers, qui correspondent grossièrement aux tuiles "interactives" d'un calque

Ainsi, rien n'empêche d'utiliser un fond de carte bien travaillé sur TileMille ou Mapbox (voir ces adaptations de Snazzy Maps) pour ensuite lui coller des zones interactives. Exemple ici :

Et voici le code associé :

Attention tout de même : si le MBTiles qui finira en TileLayer a été paramétré pour s'afficher dans une fourchette de zoom, il faut installer un maxZoom et un minZoom avec cette même fourchette sur la div 'map' pour ne pas qu'il disparaisse.

Un premier switcher pas à pas

Voici un premier switcher fonctionnel :

Et voici le code qui lui est associé :

 Passage à la boucle for

Il sera peut-être plus évident d'automatiser la méthode avec une boucle "for" pour arriver à ce résultat :

Soulignons l'importance du gridControl dans ce cas précis.

Si on l'oublie, les fenêtres interactives se superposent à chaque changement de calque, et on finit par ne plus s'y retrouver. Heureusement, une fonction gridControl.hide() permet d'y parvenir facilement.

Passons enfin au code :

 Un template gitHub

Pour ceux que ça intéresse, j'ai mis en ligne un template du dernier switcher sur gitHub.

Dès que je trouverai le temps, j'essayerais de montrer des switchers plus élaborés, notamment avec des fonds de carte changeants.

Leave a comment