Cette semaine est sorti le jeu Flight Simulator 2020, et certains joueurs se sont amusés de la présence d'un immense monolithe au nord de Melbourne.
Ce bug a pour origine une erreur dans le service cartographique OpenStreetMap (qui a entre-temps été corrigé), et cette anecdote m'a rappelé que ça faisait un moment que je voulais vous en parler.

OpenStreetMap, pour ceux qui ne connaissent pas, est ce qu'on pourrait appeler le « Wikipedia de la cartographie ». Il s'agit d'un service de cartographie libre, utlisable gratuitement, et pouvant être mis à jour par n'importe qui.
Vous pouvez donc tout à fait corriger la carte si vous voyez des erreurs dans votre voisinage, ou la compléter avec les noms de vos magasins préférés.

Je tiens un blog de développement web, donc je ne vais pas approfondir le sujet de la cartographie, bien que le sujet soit passionnant, mais nous allons plutôt voir comment nous pouvons utiliser les données d'OpenStreetMap pour afficher une carte sur nos applications web, à la place de Google Maps qui est un peu trop souvent utilisé sans se poser la question des alternatives.

Licence

Avant de commencer, on va voir rapidement la partie légale.

Les données brutes sont distribuées sous la licence libre Open Data Commons Open Database License (ODbL). Comme indiqué sur la page copyright d'OpenStreetMap, vous pouvez utiliser les données dans vos applications, à condition de créditer les contributeurs d'OpenStreetMap, et de redistribuer les données sous la même licence.
Lorsqu'on veut afficher la carte, on va utiliser les tuiles (les images des cartes, générées à partir des données brutes). Ces images sont sous licence Creative Commons CC-BY-SA 2.0 - les conditions d'utilisation sont globalement les mêmes que pour les données brutes : n'oubliez pas de mettre le copyright.

Affichage d'une carte avec Leaflet

Pour afficher une carte dynamique dans une page web, il va tout d'abord falloir choisir un serveur de tuile, le serveur qui nous fournira les fonds de carte.
La fondation OpenStreetMap n'a pas les moyens de financer des serveurs de tuiles utilisables librement par tout le monde, mais les données étant libres, de nombreux services proposent d'utiliser leurs serveurs - certains gratuitement pour des usages modérés, d'autres fournissant des services professionnels contre rémunération. Notez que vous pouvez aussi installer votre propre serveur de tuiles, si vous souhaitez être autonome.

Mon choix pour cet article s'est porté sur celui de l'association OpenStreetMap France.

On va maintenant utiliser une librairie JavaScript pour l'affichage. De nombreuses solutions existent, les plus utilisées sont OpenLayers et Leaflet ; j'utilise ce dernier dans cet exemple.

Pour afficher la carte, créer un div qui la contiendra, en lui précisant obligatoirement une taille.
Ensuite, vous pouvez initlialiser la carte, avec cet exemple de code :

<div id="mapDiv" style="width:800px; height: 400px;"></div>

<script>
    // Initialisation de la carte
    var map = L.map('mapDiv'); 

    // Initialisation des tuiles 
    var tileUrl = "https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png";
    var copyright = '&copy; Contributeurs de <a href="https://www.openstreetmap.org/">OpenStreetMap</a>';
    L.tileLayer(tileUrl, {
        attribution: copyright,
        maxZoom: 18,
        tileSize: 512,
        zoomOffset: -1,
    }).addTo(map);
    
    // On zoome sur Toulouse
    map.setView([43.60, 1.44], 10); 
</script>

Ce qui nous donne le résultat suivant :


Vous pouvez ensuite afficher toutes sorte d'informations sur la carte ou intéragir avec l'utilisateur ; je vous laisse jete un œil à la documentation pour ça.

Affichage vectoriel avec OpenMapTiles

Les données brutes étant libres, il est possible d'afficher les cartes autrement qu'en chargeant des images d'un serveur de tuiles. C'est ce que fait le projet OpenMapTiles, en proposant un système de tuiles vectorielles.
Au lieu d'afficher des images, c'est le navigateur qui dessine les objets de la carte ; permettant ainsi un affichage plus fluide et des plus d'interactions possibles (essayer de bouger avec le clic droit dans l'exemple plus bas). C'est le choix qu'a fait Qwant pour son service de cartographie Qwant Maps.

Ceci a malheureusement un coût, puisque le navigateur de l'utilisateur est plus fortement mis à contribution, et peut poser des problèmes de performances sur des ordinateurs peu puissants ou certains mobiles.

Pour afficher une carte vectorielle, j'utilise cette fois les serveurs de MapTiler, et la librairie Mapbox GL JS. OpenLayers et Leaflet ne gèrent pas l'affichage vectoriel nativement, mais peuvent fonctionner avec des plugins.

Pour afficher la carte, l'API est un peu différente, mais le système reste le même, je vous laisse regarder le code :

<div id="mapDiv" style="width:800px; height: 400px;"></div>

<script>
    var map = new mapboxgl.Map({
        container: 'mapDiv',
        style: 'https://api.maptiler.com/maps/bright/style.json?key=apikey',
        center: [1.44, 43.60],
        zoom: 10
    });
</script>

Vous pouvez ainsi voir le résultat - et voir la différence avec la carte précédente :

Vous noterez que même si l'affichage est différent, les cartes sont les mêmes. Les rues, les bâtiments ne changent pas de l'un à l'autre, car la source des données est la même.

J'espère que je vous ai donné envie d'essayer ça, et que la prochaine fois que vous devrez afficher une carte dans l'un de vos projets vous étudierez l'option OpenStreetMap.