diff options
author | Guilhem Moulin <guilhem@fripost.org> | 2025-06-07 19:02:37 +0200 |
---|---|---|
committer | Guilhem Moulin <guilhem@fripost.org> | 2025-06-07 22:57:11 +0200 |
commit | 2f933a5a891adddef9a095ce33ab17bfab2e284d (patch) | |
tree | 0d845c4dc50ffe27bce335a981370c4bf856c95c | |
parent | 8d03e7794dae3696b0a975477542a4db03136ab7 (diff) |
JS: Refactor layer creation.
-rw-r--r-- | main.js | 134 |
1 files changed, 68 insertions, 66 deletions
@@ -4222,6 +4222,7 @@ const styles = (function() { })(); const [mapLayers, featureOverlayLayer] = (function() { + const baseurl = '/'; const xyz = '/{z}/{x}/{y}.pbf'; const tileGrid = createXYZ({ extent: extent, @@ -4230,74 +4231,75 @@ const [mapLayers, featureOverlayLayer] = (function() { minZoom: 0, maxZoom: 7, }); + const isVisible = function(groupname) { + return Object.keys(layers).some((layername) => + layername.startsWith(layername + '.') && styles[lyr] !== undefined); + }; const canWebGL2 = !!document.createElement('canvas').getContext('webgl2'); + + /* Note: layers are added in the order below, so leave SvK and + * misc at the end so they show up on top of suface features */ + const rasterLayers = ['kskog']; + const vectorLayers = ['nv', 'mrr', 'skydd', 'ren', 'ri', 'avverk', 'vbk', 'svk', 'misc']; + + const ret = {}; + if (!canWebGL2) { + rasterLayers.forEach((k) => ret[k] = null); + } else { + rasterLayers.forEach((k) => ret[k] = new TileLayerGL({ + /* Naturvårdsverket has a WMS server we could use instead, but by serving it ourselves + * we can filter on he various kskog classes */ + source: new GeoTIFF({ + sources: [{ + url: baseurl + 'raster/' + k + '.tiff', + }], + normalize: false, + convertToRGB: false, + projection: projection, + wrapX: false, + interpolate: false, + }), + visible: false, + style: null, /* filled later */ + })); + rasterLayers.forEach((k) => map.addLayer(ret[k])); + } + + vectorLayers.forEach((k) => ret[k] = new VectorTileLayer({ + source: new VectorTile({ + url: baseurl + 'tiles/' + k + xyz, + format: new MVT(), + projection: projection, + wrapX: false, + transition: 0, + tileGrid: tileGrid, + }), + /* XXX switch to 'hybrid' if there are perf issues; but that seems to + * put lines above points regardless of their respective z-index */ + renderMode: 'hybrid', + declutter: false, + visible: isVisible(k), + style: function(feature, resolution) { + const style = styles[k + '.' + feature.getProperties().layer]; + if (!Array.isArray(style)) { + return style; + } else { + const maxi = style.length - 1; + const z = 10 /* Math.log2(maxResolution) */ - Math.log2(resolution); + /* use Math.floor() as VectorTile.js calls getZForResolution(resolution, 1) */ + const i = z <= 0 ? 0 : z >= maxi ? maxi : Math.floor(z); + // console.log(`resolution=${resolution}, z=${z}, i=${i}`); + return style[i]; + } + } + })); + vectorLayers.forEach(function(k) { + ret[k].set('layerGroup', k, true); + map.addLayer(ret[k]); + }); + return [ - Object.fromEntries( - /* Note: layers are added in the order below, so leave SvK and - * misc at the end so they show up on top of suface features */ - ['kskog', 'nv', 'mrr', 'skydd', 'ren', 'ri', 'avverk', 'vbk', 'svk', 'misc'] - .map(function(k) { - let visible = false; - Object.keys(layers).forEach(function(lyr) { - if (lyr.startsWith(k + '.')) { - visible ||= styles[lyr] !== undefined; - } - }); - let lyr; - if (k === 'kskog') { - if (!canWebGL2) { - return [k, null]; - } - lyr = new TileLayerGL({ - /* Naturvårdsverket has a WMS server we could use instead */ - source: new GeoTIFF({ - sources: [{ - url: '/raster/' + k + '.tiff', - }], - normalize: false, - convertToRGB: false, - projection: projection, - wrapX: false, - interpolate: false, - }), - visible: false, - style: null, - }); - } - else { - lyr = new VectorTileLayer({ - source: new VectorTile({ - url: '/tiles/' + k + xyz, - format: new MVT(), - projection: projection, - wrapX: false, - transition: 0, - tileGrid: tileGrid, - }), - /* XXX switch to 'hybrid' if there are perf issues; but that seems to - * put lines above points regardless of their respective z-index */ - renderMode: 'hybrid', - declutter: false, - visible: visible, - style: function(feature, resolution) { - const style = styles[k + '.' + feature.getProperties().layer]; - if (!Array.isArray(style)) { - return style; - } else { - const maxi = style.length - 1; - const z = 10 /* Math.log2(maxResolution) */ - Math.log2(resolution); - /* use Math.floor() as VectorTile.js calls getZForResolution(resolution, 1) */ - const i = z <= 0 ? 0 : z >= maxi ? maxi : Math.floor(z); - // console.log(`resolution=${resolution}, z=${z}, i=${i}`); - return style[i]; - } - } - }); - lyr.set('layerGroup', k, true); - } - map.addLayer(lyr); - return [k, lyr]; - })), + ret, /* We use a vector tile layer for featureOverlayLayer instead of a simple * vector layer overlay, since we don't want to clip selected geometries at |