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>