Skip to content

Leaflet

Le code ci-après illustre la création d'une carte interactive à l'aide de la librairie Leaflet. Les éléments de contrôle permettent de changer le fond de carte parmi les différents jeux de données accessible en WMTS et d'afficher/cacher les sites nucléaires via le service KANO.

Code

html

<!DOCTYPE html>
<html>
	<head>
		<title>ASNR Planet - Leaflet client demonstration</title>

		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<!-- Page icon -->
		<link rel="shortcut icon" type="image/x-icon" href="../irsn-planet-icon-64x64.png" />
		<!-- Add dependencies: Leaflet, leaflet-basemap and leaflet.markercluster -->
		<link rel="stylesheet" href="leaflet@1.3.1/leaflet.css" />
		<script src="leaflet@1.3.1/leaflet.js"></script>
		<link rel="stylesheet" href="leaflet-basemaps@0.2.3/L.Control.Basemaps.css" />
		<script src="leaflet-basemaps@0.2.3/L.Control.Basemaps-min.js"></script>
		<link rel="stylesheet" href="leaflet.markercluster@1.3.0/MarkerCluster.css" />
		<link rel="stylesheet" href="leaflet.markercluster@1.3.0/MarkerCluster.Default.css" />
		<script src="leaflet.markercluster@1.3.0/leaflet.markercluster.js"></script>

		<link rel="stylesheet" href="style.css">	
	</head>
	<body>
		<!-- Define the map -->
		<div id="map" style="position: absolute; top: 0; left:0; bottom:0; right: 0;"></div>
		<!-- Feed the map layers -->
		<script type="text/javascript">
			// 
			// Here is the subdomain and token defintion
			// Note that it can be convenient to store these variables according a flavor (dev, test, prod)
			//
			var subdomain='planet.staging.ul2i.fr'
			var apiKey='jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NTYwNDYxMC0wMjUzLTQ1NzEtYjYxOC05N2YwYmVmZmY0MjMiLCJuYW1lIjoiZG9jIiwiYXVkIjoicGxhbmV0LnN0YWdpbmcudWwyaS5mciIsImlzcyI6ImthbGlzaW8iLCJpYXQiOjE3NTA2NjY5MDV9.5NkFwnubsVu3L9LVEacorpCt8F7tr7lenPFNrWI6rjU'
			//
			// Here are the basemaps definition
			//
			var basemaps = [
				L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/osm-bright/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'OpenStreetMap',
					attribution: '© <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'
				}),
				L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/osm-terrain-bright/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'OpenStreetMap & Terrain data (bright)',
					attribution: '© <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'
				}),
				L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/osm-dark/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'OpenStreetMap (dark)',
					attribution: '© <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'
				}),
				L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/ign-ortho/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.jpeg?' + apiKey, {
					maxZoom: 18,
					label: 'Photographie Aériennes',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				}),
				L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/ign-plan-accentue/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'IGN Plan (accentué)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				}),
				L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/ign-plan-attenue/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'IGN Plan (atténué)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				}),
				L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/ign-plan-classique/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'IGN Plan (classique)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				}),
				L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/ign-plan-epure/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'IGN Plan (épuré)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				}),
				L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/ign-plan-gris/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'IGN Plan (gris)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				}),
				L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/ign-plan-standard/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'IGN Plan (standard)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				}),
				L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/ign-plan-adm/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'IGN Plan & limites administratives Admin-Express',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				})
			];
			//
			// Here are the administrative layers
			//
			var ignLimitsDark = L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/ign-limites-sombre/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'Limites administratives IGN (sombre)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				})
			var ignLimitsBright = L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/ign-limites-clair/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'Limites administratives IGN (clair)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				})
			var ignLimitsToponyms = L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/ign-limites-toponymes/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'Limites administratives IGN (toponyles)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				})
			var gadmLimitsDark = L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/gadm-dark/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'Limites GADM (sombre)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				})
			var gadmLimitsBright = L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/gadm-bright/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'Limites administrarives GADM (clair)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				})
			var gadmLimitsToponyms = L.tileLayer('https://api.' + subdomain + '/wmts/1.0.0/gadm-toponyms/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey, {
					maxZoom: 18,
					label: 'Limites administratives GADM (Toponymes)',
					attribution: '© <a href="https:/ign.fr">IGN</a> contributors'
				})
			//
			// Here is the nuclear sites overlay layer definition
			//
			var sitesCluster = L.markerClusterGroup()
			var sitesXhr = new XMLHttpRequest();
			sitesXhr.open('GET', 'https://api.' + subdomain + '/wfs?service=WFS&version=2.0.0&request=GetFeature&typeNames=site_centroid&outputformat=geojson&' + apiKey);
			sitesXhr.onreadystatechange = function() {
				if (sitesXhr.readyState == 4) {
					var sitesData = JSON.parse(sitesXhr.responseText);
					var siteLayer = L.geoJson(sitesData, {
						onEachFeature: function(feature, layer) {
							var popupText = '<b>' + feature.properties.name + '</b>'
							layer.bindPopup(popupText); 
						}
					})
					siteLayer.addTo(sitesCluster);
				}
			}
			sitesXhr.send();
			//
			// Here are the influence zones
			//
			var ziCluster = L.geoJSON()
			var ziXhr = new XMLHttpRequest();
			ziXhr.open('GET', 'https://api.' + subdomain + '/wfs?service=WFS&version=2.0.0&request=GetFeature&typeNames=zi&outputformat=geojson&' + apiKey);
			ziXhr.onreadystatechange = function() {
				if (ziXhr.readyState == 4) {
					var ziData = JSON.parse(ziXhr.responseText);
					var ziLayer = L.geoJson(ziData, {
						onEachFeature: function(feature, layer) {
							var popupText = '<b>' + feature.properties.Nom + '(' + feature.properties.Distance + ')</b>' 
							layer.bindPopup(popupText); 
						}
					})
					ziLayer.addTo(ziCluster);
				}
			}
			ziXhr.send();
			var overlays = {
				'Limites administratrives IGN (sombre)': ignLimitsDark,
				'Limites administratrives IGN (clair)': ignLimitsBright,
				'Limites administratrives IGN (toponymes)': ignLimitsToponyms,
				'Limites administratrives GADM (sombre)': gadmLimitsDark,
				'Limites administratrives GADM (clair)': gadmLimitsBright,
				'Limites administratrives GADM (toponymes)': gadmLimitsToponyms,
				'Sites': sitesCluster,
				'Zones sous influence': ziCluster
			}
			// Here is the map configuration and the controls
			var map = L.map('map', {
				center: [47, 2],
				zoom: 6,
				zoomControl: false
			});
			map.addControl(L.control.basemaps({
				position: 'bottomright',
				basemaps: basemaps,
				tileX: 66,  // tile X coordinate
				tileY: 46,  // tile Y coordinate
				tileZ: 7   // tile zoom level
			}));
			map.addControl(L.control.layers({}, overlays));
		</script>
	</body>
</html>

Résultat