aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2025-06-07 23:41:44 +0200
committerGuilhem Moulin <guilhem@fripost.org>2025-06-08 15:14:57 +0200
commitce8488b488ac218cb5b9fcf72873dc7b3d836531 (patch)
tree3682e53867dc8c4c9de9437b730440a9950ae6f0
parent1fcf00277a18c5231a2c3475071ba644373f1f76 (diff)
Add a dynamic legend.
(Long overdue…)
-rw-r--r--main.js244
-rw-r--r--style.css51
2 files changed, 274 insertions, 21 deletions
diff --git a/main.js b/main.js
index b32ed02..661a17e 100644
--- a/main.js
+++ b/main.js
@@ -39,6 +39,11 @@ import { createXYZ } from 'ol/tilegrid.js';
import VectorLayer from 'ol/layer/Vector.js';
import VectorSource from 'ol/source/Vector.js';
+import { toContext } from 'ol/render.js';
+import Polygon from 'ol/geom/Polygon.js';
+import LineString from 'ol/geom/LineString.js';
+import Point from 'ol/geom/Point.js';
+
import CircleStyle from 'ol/style/Circle.js';
import Fill from 'ol/style/Fill.js';
import Icon from 'ol/style/Icon.js';
@@ -733,6 +738,7 @@ const layers = {
//['Kommun', 'Municipality'],
//['Län', 'County'],
],
+ legend: { zoomLevel: 4 },
style: [0, .1, .5, .5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 22,
@@ -758,6 +764,7 @@ const layers = {
//['Kommun', 'Municipality'],
//['Län', 'County'],
],
+ legend: { zoomLevel: 4 },
style: [0, .1, .5, .5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 25,
@@ -788,6 +795,7 @@ const layers = {
//['Kommun', 'Municipality'],
//['Län', 'County'],
],
+ legend: { zoomLevel: 4 },
style: [0, .1, .5, .5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 24,
@@ -813,6 +821,7 @@ const layers = {
//['Kommun', 'Municipality'],
//['Län', 'County'],
],
+ legend: { zoomLevel: 4 },
style: [0, .1, .5, .5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 26,
@@ -843,6 +852,7 @@ const layers = {
//['Kommun', 'Municipality'],
//['Län', 'County'],
],
+ legend: { zoomLevel: 4 },
style: [0, .1, .5, .5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 24,
@@ -868,6 +878,7 @@ const layers = {
//['Kommun', 'Municipality'],
//['Län', 'County'],
],
+ legend: { zoomLevel: 4 },
style: [0, .1, .5, .5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 26,
@@ -895,6 +906,7 @@ const layers = {
//['Kommun', 'Municipality'],
//['Län', 'County'],
],
+ legend: { zoomLevel: 4 },
style: [0, .1, .5, .5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 20,
@@ -916,6 +928,7 @@ const layers = {
['Spänning', 'Voltage', { unit: 'kV' }],
['Ledlängd', 'geom_length', { fn: 'length' }],
],
+ legend: { zoomLevel: 5, type: 'linestring', reuse_canvas: true },
style: [1, 1.5, 2, 2, 2, 2, 3, 4, 5, 6, 8, 10].map(function(width) {
return new Style({
zIndex: 52,
@@ -927,6 +940,7 @@ const layers = {
}),
},
'svk.stolpar': {
+ legend: { zoomLevel: 5, type: 'point' },
style: [undefined, undefined, undefined, undefined, undefined]
.concat([3, 4, 5, 6, 8, 10, 15].map(function(radius) {
return new Style({
@@ -955,6 +969,7 @@ const layers = {
return a;
}}],
],
+ legend: { zoomLevel: 5, type: 'linestring' },
style: [1, 1.5, 2, 2, 2, 2, 3, 4, 5, 6, 8, 10].map(function(width) {
return new Style({
zIndex: 53,
@@ -967,6 +982,7 @@ const layers = {
}),
},
'svk.stationer': {
+ legend: { zoomLevel: 3, type: 'point' },
style: [3, 4, 5, 6, 7, 8.5, 10].map(function(radius) {
return new Style({
zIndex: 50,
@@ -1014,6 +1030,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Senast uppdaterat', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 1 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 10,
@@ -1046,6 +1063,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Senast uppdaterat', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 1 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 10,
@@ -1085,6 +1103,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Senast uppdaterat', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 1 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 17,
@@ -1129,6 +1148,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Senast uppdaterat', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 1 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 16,
@@ -1168,6 +1188,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Senast uppdaterat', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -1220,6 +1241,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Senast uppdaterat', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 1 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 11,
@@ -1262,6 +1284,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Senast uppdaterat', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 1 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 15,
@@ -1300,6 +1323,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Senast uppdaterat', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 1 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 14,
@@ -1337,6 +1361,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Senast uppdaterat', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 1 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 13,
@@ -1373,6 +1398,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Senast uppdaterat', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 1 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -1438,6 +1464,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Senast uppdaterat', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 1 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 10,
@@ -1476,6 +1503,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 7, type: 'point' },
style: [undefined, undefined, undefined, undefined, .125, .125, .25, .5, 1, 2, 4, 8].map(function(scale) {
return scale === undefined ? undefined : new Style({
zIndex: 99,
@@ -1510,6 +1538,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 7, type: 'point' },
style: [undefined, undefined, undefined, undefined, .125, .125, .25, .5, 1, 2, 4, 8].map(function(scale) {
return scale === undefined ? undefined : new Style({
zIndex: 99,
@@ -1545,6 +1574,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 7, type: 'point' },
style: [undefined, undefined, undefined, undefined, .125, .125, .25, .5, 1, 2, 4, 8].map(function(scale) {
return scale === undefined ? undefined : new Style({
zIndex: 99,
@@ -1580,6 +1610,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 7, type: 'point' },
style: [undefined, undefined, undefined, undefined, .125, .125, .25, .5, 1, 2, 4, 8].map(function(scale) {
return scale === undefined ? undefined : new Style({
zIndex: 99,
@@ -1615,6 +1646,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 7, type: 'point' },
style: [undefined, undefined, undefined, undefined, .125, .125, .25, .5, 1, 2, 4, 8].map(function(scale) {
return scale === undefined ? undefined : new Style({
zIndex: 99,
@@ -1650,6 +1682,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 7, type: 'point' },
style: [undefined, undefined, undefined, undefined, .125, .125, .25, .5, 1, 2, 4, 8].map(function(scale) {
return scale === undefined ? undefined : new Style({
zIndex: 99,
@@ -1684,6 +1717,7 @@ const layers = {
['Elområde', 'ElNamn'],
['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'],
],
+ legend: { zoomLevel: 7, type: 'point' },
style: [undefined, undefined, undefined, undefined, .125, .125, .25, .5, 1, 2, 4, 8].map(function(scale) {
return scale === undefined ? undefined : new Style({
zIndex: 99,
@@ -1716,6 +1750,7 @@ const layers = {
//['Län', 'Lan'],
['Areal för ytan', 'geom_area', { fn: 'area' }],
],
+ legend: { zoomLevel: 7 },
style: [0, 0, 0, 0, 0, .5, .75, 1, 1, 1, 1, 1].map(function(width, z) {
return new Style({
zIndex: 10,
@@ -1750,6 +1785,7 @@ const layers = {
['Ärendestatus', 'ArendeStatus'],
['Avverkad areal', 'AvvHa', { unit: 'ha' }],
],
+ legend: { zoomLevel: 7 },
style: [0, 0, 0, 0, 0, .5, .75, 1, 1, 1, 1, 1].map(function(width, z) {
return new Style({
zIndex: 10,
@@ -1804,6 +1840,7 @@ const layers = {
['Beskrivning', 'BESKRIVN'],
['Areal', 'geom_area', { fn: 'area' }],
],
+ legend: { zoomLevel: 2 },
style: [1, 1.5, 2, 3, 3.5, 4, 5, 5, 6, 7, 8, 10].map(function(width, z) {
return new Style({
zIndex: 23,
@@ -1839,6 +1876,7 @@ const layers = {
['Areal vatten', 'VATTEN_HA', { unit: 'ha' }],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 1 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -1892,6 +1930,7 @@ const layers = {
['Areal vatten', 'VATTEN_HA', { unit: 'ha' }],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 1 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -1945,6 +1984,7 @@ const layers = {
['Areal vatten', 'VATTEN_HA', { unit: 'ha' }],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -1998,6 +2038,7 @@ const layers = {
['Areal vatten', 'VATTEN_HA', { unit: 'ha' }],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2051,6 +2092,7 @@ const layers = {
['Areal vatten', 'VATTEN_HA', { unit: 'ha' }],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2104,6 +2146,7 @@ const layers = {
['Areal vatten', 'VATTEN_HA', { unit: 'ha' }],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2157,6 +2200,7 @@ const layers = {
['Areal vatten', 'VATTEN_HA', { unit: 'ha' }],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2210,6 +2254,7 @@ const layers = {
['Areal vatten', 'VATTEN_HA', { unit: 'ha' }],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2263,6 +2308,7 @@ const layers = {
return a;
}}],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2316,6 +2362,7 @@ const layers = {
['Areal vatten', 'VATTEN_HA', { unit: 'ha' }],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2369,6 +2416,7 @@ const layers = {
['Areal vatten', 'VATTEN_HA', { unit: 'ha' }],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2419,6 +2467,7 @@ const layers = {
['Beslutsmyndighet', 'BESLMYND'],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 6, type: 'point' },
style: [undefined, undefined, undefined, undefined].concat([3, 4, 6, 8, 12, 16, 20, 24].map(function(width, z) {
return new Style({
zIndex: 12,
@@ -2455,6 +2504,7 @@ const layers = {
['Areal vatten', 'VATTEN_HA', { unit: 'ha' }],
['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2514,6 +2564,7 @@ const layers = {
return a;
}}],
],
+ legend: { zoomLevel: 1 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2581,6 +2632,7 @@ const layers = {
return a;
}}],
],
+ legend: { zoomLevel: 1 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2628,6 +2680,7 @@ const layers = {
['Namn', 'NAME'],
['Areal', 'geom_area', { fn: 'area' }],
],
+ legend: { zoomLevel: 1 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2679,6 +2732,7 @@ const layers = {
return a;
}}],
],
+ legend: { zoomLevel: 1 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2714,6 +2768,7 @@ const layers = {
['N2000-ID', 'N2000_SITE', { classes: ['feature-objid'] }],
['Areal', 'geom_area', { fn: 'area' }],
],
+ legend: { zoomLevel: 1 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2745,6 +2800,7 @@ const layers = {
['Namn', 'NAMN'],
['Areal', 'geom_area', { fn: 'area' }],
],
+ legend: { zoomLevel: 1 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2789,6 +2845,7 @@ const layers = {
}}],
['Areal', 'geom_area', { fn: 'area' }],
],
+ legend: { zoomLevel: 1 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2826,6 +2883,7 @@ const layers = {
['Satus', 'STATUS'],
['Areal', 'geom_area', { fn: 'area' }],
],
+ legend: { zoomLevel: 1 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2880,6 +2938,7 @@ const layers = {
}}],
['Undertyp', 'Undertyp'],
],
+ legend: { zoomLevel: 2 },
style: [4, 8, 16, 16, 32, 32, 64, 64, 64, 128, 128, 128].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -2933,6 +2992,7 @@ const layers = {
return a;
}}],
],
+ legend: { zoomLevel: 0 },
style: [0, 1, 2, 3, 4, 5, 6].map(function(width) {
return new Style({
zIndex: 5,
@@ -3004,6 +3064,7 @@ const layers = {
return a;
}}],
],
+ legend: { zoomLevel: 0 },
style: [0, 1, 2, 3, 4, 5].map(function(width) {
return new Style({
zIndex: 6,
@@ -3080,6 +3141,7 @@ const layers = {
return a;
}}],
],
+ legend: { zoomLevel: 0 },
style: [0, 1, 2, 3, 4, 5].map(function(width) {
return new Style({
zIndex: 6,
@@ -3144,6 +3206,7 @@ const layers = {
return a;
}}],
],
+ legend: { zoomLevel: 0 },
style: [0, 1, 2, 3, 4, 5].map(function(width) {
return new Style({
zIndex: 6,
@@ -3224,11 +3287,12 @@ const layers = {
return a;
}}],
],
+ legend: { zoomLevel: 5 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
const w = Math.max(1, width);
- patternCanvas.width = 8;
+ patternCanvas.width = z < 2 ? 2 : z < 4 ? 4 : z <= 5 ? 6 : 8;
patternCanvas.height = patternCanvas.width;
patternContext.fillStyle = 'transparent';
patternContext.strokeStyle = 'rgba(158, 200, 215, 1)';
@@ -3259,6 +3323,7 @@ const layers = {
['Senast justerat', 'GRANSJUST'], /* XXX unclear what "GRANSJUST" means, just a guess */
['Areal', 'geom_area', { fn: 'area' }],
],
+ legend: { zoomLevel: 1 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -3316,6 +3381,7 @@ const layers = {
['Länsstyrelsens bedömning', 'LST_BEDOMN'],
['Källor', 'KALLOR'],
],
+ legend: { zoomLevel: 1 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
return new Style({
zIndex: 4,
@@ -3354,6 +3420,7 @@ const layers = {
['Riks-ID', 'RIKSID', { classes: ['feature-objid'] }],
['Areal', 'geom_area', { fn: 'area' }],
],
+ legend: { zoomLevel: 0 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -3421,6 +3488,7 @@ const layers = {
['Areal land', 'AREA_LAND_', { unit: 'ha' }],
['Areal vatten', 'AREA_VATTE', { unit: 'ha' }],
],
+ legend: { zoomLevel: 0 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -3479,6 +3547,7 @@ const layers = {
['Areal', 'geom_area', { fn: 'area' }],
['Referens', 'REFERENS'],
],
+ legend: { zoomLevel: 0 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -3540,6 +3609,7 @@ const layers = {
['Areal', 'geom_area', { fn: 'area' }],
['Referens', 'REFERENS'],
],
+ legend: { zoomLevel: 0 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -3599,6 +3669,7 @@ const layers = {
['Areal', 'geom_area', { fn: 'area' }],
['Referens', 'REFERENS'],
],
+ legend: { zoomLevel: 0 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -3660,6 +3731,7 @@ const layers = {
['Areal', 'geom_area', { fn: 'area' }],
['Referens', 'REFERENS'],
],
+ legend: { zoomLevel: 0 },
style: [8, 16, 32, 32, 64, 64, 128, 128, 128, 256, 256, 256].map(function(width, z) {
return new Style({
zIndex: 8,
@@ -3683,6 +3755,7 @@ const layers = {
['Signatur', 'SIGNATUR'],
['Aktualitet', 'AKTUALITET'],
],
+ legend: { zoomLevel: 0 },
style: [1, 1.5, 2, 3, 3.5, 4, 5, 5, 6, 7, 8, 10].map(function(width, z) {
return new Style({
zIndex: 4,
@@ -3713,6 +3786,7 @@ const layers = {
['Signatur', 'SIGNATUR'],
['Ledlängd', 'geom_length', { fn: 'length' }],
],
+ legend: { zoomLevel: 2, type: 'linestring' },
style: [.75, 1, 1.5, 2, 3, 4, 5, 5, 6, 7, 8, 10].map(function(width, z) {
return new Style({
zIndex: 7,
@@ -3732,6 +3806,7 @@ const layers = {
['Signatur', 'SIGNATUR'],
['Areal', 'geom_area', { fn: 'area' }],
],
+ legend: { zoomLevel: 1 },
style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width, z) {
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
@@ -3771,6 +3846,7 @@ const layers = {
['Signatur', 'SIGNATUR'],
['Areal', 'geom_area', { fn: 'area' }],
],
+ legend: { zoomLevel: 2 },
style: [.5, .5, 1, 1, 1, 1.5, 1.5, 1.5, 2, 2, 2, 2].map(function(width, z) {
return new Style({
zIndex: 5,
@@ -3829,6 +3905,7 @@ const layers = {
['Reglerbar volym', 'RV', { unit: 'Mm³' }],
['Kommentar', 'Kommentar'],
],
+ legend: { zoomLevel: 5, type: 'point' },
style: [2, 3, 4, 4, 4, 6, 8, 8, 8, 10, 16, 32].map(function(width) {
return new Style({
zIndex: 59,
@@ -3860,6 +3937,7 @@ const layers = {
return a;
}}],
],
+ legend: { zoomLevel: 1, type: 'point' },
style: [4, 6, 7, 8, 10, 12].map(function(width) {
return new Style({
zIndex: 60,
@@ -3901,7 +3979,7 @@ const layerHierarchy = [
children: [
{
text: 'Kraftledningar (befintliga)',
- layer: ['svk.ledningar', 'svk.stolpar'],
+ layer: ['svk.stolpar', 'svk.ledningar'],
},
{
text: 'Stationer',
@@ -4411,6 +4489,133 @@ const [mapLayers, featureOverlayLayer] = (function() {
})();
+/* legend panel */
+(function() {
+ const modal = document.getElementById('map-legend-panel');
+ modal.classList.add('modal');
+ modal.setAttribute('role', 'dialog');
+ modal.setAttribute('aria-hidden', 'true');
+
+ const content = document.createElement('div');
+ modal.appendChild(content);
+ content.classList.add('modal-content');
+
+ const body = document.createElement('div');
+ content.appendChild(body);
+ body.classList.add('modal-body');
+
+ const createLegend = function(ul, elem, classes) {
+ const li = document.createElement('li');
+ li.classList.add('list-group-item');
+ ul.append(li);
+
+ const t = document.createTextNode(elem.text);
+ if (elem.layer === undefined) {
+ li.appendChild(t);
+ li.classList.add('map-legend-header');
+ } else {
+ li.classList.add('d-flex', 'flex-row');
+ const div = document.createElement('div');
+ div.classList.add('map-legend-symbol');
+ li.appendChild(div);
+ const parent_height = 24; /* see CSS */
+ const [width, height] = [32, 20];
+ const symbols = {
+ polygon: new Polygon([[
+ [0, (parent_height-height)/2],
+ [width, (parent_height-height)/2],
+ [width, (parent_height+height)/2],
+ [0, (parent_height+height)/2],
+ [0, (parent_height-height)/2],
+ ]]),
+ linestring: new LineString([
+ [0, parent_height/2],
+ [width, parent_height/2]
+ ]),
+ point: new Point(
+ [width/2, parent_height/2]
+ ),
+ };
+ let canvas = null, render = null;
+ (Array.isArray(elem.layer) ? elem.layer : [elem.layer])
+ .forEach(function(layer) {
+ /* add symbols for each layer */
+ const layerGroup = layer.split('.', 1)[0];
+ if (!layerGroup || !mapLayers[layerGroup] || !layers[layer] || !layers[layer].style) {
+ console.log(`Could not find symbol for layer ${layer}, skipping`);
+ return;
+ }
+ const legend = layers[layer].legend || {};
+ if (canvas === null || !legend.reuse_canvas) {
+ canvas = document.createElement('canvas');
+ div.appendChild(canvas);
+ render = toContext(canvas.getContext('2d'),
+ { size:[width, parent_height] }
+ );
+ }
+
+ if (mapLayers[layerGroup].getSource() instanceof GeoTIFF) {
+ /* raster source */
+ render.setFillStrokeStyle(new Fill({
+ color: layers[layer].style,
+ }));
+ return render.drawGeometry(symbols.polygon);
+ }
+ else if (mapLayers[layerGroup].getSource() instanceof VectorTile) {
+ /* vector source */
+ const style = Array.isArray(layers[layer].style) ?
+ layers[layer].style[legend.zoomLevel ?? 5] :
+ layers[layer].style;
+ const legend_type = legend.type ?? 'polygon';
+ if (legend_type === 'point' && style.getImage(1) instanceof Icon && style.getImage(1).getSrc()) {
+ /* use a new <img> element since .setStyle() returns the same one and doesn't work in that case */
+ const div2 = document.createElement('div');
+ const img = document.createElement('img');
+ div2.appendChild(img);
+ img.src = style.getImage(1).getSrc();
+ img.height = height;
+ div.replaceChild(div2, canvas);
+ } else {
+ const style2 = style.clone();
+ const stroke = style2.getStroke();
+ if (legend_type === 'polygon' && stroke && stroke.getWidth() > 1) {
+ /* don't stroke too wide to avoid spilling over boxes above/below */
+ stroke.setWidth(1);
+ }
+ render.setStyle(style2);
+ return render.drawGeometry(symbols[legend_type]);
+ }
+ }
+ else {
+ throw new Error(`Cannot show legend for ${layer}`);
+ }
+ });
+ const span = document.createElement('div');
+ span.appendChild(t);
+ li.appendChild(span);
+ }
+
+ elem._legend = li;
+ if (elem.children !== undefined && elem.children.length > 0) {
+ if (classes.length > 0) {
+ li.classList.add(classes[0]);
+ classes = classes.slice(1);
+ }
+ const ul2 = document.createElement('ul');
+ ul2.classList.add('list-group', 'list-group-flush');
+ ul.appendChild(ul2);
+ elem.children.forEach((elem2) => createLegend(ul2, elem2, classes));
+ }
+ };
+
+ const ul = document.createElement('ul');
+ ul.classList.add('list-group', 'list-group-flush');
+ body.appendChild(ul);
+ layerHierarchy.forEach(function(x) {
+ createLegend(ul, x, ['h4', 'h5', 'h6']);
+ });
+})();
+
/* layer selection panel */
const infoMetadataAccordions = [];
(function() {
@@ -4451,9 +4656,17 @@ const infoMetadataAccordions = [];
const layerStyles = elem._layers.map((lyr) => styles[lyr] !== undefined);
elem._input.indeterminate = elem._layers.length <= 1 ? false
: layerStyles.slice(1).some((v) => v !== layerStyles[0]);
- if (!elem._input.indeterminate) {
+ if (elem._input.indeterminate) {
+ elem._legend.classList.remove('d-none');
+ } else {
/* keep checked value if indeterminate */
- elem._input.checked = layerStyles.every((v) => v);
+ const checked = layerStyles.every((v) => v);
+ elem._input.checked = checked;
+ if (checked) {
+ elem._legend.classList.remove('d-none');
+ } else {
+ elem._legend.classList.add('d-none');
+ }
}
if (elem.children !== undefined && elem.children.length > 0) {
setIndeterminateAndChecked(elem.children);
@@ -4488,6 +4701,12 @@ const infoMetadataAccordions = [];
v.setVisible(visible);
}
});
+ const btn = document.getElementById('map-legend-button');
+ if (Object.values(styles).some((v) => v !== null)) {
+ btn.classList.remove('disabled');
+ } else {
+ btn.classList.add('disabled');
+ }
};
const onClickFunction = function(layerList, event) {
featureOverlayLayer.setVisible(false);
@@ -4710,23 +4929,6 @@ const infoMetadataAccordions = [];
})();
})();
-/* legend panel */
-(function() {
- const modal = document.getElementById('map-legend-panel');
- modal.classList.add('modal');
- modal.setAttribute('role', 'dialog');
- modal.setAttribute('aria-hidden', 'true');
-
- const content = document.createElement('div');
- modal.appendChild(content);
- content.classList.add('modal-content');
-
- const body = document.createElement('div');
- content.appendChild(body);
- body.classList.add('modal-body');
- body.innerHTML = 'legend TODO';
-})();
-
/* popup and feature overlays */
(function() {
const popupOverlay = new Overlay({
diff --git a/style.css b/style.css
index 3569e6e..c5b527c 100644
--- a/style.css
+++ b/style.css
@@ -222,6 +222,11 @@ body.inprogress {
opacity: 1;
}
}
+#map-legend-panel .modal-body {
+ -webkit-user-select: text;
+ -moz-user-select: text;
+ user-select: text;
+}
#layer-selection-panel[aria-hidden="false"],
#map-legend-panel[aria-hidden="false"] {
animation: fade-in .25s ease-in-out both;
@@ -250,6 +255,10 @@ body.inprogress {
}
}
+#map-legend-button.disabled button {
+ color: rgb(from var(--bs-btn-color) r g b / calc(alpha*.25));
+ pointer-events: none;
+}
@media screen and (max-width: 200px) {
#layer-selection-button,
#map-legend-button,
@@ -397,6 +406,48 @@ body.inprogress {
#layer-selection-panel .accordion-item .form-check > .form-check-label {
display: inline;
}
+#map-legend-panel .list-group-flush > .list-group-item {
+ border: none;
+ padding: 0;
+}
+#map-legend-panel .modal-body > ul.list-group > li.list-group-item:not(.d-none) ~ li.list-group-item:not(.d-none) {
+ border-top: var(--bs-list-group-border-width) solid var(--bs-list-group-border-color);
+ margin-top: .5rem;
+ padding-top: .5rem;
+}
+#map-legend-panel .list-group .list-group-item.h4,
+#map-legend-panel .list-group .list-group-item.h5,
+#map-legend-panel .list-group .list-group-item.h6 {
+ margin: 0 0 .25rem 0;
+}
+#map-legend-panel .list-group .list-group-item:not(.d-none) ~ .list-group-item.h5:not(.d-none) {
+ margin-top: .125rem;
+}
+#map-legend-panel .list-group .list-group-item.h4 {
+ font-size: 1.3rem;
+}
+#map-legend-panel .list-group .list-group-item.h5 {
+ font-size: 1.05rem;
+}
+#map-legend-panel .list-group .list-group-item.h6 {
+ font-size: 1rem;
+}
+#map-legend-panel .list-group .list-group-item .map-legend-symbol {
+ /* 24px */
+ height: calc(var(--bs-body-line-height) * var(--bs-body-font-size)) !important;
+}
+#map-legend-panel .list-group .list-group-item .map-legend-symbol > * {
+ width: 32px;
+ margin-right: .5rem;
+}
+#map-legend-panel .list-group .list-group-item .map-legend-symbol img {
+ margin-left: auto;
+ margin-right: auto;
+ display: block;
+}
+#map-legend-panel .list-group .list-group-item:not(.h4,.h5,.h6):hover {
+ background-color: var(--bs-list-group-action-hover-bg);
+}
.popover {
--bs-popover-header-padding-x: .75rem;