Open Street Map (Partie 2) – Intégration d’une carte avec Leaflet

leaflet-logo[1]

Il existe différentes librairies JavaScript permettant l’intégration d’une carte sur son site, que ce soit pour une version desktop ou bien pour une version mobile. La plus connue de ces librairies est celle de Google qui est liée à Google Maps (https://developers.google.com/maps/), puis ensuite vient Open Layers qui permet l’affichage de fonds cartographiques tuilés (http://openlayers.org/) et enfin LeafLet qui est utilisé par OSM pour l’intégration de ses cartes. Nous allons voir ici le fonctionnement de cette dernière (http://leafletjs.com/).

Ce petit guide va vous présenter de manière concise et basique l’utilisation de la librairie JavaScript LeafLet et l’intégration de carte OSM. Nous verrons notamment comment intégrer la librairie au sein de son site Web, sa configuration, l’utilisation des marqueurs, l’utilisation des objets vectoriels (polygones, cercles, rectangles, …) ainsi que la gestion des pop-ups et des événements liés aux interactions avec les cartes.

Intégration à son site

L’intégration de cette bibliothèque se fait de manière assez classique, il vous faut inclure une feuille de style dans la section head de votre site :

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />

Vous devez aussi inclure la librairie JavaScript et un fichier dans lequel nous ajouterons le JavaScript propre à nos tests que nous appellerons exemple.js (pour éviter de déclarer notre code directement dans la page HTML) :

<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="exemple.js"></script>

Afin de gérer l’affichage de la carte au sein de notre site il va nous falloir intégrer un container à notre page de destination. Dans cet exemple il sera représenté par une balise DIV :

<div id="map"></div>

Et lui attribuer une hauteur au sein de nos feuilles de style :

#map { height: 400px; }

Il est tout à fait possible de réaliser les deux traitements en un :

<div id="map" style="height: 400px"></div>

Dans notre exemple, nous sommes passés par un hébergement externe, fournit par Leaflet mais il est aussi possible d’intégrer directement la feuille de style et le JavaScript localement en téléchargeant une version sur le site de LeafLet : http://leafletjs.com/download.html.

Voyons maintenant les différentes fonctions permettant d’initialiser et d’interagir avec les cartes.

Initialiser la carte

Nous allons maintenant initialiser la carte, tout en la centrant géographiquement sur l’agence Netapsys Lyon, à noter qu’il est aussi possible d’associer un niveau de zoom. Attention toutefois, ce code doit être appelé une fois le chargement de la bibliothèque réalisé (cette fonction sera ajoutée à notre fichier exemple.js).

function InitialiserCarte() {
var map = L.map('map').setView([45.7531152, 4.827906], 17);

Nous devons par la suite associer notre carte à un service externe de fournissement de tuile, Leaflet n’est pas attaché à l’un d’eux et de nombreux choix s’offrent à nous. Nous allons voir celui d’OSM. Dans l’exemple ci-dessous, nous plaçons l’URL du service de tuile dans la variable tuileURL.

// create the tile layer with correct attribution
var tuileUrl = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png';

Nous initialisons ensuite la carte à l’’aide de la fonction TileLayer (http://leafletjs.com/reference.html#tilelayer) en lui fournissant l’url du service de tuile, ainsi qu’en paramétrant le zoom maximum associé à la carte et les conditions d’attribution de la carte. Attention le zoom déclaré dans le setView doit être compris dans la plage de zoom définie par zoomMin et zoomMax de la fonction TileLayer.

var attrib='Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors';

L.TileLayer(tuileUrl, {minZoom: 8, maxZoom: 18, attribution: attrib}).addTo(map);

Il ne nous reste plus qu’à appeler cette fonction au chargement de la page. A noter qu’il serait tout à fait possible de gérer l’appel de cette fonction différemment dans le cas d’une utilisation de JQuery, avec l’inclusion de l’appel de la fonction InitialiserCarte dans un bloc  $(document).ready(function(){…}) ;.

<body onload="InitialiserCarte() ;">

Ça y est la carte est maintenant fonctionnelle, vous pouvez dès à présent jouer avec les différentes fonctionnalités de base de la carte : translation, zoom avant et arrière.

A noter qu’il existe de nombreux autres fournisseurs de tuiles, vous pouvez notamment retrouver une liste non exhaustive à cette adresse : https://gist.github.com/mourner/1804938.

Vous pouvez retrouver cet exemple sur le fiddle suivant : cliquez-ici.

carte1

Gestion des marqueurs

Vous pouvez superposer facilement sur vos tuiles des marqueurs (http://leafletjs.com/reference.html#marker) afin d’indiquer une position. Pour cela vous devez spécifier une position géographique et ajouter votre marqueur à la carte. Dans notre exemple ci-dessous nous rajoutons un marqueur sur l’agence de Lyon :

var marker = L.marker([45.7531152, 4.827906]).addTo(map);

Vous pouvez retrouver cet exemple sur le fiddle suivant : cliquez-ici.

carte2

Il est aussi possible de personnaliser ses marqueurs en les associant à une icône préalablement déclarée.

var monIcone = L.icon({
iconUrl: 'leaf-green.png',
shadowUrl: 'leaf-shadow.png',
iconSize: [38, 95], // dimension de l’icone
shadowSize: [50, 64], // taille de l’ombre
iconAnchor: [22, 94], // point ou l’icône va se positionner
shadowAnchor: [4, 62], // même chose pour l’ombre
popupAnchor: [-3, -76] // point à partir duquel le pop-up devrait s’ouvrir relativement par rapport à iconAnchor
});

var marker = L.marker([48.874384, 2.326159], {icon: monIcone}).addTo(map);

Vous pouvez retrouver cet exemple sur le fiddle suivant : cliquez-ici.

carte3

Gestion des objets vectoriels : cercle, rectangle et polygone

De la même manière que les marqueurs vous pouvez rajouter facilement un cercle (http://leafletjs.com/reference.html#circle) en superposition de vos tuiles en précisant la position, le rayon du cercle en mètre Mercator ainsi qu’en spécifiant différents paramètres de rendu.

var circle = L.circle([48.8743837, 2.326158699999951], 500, {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5
}).addTo(map);

Vous pouvez retrouver cet exemple sur le fiddle suivant : cliquez-ici.

carte4

Vous pouvez aussi ajouter des rectangles (http://leafletjs.com/reference.html#rectangle) en spécifiant les coordonnées de deux de ses sommets opposés, ainsi qu’en spécifiant différents paramètres de rendu (ici nous prendrons les coordonnées de l’agence de Lyon et de l’agence de Paris) :

var bounds = [[45.7531152, 4.827906], [48.8743837, 2.326158699999951]];

L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map);

Vous pouvez retrouver cet exemple sur le fiddle suivant : cliquez-ici.

carte5

Et enfin les polygones (http://leafletjs.com/reference.html#polygon), peuvent être ajoutés en spécifiant les différentes coordonnées le composant :

var polygon = L.polygon([
[45.7531152, 4.827906],
[48.8743837, 2.326158699999951],
[47.2103392, -1.5501954000000069]
]).addTo(map);

Vous pouvez retrouver cet exemple sur le fiddle suivant : cliquez-ici.

carte6

Il existe de nombreux autres objets vectoriels et je vous invite à consulter la documentation complète de ces objets : Path, Polyline, MultiPolyline, MultiPolygon et CircleMarker.

Gestion des pop-ups

La gestion des pop-ups (http://leafletjs.com/reference.html#popup) peut se faire de différentes manières. Cela peut se faire de manière simple en liant le pop-up à un objet vectoriel existant via la fonction bindPopup, en spécifiant le contenu à afficher :

marker.bindPopup("Exemple de texte").openPopup();

Vous pouvez retrouver cet exemple sur le fiddle suivant : cliquez-ici.

carte7

Le pop-up peut aussi se faire à la manière des autres objets vectoriels en spécifiant une position géographique ainsi qu’un contenu. La fonction openOn permet de gérer automatiquement la fermeture du pop-up. (Vous pouvez le spécifier de manière différente via la fonction closePopup : http://leafletjs.com/reference.html#path-closepopup).

var popup = L.popup()
.setLatLng([45.7531152, 4.827906])
.setContent("Ouverture du pop-up.")
.openOn(map);

Vous pouvez retrouver cet exemple sur le fiddle suivant : cliquez-ici.

carte8

Centrer la carte sur des éléments

Vous pouvez souhaiter recentrer la carte sur une position précise, ou bien sur un groupe de position, par exemple sur une liste de marqueurs que vous venez de créer. Pour cela nous allons nous baser sur l’élément latLng (http://leafletjs.com/reference.html#latlng) qui permet de définir une position géographique. Reprenons le code de définition de marqueur en passant par la fonction latLng :

var latlng1 = L.latLng(45.7531152, 4.827906);
var marker1 = L.marker(latlng1).addTo(map);
var latlng2 = L.latLng(48.8743837, 2.326158699999951);
var marker2 = L.marker(latlng2).addTo(map);

Ensuite nous allons nous aider de la fonction LatLngBounds (http://leafletjs.com/reference.html#latlngbounds)  afin de réaliser une aire géographique de position géographique en fournissant un tableau des positions précédemment créé. Puis nous effectuerons  un recentrage sur cette aire à l’aide de la fonction fitBounds (http://leafletjs.com/reference.html#map-fitbounds) :

var arrayOfLatLngs = [latlng1, latlng2];
var bounds = new L.LatLngBounds(arrayOfLatLngs);
map.fitBounds(bounds);

Vous pouvez retrouver cet exemple sur le fiddle suivant : cliquez-ici.

carte9

Gestion des évènements

Toute action réalisée au sein d’une carte, que ce soit un clic sur la carte, un déplacement, une modification du zoom déclenche un événement (http://leafletjs.com/reference.html#events) auquel nous pouvons nous abonner.

Prenons un exemple simple d’abonnement sur Evènement, clic de la carte, auquel nous associons une fonction permettant de récupérer les données de géolocalisation de ce clic sur la carte, que nous afficherons par la suite sous la forme d’une alerte.

map.on('click', onMapClick);

function onMapClick(e) {
alert("Vous venez de cliquer aux coordonnées " + e.latlng.toString());
}

Vous pouvez retrouver cet exemple sur le fiddle suivant : cliquez-ici.

Maintenant que nous savons utiliser des événements, des pop-ups et des objets vectoriels essayons de combiner tout çà. Nous allons dans cet exemple ouvrir un pop-up sur le survol d’un marker, ce pop-up contiendra la position du survol. La fin du survol déclenchera la fermeture du pop-up.

var marker = L.marker([48.85568, 4.827905699999974]).addTo(map);
var popup = L.popup();

marker.on('mouseover', function (e) {
popup.setLatLng(e.latlng)
.setContent('Vous venez de passer sur un marqueur en position : " + e.latlng.toString())
.openOn(map);
});

marker.on('mouseout', function (e) {
popup.closePopup();
});

Vous pouvez retrouver cet exemple sur le fiddle suivant : cliquez-ici.

carte10

Les différents objets vectoriels que nous avons précédemment abordés permettent la gestion Evènement, je vous conseille de consulter plus en détail la documentation afin de vous familiariser avec les différentes possibilités qu’ils proposent : http://leafletjs.com/reference.html#event-objects.

Appareil mobile et géolocalisation

Au contraire de la librairie Open Layers, Leaflet a été pensé dès le début pour la mobilité, en conséquence elle intègre des fonctionnalités pour les navigateurs mobiles et tactiles. Vous pourrez notamment effectuer un recentrage de la carte sur votre position à l’aide de la fonction locate (http://leafletjs.com/reference.html#map-locate) :

Map.locate(({setView: true, maxZoom: 12});

Il est aussi possible d’effectuer des traitements plus complexes en vous abonnant aux événements propres à la localisation, comme locationfound (http://leafletjs.com/reference.html#map-locationfound) pour déclencher des traitements sur la détection de la position et locationerror (http://leafletjs.com/reference.html#map-locationerror) lors de l’échec de la détection de la position de l’utilisateur :

map.on('locationfound', onLocationFound);
map.on('locationerror', onLocationError);

Vous pouvez consulter des exemples d’utilisation des fonctionnalités de mobilité à l’adresse suivante : http://leafletjs.com/examples/mobile.html.

Pour aller plus loin

Pour aller plus loin avec cette librairie je vous conseille de vous plonger dans sa bibliothèque de plugin. Elle recense plus de 170 plugins JavaScript permettant d’enrichir les fonctionnalités de celle-ci : http://leafletjs.com/plugins.html. Ces plugins vont par exemple permettre d’étendre ses fonctionnalités pour générer un affichage 3D des données d’OSM (http://osmbuildings.org/), gérer un profil de côte (http://mrmufflon.github.io/Leaflet.Elevation/) ou bien gérer une mini carte à la manière de Google Maps (https://github.com/Norkart/Leaflet-MiniMap).

Vous pouvez aussi consulter la section tutorial qui vous permettra de découvrir via des exemples les différentes possibilités qui s’offrent à vous via l’utilisation de LeafLet : http://leafletjs.com/examples.html.

 

Conclusion

C’était un aperçu non exhaustif de la librairie LeafLet qui doit en aucun vous empêcher de consulter la documentation complète : http://leafletjs.com/reference.html. Comme vous avez pu le constater cette librairie simplifie grandement l’implémentation et les interactions avec les cartes en s’affranchissant d’un fournisseur de tuile et en réduisant de manière conséquente le code à produire. C’est une alternative séduisante pour les développeurs souhaitant s’affranchir des classiques Google Maps. De plus l’avenir de cette librairie semble prometteur avec en 2013 l’intégration du développeur de LeafLet au sein de l’équipe de développement de MapBox (https://www.mapbox.com/).

Enregistrer

5 commentaires

  1. bonjour,
    Pourriez vous indiquer concretement comment se présentent les documents finaux de votre cours .
    En effet si votre présentation semble très claire, quand je passe à la mise en pratique cela ne fonctionne pas.  »
    je suppose qu’il me faut créer
    1 fichier.htm contenant le code de votre présentation jusqu’à l’init de la carte
    un autre fichier.js qui contiendra les fonctions comme indiquées jusqu’à gestion des marqueurs
    remarques : l’appel du fichier .js doit il se faire en indiquant le path complet  » 127.0.0.1/home/user/doc.js  » ou  » ./doc.js »
    merci pour votre réponse
     » je précise que j’ai suivi le code jusqu’à la saisie des marqueurs »
    cordialement

  2. Bonjour,

    Le chemin de votre fichier JavaScript dépend de l’endroit ou vous l’avez créé par rapport à votre fichier html qui y fait référence. Si votre fichier JavaScript se trouve dans le même répertoire que votre fichier JavaScript vous pouvez y faire référence comme ceci : « doc.js ».

    Si vous souhaitez allé plus loin sur le sujet je vous conseille cet article : https://fr.wikibooks.org/wiki/Le_langage_HTML/Liens (Liens absolus/Liens relatifs) il vous permettra de mieux vous familiariser sur la constructions de vos chemins.

    N’hésitez pas à revenir vers moi en cas de nouvelle question.

    Cordialement,
    Nicolas ROUILLY

  3. Merci pour ce tuto très clair.

    Je recherche par contre comment effectuer une recherche d’adresse, comme cela se fait avec Google Maps.

    J’aimerais pouvoir en effet positionner et centrer la carte dynamiquement selon une adresse du type « 3 rue du lac 69003 Lyon ». Google maps le permet, mais je ne trouve pas de tutos pour Openstreet Map.

    Avez-vous un lien qui expliquerait cela ?

    Merci encore.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.