LeafletDans la continuité des micro-tutoriaux précédents sur Leaflet, voyons maintenant comment créer une Polyline, et s’il est possible d’en retrouver les points qui la composent.

Il s’agit d’un préambule au travail sur les traces GPX de mon GPS. En effet, le rendu de cette trace se fera avec une (ou plusieurs) Polyline(s).

Articles précédents :

Une Polyline est un un ensemble de droites tracées entre les points qui la compose. La version la plus simple est évidemment une ligne entre deux points.


Création d’une Polyline

En se basant sur les coordonnées de quelques villes françaises, traçons une première Polyline sur notre carte.

var villes = [
	["Paris", 48.856578, 2.351828],
	["Orléans", 47.9025, 1.909],
	["Tours", 47.393611, 0.689167],
	["Poitiers", 46.581945, 0.336112],
	["Bordeaux", 44.837912, -0.579541]
];

Transformons ce tableau d’informations en tableau de points géographiques (un couple de coordonnées, au sens Leaflet du terme) et affichons le sur la carte :

function pointsArray(items) {
	var pointsArray = new Array();
	for (var i = 0; i < items.length; i++) {
		var item = items[i];
		pointsArray.push(new L.LatLng(item[1],item[2]));
	}
	return pointsArray;
}
var trajet = new L.Polyline(pointsArray(villes));
map.addLayer(trajet);

Pour le moment, les noms des villes ne sont pas utilisés.

Polyline

Polyline

L’objet ainsi créé contient notre tableau de coordonnées, et nous pouvons donc placer des markers sur les villes.

function markersArray_fromLatLngs(items, icon) {
	var markers = new L.featureGroup();
	for (var i = 0; i < items.length; i++) {
		var item = items[i];
		marker = new L.marker([item.lat,item.lng], {icon: icon});
		markers.addLayer(marker);
	}
	markers.on('mouseover', function(e){ e.layer.openPopup(); })
	       .on('mouseout', function(e){ e.layer.closePopup(); });
	return markers;
}
var cities = markersArray_fromLatLngs(trajet.getLatLngs(), cityIcon);
map.addLayer(cities);
Polyline + Markers

Polyline + Markers

Il aurait été possible de se baser sur la table des villes et la fonction « markersArray(items, icon) » utilisée dans l’article « Leaflet : gérer les layers« . Ainsi, nos markers pourraient afficher une infobulle lors du survol de la souris.

L’idée reste d’utiliser l’objet Polyline et ses données, il faut donc envisager d’étendre les propriétés de l’objet Polyline.

Etendre l’objet Polyline

Il est question de créer un objet qui va intégrer la Polyline telle que créée précédemment et les markers qui la jalonne. Le nouvel objet intégrera les fonctions que nous avions utilisé pour lire la table des villes.

L.mPolyline = L.FeatureGroup.extend({
	initialize: function(items, icon) {
		this._layers = {};
		this.addLayer(new L.Polyline(this._pointsArray(items)));
		this.addLayer(this._markersArray(items, icon));				
	}, 
	_pointsArray: function(items) {
		var pointsArray = new Array();
		for (var i = 0; i < items.length; i++) {
			var item = items[i];
			pointsArray.push(new L.LatLng(item[1],item[2]));
		}
		return pointsArray;
	},
	_markersArray: function(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;
	}
});

Il suffit maintenant d’afficher notre Polyline et ses markers ainsi :

var trajet = new L.mPolyline(villes, cityIcon);
map.addLayer(trajet);

Code complet

Au final, cela donne la page suivante :

<!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 osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
			var osmAttribution = 'Map data &copy; <a href="http://www.osm.org">OpenStreetMap</a>';

			var villes = [
				["Paris", 48.856578, 2.351828],
				["Orl&eacute;ans", 47.9025, 1.909],
				["Tours", 47.393611, 0.689167],
				["Poitiers", 46.581945, 0.336112],
				["Bordeaux", 44.837912, -0.579541]
			];

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

			L.mPolyline = L.FeatureGroup.extend({
				initialize: function(items, icon) {
					this._layers = {};
					this.addLayer(new L.Polyline(this._pointsArray(items)));
					this.addLayer(this._markersArray(items, icon));

				}, 
				_pointsArray: function(items) {
					var pointsArray = new Array();
					for (var i = 0; i < items.length; i++) {
						var item = items[i];
						pointsArray.push(new L.LatLng(item[1],item[2]));
					}
					return pointsArray;
				},

				_markersArray: function(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 map = L.map('map').setView([48.856578, 2.351828], 18);
			L.tileLayer(osmUrl, { attribution: osmAttribution }).addTo(map);

			var trajet = new L.mPolyline(villes, cityIcon);
			console.dir(trajet);
			map.addLayer(trajet);

			map.fitBounds(trajet.getBounds());
		</script>
	</body>
</html>