OpenLayers
Le code ci-après illustre la création d'une carte interactive à l'aide de la librairie OpenLayers et d'extensions OL-ext développées par Viglino : LayerSwitcher control, et Popup overlay.
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 en WFS (au format GeoJSON) via le service KANO.
Code
html
<!DOCTYPE html>
<html>
<head>
<title>ASNR Planet - OpenLayers 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 : OpenLayers version 6.13.0 css and js -->
<link rel="stylesheet" href="../openlayers/ol@6.13.0/ol.css" />
<script src="../openlayers/ol@6.13.0/ol.js"></script>
<!-- Using viglino OpenLayers extensions :
for LayerSwitcher, see : https://viglino.github.io/ol-ext/examples/control/map.switcher.html
for Popup overlay, see : http://viglino.github.io/ol-ext/examples/popup/map.popup.html
-->
<link rel="stylesheet" href="../openlayers/viglino/ol-ext.css" />
<link rel="stylesheet" href="../openlayers/viglino/map.switcher2.css" />
<script type="text/javascript" src="../openlayers/viglino/ol-ext.js"></script>
<style>
body {
margin:0;
font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif;
}
.map {
width: 100%;
height: 100vh;
}
.select {
cursor: pointer;
}
.ol-popup {
max-width:300px;
min-width:100px;
min-height:1em;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<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 osm_bright = new ol.layer.Tile({
title: 'OSM Bright',
baseLayer: true, // set 'true' to manage exclusive visibility on layers (only one base layer is shown at a time)
displayInLayerSwitcher: true, // set to 'false' to not display in the LayerSwitcher
source: new ol.source.XYZ({
attributions: '© <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/osm-bright/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: true // Visibility by default
});
var osm_terrain_bright = new ol.layer.Tile({
title: 'OSM Terrain Bright',
baseLayer: true,
source: new ol.source.XYZ({
attributions: '© <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/osm-terrain-bright/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
var osm_dark = new ol.layer.Tile({
title: 'OSM Dark',
baseLayer: true,
source: new ol.source.XYZ({
attributions: '© <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/osm-dark/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
var ign_ortho = new ol.layer.Tile({
title: 'Photographie Aériennes (IGN Ortho)',
baseLayer: true,
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/ign-ortho/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.jpeg?' + apiKey
}),
maxZoom: 18,
visible: false
});
var ign_plan_accentue = new ol.layer.Tile({
title: 'IGN Plan (accentué)',
baseLayer: true,
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/ign-plan-accentue/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
var ign_plan_attenue = new ol.layer.Tile({
title: 'IGN Plan (atténué)',
baseLayer: true,
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/ign-plan-attenue/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
var ign_plan_classique = new ol.layer.Tile({
title: 'IGN Plan (classique)',
baseLayer: true,
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/ign-plan-classique/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
var ign_plan_epure = new ol.layer.Tile({
title: 'IGN Plan (épuré)',
baseLayer: true,
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/ign-plan-epure/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
var ign_plan_gris = new ol.layer.Tile({
title: 'IGN Plan (gris)',
baseLayer: true,
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/ign-plan-gris/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
var ign_plan_standard = new ol.layer.Tile({
title: 'IGN Plan (standard)',
baseLayer: true,
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/ign-plan-standard/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
var ign_plan_adm = new ol.layer.Tile({
title: 'IGN Plan & limites administratives Admin-Express',
baseLayer: true,
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/ign-plan-adm/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
// Creating base layer group
var baseLayerGroup = new ol.layer.Group({
title: 'Fonds de carte',
openInLayerSwitcher: false, // Set to 'true' to have this group open by default in the LayerSwitcher
layers: [
osm_bright,
osm_terrain_bright,
osm_dark,
ign_ortho,
ign_plan_accentue,
ign_plan_attenue,
ign_plan_classique,
ign_plan_epure,
ign_plan_gris,
ign_plan_standard,
ign_plan_adm
]
});
//
// Here are the administrative layers
//
var ignLimitsDark = new ol.layer.Tile({
title: 'IGN Limits Dark',
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/ign-limites-sombre/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
var ignLimitsBright = new ol.layer.Tile({
title: 'IGN Limits Bright',
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/ign-limites-clair/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: true
});
var ignLimitsToponyms = new ol.layer.Tile({
title: 'Limites administratives IGN (toponymes)',
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/ign-limites-toponymes/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: true
});
var gadmLimitsDark = new ol.layer.Tile({
title: 'Limites GADM (sombre)',
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/gadm-dark/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
var gadmLimitsBright = new ol.layer.Tile({
title: 'Limites GADM (clair)',
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/gadm-bright/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
var gadmLimitsToponyms = new ol.layer.Tile({
title: 'Limites administratives GADM (Toponymes)',
source: new ol.source.XYZ({
attributions: '© <a href="https:/ign.fr">IGN</a> contributors',
url: 'https://api.' + subdomain + '/wmts/1.0.0/gadm-toponyms/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png?' + apiKey
}),
maxZoom: 18,
visible: false
});
//
// Creating adminsitrative layer group
//
var admLayerGroup = new ol.layer.Group({
title: 'Limites administratives',
openInLayerSwitcher: true, // Set to 'true' to have this group open by default in the LayerSwitcher
layers: [
ignLimitsDark,
ignLimitsBright,
ignLimitsToponyms,
gadmLimitsDark,
gadmLimitsBright,
gadmLimitsToponyms,
]
});
//
// Here is the nuclear sites overlay layer definition
//
var sites = new ol.layer.Vector({
title: 'Sites',
source: new ol.source.Vector({
attributions: '', // Write here the name of the owner of the data
format: new ol.format.GeoJSON(),
url: 'https://api.' + subdomain + '/wfs?service=WFS&version=2.0.0&request=GetFeature&typeNames=site_centroid&outputformat=geojson&' + apiKey
}),
// Styling points
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill ({
color: 'red'
}),
stroke: new ol.style.Stroke({
color: 'black',
width: 1
})
})
}),
maxZoom: 18,
visible: true // Visibility by default
});
//
// Here are the influence zones
//
var zi = new ol.layer.Vector({
title: 'Zones d\'influence',
source: new ol.source.Vector({
attributions: '', // Write here the name of the owner of the data
format: new ol.format.GeoJSON(),
url: 'https://api.' + subdomain + '/wfs?service=WFS&version=2.0.0&request=GetFeature&typeNames=zi&outputformat=geojson&' + apiKey
}),
// Styling polygons
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'blue'
}),
stroke: new ol.style.Stroke({
color: 'red',
width: 1,
})
}),
maxZoom: 18,
visible: true, // Visibility by default
opacity: 0.5 // Opacity by default
});
//
// Creating nuclear data layer group
//
var dataLayerGroup = new ol.layer.Group({
title: 'Données',
openInLayerSwitcher: true, // Set to 'true' to have this group open by default in the LayerSwitcher
layers: [
zi,
sites
]
});
/**
* Elements that make up the popup.
*/
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
//
// Adding overlay
//
var overlay = new ol.Overlay({
element: container,
autoPan: true,
offset: [0, -10]
});
//
// Popup overlay
//
var popup = new ol.Overlay.Popup ({
popupClass: "default", // Select between predefined CSS : "tooltips", "warning" "black" "default", "tips", "shadow",
closeBox: true, // Shows the popup close button
onshow: function(){ console.log("You opened the box"); },
onclose: function(){ console.log("You close the box"); },
positioning: 'auto',
autoPan: true,
autoPanAnimation: { duration: 250 }
});
//
// Loading layer groups in the map
//
var map = new ol.Map({
target: 'map',
layers: [
baseLayerGroup,
admLayerGroup,
dataLayerGroup
],
view: new ol.View({
center: ol.proj.fromLonLat([3, 47]),
zoom: 6
}),
overlays: [popup]
});
var layerSwitcher = new ol.control.LayerSwitcher();
map.addControl(layerSwitcher);
//
// Control Select
//
var select = new ol.interaction.Select({});
map.addInteraction(select);
//
// On selected => show/hide popup
//
select.getFeatures().on(['add'], function(e) {
var feature = e.element;
var content = "";
content += feature.get("name");
popup.show(feature.getGeometry().getFirstCoordinate(), content);
});
select.getFeatures().on(['remove'], function(e) {
popup.hide();
})
</script>
</body>
</html>