Introduction à Mapbox

De nos jours, il existe de nombreuses façons d’afficher une carte au sein de nos applications. On y retrouve notamment le géant Google Maps ou encore OpenLayers.

Mapbox est une autre solution offrant de nombreuses fonctionnalités allant de l’affichage d’une simple carte, la recherche de lieux, la navigation au sein de celle-ci à la customisation de cartes.

Ce sont ces cartes customisables qui rendent Mapbox populaire et qui lui permettent de se démarquer de ses concurrents.

Dans cet article, nous verrons un exemple d’utilisation de Mapbox, la solution adoptée par Facebook pour ses besoins cartographiques.

Présentation de Mapbox

Mapbox, plus particulièrement Mapbox GL JS. est une librairie open-source permettant d'intégrer des cartes customisables et interactives à nos projets. Elle offre la possibilité de modifier le style dynamiquement, notamment, grâce à l’utilisation de “vector tiles”.

Un vector tile est un format de donnée léger pour stocker nos données géospatiales. Plus de précisions sont disponibles sur la page de spécification.

Mapbox se base sur un système de source/layer, la source représente la donnée structurée que l’on souhaite ajouter à notre carte, tandis que le layer correspond à la représentation visuelle de la donnée sur la carte. Plus simplement, la source correspond à “quoi” dessiner tandis que le layer correspond à “comment” le dessiner.

Installation

CDN

Commençons par inclure les fichiers JavaScript & CSS dans la balise <head> de notre fichier HTML.

<script src='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css' rel='stylesheet' />

Ajoutons maintenant la carte à notre application. Pour ce faire, ajoutons le code suivant dans la balise <body> de notre fichier HTML.

<div id='map' style='width: 400px; height: 300px;'></div>
<script>
  mapboxgl.accessToken = 'TOKEN_MAPBOX';
  const map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/satellite-v9'
  });
</script>

Module bundler

Il est bien évidemment possible de procéder à l’installation à l’aide du module npm. Pour ce faire installons le package npm.

npm install --save mapbox-gl

Intégrons le fichier CSS dans la balise <head> de notre fichier HTML.

<link href='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css' rel='stylesheet' />

Puis ajoutons la carte en elle-même.

import mapboxgl from 'mapbox-gl'; // ou "const mapboxgl = require('mapbox-gl');"

mapboxgl.accessToken = 'TOKEN_MAPBOX';
const map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/satellite-v9'
});

Le token Mapbox est obtenable après avoir créé un compte Mapbox.

Sur notre exemple, le fond de carte sera des images satellites, cependant Mapbox propose plusieurs styles prédéfinis, notamment :

mapbox://styles/mapbox/streets-v11
streets
   mapbox://styles/mapbox/outdoors-v11
outdoors

mapbox://styles/mapbox/light-v10
light
  
mapbox://styles/mapbox/dark-v10
dark

mapbox://styles/mapbox/satellite-v9
satellite
  
mapbox://styles/mapbox/satellite-streets-v11
satellite-streets

Il est aussi possible de créer son propre style depuis le studio.

Ajout d’une source

GeoJson

Mapbox se base sur les GeoJson afin de structurer ses sources. Plusieurs types de données sont ainsi affichables, allant d’un simple point à un polygone.

Prenons l’hexagone suivant en exemple, représentant métaphoriquement la France :

const data = {
  "geometry": {
    "coordinates": [
      [
        [
          2.478075837141887,
          51.28555729996634
        ],
        [
          -3.069964926255011,
          48.84385261720661
        ],
        [
          -3.0867263787125125,
          44.512024668792264
        ],
        [
          2.578644551887038,
          42.37024120282044
        ],
        [
          8.21049257756863,
          44.67904158071579
        ],
        [
          8.193731125112606,
          48.8989769302635
        ],
        [
          2.478075837141887,
          51.28555729996634
        ]
      ]
    ],
    "type": "Polygon"
  },
  "type": "Feature",
  "properties": {
    "name": "France Hexagone"
  }
};

Nous comptons ici 7 coordonnées GPS malgré le fait qu’il s’agisse d’un hexagone. En effet, la première ainsi que la dernière coordonnées sont identiques, cela nous permet de représenter le fait qu’il s’agit d’un polygone et non d’une ligne. De plus, pour chaque coordonnée GPS, nous retrouverons d’abord la longitude puis la latitude.

La structure des GeoJson est assez rigide. Le champ properties, nous permet cependant d'ajouter toute sorte de méta-data. Dans notre cas, nous avons ajouté un champ name.

Maintenant que nous avons notre GeoJson, nous pouvons l’intégrer à notre carte. Pour éviter que la source ne soit ajoutée avant que la carte ne soit initialisée, Mapbox offre la possibilité d’ajouter les sources uniquement après le chargement de la carte.

map.on('load', function() {
   map.addSource('fr_hexa', // identifiant unique de la source
                 { 'type': 'geojson', 'data': data }
   );
});

KML

Pour les amateurs du format KML utilisé par le géant Google, il existe des librairies pour les convertir au format GeoJson.

