LeafletAprès avoir créé une carte Leaflet (Leaflet, créer votre carte rapidement) et placer des markers (Leaflet : création massive de markers), voyons comment gérer les layers, soit savoir comment changer le fond de carte à la volée ou afficher/masquer les markers qui sont présents sur la carte.


Fonds de carte

Il est possible de changer de fond de carte à la volée suivant le type de représentation que l’on souhaite. Pour des question de lisibilité, de représentation, ou simplement… pour le fun !

Le fond de carte, c’est l’ensemble des ’tiles’ qui sont mises à notre disposition par les fournisseurs comme Google Maps, OSM ou Cloud Made.

On agira sur la ligne suivante :

L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: 'Map data &copy; <a href="http://www.osm.org">OpenStreetMap</a>' }).addTo(map);

En créant 3 fonds de carte différents :

var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttribution = 'Map data &copy; <a href="http://www.osm.org">OpenStreetMap</a>';
var osmTileLayer = L.tileLayer(osmUrl, { attribution: osmAttribution });

var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/841e036a3f194a30bf64e170f94c9e59/997/256/{z}/{x}/{y}.png';
var cloudmadeAttribution = 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2011 CloudMade';
var cloudmadeTileLayer = L.tileLayer(cloudmadeUrl, { attribution: cloudmadeAttribution });

var transportURL = 'http://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png';
var transportAttribution = '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> Contributors & <a href="http://thunderforest.com/">Thunderforest</a>';
var transportTileLayer = L.tileLayer(transportURL, { attribution: transportAttribution });

Choisissons laquelle afficher lors du chargement de la carte :

var map = L.map('map').setView([48.856578, 2.351828], 18);
osmTileLayer.addTo(map);

Plaçons nos 3 fonds de carte dans un tableau, et indiquons à Leaflet de nous les présenter dans un contrôle situé en haut à droite sur la carte :

var baseMaps = {
	"OSM": osmTileLayer,
	"Transport": transportTileLayer,
	"Cloud Made": cloudmadeTileLayer
};
map.addControl(new L.Control.Layers(baseMaps, {}));

A noter qu’il s’agit d’un « ou exclusif » : il n’est pas possible de superposer ces fonds de carte, dans cette configuration.

OSM

OSM

Transport

Transport

Cloud Made

Cloud Made

Il est possible de trouver une liste des fonds de carte disponibles pour Leaflet ici. Sinon, il existe un plugin Leaflet qui gère cela pour vous : leaflet-providers.

Groupes de markers

A l’image des fonds de carte, il est possible d’utiliser un contrôler pour afficher/masquer des groupes de markers. Par contre, il est ici possible de superposer nos layers.

Définissons deux groupes de markers différents… Ici, 3 monuments de Paris et les 7 gares principales :

var monuments = [
	["Notre Dame de Paris", 48.853056, 2.349722],
	["Mus&eacute;e d'Orsay", 48.86, 2.327],
	["Museum National d'Histoire Naturelle", 48.8422, 2.3564]
];
var gares = [
	["Gare de Lyon", 48.8448, 2.3735],
	["Gare d'Austerlitz", 48.8416, 2.3661],
	["Gare de l'Est", 48.877036, 2.36],
	["Gare de Bercy", 48.839039, 2.383081],
	["Gare de Montparnasse", 48.841157, 2.320474],
	["Gare du Nord", 48.8828, 2.3567],
	["Gare Saint-Lazare", 48.8763, 2.32388]
];

J’ai très légèrement factorisé le code de l’article sur les markers  et ajouté l’intégration d’un icône personnalisé :

function markersArray(items, icon) {
	var markers = new L.featureGroup();
	for (var i = 0; i < items.length; i++) {
		var item = items[i];
		marker = new L.marker([item[1],item[2]], {icon: icon}).bindPopup(item[0]);
		markers.addLayer(marker);
	}
	markers.on('mouseover', function(e){ e.layer.openPopup(); })
	       .on('mouseout', function(e){ e.layer.closePopup(); });
	return markers;
}

var trainIcon = L.icon({
	iconUrl: 'train.png',
	iconSize: [32,37],
	iconAnchor: [16,37],
	popupAnchor:  [0,-37]
});

var monumentIcon = L.icon({
	iconUrl: 'monument.png',
	iconSize: [32,37],
	iconAnchor: [16,37],
	popupAnchor:  [0,-37]
});

