diff --git a/spatial/static/spatial/js/slidingMap.js b/spatial/static/spatial/js/slidingMap.js index 67f0eced9037c0b48724d28036666ff81b201985..4fd425f176899f79c17cf665518f3ab585f045e0 100644 --- a/spatial/static/spatial/js/slidingMap.js +++ b/spatial/static/spatial/js/slidingMap.js @@ -1,3 +1,4 @@ +// TODO: Handle most/all EPSG codes proj4.defs( 'EPSG:25833', '+proj=utm +zone=33 +ellps=GRS80 +units=m +no_defs' @@ -13,6 +14,8 @@ let timestamps = undefined; let currentParameter = "WARNING_STATUS"; let parameters = [currentParameter]; let WMSLayersDateBucket = {}; +let map = undefined; +let popup = undefined; function switchLayer(dayIndex) { @@ -32,10 +35,16 @@ function setCurrentDate(layerIndex) document.getElementById("currentDate").innerHTML=moment(parseInt(timestamps[layerIndex])).format("YYYY-MM-DD"); } +function getCurrentVisibleOLLayer() +{ + // The WMS layer returned from mapserver is found + let currentWMSLayer = WMSLayersDateBucket[currentTimestamp][currentParameter]; + // We have the ordering in the openlayers Map as a property, use that to return the OpenLayers layer + return layers[currentLayer["ordering"]]; +} async function initSlidingMap(lonLat, zoomLevel, mapAttribution) { - var map; var backgroundLayer = new ol.layer.Tile({ source: new ol.source.OSM({ @@ -52,6 +61,7 @@ async function initSlidingMap(lonLat, zoomLevel, mapAttribution) { let response = await fetch(mapserverURL + modelId + "?service=WMS&version=1.3.0&request=GetCapabilities"); let result = parser.read(await response.text()); let WMSLayers = result.Capability.Layer.Layer; + //console.info(WMSLayers[0]); // Analyze and organize layers // First dimension: Time @@ -101,7 +111,7 @@ async function initSlidingMap(lonLat, zoomLevel, mapAttribution) { params: { "LAYERS": modelId + "." + currentLayerParam + "." + dateStr, "TRANSPARENT": "TRUE" }, serverType: "mapserver", ratio: 1, - projection: ol.proj.get("EPSG:25833") + projection: ol.proj.get(currentLayer.CRS[0]) }), visible: false, opacity: 0.5 @@ -139,6 +149,13 @@ async function initSlidingMap(lonLat, zoomLevel, mapAttribution) { }); map.setView(view); + popup = new ol.Overlay({ + element: document.getElementById('popup') + }); + map.addOverlay(popup); + + map.on('singleclick', displayQueryResult); + // Add the parameter selector let radioHTML = ""; for(let i=0;i<parameters.length;i++) @@ -154,4 +171,65 @@ function switchParameter(selectedParameter) { currentParameter = selectedParameter; switchLayer(document.getElementById("layerDateRange").value); +} + +async function displayQueryResult(evt) +{ + let coordinate = proj4(map.getView().getProjection().getCode(), 'EPSG:25833', evt.coordinate) + let currentWMSLayer = WMSLayersDateBucket[currentTimestamp][currentParameter]; + let currentLayer = getCurrentVisibleOLLayer(); + //console.info(currentLayer); + const url = currentLayer.getSource().getGetFeatureInfoUrl( + coordinate, + map.getView().getResolution(), + currentWMSLayer.CRS[0], + { 'INFO_FORMAT': 'text/xml' } + ); + + //console.info(url); + let response = await fetch(url); + let responseXML = await response.text(); + + const parser = new DOMParser(); + const xmlDOM = parser.parseFromString(responseXML,"text/xml"); + const result = xmlDOM.getElementsByTagName("vipsResult")[0] + if(result) { + // We may or may not have warning status included + let warningStatus = xmlDOM.getElementsByTagName("warningStatus").length == 1 ? xmlDOM.getElementsByTagName("warningStatus")[0].getAttribute("value") : null; + let parameters = {}; + let parameterElements = xmlDOM.getElementsByTagName("parameter"); + for(let i=0;i<parameterElements.length;i++) + { + parameters[parameterElements[i].getAttribute("name")] = parameterElements[i].getAttribute("value"); + } + //console.info("warningStatus = " + warningStatus); + //console.info(parameters); + + let warningStatusTitle = warningStatus == 0 ? "N/A" + : warningStatus == 1 ? "Missing data" + : warningStatus == 2 ? "No risk" + : warningStatus == 3 ? "Possible risk" + : warningStatus == 4 ? "High risk" : ""; + + let paramHTML = "<ul>"; + paramCodes = Object.keys(parameters); + for(let i=0;i<paramCodes.length;i++) + { + paramHTML += "<li>" + paramCodes[i] + " = " + parameters[paramCodes[i]] + "</li>" + } + paramHTML += "</ul>"; + + // Render results + // TODO: Handle click outside layer + let popupElement = popup.getElement(); + $(popupElement).popover('destroy'); + popup.setPosition(evt.coordinate); + $(popupElement).popover({ + 'placement': 'top', + 'animation': false, + 'html': true, + 'content': '<h4>' + warningStatusTitle + '</h4>' + paramHTML + }); + $(popupElement).popover('show'); + } } \ No newline at end of file diff --git a/spatial/templates/spatial/slidingMap.html b/spatial/templates/spatial/slidingMap.html index b177387210a923b884996ba8c3676c2dd5946e64..3b2b777d9eeeb7e20b02b51c34c9aa2058977f04 100644 --- a/spatial/templates/spatial/slidingMap.html +++ b/spatial/templates/spatial/slidingMap.html @@ -33,5 +33,6 @@ <div class="form-group" id="paramselector" style="position: absolute; right: 20px; bottom: 20px; background-color: white; z-index: 1000;padding: 15px; border-radius: 15px;"> </div> </div> + <div id="popup" title="Location details"></div> {% endblock %} \ No newline at end of file