Contrairement au format utilisé par Mapbox, la définition du style est faite au même moment que la définition de la donnée chez Google. Ainsi, après avoir converti notre KML, nous devons redéfinir son style pour l’afficher correctement. Pour ce faire un layer est nécessaire, ce que nous verrons dans l’étape suivante.

Ajout d’un layer

Il existe plusieurs types de layers, allant d’une customisation de ligne à celle d’une image. Dans notre cas, nous nous intéresserons aux types fill et line. L’ajout d’un layer doit se faire après l’ajout de la source associée. Il est bien sûr possible d’ajouter plusieurs layers pour une seule source.

map.on('load', function() {

   // … ajout source

   map.addLayer({
            'id': 'fr_hexa_layer_fill',
            'type': 'fill',
            'source': 'fr_hexa',
            'layout': {},
            'paint': {
                'fill-color': '#1E90FF,
                'fill-opacity': 0.8
            }
        });


   map.addLayer({
            'id': 'fr_hexa_layer_line',
            'type': 'line',
            'source': 'fr_hexa',
            'layout': {
              'line-cap': 'round'
            },
            'paint': {
                'line-dasharray': [1, 2],
                'line-color': '#fff',
                'line-width': 3
            }
        });
});

Le premier layer permet de remplir notre hexagone d’un certain bleu. Les layers de type fill permettent aussi de rajouter une bordure à notre polygon. Cependant la customisation de celui-ci étant limitée, nous avons ajouté un second layer afin d’avoir un contrôle plus fin sur notre bordure. Dans notre cas, nous avons une bordure blanche en pointillé.

Derniers réglages

Centrer la carte

Maintenant que nous avons ajouté notre source et nos layers, pour une meilleure expérience utilisateur, nous souhaitons centrer notre carte sur la France. Pour ce faire, Mapbox offre la fonction fitBounds qui permet de cadrer la map sur une zone spécifique.

map.on('load', function() {
   
   // … ajout source

   // … ajout layers

   const bounds = [
     [-6.494917884024034, 51.69935897822677],  // Coin Sud-Ouest
     [9.732690059356145, 41.25166002712723]    // Coin Nord-Est
   ];

   map.fitBounds(bounds);
});

Ajout de labels

Pour plus de clarté, nous pouvons aussi afficher sur la carte des labels de façon dynamique. Dans l’exemple suivant, nous avons ajouté une nouvelle source pointant sur Paris, et nous intégrons sur la carte le champ name des properties de notre nouveau GeoJson.

map.on('load', function() {
   
   // … ajout source

   // … ajout layers

   // … centrer la carte

   const paris = {
      "geometry": {
        "coordinates": [
           2.350773675310819,
           48.86015558292965
         ],
        "type": "Point"
      },
      "type": "Feature",
      "properties": {
        "name": "Paris"
      }
   };

  map.addSource('paris_point',
                { 'type': 'geojson', 'data': paris }
   );


   map.addLayer({
            'id': 'paris_layer_name',
            'type': 'symbol',
            'source': 'paris_point',
            'layout': {
              'text-field': ['get', 'name']
            }
        });
});

Résultat final

Voilà à quoi devrait ressembler votre carte après avoir complété toutes les étapes précédentes. Il s’agit bien évidemment d’une introduction à la librairie, de nombreuses fonctionnalités plus complexes et plus avancées sont disponibles avec Mapbox.

Plugins

Parmi les plugins associables à Mapbox, on en retrouve plusieurs pour améliorer l’interface et l’expérience utilisateur, notamment :

  • mapbox-gl-draw pour dessiner/éditer nos sources directement sur la carte.
  • mapbox-gl-geocoder permettant d’ajouter une barre de recherche pour des lieux ou directement des coordonnées GPS.
  • mapboxgl-minimap qui ajoute un mini aperçu de la carte courante.

Une librairie phare permettant de nombreuses manipulations sur nos GeoJson est turf.js, c’est sur celle-ci que vous retrouverez des fonctions pour calculer l’aire d’un GeoJson ou encore trouver le centre de celui-ci.

Il existe bien évidemment des plugins pour intégrer Mapbox à nos différents frameworks préférés :

Une liste non exhaustive des plugins compatibles avec Mapbox est disponible.

Conclusion

Mapbox possède de nombreux styles prédéfinis, ce qui facilite considérablement son utilisation tout en permettant à l’utilisateur d’avoir un visuel plus que confortable.

Pour une utilisation basique, il reste un outil facile à prendre en main mais un certain niveau de connaissances est nécessaire pour exploiter tout ce que mapbox peut offrir (représentation 3D, animations, …).

Le format Geojson peut dérouter certains habitués du format KML, cependant cette différenciation entre les sources et les layers permet à Mapbox de proposer de nombreuses customisations, ce qui n’est pas le cas de tous ses concurrents.

Maintenant que vous avez toutes les cartes en main, voici un petit plus expliquant comment Facebook utilise Mapbox au sein de son application mobile.