Last active
April 15, 2024 21:58
-
-
Save ThomasG77/e4136b0fd01df07578392cb9dbffcc04 to your computer and use it in GitHub Desktop.
Add WMS from capabilities and query features - demo with URL already added https://gist.githack.com/ThomasG77/e4136b0fd01df07578392cb9dbffcc04/raw/cb89525bb850499633766fe27a47871447a13d89/map.wmscapabilities.html?lon=4.310961&lat=48.608933&z=5.7&url=https%3A%2F%2Fservices.sandre.eaufrance.fr%2Fgeo%2Fsandre%3Flanguage%3Dfre%26&layer=Hydroecoregion1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<!-- | |
Copyright (c) 2015-2020 Jean-Marc VIGLINO, | |
released under CeCILL-B (french BSD like) licence: http://www.cecill.info/ | |
--> | |
<title>ol-ext: WMS Capabilities control</title> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
<meta name="description" content="DBPedia layer for OL3" /> | |
<meta name="keywords" content="openlayers, control, source, WMS, getCapabilities, capabilites" /> | |
<!-- Grid.js --> | |
<link href="https://cdn.jsdelivr.net/npm/gridjs/dist/theme/mermaid.min.css" rel="stylesheet" /> | |
<script src="https://cdn.jsdelivr.net/npm/gridjs/dist/gridjs.umd.js"></script> | |
<!-- Openlayers --> | |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@latest/ol.css" /> | |
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ol@latest/dist/ol.js"></script> | |
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script> | |
<!-- ol-ext --> | |
<link rel="stylesheet" href="https://viglino.github.io/ol-ext/dist/ol-ext.css" /> | |
<script type="text/javascript" src="https://viglino.github.io/ol-ext/dist/ol-ext.js"></script> | |
<!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer --> | |
<script src="https://unpkg.com/elm-pep"></script> | |
<!-- Proj4 --> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.14/proj4.js"></script> | |
<!-- filesaver-js --> | |
<script type="text/javascript" src="https://cdn.rawgit.com/eligrey/FileSaver.js/aa9f4e0e/FileSaver.min.js"></script> | |
<link rel="stylesheet" href="https://viglino.github.io/ol-ext/examples/style.css" /> | |
<style> | |
#map { | |
width: 100%; | |
height: 60vh; | |
} | |
.ol-wmscapabilities ul { | |
padding: 0; | |
} | |
</style> | |
</head> | |
<body > | |
<a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a> | |
<a href="../../index.html"> | |
<h1>ol-ext: WMS Capabilities control</h1> | |
</a> | |
<div class="info"> | |
<b>ol/control/WMSCapabilities</b> is a control to load WMS layers on ol maps. | |
<br/> | |
It displays a dialog to select the service you want to add using getCapabilities of the service. | |
<br/> | |
Some services may not respond correctly because of | |
<a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing">CORS policies</a> | |
and you may have to use a proxy to access the getCapabilities... | |
<br/> | |
Listen to the <i>load</i> event to get the selected layer or options to create it. | |
<br/> | |
Look at the console for the layer definition to insert into your code. | |
</div> | |
<!-- DIV pour la carte --> | |
<div id="map"></div> | |
<div class="options"> | |
<ul> | |
<li> | |
url: | |
<input id="url" type="text" value="http://geoservices.brgm.fr/geologie" /> | |
<button onclick="cap.showDialog($('#url').val())">search</button> | |
</li> | |
<li> | |
Services : | |
<button onclick="cap.showDialog('https://geoservices.brgm.fr/geologie'); ">BRGM</button> | |
<button onclick="cap.showDialog('https://services.sandre.eaufrance.fr/geo/sandre');">Sandre</button> | |
</li> | |
</ul> | |
<button onclick="exportCarte()" style="display: none;">exportCarte</button> | |
</div> | |
<div id="wrapper"></div> | |
<script type="text/javascript"> | |
// Define proj4 2154 | |
proj4.defs("EPSG:2154","+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"); | |
if (ol.proj.proj4 && ol.proj.proj4.register) ol.proj.proj4.register(proj4); | |
// The view | |
const view = new ol.View ({ | |
zoom: 15, | |
center: [261204.43490751847, 6250258.191535994] | |
}) | |
// The map | |
var map = new ol.Map({ | |
target: 'map', | |
view: view, | |
layers: [ new ol.layer.Tile({ name:"OSM", source: new ol.source.OSM() })] | |
}); | |
map.addControl(new ol.control.LayerSwitcher({ | |
trash: true, | |
extent: true, | |
collapsed: false | |
})); | |
var plink = new ol.control.Permalink({ visible: false, localStorage: 'position' }); | |
map.addControl(plink); | |
map.addControl(new ol.control.SearchNominatim({ zoomOnSelect: 13 })); | |
if (plink.hasUrlParam('edugeo')) $('.options button').show(); | |
var cap = new ol.control.WMSCapabilities({ | |
// target: $('.options').get(0), | |
target: document.body, | |
srs: ['EPSG:2154'], | |
cors: true, | |
optional: 'token', | |
services: { | |
'BRGM': 'https://geoservices.brgm.fr/geologie', | |
'OSM': 'https://wms.openstreetmap.fr/wms', | |
'Sandre': 'https://services.sandre.eaufrance.fr/geo/sandre', //'http://services.sandre.eaufrance.fr/geo/eth_FXX', | |
'Cartorisque': 'https://mapsref.brgm.fr/wxs/refcom-env/refign', | |
'Swiss Topo': 'https://wms.geo.admin.ch/', | |
'IFREMER*': 'http://tds0.ifremer.fr/thredds/wms/CORIOLIS-GLOBAL-NRTOA-OBS_TIME_SERIE?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&LAYERS=PSAL&CRS=EPSG%3A3857', | |
'Géorisque': 'https://mapsref.brgm.fr/wxs/georisques/risques', | |
'BDRisques': 'https://mapsref.brgm.fr/wxs/risques/bdrisques', | |
'Risques': 'https://geoservices.brgm.fr/risques', | |
'Natura 2000*': 'http://ws.carmencarto.fr/WMS/119/fxx_inpn?language=fre&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&LAYERS=Zones_de_protection_speciale&CRS=EPSG%3A3857', | |
// https://www.cigalsace.org/portail/fr/page/723/flux-donnees --> | |
'Cigalsace': 'https://www.cigalsace.org/geoserver/cigal/ows', | |
'CG93-raster': 'https://geoportail93.fr/cgi-bin/mapserv?map=SIGD/raster.map', | |
'CG93-fond': 'https://geoportail93.fr/cgi-bin/mapserv?map=SIGD/fond_SIGD.map', | |
'CG94*': 'https://geo.valdemarne.fr/viewer/index.php?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&LAYERS=parcelles&CRS=EPSG%3A2154', | |
'GeoFoncier':'https://api.geofoncier.fr/referentielsoge/ogc/wxs', | |
// http://www.geolittoral.equipement.gouv.fr/rubrique.php3?id_rubrique=39 --> | |
// 'GeoLittoral*': 'http://geolittoral.application.equipement.gouv.fr/wms/metropole', | |
// http://www.sogefi-sig.com/sogefi-diffuse-des-donnees-en-wms/ --> | |
'SOGEFI': 'http://ws.sogefi-web.com/wms', | |
// http://inspire-geoportal.ec.europa.eu/discovery/ --> | |
'Photos anciennes litto': 'http://www.ifremer.fr/services/photos_anciennes', | |
'Geobretagne': 'https://geobretagne.fr/geoserver/dir_ouest/wms', | |
'Venise*': 'http://cigno.atlantedellalaguna.it/geoserver/ows?SERVICE=WMS&VERSION=1.3.0&FORMAT=image%2Fpng&LAYERS=carta_base', | |
// 'Geoportail': 'https://wxs.ign.fr/choisirgeoportail/geoportail/r/wms', | |
'Geoplateforme raster': 'https://data.geopf.fr/wms-r/ows', | |
'Geoplateforme vecteur': 'https://data.geopf.fr/wms-v/ows' | |
}, | |
// Show trace in the console | |
trace: true | |
}); | |
map.addControl(cap); | |
// Popup overlay | |
var popup = new ol.Overlay.Popup ({ | |
popupClass: "default", //"tooltips", "warning" "black" "default", "tips", "shadow", | |
closeBox: true, | |
onshow: function(){ console.log("You opened the box"); }, | |
onclose: function(){ console.log("You close the box"); }, | |
positioning: 'auto', | |
autoPan: { | |
animation: { duration: 250 } | |
} | |
}); | |
const featureLayer = new ol.layer.VectorImage({source: new ol.source.Vector()}) | |
featureLayer.setMap(map) | |
map.addOverlay(popup) | |
cap.on('load', function(e) { | |
map.addLayer(e.layer); | |
e.layer.set('legend', e.options.data.legend); | |
plink.setUrlParam('url', e.options.source.url); | |
plink.setUrlParam('layer', e.options.source.params.LAYERS); | |
}); | |
var url = plink.getUrlParam('url'); | |
var layerName = plink.getUrlParam('layer'); | |
if (url) { | |
cap.loadLayer(url, layerName); | |
} | |
const capabilities = new ol.format.WMSCapabilities() | |
const geojsonFormat = new ol.format.GeoJSON() | |
const getFeatureInfoFormat = new ol.format.WMSGetFeatureInfo() | |
let grid; | |
const capabilitiesCached = {} | |
map.on('singleclick', async function (evt) { | |
const wmsLayers = map.getLayers().getArray().filter(l => l.getSource() instanceof ol.source.TileWMS) | |
if (wmsLayers.length > 0) { | |
featureLayer.getSource().clear(); | |
const viewResolution = /** @type {number} */ (view.getResolution()); | |
const wmsSource = wmsLayers[0].getSource() | |
const urlBasis = wmsSource.getUrls()[0].split('?')[0] | |
const WMSCapabilitiesUrl = `${urlBasis}?request=GetCapabilities&service=WMS&version=1.3.0` | |
if (!(WMSCapabilitiesUrl in capabilitiesCached)) { | |
const xmlCapabilities = await fetch(WMSCapabilitiesUrl).then(res => res.text()).then(text => text) | |
const capParsed = capabilities.read(xmlCapabilities) | |
capabilitiesCached[WMSCapabilitiesUrl] = capParsed.Capability.Request.GetFeatureInfo.Format | |
} | |
const formatChoice = capabilitiesCached[WMSCapabilitiesUrl].includes('geojson') ? 'geojson' : capabilitiesCached[WMSCapabilitiesUrl].find(format => format.includes('gml')) | |
// const formatChoice = 'application/vnd.ogc.gml' | |
const url = wmsSource.getFeatureInfoUrl( | |
evt.coordinate, | |
viewResolution, | |
'EPSG:3857', | |
{'INFO_FORMAT': formatChoice}, // application/vnd.ogc.gml | |
); | |
if (url) { | |
await fetch(url).then((response) => { | |
let method = 'text' | |
if (formatChoice === 'geojson') { | |
method = 'json' | |
} | |
return response[method]() | |
}).then((content) => { | |
console.log(content); | |
let features; | |
if (formatChoice === 'geojson') { | |
features = geojsonFormat.readFeaturesFromObject(content) | |
} else { | |
// 'application/vnd.ogc.gml'. Depending of web services, may not return a geometry | |
features = getFeatureInfoFormat.readFeatures(content) | |
} | |
const featuresProps = features.map(feature => Object.fromEntries(Object.entries(feature.getProperties()).filter(([k, v]) => (!Array.isArray(v) && k !== 'geometry')))) | |
console.table(featuresProps) | |
featureLayer.getSource().addFeatures(features) | |
if (featuresProps.length > 0) { | |
if (!grid) { | |
grid = new gridjs.Grid({ | |
columns: Object.keys(featuresProps[0]), | |
data: featuresProps.map(feature => Object.entries(feature).map(([k, v]) => v)) | |
}).render(document.getElementById("wrapper")); | |
} else { | |
grid.updateConfig({ | |
// lets update the columns field only | |
columns: Object.keys(featuresProps[0]), | |
data: featuresProps.map(feature => Object.entries(feature).map(([k, v]) => v)) | |
}).forceRender(); | |
} | |
} | |
}); | |
} | |
} | |
}); | |
/* Export .carte file */ | |
function exportCarte() { | |
var lonlat = ol.proj.toLonLat(map.getView().getCenter()); | |
var carte = { | |
"param": { | |
"lon": lonlat[0], | |
"lat": lonlat[1], | |
"rot": 0, | |
"zoom": map.getView().getZoom(), | |
"titre": "WMS", | |
"description": "" | |
}, | |
"layers": [] | |
} | |
map.getLayers().getArray().forEach(function(l) { | |
if (l.getSource() instanceof ol.source.TileWMS) { | |
var wms = { | |
"wms": true, | |
"type": "WMS", | |
"name": l.get('title'), | |
"titre": l.get('title'), | |
"visibility": l.getVisible(), | |
"opacity": l.getOpacity(), | |
"copyright": l.getSource().getAttributions()()[0] || '©', | |
"wmsparam": { | |
"layer": { | |
"title": l.get('title'), | |
"extent": l.get('extent'), | |
"minResolution": l.getMinResolution(), | |
"maxResolution": l.getMaxResolution() | |
}, | |
"source": { | |
"url": l.getSource().getUrls()[0], | |
"projection": "EPSG:3857", | |
"crossOrigin": "anonymous", | |
"params": { | |
"LAYERS": l.getSource().getParams().LAYERS, | |
"FORMAT": l.getSource().getParams().FORMAT, | |
"VERSION": l.getSource().getParams().VERSION | |
} | |
}, | |
"attribution": { | |
"html": l.getSource().getAttributions()()[0] || '©' | |
}, | |
"originator": [], | |
"legend": [] | |
}, | |
"maxZoomCluster": 20, | |
"radiusCluster": 40 | |
} | |
if (l.getSource().getParams().MAP) wms.wmsparam.source.params.MAP = l.getSource().getParams().MAP; | |
carte.layers.push(wms) | |
} | |
}); | |
var blob = new Blob([JSON.stringify(carte, null, ' ')], {type: 'text/plain;charset=utf-8'}); | |
saveAs(blob, 'carte.carte'); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment