aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2025-06-14 22:12:57 +0200
committerGuilhem Moulin <guilhem@fripost.org>2025-06-15 18:34:05 +0200
commitfd662f3d3fac0f8b11e8e883409b1828cbfca3bd (patch)
tree3f5b8b1760f8483f5ba1e4714debeee79e52d09b /src
parent0fc7bdd8bf374c36fa0ba27702d1fafed09277ac (diff)
Undo splitting out to multiple files.
The reason is that we want the different modules to produce side-effects (to avoid creating functions and keeping references to it) and we therefore need to control the order in which they are inlined during `vite build`. Unfortunately this doesn't seem to be possible right now, cf. https://github.com/storybookjs/storybook/issues/30768 . This reverts commits 670bba058d83620abdb3e8db5fd4ea89dba08142, 05a018f27aba3a20fd581cb88daa8afbbd3407de and 0fc7bdd8bf374c36fa0ba27702d1fafed09277ac.
Diffstat (limited to 'src')
-rw-r--r--src/layers.js1908
-rw-r--r--src/map.js103
-rw-r--r--src/popover.js1348
-rw-r--r--src/style.css650
4 files changed, 0 insertions, 4009 deletions
diff --git a/src/layers.js b/src/layers.js
deleted file mode 100644
index 688bb44..0000000
--- a/src/layers.js
+++ /dev/null
@@ -1,1908 +0,0 @@
-/***********************************************************************
- * Copyright © 2024-2025 Guilhem Moulin <info@guilhem.se>
- * Vector and raster layer definitions
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- **********************************************************************/
-
-import CircleStyle from 'ol/style/Circle.js';
-import Fill from 'ol/style/Fill.js';
-import Icon from 'ol/style/Icon.js';
-import RegularShape from 'ol/style/RegularShape.js';
-import Stroke from 'ol/style/Stroke.js';
-import Style from 'ol/style/Style.js';
-
-/* TODO: this should really be refactored… */
-export const layers = {
- 'mrr.appr_ec': {
- 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,
- fill: new Fill({
- color: [247, 170, 67, Math.max((.2-1)/8 * z + 1, 0)],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [151, 173, 23, 1],
- }),
- });
- }),
- },
- 'mrr.appl_ec': {
- 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,
- fill: new Fill({
- color: [247, 170, 67, Math.max((.2-1)/8 * z + 1, 0)],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [197, 14, 31, 1],
- lineDash: width >= 1.5 ? [2 * width] : undefined,
- }),
- });
- }),
- },
- 'mrr.appr_met': {
- 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,
- fill: new Fill({
- color: [0, 0, 0, Math.max((.2-.4)/4 * z + .4, 0)],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [151, 173, 23, 1],
- }),
- });
- }),
- },
- 'mrr.appl_met': {
- 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,
- fill: new Fill({
- color: [0, 0, 0, Math.max((.2-.4)/4 * z + .4, 0)],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [197, 14, 31, 1],
- lineDash: width >= 1.5 ? [2 * width] : undefined,
- }),
- });
- }),
- },
- 'mrr.appr_ogd': {
- 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,
- fill: new Fill({
- color: [30, 55, 87, Math.max((.2-.4)/4 * z + .4, 0)],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [151, 173, 23, 1],
- }),
- });
- }),
- },
- 'mrr.appl_ogd': {
- 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,
- fill: new Fill({
- color: [30, 55, 87, Math.max((.2-.4)/4 * z + .4, 0)],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [197, 14, 31, 1],
- lineDash: width >= 1.5 ? [2 * width] : undefined,
- }),
- });
- }),
- },
- 'mrr.appr_dl': {
- 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,
- fill: new Fill({
- color: [228, 53, 45, Math.max((.2-1)/6 * z + 1, 0)],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [151, 173, 23, 1],
- }),
- });
- }),
- },
-
- 'svk.ledningar': {
- 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,
- stroke: new Stroke({
- color: 'black',
- width: width,
- }),
- });
- }),
- },
- '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({
- zIndex: 51,
- image: new CircleStyle({
- radius: radius,
- fill: new Fill({
- color: 'black',
- }),
- }),
- });
- })),
- },
- 'svk.transmissionsnatsprojekt': {
- 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,
- stroke: new Stroke({
- color: 'black',
- width: width,
- lineDash: [4 * width],
- }),
- });
- }),
- },
- 'svk.stationer': {
- legend: { zoomLevel: 3, type: 'point' },
- style: [3, 4, 5, 6, 7, 8.5, 10].map(function(radius) {
- return new Style({
- zIndex: 50,
- image: new RegularShape({
- radius: radius,
- points: 4,
- angle: Math.PI/4,
- fill: new Fill({
- color: 'black',
- }),
- }),
- });
- })
- .concat([.5, 1, 1.5, 2, 2].map(function(width) {
- return new Style({
- zIndex: 50,
- fill: new Fill({
- color: 'rgba(128, 128, 128, .7)',
- }),
- stroke: new Stroke({
- width: width,
- color: 'rgb(0, 0, 0)',
- }),
- });
- })),
- },
-
- 'vbk.area_current': {
- 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,
- fill: new Fill({
- color: [168, 198, 223, Math.max((.2-1)/8 * z + 1, 0)],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [56, 96, 130, 1],
- }),
- });
- }),
- },
- 'vbk.area_notcurrent': {
- 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,
- fill: new Fill({
- color: [222, 163, 199, Math.max((.2-1)/8 * z + 1, 0)],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [148, 55, 112, 1],
- lineDash: width >= 1.5 ? [2 * width] : undefined,
- }),
- });
- }),
- },
- 'vbk.offshore_completed': {
- legend: { zoomLevel: 1 },
- style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width) {
- return new Style({
- zIndex: 17,
- fill: new Fill({
- color: [38, 107, 29, .5],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [38, 107, 29, 1],
- }),
- });
- }),
- },
- 'vbk.offshore_approved': {
- legend: { zoomLevel: 1 },
- style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width) {
- return new Style({
- zIndex: 16,
- fill: new Fill({
- color: [56, 160, 44, .5],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [56, 160, 44, 1],
- }),
- });
- }),
- },
- 'vbk.offshore_amended': {
- 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');
- const w = z < 4 ? .5 : z <= 5 ? 1.5 : 4;
- patternCanvas.width = width/2;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'rgba(247, 105, 162, 1)';
- patternContext.beginPath();
- patternContext.arc(.75*patternCanvas.width, .75*patternCanvas.height, 1.5*w, 0, 2*Math.PI, true)
- patternContext.fill();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 17,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: 2*w,
- color: [247, 105, 162, 1],
- lineDash: [8 * w],
- }),
- });
- }),
- },
- 'vbk.offshore_rejected': {
- legend: { zoomLevel: 1 },
- style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width) {
- return new Style({
- zIndex: 11,
- fill: new Fill({
- color: [227, 26, 28, .5],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [227, 26, 28, 1],
- }),
- });
- }),
- },
- 'vbk.offshore_appealed': {
- legend: { zoomLevel: 1 },
- style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width) {
- return new Style({
- zIndex: 15,
- fill: new Fill({
- color: [177, 88, 40, .5],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [177, 88, 40, 1],
- }),
- });
- }),
- },
- 'vbk.offshore_applied': {
- legend: { zoomLevel: 1 },
- style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width) {
- return new Style({
- zIndex: 14,
- fill: new Fill({
- color: [255, 127, 0, .5],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [255, 128, 0, 1],
- }),
- });
- }),
- },
- 'vbk.offshore_consultation': {
- legend: { zoomLevel: 1 },
- style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width) {
- return new Style({
- zIndex: 13,
- fill: new Fill({
- color: [254, 217, 118, .65],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [254, 183, 82, 1],
- }),
- });
- }),
- },
- 'vbk.offshore_investigation': {
- 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');
- const w = z < 4 ? .5 : z <= 5 ? 1.5 : 4;
- patternCanvas.width = width*2;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(68, 90, 166, 1)';
- patternContext.lineWidth = w;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 12,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: 2*w,
- color: [68, 90, 166, 1],
- lineDash: [8 * w],
- }),
- });
- }),
- },
- 'vbk.offshore_revoked': {
- legend: { zoomLevel: 1 },
- style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width) {
- return new Style({
- zIndex: 10,
- fill: new Fill({
- color: [105, 61, 154, .5],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [105, 62, 153, 1],
- }),
- });
- }),
- },
- 'vbk.station_completed': {
- 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,
- image: new Icon({
- src: '/assets/icons/wind-turbine-completed.svg',
- declutter: 'none',
- scale: scale,
- }),
- });
- }),
- },
- 'vbk.station_processed': {
- 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,
- image: new Icon({
- src: '/assets/icons/wind-turbine-processed.svg',
- declutter: 'none',
- scale: scale,
- }),
- });
- }),
- },
- 'vbk.station_approved': {
- 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,
- image: new Icon({
- src: '/assets/icons/wind-turbine-approved.svg',
- declutter: 'none',
- scale: scale,
- }),
- });
- }),
- },
- 'vbk.station_revoked': {
- 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,
- image: new Icon({
- src: '/assets/icons/wind-turbine-revoked.svg',
- declutter: 'none',
- scale: scale,
- }),
- });
- }),
- },
- 'vbk.station_rejected': {
- 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,
- image: new Icon({
- src: '/assets/icons/wind-turbine-rejected.svg',
- declutter: 'none',
- scale: scale,
- }),
- });
- }),
- },
- 'vbk.station_dismounted': {
- 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,
- image: new Icon({
- src: '/assets/icons/wind-turbine-dismounted.svg',
- declutter: 'none',
- scale: scale,
- }),
- });
- }),
- },
- 'vbk.station_appealed': {
- 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,
- image: new Icon({
- src: '/assets/icons/wind-turbine-appealed.svg',
- declutter: 'none',
- scale: scale,
- }),
- });
- }),
- },
-
- /* Documentation at
- * https://www.skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/utforda-avverkningar---produktbeskrivning.pdf
- * */
- 'avverk.utford': {
- 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,
- fill: new Fill({
- color: [255, 102, 102, Math.max((.2-1)/8 * z + 1, 0)],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [204, 0, 0, 1],
- }),
- });
- }),
- },
- /* Documentation at
- * https://www.skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/yttre-granser-for-avverkningsanmalda-omraden---produktbeskrivning.pdf
- * */
- 'avverk.anmald': {
- 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,
- fill: (width === undefined || width === 0) ?
- new Fill({ color: [255, 102, 102, Math.max((.2-1)/8 * z + 1, 0)*.75] }) :
- (function() {
- const patternCanvas = document.createElement('canvas');
- const patternContext = patternCanvas.getContext('2d');
- const slope = 45 * Math.PI/180;
- const spacing = z < 10 ? z*2 : 40;
- const len = Math.hypot(1, slope);
- const w = patternCanvas.width = Math.round(1/len + spacing)
- const h = patternCanvas.height = Math.round(slope/len + spacing * slope);
-
- patternContext.fillStyle = 'rgba(255, 102, 102, .1)';
- patternContext.fillRect(0, 0, patternCanvas.width, patternCanvas.height);
- patternContext.strokeStyle = 'rgba(204, 0, 0, 1)';
- patternContext.lineWidth = Math.max(1, width/2);
- patternContext.beginPath();
- patternContext.moveTo(0, h);
- patternContext.lineTo(w, 0);
- patternContext.moveTo(-w, h);
- patternContext.lineTo(w, -h);
- patternContext.moveTo(0, 2*h);
- patternContext.lineTo(2*w, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Fill({ color: context.createPattern(patternCanvas, 'repeat') });
- })(),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [204, 0, 0, 1],
- lineDash: width >= 1.5 ? [2 * width] : undefined,
- }),
- });
- }),
- },
-
- 'skydd.tilltradesforbud': {
- legend: { zoomLevel: 2 },
- style: [1, 1.5, 2, 3, 3.5, 4, 5, 5, 6, 7, 8, 10].map(function(width) {
- return new Style({
- zIndex: 23,
- fill: new Fill({
- /* transparent fill so clicking the inside of the polygon triggers a popover */
- /* XXX could also use a custom renderer but that doesn't seem to work */
- color: [0, 0, 0, 0],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [255, 0, 0, 1],
- }),
- });
- }),
- },
- 'skydd.nationalpark': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(0, 55, 0, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 22,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [0, 55, 0, 1],
- }),
- });
- }),
- },
- 'skydd.naturreservat': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(7, 181, 7, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 21,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [7, 181, 7, 1],
- }),
- });
- }),
- },
- 'skydd.naturreservat_kommunalt': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(7, 181, 7, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, 0);
- patternContext.lineTo(patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, -patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, 0);
- patternContext.lineTo(patternCanvas.width, 2*patternCanvas.height);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 20,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [7, 181, 7, 1],
- }),
- });
- }),
- },
- 'skydd.naturvardsomrade': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(176, 255, 176, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 19,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [176, 255, 176, 1],
- }),
- });
- }),
- },
- 'skydd.djur_och_vaxtskyddsomrade': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(255, 255, 0, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 18,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [255, 255, 0, 1],
- }),
- });
- }),
- },
- 'skydd.kulturreservat': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(154, 102, 255, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 17,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [154, 102, 255, 1],
- }),
- });
- }),
- },
- 'skydd.vattenskyddsomrade': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(0, 105, 212, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 16,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [0, 105, 212, 1],
- }),
- });
- }),
- },
- 'skydd.landskapsbildsskyddsomrade': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(135, 110, 71, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 15,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [134, 110, 71, 1],
- }),
- });
- }),
- },
- 'skydd.skogligt_biotopskyddsomrade': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(135, 90, 71, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 14,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 4 ? .5 : z <= 5 ? 1 : 2,
- color: [134, 90, 71, 1],
- }),
- });
- }),
- },
- 'skydd.ovrigt_biotopskyddsomrade': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(255, 95, 0, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 13,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 4 ? .5 : z <= 5 ? 1 : 2,
- color: [255, 95, 0, 1],
- }),
- });
- }),
- },
- 'skydd.naturminne_yta': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(113, 0, 116, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 12,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [134, 0, 116, 1],
- }),
- });
- }),
- },
- 'skydd.naturminne_punkt': {
- legend: { zoomLevel: 6, type: 'point' },
- style: [undefined, undefined, undefined, undefined].concat([3, 4, 6, 8, 12, 16, 20, 24].map(function(width) {
- return new Style({
- zIndex: 12,
- image: new CircleStyle({
- radius: width,
- fill: new Fill({
- color: 'rgba(113, 0, 116, .5)',
- }),
- stroke: new Stroke({
- width: Math.log2(width)/2,
- color: 'rgba(113, 0, 116, 1)',
- }),
- }),
- });
- }))
- },
- 'skydd.interimistiskt_forbud': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(168, 0, 0, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 11,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [168, 0, 0, 1],
- }),
- });
- }),
- },
- 'skydd.fageldirektivet': {
- 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');
- patternCanvas.width = width*2;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(230, 0, 0, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.beginPath();
- patternContext.lineWidth *= 6;
- patternContext.moveTo(-.5*patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -.5*patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 1.5*patternCanvas.height);
- patternContext.lineTo(1.5*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 10,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 4 ? .5 : z <= 5 ? 1 : 2,
- color: [230, 0, 0, 1],
- }),
- });
- }),
- },
- 'skydd.habitatdirektivet': {
- 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');
- patternCanvas.width = width*2;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(0, 77, 168, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, 0);
- patternContext.lineTo(patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, -patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, 0);
- patternContext.lineTo(patternCanvas.width, 2*patternCanvas.height);
- patternContext.stroke();
- patternContext.beginPath();
- patternContext.lineWidth *= 6;
- patternContext.moveTo(0, -.5*patternCanvas.height);
- patternContext.lineTo(1.5*patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(-.5*patternCanvas.width, 0);
- patternContext.lineTo(patternCanvas.width, 1.5*patternCanvas.height);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 10,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 4 ? .5 : z <= 5 ? 1 : 2,
- color: [0, 77, 168, 1],
- }),
- });
- }),
- },
- 'skydd.helcom': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'rgba(130, 130, 130, 1)';
- const r = z < 5 ? (z+1)*.75 : z*.5;
- patternContext.beginPath();
- patternContext.arc(.5*patternCanvas.width, .5*patternCanvas.height, r, 0, 2*Math.PI, true)
- patternContext.fill();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 9,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [130, 130, 130, 1],
- }),
- });
- }),
- },
- 'skydd.ramsar': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'rgba(195, 0, 255, 1)';
- const r = z < 5 ? (z+1)*.75 : z*.5;
- patternContext.beginPath();
- patternContext.arc(.25*patternCanvas.width, .25*patternCanvas.height, r, 0, 2*Math.PI, true)
- patternContext.fill();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 9,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [195, 0, 255, 1],
- }),
- });
- }),
- },
- 'skydd.ospar': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'rgba(168, 0, 0, 1)';
- const r = z < 5 ? (z+1)*.75 : z*.5;
- patternContext.beginPath();
- patternContext.arc(.25*patternCanvas.width, .75*patternCanvas.height, r, 0, 2*Math.PI, true)
- patternContext.fill();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 9,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [168, 0, 0, 1],
- }),
- });
- }),
- },
- 'skydd.varldsarv': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'rgba(168, 0, 0, 1)';
- const r = z < 5 ? (z+1)*.75 : z*.5;
- patternContext.beginPath();
- patternContext.arc(.75*patternCanvas.width, .25*patternCanvas.height, r, 0, 2*Math.PI, true)
- patternContext.fill();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 9,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [168, 0, 0, 1],
- }),
- });
- }),
- },
- 'skydd.biosfarsomraden': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'rgba(131, 0, 219, 1)';
- const r = z < 5 ? (z+1)*.75 : z*.5;
- patternContext.beginPath();
- patternContext.arc(.75*patternCanvas.width, .75*patternCanvas.height, r, 0, 2*Math.PI, true)
- patternContext.fill();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 9,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [131, 0, 219, 1],
- }),
- });
- }),
- },
- 'skydd.naturvardsavtal': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(255, 0, 197, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 21,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 4 ? .5 : z <= 5 ? 1 : 2,
- color: [255, 0, 197, 1],
- }),
- });
- }),
- },
- 'skydd.naturvardsavtal_skogsstyrelsen': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(255, 0, 197, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, 0);
- patternContext.lineTo(patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, -patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, 0);
- patternContext.lineTo(patternCanvas.width, 2*patternCanvas.height);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 20,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 4 ? .5 : z <= 5 ? 1 : 2,
- color: [255, 0, 197, 1],
- }),
- });
- }),
- },
- 'skydd.atervatningsavtal': {
- legend: { zoomLevel: 0 },
- style: [0, 1, 2, 3, 4, 5, 6].map(function(width) {
- return new Style({
- zIndex: 5,
- fill: new Fill({
- color: [255, 115, 0, .4],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: .5,
- color: [255, 115, 0, 1],
- }),
- });
- })
- .concat([7, 8, 9, 10, 11].map(function() {
- const patternCanvas = document.createElement('canvas');
- const patternContext = patternCanvas.getContext('2d');
- patternCanvas.width = 16;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(255, 115, 0, 1)';
- patternContext.lineWidth = 1;
- patternContext.beginPath();
- patternContext.moveTo(0, 0);
- patternContext.lineTo(patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, -patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, 0);
- patternContext.lineTo(patternCanvas.width, 2*patternCanvas.height);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 5,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: new Stroke({
- width: 1.5,
- color: [255, 115, 0, 1],
- }),
- });
- })),
- },
- 'nv.naturvarde_sks': {
- legend: { zoomLevel: 0 },
- style: [0, 1, 2, 3, 4, 5].map(function(width) {
- return new Style({
- zIndex: 6,
- fill: new Fill({
- color: [255, 170, 0, .2],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: .5,
- color: [255, 170, 0, .8],
- }),
- });
- })
- .concat([6, 7, 8, 9, 10, 11].map(function() {
- const patternCanvas = document.createElement('canvas');
- const patternContext = patternCanvas.getContext('2d');
- patternCanvas.width = 16;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(255, 170, 0, 1)';
- patternContext.lineWidth = 1;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 6,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: new Stroke({
- width: 1.5,
- color: [255, 170, 0, 1],
- }),
- });
- })),
- },
- 'nv.nyckelbiotop': {
- legend: { zoomLevel: 0 },
- style: [0, 1, 2, 3, 4, 5].map(function(width) {
- return new Style({
- zIndex: 6,
- fill: new Fill({
- color: [217, 148, 9, .2],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: .5,
- color: [217, 148, 9, .8],
- }),
- });
- })
- .concat([6, 7, 8, 9, 10, 11].map(function() {
- const patternCanvas = document.createElement('canvas');
- const patternContext = patternCanvas.getContext('2d');
- patternCanvas.width = 16;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(217, 148, 9, 1)';
- patternContext.lineWidth = 1;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 6,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: new Stroke({
- width: 1.5,
- color: [217, 148, 9, 1],
- }),
- });
- })),
- },
- 'nv.nyckelbiotop_storskogsbruk': {
- legend: { zoomLevel: 0 },
- style: [0, 1, 2, 3, 4, 5].map(function(width) {
- return new Style({
- zIndex: 6,
- fill: new Fill({
- color: [217, 148, 9, .2],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: .5,
- color: [217, 148, 9, .8],
- }),
- });
- })
- .concat([6, 7, 8, 9, 10, 11].map(function() {
- const patternCanvas = document.createElement('canvas');
- const patternContext = patternCanvas.getContext('2d');
- patternCanvas.width = 16;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(217, 148, 9, 1)';
- patternContext.lineWidth = 1;
- patternContext.beginPath();
- patternContext.moveTo(0, 0);
- patternContext.lineTo(patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, -patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, 0);
- patternContext.lineTo(patternCanvas.width, 2*patternCanvas.height);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 6,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: new Stroke({
- width: 1.5,
- color: [217, 148, 9, 1],
- }),
- });
- })),
- },
- 'nv.sumpskog': {
- 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 = z < 2 ? 2 : z < 4 ? 4 : z <= 5 ? 6 : 8;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(158, 200, 215, 1)';
- patternContext.lineWidth = w;
- patternContext.beginPath();
- patternContext.moveTo(0, 0);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 5,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: w/2,
- color: [158, 200, 215, 1],
- }),
- });
- }),
- },
- 'nv.pagaende_naturreservatsbildning': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.setLineDash([width/4, width/4]);
- patternContext.strokeStyle = 'rgba(7, 181, 7, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(width/4, 0);
- patternContext.lineTo(width/4, patternCanvas.height);
- patternContext.stroke();
- patternContext.beginPath();
- patternContext.lineDashOffset = width/4;
- patternContext.moveTo(3*width/4, 0);
- patternContext.lineTo(3*width/4, patternCanvas.height);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 10,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 3 : 4,
- color: [7, 181, 7, 1],
- lineDash: [width/8, width/4],
- }),
- });
- }),
- },
- 'nv.snus': {
- legend: { zoomLevel: 1 },
- style: [.5, 1, 1.5, 1.5, 2, 2, 2.5, 2.5, 3, 3.5, 4, 5].map(function(width) {
- return new Style({
- zIndex: 4,
- fill: new Fill({
- color: [168,168,0,.2],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [168,77,0,.75],
- }),
- });
- }),
- },
-
- 'ri.naturvard': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(154, 230, 0, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, 0);
- patternContext.lineTo(patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, -patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, 0);
- patternContext.lineTo(patternCanvas.width, 2*patternCanvas.height);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 8,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [154, 230, 0, 1],
- }),
- });
- }),
- },
- 'ri.friluftsliv': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(0, 127, 232, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, 0);
- patternContext.lineTo(patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, -patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, 0);
- patternContext.lineTo(patternCanvas.width, 2*patternCanvas.height);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 8,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 1 : z < 4 ? 2 : z <= 5 ? 4 : 8,
- color: [0, 127, 232, 1],
- }),
- });
- }),
- },
- 'ri.rorligt_friluftsliv': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'rgba(187, 227, 212, .25)';
- patternContext.fillRect(0, 0, patternCanvas.width, patternCanvas.height);
- patternContext.strokeStyle = 'rgba(56, 151, 117, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, patternCanvas.height);
- patternContext.lineTo(patternCanvas.width, -patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, 2*patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 8,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 2 : z < 4 ? 4 : z <= 5 ? 8 : 16,
- color: [56, 151, 117, 1],
- lineDash: [width/4, width/3],
- }),
- });
- }),
- },
- 'ri.obruten_kust': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'rgba(227, 227, 187, .25)';
- patternContext.fillRect(0, 0, patternCanvas.width, patternCanvas.height);
- patternContext.strokeStyle = 'rgba(156, 158, 56, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, 0);
- patternContext.lineTo(patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, -patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, 0);
- patternContext.lineTo(patternCanvas.width, 2*patternCanvas.height);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 8,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 2 : z < 4 ? 4 : z <= 5 ? 8 : 16,
- color: [156, 158, 56, 1],
- lineDash: [width/4, width/3],
- }),
- });
- }),
- },
- 'ri.obrutet_fjall': {
- 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');
- patternCanvas.width = width;
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'rgba(255, 255, 209, .25)';
- patternContext.fillRect(0, 0, patternCanvas.width, patternCanvas.height);
- patternContext.strokeStyle = 'rgba(219, 183, 60, 1)';
- patternContext.lineWidth = z < 4 ? .5 : z <= 5 ? 1 : 2;
- patternContext.beginPath();
- patternContext.moveTo(0, 0);
- patternContext.lineTo(patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(0, -patternCanvas.height);
- patternContext.lineTo(2*patternCanvas.width, patternCanvas.height);
- patternContext.stroke();
- patternContext.moveTo(-patternCanvas.width, 0);
- patternContext.lineTo(patternCanvas.width, 2*patternCanvas.height);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 8,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 2 : z < 4 ? 4 : z <= 5 ? 8 : 16,
- color: [219, 183, 60, 1],
- lineDash: [width/4, width/3],
- }),
- });
- }),
- },
- 'ri.skyddade_vattendrag': {
- 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,
- fill: new Fill({
- color: [102, 157, 240, .25],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: z < 2 ? 2 : z < 4 ? 4 : z <= 5 ? 8 : 16,
- color: [41, 109, 197, 1],
- lineDash: [width/4, width/3],
- }),
- });
- }),
- },
-
- 'ren.betesomrade': {
- legend: { zoomLevel: 0 },
- style: [1, 1.5, 2, 3, 3.5, 4, 5, 5, 6, 7, 8, 10].map(function(width) {
- return new Style({
- zIndex: 4,
- fill: new Fill({
- /* transparent fill so clicking the inside of the polygon triggers a popover */
- /* XXX could also use a custom renderer but that doesn't seem to work */
- color: [0, 0, 0, 0],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [179, 153, 102, 1],
- }),
- });
- }),
- },
- 'ren.flyttled': {
- legend: { zoomLevel: 2, type: 'linestring' },
- style: [.75, 1, 1.5, 2, 3, 4, 5, 5, 6, 7, 8, 10].map(function(width) {
- return new Style({
- zIndex: 7,
- stroke: new Stroke({
- width: 2*width,
- color: [119, 99, 59, 1],
- lineDash: [4 * width],
- }),
- });
- }),
- },
- 'ren.riks_ren': {
- 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');
- patternCanvas.width = z < 4 ? 4 : z <= 5 ? 8 : Math.pow(2, Math.round(Math.log2(width) + 3));
- patternCanvas.height = patternCanvas.width;
- patternContext.fillStyle = 'transparent';
- patternContext.strokeStyle = 'rgba(179, 153, 102, 1)';
- patternContext.lineWidth = Math.max(1, width/2);
- patternContext.beginPath();
- patternContext.moveTo(0, 0);
- patternContext.lineTo(patternCanvas.width, 0);
- patternContext.stroke();
-
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- return new Style({
- zIndex: 6,
- fill: new Fill({
- color: context.createPattern(patternCanvas, 'repeat'),
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [179, 153, 102, 1],
- }),
- });
- }),
- },
- 'ren.omr_riks': {
- 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,
- fill: new Fill({
- color: [203, 190, 163, Math.max((.3-.5)/8 * z + .5, 0)],
- }),
- stroke: width === 0 ? undefined : new Stroke({
- width: width,
- color: [179, 153, 102, 1],
- }),
- });
- }),
- },
-
- /* Documentation at
- * https://www.smhi.se/polopoly_fs/1.34541!/dammprod%202013_3%2C%20beskrivning%2C%20SVAR2012_2.pdf
- * */
- 'misc.dammar': {
- 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,
- image: new CircleStyle({
- radius: width,
- fill: new Fill({
- color: 'rgb(219, 30, 42)',
- }),
- stroke: new Stroke({
- width: Math.log2(width) * 2/5,
- color: 'rgb(128, 17, 25)',
- }),
- }),
- });
- }),
- },
-
- 'misc.gigafactories': {
- legend: { zoomLevel: 1, type: 'point' },
- style: [4, 6, 7, 8, 10, 12].map(function(width) {
- return new Style({
- zIndex: 60,
- image: new CircleStyle({
- radius: width,
- fill: new Fill({
- color: 'rgb(152, 78, 163)',
- }),
- stroke: new Stroke({
- width: Math.log2(width) * 2/5,
- color: 'rgb(119, 61, 128)',
- }),
- }),
- });
- })
- .concat([1.5, 2, 2, 2, 2, 2].map(function(width) {
- return new Style({
- zIndex: 58,
- fill: new Fill({
- color: 'rgba(152, 78, 163, .4)',
- }),
- stroke: new Stroke({
- width: width,
- color: 'rgb(119, 61, 128)',
- }),
- });
- })),
- },
-
- 'kskog.1' : { style: [ 56, 168, 0, .2] }, /* #1 Sannolikt kontinuitetsskog (preciserad) */
- 'kskog.2' : { style: [169, 0, 230, .2] }, /* #2 Sannolikt påverkad kontinuitetsskog (preciserad) */
- 'kskog.3' : { style: [152, 230, 0, .2] }, /* #3 Sannolikt kontinuitetsskog i fjällen (grövre precisering) */
- 'kskog.4' : { style: [ 76, 115, 0, .2] }, /* #4 Potentiell kontinuitetsskog (2015) */
-};
diff --git a/src/map.js b/src/map.js
deleted file mode 100644
index 5a751e6..0000000
--- a/src/map.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/***********************************************************************
- * Copyright © 2024-2025 Guilhem Moulin <info@guilhem.se>
- * Map base setup
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- **********************************************************************/
-
-import Map from 'ol/Map.js';
-import View from 'ol/View.js';
-import TileLayer from 'ol/layer/Tile.js';
-
-import WMTS from 'ol/source/WMTS.js';
-import WMTSTileGrid from 'ol/tilegrid/WMTS.js';
-
-import proj4 from 'proj4';
-import { get as getProjection } from 'ol/proj.js';
-import { register as registerProjection } from 'ol/proj/proj4.js';
-
-proj4.defs('EPSG:3006', '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs');
-registerProjection(proj4);
-
-export const projection = getProjection('EPSG:3006');
-
-/* Lantmäteriet uses a tile-scheme where the origin (upper-left corner) is at
- * N8500000 E-1200000 (SWEREF99 TM), where each tile is 256×256 pixels, and where
- * the resolution at level 0 is 4096m per pixel (each side is 1048.576km long).
- *
- * https://www.lantmateriet.se/globalassets/geodata/geodatatjanster/tb_twk_visning_cache_v1.1.0.pdf
- * https://www.lantmateriet.se/globalassets/geodata/geodatatjanster/tb_twk_visning-oversiktlig_v1.0.3.pdf
- *
- * We set the extent to a 4×4 tiles square at level 2 (1024px = 1048.576km per
- * side) somehow centered on Norrbotten and Västerbotten, and zoom in from there.
- * This represent a TILEROW (x) offset of 5, and a TILECOL (y) offset of 2.
- */
-export const extent = [110720, 6927136, 1159296, 7975712];
-
-/* XXX using the topowebbcache WMTS is fine for testing (as it doesn't require
- * authentication) but not in production in a public instance as doing so would
- * violate its current terms of use (as of January 2024 it's not CC0 open data).
- * See
- *
- * https://www.lantmateriet.se/sv/om-lantmateriet/Rattsinformation/upphovsratt-och-publicering-av-lantmateriets-geografiska-information/
- * https://www.lantmateriet.se/sv/kartor/vara-karttjanster/min-karta/#anchor-2
- * https://help.locusmap.eu/topic/support-for-swedish-lantmateriets-min-karta-wms
- *
- * More precise background maps might be available in the future as open data,
- * though:
- *
- * https://www.lantmateriet.se/sv/om-lantmateriet/press/nyheter/lantmateriets-arbete-mot-oppna-data-i-full-gang/
- * https://ext-geodatakatalog.lansstyrelsen.se/GeodataKatalogen/srv/swe/catalog.search#/map uses
- * https://api.lantmateriet.se/open/topowebb-ccby/v1/wmts/token/3c3a9cf47e7cb5ea24542d40d19698/?layer=topowebb&style=default&tilematrixset=3006&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/png&TileMatrix=7&TileCol=237&TileRow=155
- */
-export const baseMapSource = new WMTS({
- url: undefined,
- version: '1.0.0',
- style: 'default',
- matrixSet: '3006',
- format: 'image/png',
- tileGrid: new WMTSTileGrid({
- extent: extent,
- // https://www.lantmateriet.se/globalassets/geodata/geodatatjanster/tb_twk_visning-oversiktlig_v1.0.3.pdf
- tileSize: 256,
- origin: [-1200000, 8500000],
- resolutions: [4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8],
- matrixIds: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
- }),
- projection: projection,
- wrapX: false,
- crossOrigin: 'anonymous',
-});
-
-const view = new View({
- projection: projection,
- extent: extent,
- showFullExtent: true,
- /* center of the bbox of the Norrbotten and Västerbotten geometries */
- center: [694767.48, 7338176.57],
- zoom: 1,
- enableRotation: false,
- resolutions: [1024, 512, 256, 128, 64, 32, 16, 8],
- constrainResolution: false,
-});
-
-export const map = new Map({
- controls: [],
- view: view,
- layers: [
- new TileLayer({
- source: baseMapSource
- }),
- ],
-});
diff --git a/src/popover.js b/src/popover.js
deleted file mode 100644
index 7080711..0000000
--- a/src/popover.js
+++ /dev/null
@@ -1,1348 +0,0 @@
-/***********************************************************************
- * Copyright © 2024-2025 Guilhem Moulin <info@guilhem.se>
- * Popup and feature overlays
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- **********************************************************************/
-
-import Overlay from 'ol/Overlay.js';
-import Stroke from 'ol/style/Stroke.js';
-import Style from 'ol/style/Style.js';
-import VectorTileLayer from 'ol/layer/VectorTile.js';
-
-import { Popover } from 'bootstrap';
-
-import { map } from './map.js';
-
-/* return an <a> tag with the given URL and optional text */
-const reURL = new RegExp('^https?://', 'i');
-const formatLink = function(url, text) {
- if (url == null || typeof url !== 'string' || !reURL.test(url)) {
- return url;
- }
- const a = document.createElement('a');
- a.href = url;
- a.target = '_blank';
- if (text != null && text !== '') {
- const t = document.createTextNode(text + ' ');
- a.appendChild(t);
- }
- const i = document.createElement('i');
- i.classList.add('bi', 'bi-box-arrow-up-right');
- a.appendChild(i);
- return a;
-};
-
-/* test a condition on the field maps */
-const condField = function(cond, k) {
- if (Array.isArray(cond)) {
- return cond.includes(k);
- }
- if (cond instanceof RegExp) {
- return cond.test(k);
- }
- return cond(k);
-};
-/* filter fields by condition */
-const filterFields = function(k, fields) {
- return fields.map(function(v) {
- if (v.cond == null || condField(v.cond, k)) {
- return v;
- }
- }).filter((f) => f != null);
-};
-/* filter fields using a pre-built map */
-const mapFields = function(k, fieldMap, fields) {
- if (fields === undefined) {
- return fieldMap.map((v) => k[v]);
- }
- return fields.map(function(v) {
- if (!Array.isArray(v)) {
- return fieldMap[v];
- } else if (condField(v[1], k)) {
- return fieldMap[v[0]];
- }
- }).filter((f) => f !== undefined);
-};
-/* pre-build the field map so we don't need to duplicate objects accross layers */
-const mkFieldMap = function(fieldMap) {
- return Object.fromEntries(Object.entries(fieldMap).map(function([k, o]) {
- if (typeof o === 'string') {
- return [k, {key: k, desc: o}];
- } else {
- return [k, Object.assign(o, {key: k})];
- }
- }));
-};
-
-const LAYERS = {
- svk: {
- ledningar: {
- title: 'Kraftledning (befintlig)',
- fields: [
- { key: 'Placement', desc: 'Förläggning' },
- { key: 'Voltage', desc: 'Spänning', unit: 'kV' },
- { key: 'geom_length', desc: 'Ledlängd', fn: 'length' },
- ],
- },
- transmissionsnatsprojekt: {
- title: 'Transmissionsnätsprojekt',
- fields: [
- { key: 'Name', desc: 'Projektnamn' },
- { key: 'Voltage', desc: 'Spänning', unit: 'kV' },
- { key: 'Url', desc: 'Länk', fn: formatLink },
- ],
- },
- },
-
- misc: {
- gigafactories: {
- title: 'Stor industrisatsning',
- fields: [
- { key: 'Name', desc: 'Namn' },
- { key: 'Url', desc: 'Länk', fn: formatLink },
- ],
- },
- dammar: {
- /* Documentation at
- * https://www.smhi.se/polopoly_fs/1.34541!/dammprod%202013_3%2C%20beskrivning%2C%20SVAR2012_2.pdf */
- title: 'Damm',
- fields: [
- { key: 'DNamn', desc: 'Dammenhetens namn' },
- { key: 'Namn', desc: 'Dammanläggningens namn' },
- { key: 'LST_OBJID', desc: 'Länsnr', classes: ['feature-objid'] },
- { key: 'Status', desc: 'Status', fn: (v) => v === 1 ? 'Befintlig damm' : v === 2 ? 'Fd. damm' : '' },
- //{ key: 'Regleringstyp', desc: 'Regleringstyp' },
- { key: 'ByggAr', desc: 'Byggår' },
- { key: 'DammHojd', desc: 'Dammhöjd', unit: 'm' },
- { key: 'KronLangd', desc: 'Krönlängd', unit: 'm' },
- { key: 'Fiskvag', desc: 'Fiskväg', fn: (v) =>
- v === 1 ? 'Bassängtrappa' :
- v === 2 ? 'Denilränna' :
- v === 3 ? 'Slitsränna' :
- v === 4 ? 'Omlöp' :
- v === 5 ? 'Inlöp' :
- v === 6 ? 'Ålledare' :
- v === 7 ? 'Smoltränna' :
- v === 8 ? 'Okänd typ' :
- v === 9 ? 'Ingen' :
- v === 10 ? 'Annan' :
- null },
- { key: 'HARO', desc: 'Huvudavrinningsområdesnummer', classes: ['feature-objid'] },
- { key: 'Vattendistrikt', desc: 'Vattendistrikt', classes: ['feature-objid'] },
- { key: 'Verksamhet', desc: 'Verksamhet', fn: (v) =>
- v === 1 ? 'Kraftproduktion' :
- v === 2 ? 'Industri' :
- v === 3 ? 'Sjöfart' :
- v === 4 ? 'Invallning' :
- v === 5 ? 'Vattenförsörjning' :
- v === 6 ? 'Spegeldamm' :
- v === 7 ? 'Historisk' :
- v === 8 ? 'Övrigt' :
- null },
- { key: 'DG', desc: 'Högsta dämningsgräns', unit: 'm' },
- { key: 'SG', desc: 'Lägsta sänkningsgräns', unit: 'm' },
- { key: 'MY', desc: 'Magasinsyta', unit: 'km²' },
- { key: 'RV', desc: 'Reglerbar volym', unit: 'Mm³' },
- { key: 'Kommentar', desc: 'Kommentar' },
- ],
- },
- },
-};
-
-
-LAYERS.mrr = {};
-(function() {
- const fields = [
- { key: 'name', desc: 'Namn' },
- { key: 'mineral', desc: 'Koncessionsmineral', cond: (i) => i < 6 },
- { key: 'owners', desc: 'Ägare', cond: [0,2,4] },
- { key: 'owners', desc: 'Sökande', cond: [1,3,5] },
- { key: 'conc_name', desc: 'Tillhörande bearbetnings\u00ADkoncession(er)', cond: [6] },
- { key: 'licenceid', desc: 'Tillståndsid', classes: ['feature-attr-mrr-license-id'], cond: [0,2,4,6] },
- { key: 'geom_area', desc: 'Areal', fn: 'area' },
- { key: 'validfrom', desc: 'Giltig från', cond: [0,2,4] },
- { key: 'validto', desc: 'Giltig till', cond: [0,2,4] },
- { key: 'diarynr', desc: 'Diarienummer', classes: ['feature-attr-dnr'] },
- { key: 'appl_date', desc: 'Ansökningsdatum' },
- { key: 'dec_date', desc: 'Beslutsdatum', cond: [0,2,4,6] },
- ];
- Object.entries({
- ec: 'Bearbetningskoncession',
- met: 'Undersökningstillstånd, metaller och industrimineral',
- ogd: 'Undersökningstillstånd, olja, gas och diamant',
- })
- .flatMap(([k, title]) => [
- /* don't use Object.entries() to guaranty ordering */
- ['appr', 'beviljad'], /* even index */
- ['appl', 'ansökt'], /* odd index */
- ].map(([a,b]) => [a + '_' + k, title + ' \u2013 ' + b]))
- .concat([['appr_dl', 'Markanvisning till koncession']]) /* index #6 */
- .forEach(([k, title], idx) => LAYERS.mrr[k] = { title, fields: filterFields(idx, fields) });
-})();
-
-
-LAYERS.vbk = {};
-(function() {
- const fieldMap = mkFieldMap({
- Projektnamn: 'Projektnamn',
- OmrID: { desc: 'Områdes-ID', classes: ['feature-objid'] },
- AntalVerk: 'Aktuella verk',
- AntalEjXY: 'Antal ej koordinatsatta verk',
- Projektstatus: 'Projektstatus',
- Diarienummer: 'Diarienummer',
- geom_area: { desc: 'Areal', fn: 'area' },
- Calprod: { desc: 'Beräknad årsproduktion', unit: 'GWh' },
- PlaneradByggstart: 'Planerad byggstart',
- PlaneratDrift: 'Planerat drifttagande',
- AndringsansokanPagar: 'Ändringsansökan pågår',
- UnderByggnation: 'Under byggnation',
- Organisationsnamn: 'Verksamhetsutövare',
- Organisationsnummer: { desc: 'Organisationsnummer', classes: ['feature-orgnr'] },
- SamradsunderlagInlamnat: 'Samrådsunderlag inlämnat',
- AnsokanInlamnat: 'Tillståndsansökan inlämnad',
- AnsokanAterkallad: 'Tillståndsansökan återkallad',
- AnsokanBeviljad: 'Tillståndsansökan beviljad',
- AnsokanAvslagen: 'Tillståndsansökan avslagen',
- AnsokanOverklagad: 'Överklagad',
- Natura2000_Ansokan: 'Natura2000 ansökan',
- Natura2000_Beslutdatum: 'Natura2000 beslutsdatum',
- Uppfort: 'Parken uppförd',
- PlaneratAntalVerkMin: 'Planerat antal verk (min)',
- PlaneratAntalVerkMax: 'Planerat antal verk (max)',
- PlaneradHojdMin: { desc: 'Panerad totalhöjd (min)', unit: 'm' },
- PlaneradHojdMax: { desc: 'Panerad totalhöjd (max)', unit: 'm' },
- PlaneradProduktionMin: { desc: 'Planerad årsproduktion (min)', unit: 'GWh' },
- PlaneradProduktionMax: { desc: 'Planerad årsproduktion (max)', unit: 'GWh' },
- BeviljatAntalVerk: 'Beviljat antal verk',
- UppfortAntalVerk: 'Uppfört antal verk',
- BeviljadMaxhojd: { desc: 'Beviljad maxhöjd', unit: 'm' },
- InstalleradEffekt: { desc: 'Installerad effekt', unit: 'MW' },
- ElNamn: 'Elområde',
- SenasteUppdaterat: 'Senast uppdaterat',
- });
-
- Object.entries({
- current: null,
- notcurrent: ' \u2013 ej aktuell',
- })
- .forEach(([k, title]) => LAYERS.vbk['area_' + k] = {
- title: 'Landbaserad projekteringsområde för vindkraft' + (title ?? ''),
- fields: mapFields(k, fieldMap, [
- 'Projektnamn',
- 'OmrID',
- 'AntalVerk',
- 'AntalEjXY',
- 'geom_area',
- 'Calprod',
- 'PlaneradByggstart',
- 'PlaneratDrift',
- 'AndringsansokanPagar',
- ['UnderByggnation', ['current']],
- 'Organisationsnamn',
- 'Organisationsnummer',
- 'ElNamn',
- 'SenasteUppdaterat',
- ]),
- });
-
- [
- ['completed', /* 0 */ 'uppförd'],
- ['approved', /* 1 */ 'tillståndsansökan beviljad'],
- ['amended', /* 2 */ 'ändringsansökan'],
- ['rejected', /* 3 */ 'tillståndsansökan avslagen'],
- ['appealed', /* 4 */ 'överklagad'],
- ['applied', /* 5 */ 'tillståndsansökan inlämnad'],
- ['consultation', /* 6 */ 'samråd inför tillståndsansökan'],
- ['investigation', /* 7 */ 'inledande undersökningar'],
- ['revoked', /* 8 */ 'inte aktuell eller återkallad'],
- ]
- .forEach(([k, title], idx) => LAYERS.vbk['offshore_' + k] = {
- title: 'Havsbaserad vindkraft \u2013 ' + title,
- fields: mapFields(idx, fieldMap, [
- 'Projektnamn',
- 'OmrID',
- 'Organisationsnamn',
- 'Organisationsnummer',
- 'Projektstatus',
- 'Diarienummer',
- ['AndringsansokanPagar', [1,2,4]],
- 'geom_area',
- ['SamradsunderlagInlamnat', (i) => i <= 6 || i === 8],
- ['AnsokanInlamnat', (i) => i <= 5 || i === 8],
- ['AnsokanAterkallad', [8]],
- ['AnsokanBeviljad', [0,1,4,8]],
- ['AnsokanAvslagen', [3,8]],
- ['AnsokanOverklagad', [0,1,3,4,8]],
- ['Natura2000_Ansokan', (i) => i !== 2],
- ['Natura2000_Beslutdatum', (i) => i !== 2],
- ['UnderByggnation', [1]],
- ['PlaneratAntalVerkMin', (i) => i > 0],
- ['PlaneratAntalVerkMax', (i) => i > 0],
- ['PlaneradHojdMin', (i) => i > 0],
- ['PlaneradHojdMax', (i) => i > 0],
- ['PlaneradProduktionMin', (i) => i > 0],
- ['PlaneradProduktionMax', (i) => i > 0],
- ['PlaneradByggstart', (i) => i > 0],
- ['Uppfort', [0,8]],
- ['PlaneratDrift', (i) => i > 0],
- ['BeviljatAntalVerk', [0,1,4,8]],
- ['UppfortAntalVerk', [0,8]],
- ['BeviljadMaxhojd', [0,1,4,8]],
- ['InstalleradEffekt', [0]],
- ['Calprod', [0]],
- 'ElNamn',
- 'SenasteUppdaterat',
- ]),
- });
-
- Object.assign(fieldMap, mkFieldMap({
- VerkID: { desc: 'Verk-ID', classes: ['feature-objid'] },
- Status: 'Status',
- Handlingstyp: 'Handlingstyp',
- MB_Tillstand: 'Miljöbalken tillstånd tidsbegränsning',
- Uppfort: 'Uppförandedatum',/* override previous def */
- Totalhojd: { desc: 'Totalhöjd', unit: 'm' },
- Navhojd: { desc: 'Navhöjd', unit: 'm' },
- Rotordiameter: { desc: 'Rotordiameter', unit: 'm' },
- Maxeffekt: { desc: 'Maxeffekt', unit: 'MW' },
- Fabrikat: 'Fabrikat',
- Modell: 'Modell',
- Placering: 'Placering',
- }));
-
- [
- ['completed', /* 0 */ 'uppfört'],
- ['approved', /* 1 */ 'beviljat'],
- ['rejected', /* 2 */ 'avslagit/nekat'],
- ['processed', /* 3 */ 'handlagt'],
- ['dismounted', /* 4 */ 'nedmonterat'],
- ['appealed', /* 5 */ 'överklagat'],
- ['revoked', /* 6 */ 'inte aktuell eller återkallad'],
- ]
- .forEach(([k, title], idx) => LAYERS.vbk['station_' + k] = {
- title: 'Landbaserad vindkraftverk \u2013 ' + title,
- fields: mapFields(idx, fieldMap, [
- 'VerkID',
- 'OmrID',
- 'Projektnamn',
- 'Status',
- 'Handlingstyp',
- ['Uppfort', [0,4,6]],
- 'MB_Tillstand',
- 'Totalhojd',
- 'Navhojd',
- 'Rotordiameter',
- 'Maxeffekt',
- 'Calprod',
- 'Fabrikat',
- 'Modell',
- 'Organisationsnamn',
- 'Organisationsnummer',
- 'Placering',
- 'ElNamn',
- 'SenasteUppdaterat',
- ]),
- });
-})();
-
-
-LAYERS.avverk = {};
-(function() {
- const zeroIsNull = (v) => v > 0 ? v : null;
- const fieldMap = mkFieldMap({
- /* Documentation at
- * https://www.skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/utforda-avverkningar---produktbeskrivning.pdf
- * and
- * https://www.skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/yttre-granser-for-avverkningsanmalda-omraden---produktbeskrivning.pdf
- */
- Beteckn: { desc: 'Ärendebeteckning', classes: ['feature-objid'] },
- ArendeAr: 'Registeringsår',
- Inkomdatum: 'Inkom datum',
- Skogstyp: 'Skogstyp',
- Avvdatum: 'Datum för avverkning',
- KallaDatum: 'Ursprung för datum för avverkning',
- AnmaldHa: { desc: 'Areal anmält', unit: 'ha' },
- NatforHa: { desc: 'Areal naturlig föryngring', unit: 'ha', fn: zeroIsNull },
- SkogsodlHa: { desc: 'Areal plantering', unit: 'ha', fn: zeroIsNull },
- AvvSasong: 'Avverkningssäsong',
- Avverktyp: 'Avverkningstyp',
- ArendeStatus: 'Ärendestatus',
- AvvHa: { desc: 'Avverkad areal', unit: 'ha' },
- geom_area: { desc: 'Areal för ytan', fn: 'area' },
- });
-
- LAYERS.avverk.utford = {
- title: 'Utförd avverkning',
- fields: mapFields(fieldMap, [
- 'Beteckn',
- 'ArendeAr',
- 'Skogstyp',
- 'AnmaldHa',
- 'NatforHa',
- 'Avverktyp',
- 'Avvdatum',
- 'KallaDatum',
- 'geom_area',
- ]),
- };
-
- LAYERS.avverk.anmald = {
- title: 'Avverkningsanmälansområde',
- fields: mapFields(fieldMap, [
- 'Beteckn',
- 'Inkomdatum',
- 'ArendeAr',
- 'AnmaldHa',
- 'NatforHa',
- 'SkogsodlHa',
- 'AvvSasong',
- 'ArendeStatus',
- 'AvvHa',
- ]),
- };
-})();
-
-
-LAYERS.skydd = {};
-(function() {
- const fieldMap = mkFieldMap({
- NVRID: { desc: 'NVR-ID', classes: ['feature-objid'] },
- FORSKRNAMN: 'Föreskriftsområde',
- OBJEKTNAMN: 'Namn',
- NAMN: 'Namn',
- BESLSTAT: 'Beslutsstatus',
- FORESKRTYP: 'Föreskriftstyp',
- FORESKRIFT: 'Föreskriftssubtyp',
- FRANDATUM: 'Från datum',
- TILLDATUM: 'Till datum',
- BESKRIVN: 'Beskrivning',
- geom_area: { desc: 'Areal', fn: 'area' },
-
- SKYDDSTYP: 'Skyddstyp',
- BESLSTATUS: 'Beslutsstatus',
- URSBESLDAT: 'Beslutsdatum (bildande)',
- URSGALLDAT: 'Ursprungligt gällandedatum',
- SENGALLDAT: 'Senaste gällandedatum',
- FORVALTARE: 'Förvaltare',
- IUCNKAT: 'IUCN-kategori',
- DIARIENR: { desc: 'Diarienummer', classes: ['feature-attr-dnr'] },
- LAGRUM: 'Lagrum',
- BESLMYND: 'Beslutsmyndighet',
- LAND_HA: { desc: 'Areal land', unit: 'ha' },
- VATTEN_HA: { desc: 'Areal vatten', unit: 'ha' },
- SKOG_HA: { desc: 'Skogsmarksareal', unit: 'ha' },
-
- IKRAFTDATF: 'Ikraftträdandedatum föreskrifter',
- TILLSYNSMH: 'Tillsynsmyndighet',
- PROVNMHTIL: 'Prövningsmyndighet tillstånd',
- PROVNMHDIS: 'Prövningsmyndighet dispens',
-
- NAME: 'Namn',
- RAMSAR_ID: { desc: 'Ramsar-ID', classes: ['feature-objid'] },
- LEGAL_ACT: 'Rättsakt',
- URSPR_BESL: 'Ursprungligt beslutsdatum',
- SEN_BESLUT: 'Senaste beslutsdatum',
- LINK: { desc: 'Länk', fn: formatLink },
- });
-
- LAYERS.skydd.tilltradesforbud = {
- title: 'Tillträdesförbud',
- fields: mapFields(fieldMap, [
- 'NVRID',
- 'FORSKRNAMN',
- 'OBJEKTNAMN',
- 'BESLSTAT',
- 'FORESKRTYP',
- 'FORESKRIFT',
- 'FRANDATUM',
- 'TILLDATUM',
- 'BESKRIVN',
- 'geom_area',
- ]),
- };
-
- /* Nationella skyddsformer från Naturvårdsregistret */
- const isSurface = (k) => !/_punkt$/.test(k);
- Object.entries({
- nationalpark: 'Nationalpark',
- naturreservat: 'Naturreservat',
- naturreservat_kommunalt: 'Kommunalt naturreservat',
- naturvardsomrade: 'Naturvårdsområde',
- djur_och_vaxtskyddsomrade: 'Djur- och växtskyddsområde',
- kulturreservat: 'Kulturreservat',
- vattenskyddsomrade: 'Vattenskyddsområden',
- landskapsbildsskyddsomrade: 'Landskapsbildsskyddsområde',
- ovrigt_biotopskyddsomrade: 'Biotopskydd utanför skogsmark',
- naturminne_yta: 'Naturminne (yta)',
- naturminne_punkt: 'Naturminne (punkt)',
- interimistiskt_forbud: 'Interimistiskt förbud',
- })
- .forEach(([k, title]) => LAYERS.skydd[k] = {
- title: title,
- fields: mapFields(k, fieldMap, [
- 'NVRID',
- 'NAMN',
- 'SKYDDSTYP',
- 'BESLSTATUS',
- 'URSBESLDAT',
- ['URSGALLDAT', (k) => k !== 'vattenskyddsomrade'],
- ['SENGALLDAT', (k) => k !== 'vattenskyddsomrade'],
- ['FORVALTARE', (k) => k !== 'vattenskyddsomrade'],
- ['IKRAFTDATF', (k) => k === 'vattenskyddsomrade'],
- 'IUCNKAT',
- 'DIARIENR',
- 'LAGRUM',
- 'BESLMYND',
- ['TILLSYNSMH', (k) => k === 'vattenskyddsomrade'],
- ['PROVNMHTIL', (k) => k === 'vattenskyddsomrade'],
- ['PROVNMHDIS', (k) => k === 'vattenskyddsomrade'],
- ['geom_area', isSurface],
- ['LAND_HA', isSurface],
- ['VATTEN_HA', isSurface],
- ['SKOG_HA', isSurface],
- ]),
- });
-
- /* Natura 2000-områden */
- (function() {
- const fields = [
- { key: 'SITE_CODE', desc: 'Områdeskod', classes: ['feature-objid'] },
- { key: 'NAMN', desc: 'Namn' },
- { key: 'OMRADESTYP', desc: 'Områdestyp' },
- { key: 'UPPLAMNARE', desc: 'Uppgiftslämnare' },
- { key: 'SPA_DATUM', desc: 'SPA-datum' },
- { key: 'SCI_FORSL', desc: 'SCI-förslagsdatum' },
- { key: 'SCI_DATUM', desc: 'SCI-datum' },
- { key: 'SAC_DATUM', desc: 'SAC-datum' },
- fieldMap.geom_area,
- { key: 'KVALITET', desc: 'Kvalitet' },
- { key: 'KARAKTAR', desc: 'Kännetecken för området' },
- { key: 'ARTER', desc: 'Arter' },
- { key: 'NATURTYPER', desc: 'Naturtyper' },
- { key: 'BEVPLAN', desc: 'Bevarandeplan', fn: formatLink },
- ];
- Object.entries({
- fageldirektivet: 'Fågeldirektivet (SPA)',
- habitatdirektivet: 'Art- och habitatdirektivet (SCI)',
- })
- .forEach(([k, title]) => LAYERS.skydd[k] = { title, fields });
- })();
-
- /* Områden med internationell status */
- LAYERS.skydd.helcom = {
- title: 'Marina skyddade områden (Helcom MPA)',
- fields: mapFields(fieldMap, [ 'NAME', 'geom_area' ]),
- };
-
- LAYERS.skydd.ramsar = {
- title: 'Ramsar-områden (Våtmarkskonventionen)',
- fields: mapFields(fieldMap, [
- 'RAMSAR_ID',
- 'SKYDDSTYP',
- 'NAMN',
- 'geom_area',
- 'LAND_HA',
- 'VATTEN_HA',
- 'SKOG_HA',
- 'URSPR_BESL',
- 'SEN_BESLUT',
- 'LEGAL_ACT',
- 'LINK',
- ]),
- };
-
- LAYERS.skydd.ospar = {
- title: 'Marina skyddade områden (Ospar MPA)',
- fields: [
- { key: 'ORIGIN', desc: 'Ursprung' },
- { key: 'NAMN_N2000', desc: 'N2000-namn' },
- { key: 'MPA_ID', desc: 'MPA-ID', classes: ['feature-objid'] },
- { key: 'MPA_NAMN', desc: 'MPA-namn' },
- { key: 'N2000_SITE', desc: 'N2000-ID', classes: ['feature-objid'] },
- fieldMap.geom_area,
- ],
- };
-
- LAYERS.skydd.varldsarv = {
- title: 'Världsarv med mycket höga naturvärden (Unesco)',
- fields: mapFields(fieldMap, [ 'NAMN', 'geom_area' ]),
- };
-
- LAYERS.skydd.naturvardsavtal = {
- title: 'Naturvårdsavtal (Naturvårdsverket, Länsstyrelsen)',
- fields: [
- { key: 'ID', desc: 'ID', classes: ['feature-objid'] },
- { key: 'OBJNAMN', desc: 'Namn' },
- { key: 'FASTBET', desc: 'Fastighet', classes: ['feature-objid'] },
- { key: 'DATSTART', desc: 'Giltig från' },
- { key: 'DATSLUT', desc: 'Giltig till' },
- { key: 'DIARIENRNV', desc: 'Diarienummer', classes: ['feature-attr-dnr'] },
- { key: 'STATUS', desc: 'Satus' },
- fieldMap.geom_area,
- ],
- };
-})();
-
-(function() {
- const fieldMap = mkFieldMap({
- Beteckn: { desc: 'Ärendebeteckning', classes: ['feature-objid'] },
- Biotyp: { desc: 'Biotopkategori' },
- Naturtyp: { desc: 'Skogstyp' },
- ArendeAr: { desc: 'Registeringsår' },
- geom_area: { desc: 'Areal', fn: 'area' },
- AreaProd: { desc: 'Skogsmarksareal', unit: 'ha' },
- Datbeslut: { desc: 'Beslutsdatum' },
- Url: { desc: 'Länk', fn: (v) => formatLink(v, 'Skogens Pärlor') },
- NvaTyp: 'Biotopkategori',
- DatAvtal: 'Avtalsdatum',
- Undertyp: 'Undertyp',
- AvtalatDatum: 'Avtalat datum',
- Objnamn: 'Objektnamn',
- Datinv: 'Datum för fältinventering',
- });
-
- LAYERS.skydd.skogligt_biotopskyddsomrade = {
- title: 'Biotopskydd i skogsmark',
- fields: mapFields(fieldMap, [
- 'Beteckn',
- 'Biotyp',
- 'Naturtyp',
- 'ArendeAr',
- 'geom_area',
- 'AreaProd',
- 'Datbeslut',
- 'Url',
- ]),
- };
- LAYERS.skydd.naturvardsavtal_skogsstyrelsen = {
- title: 'Naturvårdsavtal (Skogsstyrelsen)',
- fields: mapFields(fieldMap, [
- 'Beteckn',
- 'ArendeAr',
- 'NvaTyp',
- 'Naturtyp',
- 'DatAvtal',
- 'geom_area',
- 'AreaProd',
- 'Url',
- 'Undertyp',
- ]),
- };
-
- LAYERS.skydd.atervatningsavtal = {
- title: 'Återvätningsavtal',
- fields: mapFields(fieldMap, [
- 'Beteckn',
- 'ArendeAr',
- 'AvtalatDatum',
- 'geom_area',
- 'Url',
- ]),
- };
-
- LAYERS.nv = {};
- Object.assign(fieldMap, mkFieldMap(Object.fromEntries(
- [1,2,3].map((i) => [`Biotop${i}`, `Biotoptyp #${i}`]).concat(
- [1,2,3,4,5,6,7,8].map((i) => [`Beskrivn${i}`, `Nyckelord #${i} som beskriver objektet`])
- ))));
- LAYERS.nv.naturvarde_sks = {
- title: 'Objekt med naturvärden (Skogsstyrelsen)',
- fields: mapFields(fieldMap, [
- 'Beteckn',
- 'Objnamn',
- 'Datinv',
- 'Biotop1', 'Biotop2', 'Biotop3',
- 'Beskrivn1', 'Beskrivn2', 'Beskrivn3',
- 'geom_area',
- 'Url',
- ]),
- };
- LAYERS.nv.nyckelbiotop = {
- title: 'Nyckelbiotop (Skogsstyrelsen)',
- fields: mapFields(fieldMap, [
- 'Beteckn',
- 'Objnamn',
- 'Datinv',
- 'Biotop1', 'Biotop2', 'Biotop3',
- 'Beskrivn1', 'Beskrivn2', 'Beskrivn3', 'Beskrivn4', 'Beskrivn5', 'Beskrivn6', 'Beskrivn7', 'Beskrivn8',
- 'geom_area',
- 'Url',
- ]),
- };
- LAYERS.nv.nyckelbiotop_storskogsbruk = {
- title: 'Nyckelbiotop (storskogsbruket)',
- fields: [
- { key: 'Org', desc: 'Uppgifter lämnade av' },
- { key: 'InkomDatum', desc: 'Inkom datum' },
- fieldMap.geom_area,
- fieldMap.Url,
- ],
- };
-
- LAYERS.nv.sumpskog = {
- title: 'Sumpskog',
- fields: [
- { key: 'Namn', desc: 'Objektnamn' },
- { key: 'Tradtext', desc: 'Skogstyp' },
- { key: 'Hydrtext', desc: 'Hydrologisk typ' },
- { key: 'Delklass', desc: 'Klass på delobjektet' },
- { key: 'Klassu', desc: 'Klass på objektet' },
- { key: 'Lovandel', desc: 'Andel löv' },
- { key: 'Andelva', desc: 'Andel öppet vatten' },
- { key: 'Krontakn', desc: 'Krontäckning' },
- { key: 'Huggklas', desc: 'Huggningsklass' },
- { key: 'Ingrepp', desc: 'Ingrepp på delobjekt (max 4)' },
- { key: 'Ingrpavv', desc: 'Grad av påverkan på delobjekt (max 4)' },
- { key: 'Objnyck', desc: 'Nyckelord på objektnivå' },
- { key: 'Delnyck', desc: 'Nyckelord på delobjektsnivå' },
- { key: 'Flygar', desc: 'Flygbildsår' },
- { key: 'Faltdat', desc: 'Datum för fältbesök' },
- { key: 'Invtekn', desc: 'Inventeringsteknik' },
- { key: 'Invdat', desc: 'Inventeringdatum' },
- { key: 'Ansvmynd', desc: 'Ansvarig myndighet' },
- fieldMap.geom_area,
- fieldMap.Url,
- ],
- };
-})();
-
-LAYERS.nv.pagaende_naturreservatsbildning = {
- title: 'Pågående naturreservatsbildning',
- fields: [
- { key: 'NAMN', desc: 'Objektnamn' },
- /* XXX unclear what "GRANSJUST" means, just a guess */
- { key: 'GRANSJUST', desc: 'Senast justerat' },
- { key: 'geom_area', desc: 'Areal', fn: 'area' },
- ],
-};
-
-LAYERS.nv.snus = {
- title: 'Skyddsvärd statlig skog',
- fields: [
- { key: 'NAMN', desc: 'Objektnamn' },
- { key: 'AR', desc: 'År' },
- { key: 'NATURGEOGR', desc: 'Naturgeografisk region', classes: ['feature-objid'] },
- { key: 'OBJEKTKATE', desc: 'Objektskategori', classes: ['feature-objid'] },
- { key: 'MARKAGARE', desc: 'Markägare' },
- { key: 'VARDEKARNA', desc: 'Areal värdekärna', unit: 'ha' },
- { key: 'UTV_MARK', desc: 'Areal utvecklingsmark', unit: 'ha' },
- { key: 'TOTAL_AREA', desc: 'Totalareal', unit: 'ha' },
- { key: 'LAND', desc: 'Areal land', unit: 'ha' },
- { key: 'VATTEN', desc: 'Areal vatten', unit: 'ha' },
- { key: 'PROD_SKOG', desc: 'Areal produktiv skogsmark', unit: 'ha' },
- { key: 'SKOG_O_FJG', desc: 'Areal produktiv skogsmark ovanför fjällnära gräns', unit: 'ha' },
- { key: 'SKOG_N_FJG', desc: 'Areal produktiv skogsmark nedanför fjällnära gräns', unit: 'ha' },
- { key: 'SKYDDSZON', desc: 'Areal skyddszon', unit: 'ha' },
- { key: 'ARRO_MARK', desc: 'Areal arronderingsmark', unit: 'ha' },
- { key: 'KRITERIER', desc: 'Kriterier för urval' },
- { key: 'BESKRIVN', desc: 'Beskrivning av området' },
- { key: 'LST_BEDOMN', desc: 'Länsstyrelsens bedömning' },
- { key: 'KALLOR', desc: 'Källor' },
- ],
-};
-
-LAYERS.ri = {};
-(function() {
- const fieldMap = mkFieldMap({
- NAMN: 'Namn',
- SKYDD: 'Skydd',
- AMNESOMRAD: 'Ämnesområde',
- AMNESOMR: 'Ämnesområde',
- OMRADESNR: { desc: 'Områdesnummer', classes: ['feature-objid'] },
- BESKRIVNIN: { desc: 'Beskrivning', fn: formatLink },
- LANK_VARDE: { desc: 'Länk värdebeskrivning', fn: formatLink },
- LAGRUM: 'Lagrum',
- BESLUTSDAT: 'Beslutsdatum',
- BESLDATUM: 'Beslutsdatum',
- ARENDENR: { desc: 'Ärendenummer', classes: ['feature-attr-dnr'] },
- LANK_BESLU: { desc: 'Länk beslut', fn: formatLink },
- AKTIVITET: 'Aktivitet',
- NATURTYP: 'Naturtyp',
- ORGINALID: { desc: 'Original-ID', classes: ['feature-objid'] },
- RIKSID: { desc: 'Riks-ID', classes: ['feature-objid'] },
- geom_area: { desc: 'Areal', fn: 'area' },
- AREA_LAND_: { desc: 'Areal land', unit: 'ha' },
- AREA_VATTE: { desc: 'Areal vatten', unit: 'ha' },
- });
- LAYERS.ri.naturvard = {
- title: 'Riksintresse naturvård',
- fields: mapFields(fieldMap, [
- 'NAMN',
- 'SKYDD',
- 'AMNESOMRAD',
- 'BESKRIVNIN',
- 'LAGRUM',
- 'BESLUTSDAT',
- 'ORGINALID',
- 'RIKSID',
- 'geom_area',
- ]),
- };
- LAYERS.ri.friluftsliv = {
- title: 'Riksintresse friluftsliv',
- fields: mapFields(fieldMap, [
- 'NAMN',
- 'SKYDD',
- 'AMNESOMR',
- 'OMRADESNR',
- 'LANK_VARDE',
- 'LAGRUM',
- 'BESLDATUM',
- 'ARENDENR',
- 'LANK_BESLU',
- 'AKTIVITET',
- 'NATURTYP',
- 'geom_area',
- 'AREA_LAND_',
- 'AREA_VATTE',
- ]),
- };
-
- Object.assign(fieldMap, mkFieldMap({
- METODBESKR: 'Metodbeskrivning',
- TILLKDATUM: 'Tillkomstdatum',
- REVDATUM: 'Revisionsdatum',
- ANM: 'Anmärkning',
- OBJEKTLANK: { desc: 'Objektlänk', fn: formatLink },
- REFERENS: 'Referens',
- OBJTYP: 'Objekttyp',
- ORIGINALID: fieldMap.ORGINALID,
- DIG_SKALA: { desc: 'Digitaliseringsskala', fn: (v) => v > 0 ? v : null },
- }));
- [
- ['rorligt_friluftsliv', /* 0 */ 'rörligt friluftsliv (MB 4 kap 1§ och 2§)'],
- ['obruten_kust', /* 1 */ 'obruten kust (MB 4 kap 3§)'],
- ['obrutet_fjall', /* 2 */ 'obrutet fjäll (MB 4 kap 5§)'],
- ['skyddade_vattendrag', /* 3 */ 'skyddade vattendrag (MB 4 kap 6§)'],
- ]
- .forEach(([k, title], idx) => LAYERS.ri[k] = {
- title: 'Riksintresse ' + title,
- fields: mapFields(idx, fieldMap, [
- 'NAMN',
- 'BESKRIVNIN',
- 'METODBESKR',
- 'TILLKDATUM',
- 'REVDATUM',
- ['OBJTYP', [1]],
- ['ANM', [0,1,3]],
- ['DIG_SKALA', [3]],
- 'OBJEKTLANK',
- 'geom_area',
- 'ORIGINALID',
- 'REFERENS',
- ]),
- });
-})();
-
-
-LAYERS.ren = {
- betesomrade: {
- title: 'Samebyarnas betesområde',
- fields: [
- { key: 'NAMN', desc: 'Sameby' },
- { key: 'SAMEBY_TYP', desc: 'Samebys typ' },
- { key: 'SIGNATUR', desc: 'Signatur' },
- { key: 'AKTUALITET', desc: 'Aktualitet' },
- { key: 'geom_area', desc: 'Areal', fn: 'area' },
- ],
- },
- flyttled: {
- title: 'Samebyarnas markanvändningsredovisning \u2013 flyttled',
- fields: [
- { key: 'LED_ID', desc: 'Led-ID', classes: ['feature-objid'], fn: (v) => v > 0 ? v : null },
- { key: 'SAMEBY1', desc: 'Sameby #1' },
- { key: 'SAMEBY2', desc: 'Sameby #2' },
- { key: 'SAMEBY3', desc: 'Sameby #3' },
- { key: 'BESKRIVNIN', desc: 'Beskrivning' },
- { key: 'ARSTID', desc: 'Årstid' },
- { key: 'RIKSINTR', desc: 'Riksintresse' },
- { key: 'FAST_LED', desc: 'Fast led' },
- { key: 'AKTUALITET', desc: 'Aktualitet' },
- { key: 'SIGNATUR', desc: 'Signatur' },
- { key: 'geom_length', desc: 'Ledlängd', fn: 'length' },
- ],
- },
- riks_ren: {
- title: 'Riksintresse rennäring',
- fields: [
- { key: 'LAGRUM', desc: 'Lagrum' },
- { key: 'AKTUALITET', desc: 'Aktualitet' },
- { key: 'SIGNATUR', desc: 'Signatur' },
- { key: 'geom_area', desc: 'Areal', fn: 'area' },
- ],
- },
- omr_riks: {
- title: '(Kärn)områden av riksintresse rennäring',
- fields: [
- { key: 'OMR_NR', desc: 'Områdes-ID', classes: ['feature-objid'] },
- { key: 'LANK', desc: 'Länk' },
- { key: 'ARET_RUNT', desc: 'Årets runt' },
- { key: 'SAMEBY', desc: 'Sameby' },
- { key: 'ANSVARIG', desc: 'Ansvarig' },
- { key: 'AKTUALITET', desc: 'Aktualitet' },
- { key: 'SIGNATUR', desc: 'Signatur' },
- { key: 'geom_area', desc: 'Areal', fn: 'area' },
- ],
- },
-};
-
-
-
-/* format value to HTML */
-const formatValue = function(value, options) {
- let unit = options?.unit;
- if (options?.fn == null) {
- /* no-op */
- } else if (typeof options.fn === 'function') {
- value = options.fn(value);
- } else if (options.fn === 'length' && typeof value === 'number' && unit == null) {
- if (value < 1000) {
- unit = 'm';
- } else {
- value /= 1000;
- value = Math.round(value*100) / 100;
- unit = 'km';
- }
- } else if (options.fn === 'area' && typeof value === 'number' && unit == null) {
- if (value < 10000) {
- unit = 'm²';
- } else if (value < 10000 * 10000) {
- value /= 10000;
- unit = 'ha';
- } else {
- value /= 1000000;
- unit = 'km²';
- }
- value = Math.round(value*100) / 100;
- }
- if (value == null) {
- return null;
- }
- if (value instanceof HTMLElement) {
- return value;
- }
- switch (typeof value) {
- case 'boolean':
- return document.createTextNode(value ? 'Ja' : 'Nej');
- case 'string':
- return document.createTextNode(value);
- case 'number':
- if (unit != null) {
- return document.createTextNode(value.toLocaleString('sv-SE') + '\u202F' + unit);
- }
- return document.createTextNode(value.toString());
- default:
- return null;
- }
-};
-
-/* turn the properties into a fine <table> */
-const formatFeaturePropertiesToHTML = function(properties) {
- const table = document.createElement('table');
- table.classList.add('table', 'table-sm', 'table-borderless', 'table-hover');
-
- const tbody = document.createElement('tbody');
- table.appendChild(tbody);
-
- const def = LAYERS[properties.layer_group][properties.layer];
- def.fields.forEach(function(field) {
- const tr = document.createElement('tr');
- tbody.appendChild(tr);
-
- const th = document.createElement('th');
- th.setAttribute('scope', 'row');
- tr.appendChild(th);
- const textDesc = document.createTextNode(field.desc);
- th.appendChild(textDesc);
-
- const td = document.createElement('td');
- tr.appendChild(td);
- const v = formatValue(properties[field.key], field);
- if (v != null) {
- td.appendChild(v);
- }
- field.classes?.forEach?.((c) => td.classList.add(c));
- });
-
- const content = document.createElement('div');
- if (def.title != null) {
- const h = document.createElement('h6');
- content.appendChild(h);
- const textNode = document.createTextNode(def.title);
- h.appendChild(textNode);
- }
-
- content.appendChild(table);
- return content;
-};
-
-/* Initialize popup overlay with the give map and HTML element */
-let popupOverlay = null;
-(function() {
- popupOverlay = new Overlay({
- stopEvent: true,
- element: document.getElementById('popup'),
- });
- map.addOverlay(popupOverlay);
-})();
-
-let featureOverlayLayer = null;
-let overlayAttributes = [],
- overlayAttrIdx = 0,
- mapSources = {};
-/* Clear the highlighted feature list and make the overlay layer invisible */
-const disposeFeatureOverlay = function() {
- if (featureOverlayLayer?.getVisible?.()) {
- featureOverlayLayer.setVisible(false);
- featureOverlayLayer.changed();
- }
- /* clear the overlay list */
- overlayAttributes = [];
- overlayAttrIdx = 0;
- mapSources = {};
-}
-
-let popover = null;
-/* Clear overlay layer and dispose popover */
-export const disposePopover = function() {
- disposeFeatureOverlay();
- if (popover?.tip != null) {
- popover.dispose();
- }
-};
-
-/* Initialize popover on the given map */
-(function() {
- featureOverlayLayer = new VectorTileLayer({
- zIndex: 65535,
- declutter: false,
- visible: false,
- renderMode: 'vector',
- style: null,
- map: map,
- });
-
- const header = document.createElement('div');
- header.classList.add('d-flex');
-
- const headerGrabbingArea = document.createElement('div');
- headerGrabbingArea.classList.add('flex-grow-1', 'grabbing-area', 'pe-2', 'me-2');
- header.appendChild(headerGrabbingArea);
-
- const pageNode = document.createElement('h6');
- headerGrabbingArea.appendChild(pageNode);
-
- headerGrabbingArea.onmousedown = function(event) {
- /* move the popover around */
- if (event.button != 0) {
- return;
- }
- const popoverTip = popover.tip;
- if (popoverTip.classList.contains('popover-maximized')) {
- return;
- }
- headerGrabbingArea.classList.add('grabbing-area-grabbed');
-
- if (!popoverTip.classList.contains('popover-detached')) {
- /* detach popover tip */
- popoverTip.classList.add('popover-detached');
- const rect = popoverTip.getBoundingClientRect();
- const style = popoverTip.style;
- style.display = 'none'; /* avoid reflows between the following assignments */
- style.position = 'absolute';
- style.transform = '';
- style.inset = `${rect.top}px auto auto ${rect.left}px`;
- style.display = '';
- }
-
- let clientX = event.clientX, clientY = event.clientY;
- document.onmousemove = function(event) {
- const offsetX = clientX - event.clientX;
- const offsetY = clientY - event.clientY;
- clientX = event.clientX;
- clientY = event.clientY;
- popoverTip.style.top = (popoverTip.offsetTop - offsetY).toString() + 'px';
- popoverTip.style.left = (popoverTip.offsetLeft - offsetX).toString() + 'px';
- };
-
- document.onmouseup = function(event) {
- /* done moving around */
- if (event.button != 0) {
- return;
- }
- headerGrabbingArea.classList.remove('grabbing-area-grabbed');
- document.onmousemove = null;
- document.onmouseup = null;
- };
- };
-
- /* current number page and total page count */
- const pageNum = document.createElement('span');
- const pageCount = document.createElement('span');
- pageNode.appendChild(document.createTextNode('Träff '));
- pageNode.appendChild(pageNum);
- pageNode.appendChild(document.createTextNode(' av '));
- pageNode.appendChild(pageCount);
-
- /* highlight a feature */
- const featureOverlayStyle = new Style({
- stroke: new Stroke({
- color: 'rgba(0, 255, 255, .8)',
- width: 3,
- }),
- });
- const highlightFeature = function(layer_group, layer, id) {
- const source = mapSources[layer_group];
- if (source == null) {
- return;
- }
- if (featureOverlayLayer.getSource() !== source) {
- /* console.log('Updating source for feature overlay layer'); */
- featureOverlayLayer.setVisible(false);
- featureOverlayLayer.setSource(source);
- }
- featureOverlayLayer.setStyle(function(feature) {
- if (feature.getId() === id && feature.getProperties().layer === layer) {
- return featureOverlayStyle;
- }
- });
- featureOverlayLayer.setVisible(true);
- featureOverlayLayer.changed();
- };
- /* highlight the feature at index overlayAttrIdx within the CGI reply list */
- const refreshPopover = function() {
- const attr = overlayAttributes[overlayAttrIdx];
- highlightFeature(attr.layer_group, attr.layer, attr.ogc_fid);
-
- pageNum.innerHTML = (overlayAttrIdx + 1).toString();
- const content = formatFeaturePropertiesToHTML(attr);
- popover.tip.getElementsByClassName('popover-body')[0].replaceChildren(content);
- };
- /* go back/forward in the overlayAttributes list */
- const onClickPageChange = function(event, offset) {
- const btn = event.target;
- if (btn.classList.contains('disabled') || popover?.tip == null) {
- return;
- }
- if (overlayAttrIdx + offset < 0 || overlayAttrIdx + offset > overlayAttributes.length - 1) {
- return; /* out of range */
- }
-
- overlayAttrIdx += offset;
- if (overlayAttrIdx < 1) {
- btnPrev.classList.add('disabled');
- } else {
- btnPrev.classList.remove('disabled');
- }
- if (overlayAttrIdx < overlayAttributes.length - 1) {
- btnNext.classList.remove('disabled');
- } else {
- btnNext.classList.add('disabled');
- }
-
- refreshPopover();
- setTimeout(function() { btn.blur() }, 100);
- };
-
- /* control buttons */
- const btnPrev = document.createElement('button');
- btnPrev.classList.add('popover-button', 'popover-button-prev');
- btnPrev.setAttribute('type', 'button');
- btnPrev.title = 'Föregående träff';
- btnPrev.setAttribute('aria-label', btnPrev.title);
- btnPrev.onclick = function(event) {
- return onClickPageChange(event, -1);
- };
-
- const btnNext = document.createElement('button');
- btnNext.classList.add('popover-button', 'popover-button-next');
- btnNext.setAttribute('type', 'button');
- btnNext.title = 'Nästa träff';
- btnNext.setAttribute('aria-label', btnNext.title);
- btnNext.onclick = function(event) {
- return onClickPageChange(event, +1);
- };
-
- const btnExpand = document.createElement('button');
- btnExpand.classList.add('popover-button', 'popover-button-expand');
- btnExpand.setAttribute('type', 'button');
- const btnExpandTitle = 'Förstora';
- const btnExpandTitle2 = 'Förminska';
- btnExpand.setAttribute('aria-label', btnExpand.title);
- btnExpand.onclick = function() { /* maximize or reduce the popover */
- if (popover?.tip == null) {
- return;
- }
- if (!popover.tip.classList.contains('popover-maximized')) {
- popover.tip.classList.add('popover-maximized');
- btnExpand.classList.replace('popover-button-expand', 'popover-button-reduce');
- btnExpand.title = btnExpandTitle2;
- btnExpand.setAttribute('aria-label', btnExpand.title);
- } else {
- popover.tip.classList.remove('popover-maximized');
- btnExpand.classList.replace('popover-button-reduce', 'popover-button-expand');
- btnExpand.title = btnExpandTitle;
- btnExpand.setAttribute('aria-label', btnExpand.title);
- }
- setTimeout(function() { btnExpand.blur() }, 100);
- };
-
- const btnClose = document.createElement('button');
- btnClose.classList.add('popover-button', 'popover-button-close');
- btnClose.setAttribute('type', 'button');
- btnClose.title = 'Stäng';
- btnClose.setAttribute('aria-label', btnClose.title);
- btnClose.onclick = disposePopover;
-
- header.appendChild(btnPrev);
- header.appendChild(btnNext);
- header.appendChild(btnExpand);
- header.appendChild(btnClose);
-
- const container0 = map.getViewport().getElementsByClassName('ol-overlaycontainer-stopevent')[0];
- map.on('singleclick', function(event) {
- disposeFeatureOverlay();
-
- /* dispose any pre-existing popover if not in detached mode */
- popover = Popover.getInstance(popupOverlay.element);
- if (popover?.tip != null && !popover.tip.classList.contains('popover-detached')) {
- popover.dispose();
- }
-
- const size = event.map.getSize();
- if (size[0] < 576 || size[1] < 576) {
- return; /* skip popover if the map is too small */
- }
-
- /* unclear how many feature we'll find, don't render prev/next buttons for now */
- pageNode.classList.add('d-none');
- btnPrev.classList.add('d-none', 'disabled');
- btnNext.classList.add('d-none', 'disabled');
-
- /* never start in maximized mode */
- if (popover?.tip != null) {
- popover.tip.classList.remove('popover-maximized');
- }
- btnExpand.classList.replace('popover-button-reduce', 'popover-button-expand');
- btnExpand.title = btnExpandTitle;
- btnExpand.setAttribute('aria-label', btnExpand.title);
-
- const fetch_body = [];
- event.map.forEachFeatureAtPixel(event.pixel, function(feature, layer) {
- const layerGroup = layer.get('layerGroup');
- const layerName = feature.getProperties().layer;
- mapSources[layerGroup] ??= layer.getSource();
- const def = layerName != null ? LAYERS[layerGroup][layerName] : null;
- if (def?.fields == null) {
- /* skip layers which didn't opt-in for popover */
- return false;
- }
- if (fetch_body.length === 0) {
- /* first feature in the list, mark cursor and detached popover as in-progress */
- document.body.classList.add('inprogress');
- popover?.tip?.classList?.add?.('inprogress');
- }
- fetch_body.push({
- layer_group: layerGroup,
- layer: layerName,
- fid: feature.getId() ?? -1,
- });
- if (fetch_body.length >= 100) {
- return true; /* enough matches already, stop detection here */
- }
- }, {
- hitTolerance: 5,
- checkWrapped: false,
- layerFilter: (lyr) => lyr.get('layerGroup') != null,
- });
-
- if (fetch_body.length === 0) {
- /* no feature at pixel (or only within layers which didn't opt-in for popover) */
- if (popover?.tip != null) {
- /* dispose pre-detached popover */
- popover.dispose();
- }
- return;
- }
-
- fetch('/q', {
- method: 'POST',
- body: JSON.stringify(fetch_body),
- headers: {
- 'Content-Type': 'application/json; charset=UTF-8',
- },
- })
- .then(function(resp) {
- if (resp.status === 200) {
- return resp.json();
- } else {
- throw new Error(`${resp.url} [${resp.status}]`);
- }
- })
- .then(function(data) {
- /* the data is received from the CGI in the order it was sent */
- /* TODO optimizations on the CGI would break the above assumption, so the
- * decoded JSON response would need to be reordered to match fetch_body */
- overlayAttributes = data;
- if (overlayAttributes.length === 0) {
- /* couldn't fetch any attribute for feature(s) at pixel */
- if (popover?.tip != null) {
- /* dispose pre-detached popover */
- popover.dispose();
- }
- return;
- }
-
- pageCount.innerHTML = overlayAttributes.length.toString();
- if (overlayAttributes.length >= 2) {
- /* render prev/pre buttons */
- btnNext.classList.remove('d-none', 'disabled');
- btnPrev.classList.remove('d-none');
- pageNode.classList.remove('d-none');
- }
- if (popover?.tip == null) {
- /* create a new popover (we're not already showing one in detached mode) */
- pageNum.innerHTML = (overlayAttrIdx + 1).toString();
- popupOverlay.setPosition(event.coordinate);
-
- const attr = overlayAttributes[0];
- highlightFeature(attr.layer_group, attr.layer, attr.ogc_fid);
- popover = new Popover(popupOverlay.element, {
- template: '<div class="popover" role="tooltip"><div class="popover-arrow"></div>' +
- '<div class="popover-header"></div><div class="popover-body"></div></div>',
- title: header,
- content: formatFeaturePropertiesToHTML(attr),
- html: true,
- placement: 'right',
- fallbackPlacements: ['right', 'left', 'bottom', 'top'],
- container: container0,
- });
- popover.show();
- }
- else if (popover.tip.classList.contains('popover-detached')) {
- /* update existing detached mode popover */
- refreshPopover();
- popover.tip.classList.remove('inprogress');
- }
- })
- .catch(function(e) {
- console.log(e);
- })
- .finally(function() {
- /* remove in-progress marking on the cursor */
- document.body.classList.remove('inprogress');
- });
- });
-})();
diff --git a/src/style.css b/src/style.css
deleted file mode 100644
index cf7fc86..0000000
--- a/src/style.css
+++ /dev/null
@@ -1,650 +0,0 @@
-@import "~bootstrap/dist/css/bootstrap.css";
-@import "~bootstrap-icons/font/bootstrap-icons.css";
-@import "~ol/ol.css";
-
-html, body {
- margin: 0;
- height: 100%;
- --ol-foreground-color: var(--bs-body-color);
- --ol-background-color: var(--bs-body-bg);
-
- /* highlight non-bootstrapy style */
- --ol-accent-background-color: red;
- --ol-subtle-background-color: red;
- --ol-partial-background-color: red;
- --ol-subtle-foreground-color: red;
- --ol-brand-color: red;
-}
-
-#map {
- position: absolute;
- top: 0;
- bottom: 0;
- width: 100%;
- --map-container-padding: 1rem;
-}
-
-body.inprogress {
- cursor: wait;
-}
-
-#map-control-container {
- --map-menu-spacing: .5em;
- position: absolute;
- padding: var(--map-container-padding);
- display: flex;
- justify-content: flex-end;
- width: 100%;
- height: 100%;
-}
-@media screen and (max-width: 767px), screen and (max-height: 767px) {
- #map {
- --map-container-padding: .5rem;
- }
-}
-
-#zoom-control {
- position: absolute;
- margin-left: var(--map-container-padding);
- margin-top: var(--map-container-padding);
-}
-#zoom-control .ol-zoom {
- position: relative;
- display: block;
- width: revert;
- top: auto;
- left: auto;
- pointer-events: auto;
-}
-#zoom-control .ol-zoomslider {
- margin-top: .5rem;
- position: relative;
- display: block;
- width: revert;
- top: auto;
- left: auto;
- padding: 10px 0;
-
- background-color: RGBA(var(--bs-body-bg-rgb), .95);
- border-radius: var(--bs-modal-border-radius);
- border: var(--bs-modal-border-width) solid var(--bs-modal-border-color);
- overflow-y: hidden;
- z-index: 0;
-}
-#zoom-control .ol-zoomslider::after {
- content: "";
- position: absolute;
- top: 3%;
- left: calc(50% - 3px);
- width: 6px;
- height: 94%;
- background-color: RGBA(211, 212, 213, .4);
- border-radius: 5px;
- border: var(--bs-modal-border-width) solid var(--bs-modal-border-color);
- cursor: pointer;
- pointer-events: auto;
-}
-#zoom-control button.ol-zoomslider-thumb {
- z-index: 10;
- height: 10px;
- width: 80%;
- margin: 0 auto;
- padding: 0;
- pointer-events: auto;
-}
-
-.ol-scale-line {
- display: block;
- width: revert;
- height: revert;
- top: auto;
- bottom: var(--map-container-padding);
- left: var(--map-container-padding);
- z-index: 0;
-
- padding: .5rem;
- background-color: RGBA(var(--bs-body-bg-rgb), .95);
- background-clip: padding-box;
- border: var(--bs-modal-border-width) solid var(--bs-modal-border-color);
- border-radius: var(--bs-modal-border-radius);
- pointer-events: auto;
-}
-.ol-scale-line-inner {
- border: 1px solid var(--bs-body-color);
- border-top: none;
- color: var(--bs-body-color);
- font-size: 80%;
- margin: 0;
-}
-
-#map-menu {
- position: relative;
-}
-@media screen and (min-width: 576px) {
- #map-menu > .ol-control > button {
- font-size: 150%;
- }
-}
-@media screen and (min-width: 768px) {
- #map-menu > .ol-control > button {
- font-size: 200%;
- }
- #zoom-control > .ol-zoom > button {
- font-size: 120%;
- }
-}
-#map-menu > * {
- margin-bottom: var(--map-menu-spacing);
- pointer-events: auto;
-}
-@media screen and (max-width: 767px) {
- #map-control-container {
- --map-menu-spacing: .25rem;
- }
- .ol-scale-line-inner {
- font-size: 70%;
- }
-}
-
-#map-menu > .ol-control {
- position: relative;
- inset: initial;
-}
-
-.ol-control {
- background: none;
- border: none;
- outline: none; /* eslint-disable-line css/use-baseline */
-}
-.ol-control button.btn {
- --bs-btn-padding-x: 0.5rem;
- --bs-btn-padding-y: 0.5rem;
- display: block;
- margin: 0;
- padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x);
- width: auto;
- height: auto;
- font-weight: bold;
- text-decoration: none;
- font-size: inherit;
- text-align: center;
- color: var(--bs-btn-color);
- background-color: var(--bs-btn-bg);
- border-radius: var(--bs-btn-border-radius);
- border: var(--bs-btn-border-width) solid var(--bs-btn-border-color);
-}
-.ol-control button.btn:focus:not(:focus-visible, :hover) {
- text-decoration: none;
- color: var(--bs-btn-color);
- background-color: var(--bs-btn-bg);
- border-color: var(--bs-btn-border-color);
- outline: none; /* eslint-disable-line css/use-baseline */
-}
-.ol-control button.btn:hover,
-.ol-control button.btn:focus-visible {
- text-decoration: none;
- color: var(--bs-btn-hover-color);
- background-color: var(--bs-btn-hover-bg);
- border-color: var(--bs-btn-hover-border-color);
- outline: none; /* eslint-disable-line css/use-baseline */
-}
-.btn-light, .btn-dark {
- --bs-btn-border-color: var(--bs-btn-hover-border-color);
-}
-
-#map-control-container[aria-hidden="true"],
-#layer-selection-panel[aria-hidden="true"],
-#map-legend-panel[aria-hidden="true"] {
- display: none;
-}
-#layer-selection-panel,
-#map-legend-panel {
- position: relative;
- margin-left: 0;
- margin-right: var(--map-menu-spacing);
- font-size: medium;
- z-index: 11;
- height: max-content;
- max-height: 100%;
- pointer-events: auto;
- --bs-modal-color: var(--bs-body-color);
- --bs-modal-padding: .75rem;
-}
-#layer-selection-panel {
- /*min-width: min-content;*/
- /*max-width: 35%;*/
- /*width: revert;*/
- max-width: 360px;
-}
-#map-legend-panel {
- max-width: 410px;
-}
-@keyframes fade-in {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
-}
-#map-legend-panel .modal-body {
- -webkit-user-select: text;
- -moz-user-select: text;
- user-select: text; /* eslint-disable-line css/use-baseline */
-}
-#layer-selection-panel[aria-hidden="false"],
-#map-legend-panel[aria-hidden="false"] {
- animation: fade-in .25s ease-in-out both;
- display: block;
-}
-
-@media screen and (max-aspect-ratio: .75), screen and (max-width: 460px) {
- /* 4/3 in portrait mode, likely mobile in portrait mode */
- #map-control-container {
- flex-direction: column-reverse;
- }
- #map-menu {
- display: flex;
- justify-content: flex-end;
- }
- #map-menu > * {
- margin-bottom: 0;
- margin-left: var(--map-menu-spacing);
- }
- #map-menu .ol-full-screen {
- display: none;
- }
- #layer-selection-panel,
- #map-legend-panel {
- margin: var(--map-menu-spacing) 0 0 auto;
- }
-}
-
-#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,
- #age-filter-button,
- #export-to-image,
- #layer-selection-panel,
- #map-legend-panel,
- #map-menu .ol-full-screen {
- display: none;
- }
-}
-@media screen and (max-height: 576px), screen and (max-width: 500px) {
- #zoom-control .ol-zoomslider {
- display: none;
- }
-}
-@media screen and (max-width: 300px), screen and (max-height: 300px) {
- body {
- --bs-body-font-size: .8rem;
- }
- .ol-control button.btn {
- --bs-btn-padding-x: 0.4rem;
- --bs-btn-padding-y: 0.4rem;
- }
-}
-#info-modal {
- /* close the modal when clicking the backdrop */
- pointer-events: none;
- -webkit-user-select: text;
- -moz-user-select: text;
- user-select: text; /* eslint-disable-line css/use-baseline */
- --bs-modal-header-padding: 1rem;
- --modal-info-padding-x: var(--bs-modal-header-padding);
- --modal-info-padding-y: .5rem;
- --modal-info-bg-light: rgba(0, 0, 0, .08);
-}
-#info-modal .modal-header {
- padding: var(--modal-info-padding-y) var(--modal-info-padding-x);
-}
-#info-modal .list-group-item,
-#info-modal {
- --bs-list-group-border-width: 1px;
-}
-#info-accordion {
- --bs-accordion-active-bg: var(--bs-accordion-bg);
- --bs-accordion-active-color: var(--bs-body-color);
- --bs-accordion-btn-padding-x: 0;
- --bs-accordion-btn-padding-y: .025rem;
- --bs-accordion-btn-focus-box-shadow: none;
- --bs-accordion-body-padding-x: 0;
- --bs-accordion-body-padding-y: 0;
- --bs-accordion-btn-active-bg: var(--modal-info-bg-light);
- padding: 0 var(--modal-info-padding-x);
-}
-#info-modal .accordion-item {
- border: none;
-}
-#info-modal .accordion-header > .accordion-button[aria-expanded="false"]:hover {
- background-color: rgb(from var(--modal-info-bg-light) r g b / calc(alpha*.4));
-}
-#info-modal .accordion-header > .accordion-button[aria-expanded="true"] {
- background-color: var(--bs-accordion-btn-active-bg);
-}
-#info-modal ul.list-group > li.list-group-item {
- padding: .3rem 0;
- border: none;
-}
-#info-modal ul.list-group > li.list-group-item:last-child {
- padding-bottom: var(--modal-info-padding-y);
-}
-#info-body > ul.list-group {
- margin-top: var(--modal-info-padding-y);
- border-top: var(--bs-list-group-border-width) solid var(--modal-info-bg-light);
- padding: 0 var(--modal-info-padding-x);
-}
-#info-modal ul.list-group > li.list-group-item:not(:first-child) {
- border-top: var(--bs-list-group-border-width) solid var(--modal-info-bg-light);
-}
-#info-accordion > .accordion-item:not(:last-child) ul.list-group > li.list-group-item:last-child {
- border-bottom: var(--bs-list-group-border-width) solid var(--modal-info-bg-light);
-}
-#info-modal .modal-body ul.list-group > li.list-group-item:not(.text-muted):hover {
- background-color: rgb(from var(--modal-info-bg-light) r g b / calc(alpha*.4));
-}
-#info-body {
- padding: var(--modal-info-padding-y) 0;
-}
-#info-body > ul.list-group > li.list-group-item p,
-#info-modal .accordion-body ul.list-group > li.list-group-item p {
- margin: 0;
-}
-#info-body > ul.list-group > li.list-group-item h6,
-#info-modal .accordion-body ul.list-group > li.list-group-item h6 {
- margin: .05rem 0 .15rem 0;
- font-size: 1.15rem;
-}
-#info-modal .modal-body a {
- color: inherit;
- text-decoration: none;
-}
-#info-modal .modal-body a:hover {
- opacity: .8;
- text-decoration: underline;
-}
-#info-modal .modal-body .info-credits {
- border-top: var(--bs-list-group-border-width) solid var(--modal-info-bg-light);
- padding: var(--modal-info-padding-y) var(--modal-info-padding-x) 0 var(--modal-info-padding-x);
- margin: 0;
-}
-
-.ol-overlaycontainer-stopevent .modal-backdrop.show {
- pointer-events: auto;
-}
-
-#layer-selection-panel .accordion {
- --bs-accordion-active-bg: var(--bs-accordion-bg);
- --bs-accordion-active-color: var(--bs-body-color);
- --bs-accordion-btn-padding-x: 0;
- --bs-accordion-btn-padding-y: 0;
- --bs-accordion-btn-focus-box-shadow: none;
- --bs-accordion-body-padding-x: 0;
- --bs-accordion-body-padding-y: 0;
-}
-#layer-selection-panel .accordion-item {
- border: none;
-}
-#layer-selection-panel .accordion-body .list-group {
- padding-left: 1.5em;
-}
-#layer-selection-panel .accordion .list-group.list-group-flush > .list-group-item {
- padding: 0;
- border: none;
-}
-#layer-selection-panel .accordion-item .form-check {
- padding-left: 0;
- margin: 0.125rem 0 0 0;
-}
-#layer-selection-panel .accordion-item:first-child .form-check {
- margin-top: 0;
-}
-#layer-selection-panel .accordion-header > .accordion-button[aria-expanded="true"] {
- padding-bottom: 0.125rem;
- margin-bottom: 0.125rem;
-}
-#layer-selection-panel .accordion-header > .accordion-button > .form-check > .form-check-input,
-#layer-selection-panel .accordion > .accordion-item > .form-check > .form-check-input {
- margin-left: 0;
- float: none;
-}
-#layer-selection-panel .accordion-item .form-check > .form-check-input,
-#layer-selection-panel .accordion-item .list-group-item > .d-inline-flex > .form-check-input {
- margin-right: .5em !important;
-}
-#layer-selection-panel .accordion-header > .accordion-button > .form-check > .form-check-label,
-#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);
-}
-
-#age-filter-modal .modal-body .btn-group {
- width: 100%;
-}
-#age-filter-modal .age-filter-infotext {
- margin: 0 0 var(--bs-modal-padding) 0;
-}
-#age-filter-form .age-filter-settings .age-filter-settings-desc {
- margin: var(--bs-modal-padding) 0;
-}
-#age-filter-form .age-filter-settings {
- margin: 0 0 var(--bs-modal-padding) 0;
-}
-#age-filter-form .age-filter-settings p.text-muted {
- margin: 0;
-}
-#age-filter-modal p {
- -webkit-user-select: text;
- -moz-user-select: text;
- user-select: text; /* eslint-disable-line css/use-baseline */
-}
-
-.popover {
- --bs-popover-header-padding-x: .75rem;
- --bs-popover-header-padding-y: .5rem;
- --bs-popover-body-offset-x: .3rem;
- --bs-popover-body-padding-x: calc(var(--bs-popover-header-padding-x) - var(--bs-popover-body-offset-x));
- --bs-popover-body-padding-y: .5rem;
- --bs-popover-header-bg: var(--bs-popover-bg);
- --bs-popover-zindex: 1000;
- --bs-popover-max-width: 450px;
- width: var(--bs-popover-max-width);
- pointer-events: auto;
-}
-.popover.popover-maximized {
- --bs-popover-header-padding-x: 1rem;
- --bs-popover-header-padding-y: 1rem;
- --bs-popover-body-padding-y: 1rem;
- --bs-popover-body-offset-x: .5rem;
- --bs-popover-font-size: 1rem;
-}
-.popover.inprogress > .popover-header,
-.popover.inprogress > .popover-body {
- filter: opacity(70%);
- pointer-events: none;
-}
-.popover-header {
- -webkit-user-select: none;
- -moz-user-select: none;
- user-select: none; /* eslint-disable-line css/use-baseline */
- --bs-heading-color: var(--bs-popover-header-color);
-}
-.popover-header h5, .popover-header h6 {
- line-height: var(--bs-body-line-height);
- vertical-align: middle;
- margin: 0;
-}
-.popover-body {
- -webkit-user-select: text;
- -moz-user-select: text;
- user-select: text; /* eslint-disable-line css/use-baseline */
- max-height: 40vh;
- overflow: auto auto;
-}
-.popover.popover-maximized .popover-body {
- max-height: calc(100% - 2*var(--bs-popover-header-padding-y) - var(--bs-body-line-height)*var(--bs-popover-font-size) - var(--bs-popover-border-width));
-}
-.popover-body h6, .popover-body h5 {
- margin-bottom: var(--bs-popover-body-padding-y);
- margin-left: calc(var(--bs-popover-header-padding-x) - var(--bs-popover-body-padding-x));
- margin-right: calc(var(--bs-popover-header-padding-x) - var(--bs-popover-body-padding-x));
-}
-.popover.popover-maximized .popover-body h5,
-.popover.popover-maximized .popover-body h6 {
- font-size: calc(1.2 * var(--bs-popover-font-size));
-}
-.popover-body .table {
- --bs-table-bg: none;
- --bs-table-hover-bg: rgba(0, 0, 0, .04);
- --bs-table-bg-padding-y: .1rem;
- margin: 0;
-}
-.popover.popover-maximized .popover-body .table {
- --bs-table-hover-bg: none;
- --bs-table-bg-padding-y: .5rem;
-}
-.popover.popover-maximized .popover-body .table tr:nth-of-type(2n+1) {
- background: rgba(0, 0, 0, .05);
-}
-.popover-body table > tbody > tr > th[scope="row"] {
- font-style: italic;
- padding-right: .75em;
- font-weight: normal;
-}
-.popover .popover-body table > tbody > tr > th[scope="row"] {
- width: 35%;
-}
-.popover-body table > tbody > tr > th[scope="row"],
-.popover-body table > tbody > tr > td {
- padding: var(--bs-table-bg-padding-y) var(--bs-popover-body-offset-x);
-}
-.feature-attr-mrr-license-id, .feature-attr-dnr, .feature-objid, .feature-orgnr {
- font-family: var(--bs-font-monospace);
- word-wrap: break-word;
-}
-
-/* inspired from bootstrap's .btn-close */
-.popover-header .popover-button {
- box-sizing: content-box;
- width: 1em;
- height: 1em;
- padding: 0.25em 0.25em;
- color: #000;
- background: transparent var(--popover-button-icon) center/1em auto no-repeat;
- border: 0;
- border-radius: 0.375rem;
- opacity: .5;
-}
-.popover-header .popover-button:hover {
- text-decoration: none;
- opacity: .75;
-}
-.popover-header .popover-button:focus {
- outline: 0; /* eslint-disable-line css/use-baseline */
- box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
- opacity: 1;
-}
-.popover-header .popover-button:disabled, .popover-header .popover-button.disabled {
- pointer-events: none;
- opacity: .25;
-}
-
-/* SVG from bootstrap icons v1.11.0 (released under MIT License) */
-.popover-header .popover-button-prev {
- --popover-button-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath transform='scale(1.3799) translate(-2.2025 -2.2025)' d='M10 12.796V3.204L4.519 8zm-.659.753-5.48-4.796a1 1 0 0 1 0-1.506l5.48-4.796A1 1 0 0 1 11 3.204v9.592a1 1 0 0 1-1.659.753'/%3e%3c/svg%3e");
-}
-.popover-header .popover-button-next {
- --popover-button-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath transform='scale(1.3799) translate(-2.2025 -2.2025)' d='M6 12.796V3.204L11.481 8zm.659.753 5.48-4.796a1 1 0 0 0 0-1.506L6.66 2.451C6.011 1.885 5 2.345 5 3.204v9.592a1 1 0 0 0 1.659.753'/%3e%3c/svg%3e");
-}
-.popover-header .popover-button-expand {
- --popover-button-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707m4.344-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707'/%3e%3c/svg%3e");
-}
-.popover-header .popover-button-reduce {
- --popover-button-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.172 15.828a.5.5 0 0 0 .707 0l4.096-4.096V14.5a.5.5 0 1 0 1 0v-3.975a.5.5 0 0 0-.5-.5H1.5a.5.5 0 0 0 0 1h2.768L.172 15.121a.5.5 0 0 0 0 .707M15.828.172a.5.5 0 0 0-.707 0l-4.096 4.096V1.5a.5.5 0 1 0-1 0v3.975a.5.5 0 0 0 .5.5H14.5a.5.5 0 0 0 0-1h-2.768L15.828.879a.5.5 0 0 0 0-.707'/%3e%3c/svg%3e");
-}
-.popover-header .popover-button-close {
- --popover-button-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath transform='scale(1.3332) translate(-2 -2)' d='M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z'/%3e%3c/svg%3e");
-}
-
-.popover:not(.popover-maximized) .grabbing-area {
- cursor: move; /* fallback if grab cursor is unsupported */
- cursor: grab;
- cursor: -moz-grab;
- cursor: -webkit-grab;
-}
-.popover:not(.popover-maximized) .grabbing-area.grabbing-area-grabbed {
- cursor: grabbing;
- cursor: -moz-grabbing;
- cursor: -webkit-grabbing;
-}
-.popover.popover-detached > .popover-arrow,
-.popover.popover-maximized > .popover-arrow {
- display: none;
-}
-.popover.popover-maximized {
- position: relative !important;
- inset: 0 !important;
- transform: none !important;
- margin: calc(.75*var(--map-container-padding)) auto !important;
- --bs-popover-max-width: calc(100vw - 1.5*var(--map-container-padding));
- height: calc(100vh - 1.5*var(--map-container-padding));
- animation: fade-in .25s ease-in-out both;
-}
-@media screen and (min-width: 1280px) {
- .popover.popover-maximized {
- --bs-popover-max-width: 1280px;
- }
-}
-@media screen and (min-height: 1920px) {
- .popover.popover-maximized {
- height: 1920px;
- margin-top: calc(50vh - 960px) !important;
- margin-bottom: calc(50vh - 960px) !important;
- }
-}