var Monuments = markersArray(monuments, monumentIcon);
var Gares = markersArray(gares, trainIcon);

map.addLayer(Monuments);
map.addLayer(Gares);

Nos deux groupes de markers sont maintenant affichés sur la carte. Associons les dans un tableau pour les ajouter au même contrôle qui gère les fonds de carte.

var overlayMaps = {
	'Monuments':Monuments,
	'Gares':Gares
};

map.addControl(new L.Control.Layers(baseMaps, overlayMaps));

Et afin d’afficher tous les markers sur la carte, gérons maintenant la somme des deux « bounds ».

var bounds = Monuments.getBounds();
bounds = bounds.extend(Gares.getBounds());
map.fitBounds(bounds);
Tous les markers

Tous les markers

Les gares

Les gares

Code complet
<!doctype html>
<html>
	<head>
		<title>leaflet-gpx demo</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
		<style>
			html { height: 100% }
			body { height: 100%; margin: 0; padding: 0 }
			#map { 
				width: 800px;
				height: 480px; 
 }
		</style>
 		<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
 		<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>

 		<script type="text/javascript">

 			var monuments = [
				["Notre Dame de Paris", 48.853056, 2.349722],
				["Mus&eacute;e d'Orsay", 48.86, 2.327],
				["Museum National d'Histoire Naturelle", 48.8422, 2.3564]
			];
			var gares = [
				["Gare de Lyon", 48.8448, 2.3735],
				["Gare d'Austerlitz", 48.8416, 2.3661],
				["Gare de l'Est", 48.877036, 2.36],
				["Gare de Bercy", 48.839039, 2.383081],
				["Gare de Montparnasse", 48.841157, 2.320474],
				["Gare du Nord", 48.8828, 2.3567],
				["Gare Saint-Lazare", 48.8763, 2.32388]
			];

			function markersArray(items, icon) {
				var markers = new L.featureGroup();
				for (var i = 0; i < items.length; i++) {
					var item = items[i];
					marker = new L.marker([item[1],item[2]], {icon: icon}).bindPopup(item[0]);
					markers.addLayer(marker);
				}
 				markers.on('mouseover', function(e){ e.layer.openPopup(); })
				       .on('mouseout', function(e){ e.layer.closePopup(); });
				return markers;
			}
		</script>
	</head>
	<body>
		<div id="map"></div>
		<script type="text/javascript">
			var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
			var osmAttribution = 'Map data &copy; <a href="http://www.osm.org">OpenStreetMap</a>';
			var osmTileLayer = L.tileLayer(osmUrl, { attribution: osmAttribution });

			var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/841e036a3f194a30bf64e170f94c9e59/997/256/{z}/{x}/{y}.png';
			var cloudmadeAttribution = 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2011 CloudMade';
			var cloudmadeTileLayer = L.tileLayer(cloudmadeUrl, { attribution: cloudmadeAttribution });

			var transportURL = 'http://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png';
			var transportAttribution = '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> Contributors & <a href="http://thunderforest.com/">Thunderforest</a>';
			var transportTileLayer = L.tileLayer(transportURL, { attribution: transportAttribution });

			var baseMaps = {
				"OSM": osmTileLayer,
				"Transport": transportTileLayer,
				"Cloud Made": cloudmadeTileLayer
			};

			var map = L.map('map').setView([48.856578, 2.351828], 18);
			osmTileLayer.addTo(map);

			var trainIcon = L.icon({
				iconUrl: 'train.png',
				iconSize: [32,37],
				iconAnchor: [16,37],
				popupAnchor: [0,-37]
			});

			var monumentIcon = L.icon({
				iconUrl: 'monument.png',
				iconSize: [32,37],
				iconAnchor: [16,37],
				popupAnchor: [0,-37]
			});

			var Monuments = markersArray(monuments, monumentIcon);
			var Gares = markersArray(gares, trainIcon);

			map.addLayer(Monuments);
			map.addLayer(Gares);
			var bounds = Monuments.getBounds();
			bounds = bounds.extend(Gares.getBounds());
			map.fitBounds(bounds);

			var overlayMaps = {
				'Monuments':Monuments,
				'Gares':Gares
			};

			map.addControl(new L.Control.Layers(baseMaps, overlayMaps));
		</script>
	</body>
</html>