From 43f86e9a669fe4905a1aac48cc6b114e3f94931a Mon Sep 17 00:00:00 2001 From: Miko Date: Fri, 3 Jan 2025 22:53:51 +0100 Subject: [PATCH] add control for contour lines --- public/resources/contour-control.js | 65 ++++++++++++++++ public/templates/data.tmpl | 110 +++++++++++++++++++--------- 2 files changed, 140 insertions(+), 35 deletions(-) create mode 100644 public/resources/contour-control.js diff --git a/public/resources/contour-control.js b/public/resources/contour-control.js new file mode 100644 index 0000000..0bf2f02 --- /dev/null +++ b/public/resources/contour-control.js @@ -0,0 +1,65 @@ +class MaplibreContourControl { + constructor(options) { + this.source = options["source"]; + this.confLayers = options["layers"]; + this.visibility = options["visibility"]; + } + + getDefaultPosition() { + const defaultPosition = "top-right"; + return defaultPosition; + } + + onAdd(map) { + this.map = map; + this.controlContainer = document.createElement("div"); + this.controlContainer.classList.add("maplibregl-ctrl"); + this.controlContainer.classList.add("maplibregl-ctrl-group"); + this.contourButton = document.createElement("button"); + this.contourButton.type = "button"; + this.contourButton.textContent = "C"; + + this.map.on("style.load", () => { + this.confLayers.forEach(layer => { + this.map.setLayoutProperty(layer, "visibility", this.visibility ? "visible" : "none"); + if (this.visibility) { + this.controlContainer.classList.add("maplibre-ctrl-contour-active"); + this.contourButton.title = "Disable Contours"; + } else { + this.contourButton.title = "Ensable Contours"; + } + }); + }); + + this.contourButton.addEventListener("click", () => { + this.confLayers.forEach(layer => { + var visibility = this.map.getLayoutProperty(layer, "visibility"); + if (visibility === "visible") { + this.map.setLayoutProperty(layer, "visibility", "none"); + this.controlContainer.classList.remove("maplibre-ctrl-contour-active"); + this.contourButton.title = "Disable Contours"; + } else { + this.controlContainer.classList.add("maplibre-ctrl-contour-active"); + this.map.setLayoutProperty(layer, "visibility", "visible"); + this.contourButton.title = "Enable Contours"; + } + }); + }); + this.controlContainer.appendChild(this.contourButton); + return this.controlContainer; + } + + onRemove() { + if ( + !this.controlContainer || + !this.controlContainer.parentNode || + !this.map || + !this.contourButton + ) { + return; + } + this.contourButton.removeEventListener("click"); + this.controlContainer.parentNode.removeChild(this.controlContainer); + this.map = undefined; + } +}; diff --git a/public/templates/data.tmpl b/public/templates/data.tmpl index 300cb28..0d823f0 100644 --- a/public/templates/data.tmpl +++ b/public/templates/data.tmpl @@ -10,6 +10,7 @@ + {{/use_maplibre}} {{^use_maplibre}} @@ -71,10 +73,9 @@ }; {{/is_terrain}} {{#is_terrain}} - let baseUrl = window.location.origin; - console.log(baseUrl); - baseUrl = baseUrl + "/data/{{id}}/contour/{z}/{x}/{y}" - console.log(baseUrl); + + let baseUrl = window.location.origin; + var style = { version: 8, sources: { @@ -90,42 +91,64 @@ }, "contour": { "type": "vector", - "tiles": [ baseUrl ], + "tiles": [ baseUrl + "/data/{{id}}/contour/{z}/{x}/{y}" ], } }, + "glyphs": "local://fonts/{fontstack}/{range}.pbf", "terrain": { "source": "terrain" }, - "layers": [ - { - "id": "background", - "paint": { - "background-color": "hsl(190, 99%, 63%)" - }, - "type": "background" - }, - { - "id": "hillshade", - "source": "hillshade", - "type": "hillshade", - "paint": { - "hillshade-shadow-color": "hsl(39, 21%, 33%)", - "hillshade-illumination-direction": 315, - "hillshade-exaggeration": 0.8 - } - }, - { - "id": "contours", - "type": "line", - "source": "contour", - "source-layer": "contours", - "paint": { - "line-opacity": 0.5, - "line-width": ["match", ["get", "level"], 1, 1, 0.5] - } - } - ] - }; + "layers": [ + { + "id": "background", + "paint": { + "background-color": "hsl(190, 99%, 63%)" + }, + "type": "background" + }, + { + "id": "hillshade", + "source": "hillshade", + "type": "hillshade", + "paint": { + "hillshade-shadow-color": "hsl(39, 21%, 33%)", + "hillshade-illumination-direction": 315, + "hillshade-exaggeration": 0.8 + } + }, + { + "id": "contours", + "type": "line", + "source": "contour", + "source-layer": "contours", + "paint": { + "line-opacity": 0.5, + "line-width": ["match", ["get", "level"], 1, 1, 0.5] + } + }, + { + "id": 'contour-label', + "type": 'symbol', + "source": 'contour', + "source-layer": 'contours', + "filter": ['>', ['get', 'level'], 0], + "paint": { + 'text-halo-color': 'white', + 'text-halo-width': 1 + }, + "layout": { + 'symbol-placement': 'line', + 'text-size': 10, + 'text-field': [ + 'concat', + ['number-format', ['get', 'ele'], {}], + '\'' + ], + 'text-font': ['Noto Sans Bold'] + } + } + ] + }; {{/is_terrain}} var map = new maplibregl.Map({ @@ -134,17 +157,33 @@ maxPitch: 85, style: style }); + map.addControl(new maplibregl.NavigationControl({ visualizePitch: true, showZoom: true, showCompass: true })); {{#is_terrain}} + map.addControl( new maplibregl.TerrainControl({ source: "terrain", }) ); + + map.addControl( + new MaplibreContourControl({ + source: "contour", + visibility: false, + layers: [ "contours", "contour-label" ] + }) + ); + + //map.addControl( + // new ElevationInfo({ + // url: baseUrl + "/data/{{id}}/elvation/{z}/{x}/{y}" + // }) + //); {{/is_terrain}} {{^is_terrain}} @@ -153,6 +192,7 @@ showInspectButton: false }); map.addControl(inspect); + map.on('styledata', function() { var layerList = document.getElementById('layerList'); layerList.innerHTML = '';