aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2025-06-07 19:02:37 +0200
committerGuilhem Moulin <guilhem@fripost.org>2025-06-07 22:57:11 +0200
commit2f933a5a891adddef9a095ce33ab17bfab2e284d (patch)
tree0d845c4dc50ffe27bce335a981370c4bf856c95c
parent8d03e7794dae3696b0a975477542a4db03136ab7 (diff)
JS: Refactor layer creation.
-rw-r--r--main.js134
1 files changed, 68 insertions, 66 deletions
diff --git a/main.js b/main.js
index 111f1be..16171d7 100644
--- a/main.js
+++ b/main.js
@@ -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