/*********************************************************************** * Copyright © 2024-2025 Guilhem Moulin * 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 . **********************************************************************/ 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'; /* TODO: this should really be refactored… */ const layers = {} layers.mrr = { appr_ec: { title: 'Bearbetningskoncession \u2013 beviljad', fields: [ ['Namn', 'name'], ['Koncessionsmineral', 'mineral'], ['Ägare', 'owners'], ['Tillståndsid', 'licenceid', { classes: ['feature-attr-mrr-license-id'] }], ['Areal', 'geom_area', { fn: 'area' }], ['Giltig från', 'validfrom'], ['Giltig till', 'validto'], ['Diarienummer', 'diarynr', { classes: ['feature-attr-dnr'] }], ['Ansökningsdatum', 'appl_date'], ['Beslutsdatum', 'dec_date'], //['Kommun', 'Municipality'], //['Län', 'County'], ], }, appl_ec: { title: 'Bearbetningskoncession \u2013 ansökt', fields: [ ['Namn', 'name'], ['Koncessionsmineral', 'mineral'], ['Sökande', 'owners'], ['Areal', 'geom_area', { fn: 'area' }], ['Ansökningsdatum', 'appl_date'], ['Diarienummer', 'diarynr', { classes: ['feature-attr-dnr'] }], //['Kommun', 'Municipality'], //['Län', 'County'], ], }, appr_met: { title: 'Undersökningstillstånd, metaller och industrimineral \u2013 beviljad', fields: [ ['Namn', 'name'], ['Koncessionsmineral', 'mineral'], ['Ägare', 'owners'], ['Tillståndsid', 'licenceid', { classes: ['feature-attr-mrr-license-id'] }], ['Areal', 'geom_area', { fn: 'area' }], ['Giltig från', 'validfrom'], ['Giltig till', 'validto'], ['Diarienummer', 'diarynr', { classes: ['feature-attr-dnr'] }], ['Ansökningsdatum', 'appl_date'], ['Beslutsdatum', 'dec_date'], //['Kommun', 'Municipality'], //['Län', 'County'], ], }, appl_met: { title: 'Undersökningstillstånd, metaller och industrimineral \u2013 ansökt', fields: [ ['Namn', 'name'], ['Koncessionsmineral', 'mineral'], ['Sökande', 'owners'], ['Areal', 'geom_area', { fn: 'area' }], ['Ansökningsdatum', 'appl_date'], ['Diarienummer', 'diarynr', { classes: ['feature-attr-dnr'] }], //['Kommun', 'Municipality'], //['Län', 'County'], ], }, appr_ogd: { title: 'Undersökningstillstånd, olja, gas och diamant \u2013 beviljad', fields: [ ['Namn', 'name'], ['Koncessionsmineral', 'mineral'], ['Ägare', 'owners'], ['Tillståndsid', 'licenceid', { classes: ['feature-attr-mrr-license-id'] }], ['Areal', 'geom_area', { fn: 'area' }], ['Giltig från', 'validfrom'], ['Giltig till', 'validto'], ['Diarienummer', 'diarynr', { classes: ['feature-attr-dnr'] }], ['Ansökningsdatum', 'appl_date'], ['Beslutsdatum', 'dec_date'], //['Kommun', 'Municipality'], //['Län', 'County'], ], }, appl_ogd: { title: 'Undersökningstillstånd, olja, gas och diamant \u2013 ansökt', fields: [ ['Namn', 'name'], ['Koncessionsmineral', 'mineral'], ['Sökande', 'owners'], ['Areal', 'geom_area', { fn: 'area' }], ['Ansökningsdatum', 'appl_date'], ['Diarienummer', 'diarynr', { classes: ['feature-attr-dnr'] }], //['Kommun', 'Municipality'], //['Län', 'County'], ], }, appr_dl: { title: 'Markanvisning till koncession', fields: [ ['Namn', 'name'], ['Tillhörande bearbetnings\u00ADkoncession(er)', 'conc_name'], ['Tillståndsid', 'licenceid', { classes: ['feature-attr-mrr-license-id'] }], ['Areal', 'geom_area', { fn: 'area' }], ['Diarienummer', 'diarynr', { classes: ['feature-attr-dnr'] }], ['Ansökningsdatum', 'appl_date'], ['Beslutsdatum', 'dec_date'], //['Kommun', 'Municipality'], //['Län', 'County'], ], }, }; layers.svk = { ledningar: { title: 'Kraftledning (befintlig)', fields: [ ['Förläggning', 'Placement'], ['Spänning', 'Voltage', { unit: 'kV' }], ['Ledlängd', 'geom_length', { fn: 'length' }], ], }, transmissionsnatsprojekt: { title: 'Transmissionsnätsprojekt', fields: [ ['Projektnamn', 'Name'], ['Spänning', 'Voltage', { unit: 'kV' }], ['Länk', 'Url', { fn: function(v) { if (v == null | v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ], }, }; layers.vbk = { area_current: { title: 'Landbaserad projekteringsområde för vindkraft', fields: [ ['Projektnamn', 'Projektnamn'], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Aktuella verk', 'AntalVerk'], ['Antal ej koordinatsatta verk', 'AntalEjXY'], ['Areal', 'geom_area', { fn: 'area' }], ['Beräknad årsproduktion', 'Calprod', { unit: 'GWh' }], ['Planerad byggstart', 'PlaneradByggstart'], ['Planerat drifttagande', 'PlaneratDrift'], ['Ändringsansökan pågår', 'AndringsansokanPagar'], ['Under byggnation', 'UnderByggnation'], ['Organisationsnamn', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], //['Kommun', 'KOMNAMN'], //['Län', 'LANSNAMN'], ['Elområde', 'ElNamn'], ['Senast uppdaterat', 'SenasteUppdaterat'], ], }, area_notcurrent: { title: 'Landbaserad projekteringsområde för vindkraft \u2013 ej aktuell', fields: [ ['Projektnamn', 'Projektnamn'], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Aktuella verk', 'AntalVerk'], ['Antal ej koordinatsatta verk', 'AntalEjXY'], ['Areal', 'geom_area', { fn: 'area' }], ['Beräknad årsproduktion', 'Calprod', { unit: 'GWh' }], ['Planerad byggstart', 'PlaneradByggstart'], ['Planerat drifttagande', 'PlaneratDrift'], ['Ändringsansökan pågår', 'AndringsansokanPagar'], ['Organisationsnamn', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], //['Kommun', 'KOMNAMN'], //['Län', 'LANSNAMN'], ['Elområde', 'ElNamn'], ['Senast uppdaterat', 'SenasteUppdaterat'], ], }, offshore_completed: { title: 'Havsbaserad vindkraft \u2013 tillståndsansökan uppförd', fields: [ ['Projektnamn', 'Projektnamn'], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Verksamhetsutövare', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Projektstatus', 'Projektstatus'], ['Diarienummer', 'Diarienummer'], ['Areal', 'geom_area', { fn: 'area' }], ['Samrådsunderlag inlämnat', 'SamradsunderlagInlamnat'], ['Tillståndsansökan inlämnad', 'AnsokanInlamnat'], ['Tillståndsansökan beviljad', 'AnsokanBeviljad'], ['Överklagad', 'AnsokanOverklagad'], ['Natura2000 ansökan', 'Natura2000_Ansokan'], ['Natura2000 beslutsdatum', 'Natura2000_Beslutdatum'], ['Parken uppförd', 'Uppfort'], ['Beviljat antal verk', 'BeviljatAntalVerk'], ['Uppfört antal verk', 'UppfortAntalVerk'], ['Beviljad maxhöjd', 'BeviljadMaxhojd', { unit: 'm' }], ['Installerad effekt', 'InstalleradEffekt', { unit: 'MW' }], ['Beräknad årsproduktion', 'Calprod', { unit: 'GWh' }], ['Elområde', 'ElNamn'], ['Senast uppdaterat', 'SenasteUppdaterat'], ], }, offshore_approved: { title: 'Havsbaserad vindkraft \u2013 tillståndsansökan beviljad', fields: [ ['Projektnamn', 'Projektnamn'], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Verksamhetsutövare', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Projektstatus', 'Projektstatus'], ['Diarienummer', 'Diarienummer'], ['Ändringsansökan pågår', 'AndringsansokanPagar'], ['Areal', 'geom_area', { fn: 'area' }], ['Samrådsunderlag inlämnat', 'SamradsunderlagInlamnat'], ['Tillståndsansökan inlämnad', 'AnsokanInlamnat'], ['Tillståndsansökan återkallad', 'AnsokanAterkallad'], ['Tillståndsansökan beviljad', 'AnsokanBeviljad'], ['Natura2000 ansökan', 'Natura2000_Ansokan'], ['Natura2000 beslutsdatum', 'Natura2000_Beslutdatum'], ['Under byggnation', 'UnderByggnation'], ['Planerat antal verk (min)', 'PlaneratAntalVerkMin'], ['Planerat antal verk (max)', 'PlaneratAntalVerkMax'], ['Panerad totalhöjd (min)', 'PlaneradHojdMin', { unit: 'm' }], ['Panerad totalhöjd (max)', 'PlaneradHojdMax', { unit: 'm' }], ['Planerad årsproduktion (min)', 'PlaneradProduktionMin', { unit: 'GWh' }], ['Planerad årsproduktion (max)', 'PlaneradProduktionMax', { unit: 'GWh' }], ['Planerad byggstart', 'PlaneradByggstart'], ['Planerat drifttagande', 'PlaneratDrift'], ['Beviljat antal verk', 'BeviljatAntalVerk'], ['Beviljad maxhöjd', 'BeviljadMaxhojd', { unit: 'm' }], ['Elområde', 'ElNamn'], ['Senast uppdaterat', 'SenasteUppdaterat'], ], }, offshore_amended: { title: 'Havsbaserad vindkraft \u2013 ändringsansökan', fields: [ ['Projektnamn', 'Projektnamn'], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Verksamhetsutövare', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Projektstatus', 'Projektstatus'], ['Diarienummer', 'Diarienummer'], //['Ändringsansökan pågår', 'AndringsansokanPagar'], ['Areal', 'geom_area', { fn: 'area' }], ['Samrådsunderlag inlämnat', 'SamradsunderlagInlamnat'], ['Tillståndsansökan inlämnad', 'AnsokanInlamnat'], //['Natura2000 ansökan', 'Natura2000_Ansokan'], //['Natura2000 beslutsdatum', 'Natura2000_Beslutdatum'], ['Planerat antal verk (min)', 'PlaneratAntalVerkMin'], ['Planerat antal verk (max)', 'PlaneratAntalVerkMax'], ['Panerad totalhöjd (min)', 'PlaneradHojdMin', { unit: 'm' }], ['Panerad totalhöjd (max)', 'PlaneradHojdMax', { unit: 'm' }], ['Planerad årsproduktion (min)', 'PlaneradProduktionMin', { unit: 'GWh' }], ['Planerad årsproduktion (max)', 'PlaneradProduktionMax', { unit: 'GWh' }], ['Planerad byggstart', 'PlaneradByggstart'], ['Planerat drifttagande', 'PlaneratDrift'], ['Elområde', 'ElNamn'], ['Senast uppdaterat', 'SenasteUppdaterat'], ], }, offshore_rejected: { title: 'Havsbaserad vindkraft \u2013 tillståndsansökan avslagen', fields: [ ['Projektnamn', 'Projektnamn'], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Verksamhetsutövare', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Projektstatus', 'Projektstatus'], ['Diarienummer', 'Diarienummer'], ['Areal', 'geom_area', { fn: 'area' }], ['Samrådsunderlag inlämnat', 'SamradsunderlagInlamnat'], ['Tillståndsansökan inlämnad', 'AnsokanInlamnat'], ['Tillståndsansökan avslagen', 'AnsokanAvslagen'], ['Natura2000 ansökan', 'Natura2000_Ansokan'], ['Natura2000 beslutsdatum', 'Natura2000_Beslutdatum'], ['Planerat antal verk (min)', 'PlaneratAntalVerkMin'], ['Planerat antal verk (max)', 'PlaneratAntalVerkMax'], ['Panerad totalhöjd (min)', 'PlaneradHojdMin', { unit: 'm' }], ['Panerad totalhöjd (max)', 'PlaneradHojdMax', { unit: 'm' }], ['Planerad årsproduktion (min)', 'PlaneradProduktionMin', { unit: 'GWh' }], ['Planerad årsproduktion (max)', 'PlaneradProduktionMax', { unit: 'GWh' }], ['Planerad byggstart', 'PlaneradByggstart'], ['Planerat drifttagande', 'PlaneratDrift'], ['Elområde', 'ElNamn'], ['Senast uppdaterat', 'SenasteUppdaterat'], ], }, offshore_appealed: { title: 'Havsbaserad vindkraft \u2013 överklagad', fields: [ ['Projektnamn', 'Projektnamn'], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Verksamhetsutövare', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Projektstatus', 'Projektstatus'], ['Diarienummer', 'Diarienummer'], ['Areal', 'geom_area', { fn: 'area' }], ['Samrådsunderlag inlämnat', 'SamradsunderlagInlamnat'], ['Tillståndsansökan inlämnad', 'AnsokanInlamnat'], ['Tillståndsansökan beviljad', 'AnsokanBeviljad'], ['Överklagad', 'AnsokanOverklagad'], ['Natura2000 ansökan', 'Natura2000_Ansokan'], ['Natura2000 beslutsdatum', 'Natura2000_Beslutdatum'], ['Planerat antal verk (min)', 'PlaneratAntalVerkMin'], ['Planerat antal verk (max)', 'PlaneratAntalVerkMax'], ['Panerad totalhöjd (min)', 'PlaneradHojdMin', { unit: 'm' }], ['Panerad totalhöjd (max)', 'PlaneradHojdMax', { unit: 'm' }], ['Planerad årsproduktion (min)', 'PlaneradProduktionMin', { unit: 'GWh' }], ['Planerad årsproduktion (max)', 'PlaneradProduktionMax', { unit: 'GWh' }], ['Planerad byggstart', 'PlaneradByggstart'], ['Planerat drifttagande', 'PlaneratDrift'], ['Beviljat antal verk', 'BeviljatAntalVerk'], ['Beviljad maxhöjd', 'BeviljadMaxhojd', { unit: 'm' }], ['Elområde', 'ElNamn'], ['Senast uppdaterat', 'SenasteUppdaterat'], ], }, offshore_applied: { title: 'Havsbaserad vindkraft \u2013 tillståndsansökan inlämnad', fields: [ ['Projektnamn', 'Projektnamn'], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Verksamhetsutövare', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Projektstatus', 'Projektstatus'], ['Diarienummer', 'Diarienummer'], ['Areal', 'geom_area', { fn: 'area' }], ['Samrådsunderlag inlämnat', 'SamradsunderlagInlamnat'], ['Tillståndsansökan inlämnad', 'AnsokanInlamnat'], ['Natura2000 ansökan', 'Natura2000_Ansokan'], ['Natura2000 beslutsdatum', 'Natura2000_Beslutdatum'], ['Planerat antal verk (min)', 'PlaneratAntalVerkMin'], ['Planerat antal verk (max)', 'PlaneratAntalVerkMax'], ['Panerad totalhöjd (min)', 'PlaneradHojdMin', { unit: 'm' }], ['Panerad totalhöjd (max)', 'PlaneradHojdMax', { unit: 'm' }], ['Planerad årsproduktion (min)', 'PlaneradProduktionMin', { unit: 'GWh' }], ['Planerad årsproduktion (max)', 'PlaneradProduktionMax', { unit: 'GWh' }], ['Planerad byggstart', 'PlaneradByggstart'], ['Planerat drifttagande', 'PlaneratDrift'], ['Elområde', 'ElNamn'], ['Senast uppdaterat', 'SenasteUppdaterat'], ], }, offshore_consultation: { title: 'Havsbaserad vindkraft \u2013 samråd inför tillståndsansökan', fields: [ ['Projektnamn', 'Projektnamn'], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Verksamhetsutövare', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Projektstatus', 'Projektstatus'], ['Diarienummer', 'Diarienummer'], ['Areal', 'geom_area', { fn: 'area' }], ['Samrådsunderlag inlämnat', 'SamradsunderlagInlamnat'], ['Natura2000 ansökan', 'Natura2000_Ansokan'], ['Natura2000 beslutsdatum', 'Natura2000_Beslutdatum'], ['Planerat antal verk (min)', 'PlaneratAntalVerkMin'], ['Planerat antal verk (max)', 'PlaneratAntalVerkMax'], ['Panerad totalhöjd (min)', 'PlaneradHojdMin', { unit: 'm' }], ['Panerad totalhöjd (max)', 'PlaneradHojdMax', { unit: 'm' }], ['Planerad årsproduktion (min)', 'PlaneradProduktionMin', { unit: 'GWh' }], ['Planerad årsproduktion (max)', 'PlaneradProduktionMax', { unit: 'GWh' }], ['Planerad byggstart', 'PlaneradByggstart'], ['Planerat drifttagande', 'PlaneratDrift'], ['Elområde', 'ElNamn'], ['Senast uppdaterat', 'SenasteUppdaterat'], ], }, offshore_investigation: { title: 'Havsbaserad vindkraft \u2013 inledande undersökningar', fields: [ ['Projektnamn', 'Projektnamn'], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Verksamhetsutövare', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Projektstatus', 'Projektstatus'], ['Diarienummer', 'Diarienummer'], ['Areal', 'geom_area', { fn: 'area' }], ['Natura2000 ansökan', 'Natura2000_Ansokan'], ['Natura2000 beslutsdatum', 'Natura2000_Beslutdatum'], ['Planerat antal verk (min)', 'PlaneratAntalVerkMin'], ['Planerat antal verk (max)', 'PlaneratAntalVerkMax'], ['Panerad totalhöjd (min)', 'PlaneradHojdMin', { unit: 'm' }], ['Panerad totalhöjd (max)', 'PlaneradHojdMax', { unit: 'm' }], ['Planerad årsproduktion (min)', 'PlaneradProduktionMin', { unit: 'GWh' }], ['Planerad årsproduktion (max)', 'PlaneradProduktionMax', { unit: 'GWh' }], ['Planerad byggstart', 'PlaneradByggstart'], ['Planerat drifttagande', 'PlaneratDrift'], ['Elområde', 'ElNamn'], ['Senast uppdaterat', 'SenasteUppdaterat'], ], }, offshore_revoked: { title: 'Havsbaserad vindkraft \u2013 inte aktuell eller återkallad', fields: [ ['Projektnamn', 'Projektnamn'], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Verksamhetsutövare', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Projektstatus', 'Projektstatus'], ['Diarienummer', 'Diarienummer'], ['Areal', 'geom_area', { fn: 'area' }], ['Samrådsunderlag inlämnat', 'SamradsunderlagInlamnat'], ['Tillståndsansökan inlämnad', 'AnsokanInlamnat'], ['Tillståndsansökan återkallad', 'AnsokanAterkallad'], ['Tillståndsansökan beviljad', 'AnsokanBeviljad'], ['Överklagad', 'AnsokanOverklagad'], ['Natura2000 ansökan', 'Natura2000_Ansokan'], ['Natura2000 beslutsdatum', 'Natura2000_Beslutdatum'], ['Planerat antal verk (min)', 'PlaneratAntalVerkMin'], ['Planerat antal verk (max)', 'PlaneratAntalVerkMax'], ['Panerad totalhöjd (min)', 'PlaneradHojdMin', { unit: 'm' }], ['Panerad totalhöjd (max)', 'PlaneradHojdMax', { unit: 'm' }], ['Planerad årsproduktion (min)', 'PlaneradProduktionMin', { unit: 'GWh' }], ['Planerad årsproduktion (max)', 'PlaneradProduktionMax', { unit: 'GWh' }], ['Planerad byggstart', 'PlaneradByggstart'], ['Planerat drifttagande', 'PlaneratDrift'], ['Beviljat antal verk', 'BeviljatAntalVerk'], ['Beviljad maxhöjd', 'BeviljadMaxhojd', { unit: 'm' }], ['Elområde', 'ElNamn'], ['Senast uppdaterat', 'SenasteUppdaterat'], ], }, station_completed: { title: 'Landbaserad vindkraftverk \u2013 uppfört', fields: [ ['Verk-ID', 'VerkID', { classes: ['feature-objid'] }], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Projektnamn', 'Projektnamn'], ['Status', 'Status'], ['Handlingstyp', 'Handlingstyp'], ['Uppförandedatum', 'Uppfort'], ['Miljöbalken tillstånd tidsbegränsning', 'MB_Tillstand'], ['Totalhöjd', 'Totalhojd', { unit: 'm' }], ['Navhöjd', 'Navhojd', { unit: 'm' }], ['Rotordiameter', 'Rotordiameter', { unit: 'm' }], ['Maxeffekt', 'Maxeffekt', { unit: 'MW' }], ['Beräknad årsproduktion', 'Calprod', { unit: 'GWh' }], ['Fabrikat', 'Fabrikat'], ['Modell', 'Modell'], ['Organisationsnamn', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Placering', 'Placering'], //['Kommun', 'KOMNAMN'], //['Län', 'LANSNAMN'], ['Elområde', 'ElNamn'], ['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'], ], }, station_processed: { title: 'Landbaserad vindkraftverk \u2013 handlagt', fields: [ ['Verk-ID', 'VerkID', { classes: ['feature-objid'] }], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Projektnamn', 'Projektnamn'], ['Status', 'Status'], ['Handlingstyp', 'Handlingstyp'], ['Totalhöjd', 'Totalhojd', { unit: 'm' }], ['Navhöjd', 'Navhojd', { unit: 'm' }], ['Rotordiameter', 'Rotordiameter', { unit: 'm' }], ['Maxeffekt', 'Maxeffekt', { unit: 'MW' }], ['Beräknad årsproduktion', 'Calprod', { unit: 'GWh' }], ['Fabrikat', 'Fabrikat'], ['Modell', 'Modell'], ['Organisationsnamn', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Placering', 'Placering'], //['Kommun', 'KOMNAMN'], //['Län', 'LANSNAMN'], ['Elområde', 'ElNamn'], ['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'], ], }, station_approved: { title: 'Landbaserad vindkraftverk \u2013 beviljat', fields: [ ['Verk-ID', 'VerkID', { classes: ['feature-objid'] }], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Projektnamn', 'Projektnamn'], ['Status', 'Status'], ['Handlingstyp', 'Handlingstyp'], ['Miljöbalken tillstånd tidsbegränsning', 'MB_Tillstand'], ['Totalhöjd', 'Totalhojd', { unit: 'm' }], ['Navhöjd', 'Navhojd', { unit: 'm' }], ['Rotordiameter', 'Rotordiameter', { unit: 'm' }], ['Maxeffekt', 'Maxeffekt', { unit: 'MW' }], ['Beräknad årsproduktion', 'Calprod', { unit: 'GWh' }], ['Fabrikat', 'Fabrikat'], ['Modell', 'Modell'], ['Organisationsnamn', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Placering', 'Placering'], //['Kommun', 'KOMNAMN'], //['Län', 'LANSNAMN'], ['Elområde', 'ElNamn'], ['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'], ], }, station_revoked: { title: 'Landbaserad vindkraftverk \u2013 inte längre aktuell/återkallat', fields: [ ['Verk-ID', 'VerkID', { classes: ['feature-objid'] }], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Projektnamn', 'Projektnamn'], ['Status', 'Status'], ['Handlingstyp', 'Handlingstyp'], ['Miljöbalken tillstånd tidsbegränsning', 'MB_Tillstand'], ['Totalhöjd', 'Totalhojd', { unit: 'm' }], ['Navhöjd', 'Navhojd', { unit: 'm' }], ['Rotordiameter', 'Rotordiameter', { unit: 'm' }], ['Maxeffekt', 'Maxeffekt', { unit: 'MW' }], ['Beräknad årsproduktion', 'Calprod', { unit: 'GWh' }], ['Fabrikat', 'Fabrikat'], ['Modell', 'Modell'], ['Organisationsnamn', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Placering', 'Placering'], //['Kommun', 'KOMNAMN'], //['Län', 'LANSNAMN'], ['Elområde', 'ElNamn'], ['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'], ], }, station_rejected: { title: 'Landbaserad vindkraftverk \u2013 avslagit/nekat', fields: [ ['Verk-ID', 'VerkID', { classes: ['feature-objid'] }], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Projektnamn', 'Projektnamn'], ['Status', 'Status'], ['Handlingstyp', 'Handlingstyp'], ['Miljöbalken tillstånd tidsbegränsning', 'MB_Tillstand'], ['Totalhöjd', 'Totalhojd', { unit: 'm' }], ['Navhöjd', 'Navhojd', { unit: 'm' }], ['Rotordiameter', 'Rotordiameter', { unit: 'm' }], ['Maxeffekt', 'Maxeffekt', { unit: 'MW' }], ['Beräknad årsproduktion', 'Calprod', { unit: 'GWh' }], ['Fabrikat', 'Fabrikat'], ['Modell', 'Modell'], ['Organisationsnamn', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Placering', 'Placering'], //['Kommun', 'KOMNAMN'], //['Län', 'LANSNAMN'], ['Elområde', 'ElNamn'], ['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'], ], }, station_dismounted: { title: 'Landbaserad vindkraftverk \u2013 nedmonterat', fields: [ ['Verk-ID', 'VerkID', { classes: ['feature-objid'] }], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Projektnamn', 'Projektnamn'], ['Status', 'Status'], ['Handlingstyp', 'Handlingstyp'], ['Uppförandedatum', 'Uppfort'], ['Totalhöjd', 'Totalhojd', { unit: 'm' }], ['Navhöjd', 'Navhojd', { unit: 'm' }], ['Rotordiameter', 'Rotordiameter', { unit: 'm' }], ['Maxeffekt', 'Maxeffekt', { unit: 'MW' }], ['Beräknad årsproduktion', 'Calprod', { unit: 'GWh' }], ['Fabrikat', 'Fabrikat'], ['Modell', 'Modell'], ['Organisationsnamn', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Placering', 'Placering'], //['Kommun', 'KOMNAMN'], //['Län', 'LANSNAMN'], ['Elområde', 'ElNamn'], ['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'], ], }, station_appealed: { title: 'Landbaserad vindkraftverk \u2013 överklagat', fields: [ ['Verk-ID', 'VerkID', { classes: ['feature-objid'] }], ['Områdes-ID', 'OmrID', { classes: ['feature-objid'] }], ['Projektnamn', 'Projektnamn'], ['Status', 'Status'], ['Handlingstyp', 'Handlingstyp'], ['Totalhöjd', 'Totalhojd', { unit: 'm' }], ['Navhöjd', 'Navhojd', { unit: 'm' }], ['Rotordiameter', 'Rotordiameter', { unit: 'm' }], ['Maxeffekt', 'Maxeffekt', { unit: 'MW' }], ['Beräknad årsproduktion', 'Calprod', { unit: 'GWh' }], ['Fabrikat', 'Fabrikat'], ['Modell', 'Modell'], ['Organisationsnamn', 'Organisationsnamn'], ['Organisationsnummer', 'Organisationsnummer', { classes: ['feature-orgnr'] }], ['Placering', 'Placering'], //['Kommun', 'KOMNAMN'], //['Län', 'LANSNAMN'], ['Elområde', 'ElNamn'], ['Datum för senaste uppdatering av verk', 'SenasteUppdaterat'], ], }, }; layers.avverk = { /* Documentation at * https://www.skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/utforda-avverkningar---produktbeskrivning.pdf * */ utford: { title: 'Utförd avverkning', fields: [ ['Ärendebeteckning', 'Beteckn', { classes: ['feature-objid'] }], ['Registeringsår', 'ArendeAr'], ['Skogstyp', 'Skogstyp'], ['Areal anmält', 'AnmaldHa', { unit: 'ha' }], ['Areal naturlig föryngring', 'NatforHa', { unit: 'ha', fn: (v) => v === 0 ? '' : v }], //['Areal plantering', 'SkogsodlHa', { unit: 'ha', fn: (v) => v === 0 ? '' : v }], ['Avverkningstyp', 'Avverktyp'], ['Datum för avverkning', 'Avvdatum'], ['Ursprung för datum för avverkning', 'KallaDatum'], //['Ursprung för areal avverkning', 'KallaAreal'], //['Kommun', 'Kommun'], //['Län', 'Lan'], ['Areal för ytan', 'geom_area', { fn: 'area' }], ], }, /* Documentation at * https://www.skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/yttre-granser-for-avverkningsanmalda-omraden---produktbeskrivning.pdf * */ anmald: { title: 'Avverkningsanmälansområde', fields: [ ['Ärendebeteckning', 'Beteckn', { classes: ['feature-objid'] }], ['Inkom datum', 'Inkomdatum'], ['Registeringsår', 'ArendeAr'], //['Skogstyp', 'Skogstyp'], ['Areal anmält', 'AnmaldHa', { unit: 'ha' }], ['Areal naturlig föryngring', 'NatforHa', { unit: 'ha', fn: (v) => v === 0 ? '' : v }], ['Areal plantering', 'SkogsodlHa', { unit: 'ha', fn: (v) => v === 0 ? '' : v }], ['Avverkningssäsong', 'AvvSasong'], //['Avverkningstyp', 'Avverktyp'], //['Ändamål', 'Andamal'], //['Kommun', 'Kommun'], //['Län', 'Lan'], ['Ärendestatus', 'ArendeStatus'], ['Avverkad areal', 'AvvHa', { unit: 'ha' }], ], }, }; layers.skyyd = { tilltradesforbud: { title: 'Tillträdesförbud', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Föreskriftsområde', 'FORSKRNAMN'], ['Namn', 'OBJEKTNAMN'], ['Beslutsstatus', 'BESLSTAT'], ['Föreskriftstyp', 'FORESKRTYP'], ['Föreskriftssubtyp', 'FORESKRIFT'], ['Från datum', 'FRANDATUM'], ['Till datum', 'TILLDATUM'], ['Beskrivning', 'BESKRIVN'], ['Areal', 'geom_area', { fn: 'area' }], ], }, nationalpark: { title: 'Nationalpark', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ursprungligt gällandedatum', 'URSGALLDAT'], ['Senaste gällandedatum', 'SENGALLDAT'], ['Förvaltare', 'FORVALTARE'], ['IUCN-kategori', 'IUCNKAT'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Beslutsmyndighet', 'BESLMYND'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, naturreservat: { title: 'Naturreservat', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ursprungligt gällandedatum', 'URSGALLDAT'], ['Senaste gällandedatum', 'SENGALLDAT'], ['Förvaltare', 'FORVALTARE'], ['IUCN-kategori', 'IUCNKAT'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Beslutsmyndighet', 'BESLMYND'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, naturreservat_kommunalt: { title: 'Kommunalt naturreservat', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ursprungligt gällandedatum', 'URSGALLDAT'], ['Senaste gällandedatum', 'SENGALLDAT'], ['Förvaltare', 'FORVALTARE'], ['IUCN-kategori', 'IUCNKAT'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Beslutsmyndighet', 'BESLMYND'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, naturvardsomrade: { title: 'Naturvårdsområde', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ursprungligt gällandedatum', 'URSGALLDAT'], ['Senaste gällandedatum', 'SENGALLDAT'], ['Förvaltare', 'FORVALTARE'], ['IUCN-kategori', 'IUCNKAT'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Beslutsmyndighet', 'BESLMYND'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, djur_och_vaxtskyddsomrade: { title: 'Djur- och växtskyddsområde', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ursprungligt gällandedatum', 'URSGALLDAT'], ['Senaste gällandedatum', 'SENGALLDAT'], ['Förvaltare', 'FORVALTARE'], ['IUCN-kategori', 'IUCNKAT'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Beslutsmyndighet', 'BESLMYND'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, kulturreservat: { title: 'Kulturreservat', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ursprungligt gällandedatum', 'URSGALLDAT'], ['Senaste gällandedatum', 'SENGALLDAT'], ['Förvaltare', 'FORVALTARE'], ['IUCN-kategori', 'IUCNKAT'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Beslutsmyndighet', 'BESLMYND'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, vattenskyddsomrade: { title: 'Vattenskyddsområden', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ikraftträdandedatum föreskrifter', 'IKRAFTDATF'], ['Beslutsmyndighet', 'BESLMYND'], ['Tillsynsmyndighet', 'TILLSYNSMH'], ['Prövningsmyndighet tillstånd', 'PROVNMHTIL'], ['Prövningsmyndighet dispens', 'PROVNMHDIS'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, landskapsbildsskyddsomrade: { title: 'Landskapsbildsskyddsområde', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ursprungligt gällandedatum', 'URSGALLDAT'], ['Senaste gällandedatum', 'SENGALLDAT'], ['Förvaltare', 'FORVALTARE'], ['IUCN-kategori', 'IUCNKAT'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Beslutsmyndighet', 'BESLMYND'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, skogligt_biotopskyddsomrade: { title: 'Biotopskydd i skogsmark', fields: [ ['Ärendebeteckning', 'Beteckn', { classes: ['feature-objid'] }], ['Biotopkategori', 'Biotyp'], ['Skogstyp', 'Naturtyp'], ['Registeringsår', 'ArendeAr'], ['Areal', 'geom_area', { fn: 'area' }], ['Skogsmarksareal', 'AreaProd', { unit: 'ha' }], ['Beslutsdatum', 'Datbeslut'], ['Länk', 'Url', { fn: function(v) { if (v == null | v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ], }, ovrigt_biotopskyddsomrade: { title: 'Biotopskydd utanför skogsmark', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ursprungligt gällandedatum', 'URSGALLDAT'], ['Senaste gällandedatum', 'SENGALLDAT'], ['Förvaltare', 'FORVALTARE'], ['IUCN-kategori', 'IUCNKAT'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Beslutsmyndighet', 'BESLMYND'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, naturminne_yta: { title: 'Naturminne (yta)', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ursprungligt gällandedatum', 'URSGALLDAT'], ['Senaste gällandedatum', 'SENGALLDAT'], ['Förvaltare', 'FORVALTARE'], ['IUCN-kategori', 'IUCNKAT'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Beslutsmyndighet', 'BESLMYND'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, naturminne_punkt: { title: 'Naturminne (punkt)', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ursprungligt gällandedatum', 'URSGALLDAT'], ['Senaste gällandedatum', 'SENGALLDAT'], ['Förvaltare', 'FORVALTARE'], ['IUCN-kategori', 'IUCNKAT'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Beslutsmyndighet', 'BESLMYND'], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, interimistiskt_forbud: { title: 'Interimistiskt förbud', fields: [ ['NVR-ID', 'NVRID', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Beslutsstatus', 'BESLSTATUS'], ['Beslutsdatum (bildande)', 'URSBESLDAT'], ['Ursprungligt gällandedatum', 'URSGALLDAT'], ['Senaste gällandedatum', 'SENGALLDAT'], ['Förvaltare', 'FORVALTARE'], ['IUCN-kategori', 'IUCNKAT'], ['Diarienummer', 'DIARIENR', { classes: ['feature-attr-dnr'] }], ['Lagrum', 'LAGRUM'], ['Beslutsmyndighet', 'BESLMYND'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ], }, fageldirektivet: { title: 'Fågeldirektivet (SPA)', fields: [ ['Områdeskod', 'SITE_CODE', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Områdestyp', 'OMRADESTYP'], ['Uppgiftslämnare', 'UPPLAMNARE'], ['SPA-datum', 'SPA_DATUM'], ['SCI-förslagsdatum', 'SCI_FORSL'], ['SCI-datum', 'SCI_DATUM'], ['SAC-datum', 'SAC_DATUM'], ['Areal', 'geom_area', { fn: 'area' }], ['Kvalitet', 'KVALITET'], ['Kännetecken för området', 'KARAKTAR'], ['Arter', 'ARTER'], ['Naturtyper', 'NATURTYPER'], ['Bevarandeplan', 'BEVPLAN', { fn: function(v) { const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ], }, habitatdirektivet: { title: 'Art- och habitatdirektivet (SCI)', fields: [ ['Områdeskod', 'SITE_CODE', { classes: ['feature-objid'] }], ['Namn', 'NAMN'], ['Områdestyp', 'OMRADESTYP'], ['Uppgiftslämnare', 'UPPLAMNARE'], ['SPA-datum', 'SPA_DATUM'], ['SCI-förslagsdatum', 'SCI_FORSL'], ['SCI-datum', 'SCI_DATUM'], ['SAC-datum', 'SAC_DATUM'], ['Areal', 'geom_area', { fn: 'area' }], ['Kvalitet', 'KVALITET'], ['Kännetecken för området', 'KARAKTAR'], ['Arter', 'ARTER'], ['Naturtyper', 'NATURTYPER'], ['Bevarandeplan', 'BEVPLAN', { fn: function(v) { const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ], }, helcom: { title: 'Marina skyddade områden (Helcom MPA)', fields: [ ['Namn', 'NAME'], ['Areal', 'geom_area', { fn: 'area' }], ], }, ramsar: { title: 'Ramsar-områden (Våtmarkskonventionen)', fields: [ ['Ramsar-ID', 'RAMSAR_ID', { classes: ['feature-objid'] }], ['Skyddstyp', 'SKYDDSTYP'], ['Namn', 'NAMN'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'LAND_HA', { unit: 'ha' }], ['Areal vatten', 'VATTEN_HA', { unit: 'ha' }], ['Skogsmarksareal', 'SKOG_HA', { unit: 'ha' }], ['Ursprungligt beslutsdatum', 'URSPR_BESL'], ['Senaste beslutsdatum', 'SEN_BESLUT'], ['Rättsakt', 'LEGAL_ACT'], ['Länk', 'LINK', { fn: function(v) { if (v == null || v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ], }, ospar: { title: 'Marina skyddade områden (Ospar MPA)', fields: [ ['Ursprung', 'ORIGIN'], ['N2000-namn', 'NAMN_N2000'], ['MPA-ID', 'MPA_ID', { classes: ['feature-objid'] }], ['MPA-namn', 'MPA_NAMN'], ['N2000-ID', 'N2000_SITE', { classes: ['feature-objid'] }], ['Areal', 'geom_area', { fn: 'area' }], ], }, varldsarv: { title: 'Världsarv med mycket höga naturvärden (Unesco)', fields: [ ['Namn', 'NAMN'], ['Areal', 'geom_area', { fn: 'area' }], ], }, biosfarsomraden: { title: 'Biosfärsområde (Unesco)', fields: [ ['Namn', 'NAMN'], ['Skyddstyp', 'SKYDDSTYP'], ['Länk', 'LINK', { fn: function(v) { if (v == null || v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ['Areal', 'geom_area', { fn: 'area' }], ], }, naturvardsavtal: { title: 'Naturvårdsavtal (Naturvårdsverket, Länsstyrelsen)', fields: [ ['ID', 'ID', { classes: ['feature-objid'] }], ['Namn', 'OBJNAMN'], ['Fastighet', 'FASTBET', { classes: ['feature-objid'] }], ['Giltig från', 'DATSTART'], ['Giltig till', 'DATSLUT'], ['Diarienummer', 'DIARIENRNV', { classes: ['feature-attr-dnr'] }], ['Satus', 'STATUS'], ['Areal', 'geom_area', { fn: 'area' }], ], }, naturvardsavtal_skogsstyrelsen: { title: 'Naturvårdsavtal (Skogsstyrelsen)', fields: [ ['Ärendebeteckning', 'Beteckn', { classes: ['feature-objid'] }], ['Registeringsår', 'ArendeAr'], ['Biotopkategori', 'NvaTyp'], ['Skogstyp', 'Naturtyp'], ['Avtalsdatum', 'DatAvtal'], ['Areal', 'geom_area', { fn: 'area' }], ['Skogsmarksareal', 'AreaProd', { unit: 'ha' }], ['Länk', 'Url', { fn: function(v) { if (v == null | v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ['Undertyp', 'Undertyp'], ], }, atervatningsavtal: { title: 'Återvätningsavtal', fields: [ ['Ärendebeteckning', 'Beteckn', { classes: ['feature-objid'] }], ['Ärendeår', 'ArendeAr'], ['Avtalat datum', 'AvtalatDatum'], ['Areal', 'geom_area', { fn: 'area' }], ['Länk', 'Url', { fn: function(v) { if (v == null || v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ], }, }; layers.nv = { naturvarde_sks: { title: 'Objekt med naturvärden (Skogsstyrelsen)', fields: [ ['Ärendebeteckning', 'Beteckn', { classes: ['feature-objid'] }], ['Namn', 'Objnamn'], ['Datum för fältinventering', 'Datinv'], ['Biotoptyp #1', 'Biotop1'], ['Biotoptyp #2', 'Biotop2'], ['Biotoptyp #3', 'Biotop3'], ['Nyckelord #1 som beskriver objektet', 'Beskrivn1'], ['Nyckelord #2 som beskriver objektet', 'Beskrivn2'], ['Nyckelord #3 som beskriver objektet', 'Beskrivn3'], ['Areal', 'geom_area', { fn: 'area' }], ['Länk', 'Url', { fn: function(v) { if (v == null || v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ], }, nyckelbiotop: { title: 'Nyckelbiotop (Skogsstyrelsen)', fields: [ ['Ärendebeteckning', 'Beteckn', { classes: ['feature-objid'] }], ['Namn', 'Objnamn'], ['Datum för fältinventering', 'Datinv'], ['Biotoptyp #1', 'Biotop1'], ['Biotoptyp #2', 'Biotop2'], ['Biotoptyp #3', 'Biotop3'], ['Nyckelord #1 som beskriver objektet', 'Beskrivn1'], ['Nyckelord #2 som beskriver objektet', 'Beskrivn2'], ['Nyckelord #3 som beskriver objektet', 'Beskrivn3'], ['Nyckelord #4 som beskriver objektet', 'Beskrivn4'], ['Nyckelord #5 som beskriver objektet', 'Beskrivn5'], ['Nyckelord #6 som beskriver objektet', 'Beskrivn6'], ['Nyckelord #7 som beskriver objektet', 'Beskrivn7'], ['Nyckelord #8 som beskriver objektet', 'Beskrivn8'], ['Areal', 'geom_area', { fn: 'area' }], ['Länk', 'Url', { fn: function(v) { if (v == null || v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ], }, nyckelbiotop_storskogsbruk: { title: 'Nyckelbiotop (storskogsbruket)', fields: [ ['Uppgifter lämnade av', 'Org'], ['Inkom datum', 'InkomDatum'], ['Areal', 'geom_area', { fn: 'area' }], ['Länk', 'Url', { fn: function(v) { if (v == null || v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ], }, sumpskog: { title: 'Sumpskog', fields: [ ['Objektnamn', 'Namn'], ['Skogstyp', 'Tradtext'], ['Hydrologisk typ', 'Hydrtext'], ['Klass på delobjektet', 'Delklass'], ['Klass på objektet', 'Klassu'], ['Andel löv', 'Lovandel'], ['Andel öppet vatten', 'Andelva'], ['Krontäckning', 'Krontakn'], ['Huggningsklass', 'Huggklas'], ['Ingrepp på delobjekt (max 4)', 'Ingrepp'], ['Grad av påverkan på delobjekt (max 4)', 'Ingrpavv'], ['Nyckelord på objektnivå', 'Objnyck'], ['Nyckelord på delobjektsnivå', 'Delnyck'], ['Flygbildsår', 'Flygar'], ['Datum för fältbesök', 'Faltdat'], ['Inventeringsteknik', 'Invtekn'], ['Inventeringdatum', 'Invdat'], ['Ansvarig myndighet', 'Ansvmynd'], ['Areal', 'geom_area', { fn: 'area' }], ['Länk', 'Url', { fn: function(v) { if (v == null || v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ], }, pagaende_naturreservatsbildning: { title: 'Pågående naturreservatsbildning', fields: [ ['Objektnamn', 'NAMN'], ['Senast justerat', 'GRANSJUST'], /* XXX unclear what "GRANSJUST" means, just a guess */ ['Areal', 'geom_area', { fn: 'area' }], ], }, snus: { title: 'Skyddsvärd statlig skog', fields: [ ['Objektnamn', 'NAMN'], ['År', 'AR'], ['Naturgeografisk region', 'NATURGEOGR', { classes: ['feature-objid'] }], ['Objektskategori', 'OBJEKTKATE', { classes: ['feature-objid'] }], ['Markägare', 'MARKAGARE'], ['Areal värdekärna', 'VARDEKARNA', { unit: 'ha' }], ['Areal utvecklingsmark', 'UTV_MARK', { unit: 'ha' }], ['Totalareal', 'TOTAL_AREA', { unit: 'ha' }], ['Areal land', 'LAND', { unit: 'ha' }], ['Areal vatten', 'VATTEN', { unit: 'ha' }], ['Areal produktiv skogsmark', 'PROD_SKOG', { unit: 'ha' }], ['Areal produktiv skogsmark ovanför fjällnära gräns', 'SKOG_O_FJG', { unit: 'ha' }], ['Areal produktiv skogsmark nedanför fjällnära gräns', 'SKOG_N_FJG', { unit: 'ha' }], ['Areal skyddszon', 'SKYDDSZON', { unit: 'ha' }], ['Areal arronderingsmark', 'ARRO_MARK', { unit: 'ha' }], ['Kriterier för urval', 'KRITERIER'], ['Beskrivning av området', 'BESKRIVN'], ['Länsstyrelsens bedömning', 'LST_BEDOMN'], ['Källor', 'KALLOR'], ], }, }; layers.ri = { naturvard: { title: 'Riksintresse naturvård', fields: [ ['Namn', 'NAMN'], ['Skydd', 'SKYDD'], ['Ämnesområde', 'AMNESOMRAD'], ['Beskrivning', 'BESKRIVNIN', { fn: function(v) { if (v == null || !(v.startsWith('http://') || v.startsWith('https://'))) { return v; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ['Lagrum', 'LAGRUM'], ['Beslutsdatum', 'BESLUTSDAT'], ['Original-ID', 'ORGINALID', { classes: ['feature-objid'] }], ['Riks-ID', 'RIKSID', { classes: ['feature-objid'] }], ['Areal', 'geom_area', { fn: 'area' }], ], }, friluftsliv: { title: 'Riksintresse friluftsliv', fields: [ ['Namn', 'NAMN'], ['Skydd', 'SKYDD'], ['Ämnesområde', 'AMNESOMR'], ['Områdesnummer', 'OMRADESNR', { classes: ['feature-objid'] }], ['Länk värdebeskrivning', 'LANK_VARDE', { fn: function(v) { if (v == null | v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ['Lagrum', 'LAGRUM'], ['Beslutsdatum', 'BESLDATUM'], ['Ärendenummer', 'ARENDENR', { classes: ['feature-attr-dnr'] }], ['Länk, beslut', 'LANK_BESLU', { fn: function(v) { if (v == null | v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ['Aktivitet', 'AKTIVITET'], ['Naturtyp', 'NATURTYP'], ['Areal', 'geom_area', { fn: 'area' }], ['Areal land', 'AREA_LAND_', { unit: 'ha' }], ['Areal vatten', 'AREA_VATTE', { unit: 'ha' }], ], }, rorligt_friluftsliv: { title: 'Riksintresse rörligt friluftsliv (MB 4 kap 1§ och 2§)', fields: [ ['Namn', 'NAMN'], //['Original-ID', 'ORIGINALID', { classes: ['feature-objid'] }], ['Beskrivning', 'BESKRIVNIN'], //['Metodbeskrivning', 'METODBESKR'], //['Tillk. datum', 'TILLKDATUM'], //['Rev. datum', 'REVDATUM'], ['Anmärkning', 'ANM'], ['Länk', 'OBJEKTLANK', { fn: function(v) { if (v == null || v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ['Areal', 'geom_area', { fn: 'area' }], ['Referens', 'REFERENS'], ], }, obruten_kust: { title: 'Riksintresse obruten kust (MB 4 kap 3§)', fields: [ ['Namn', 'NAMN'], //['Original-ID', 'ORIGINALID', { classes: ['feature-objid'] }], ['Beskrivning', 'BESKRIVNIN'], //['Metodbeskrivning', 'METODBESKR'], //['Tillk. datum', 'TILLKDATUM'], //['Rev. datum', 'REVDATUM'], ['Anmärkning', 'ANM'], ['Objekttyp', 'OBJTYP'], ['Länk', 'OBJEKTLANK', { fn: function(v) { if (v == null || v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ['Areal', 'geom_area', { fn: 'area' }], ['Referens', 'REFERENS'], ], }, obrutet_fjall: { title: 'Riksintresse obrutet fjäll (MB 4 kap 5§)', fields: [ ['Namn', 'NAMN'], //['Original-ID', 'ORIGINALID', { classes: ['feature-objid'] }], ['Beskrivning', 'BESKRIVNIN'], ['Metodbeskrivning', 'METODBESKR'], ['Tillk. datum', 'TILLKDATUM'], //['Rev. datum', 'REVDATUM'], ['Länk', 'OBJEKTLANK', { fn: function(v) { if (v == null || v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ['Areal', 'geom_area', { fn: 'area' }], ['Referens', 'REFERENS'], ], }, skyddade_vattendrag: { title: 'Riksintresse skyddade vattendrag (MB 4 kap 6§)', fields: [ ['Namn', 'NAMN'], //['Original-ID', 'ORIGINALID', { classes: ['feature-objid'] }], ['Beskrivning', 'BESKRIVNIN'], ['Metodbeskrivning', 'METODBESKR'], ['Tillk. datum', 'TILLKDATUM'], ['Rev. datum', 'REVDATUM'], ['Anmärkning', 'ANM'], ['Digitaliseringsskala', 'DIG_SKALA'], ['Länk', 'OBJEKTLANK', { fn: function(v) { if (v == null || v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ['Areal', 'geom_area', { fn: 'area' }], ['Referens', 'REFERENS'], ], }, }; layers.ren = { betesomrade: { title: 'Samebyarnas betesområde', fields: [ ['Sameby', 'NAMN'], ['Samebys typ', 'SAMEBY_TYP'], ['Signatur', 'SIGNATUR'], ['Aktualitet', 'AKTUALITET'], ], }, flyttled: { title: 'Samebyarnas markanvändningsredovisning \u2013 flyttled', fields: [ ['Led-ID', 'LED_ID', { classes: ['feature-objid'], fn: (v) => v === 0 ? '' : v }], ['Sameby #1', 'SAMEBY1'], ['Sameby #2', 'SAMEBY2'], ['Sameby #3', 'SAMEBY3'], ['Beskrivning', 'BESKRIVNIN'], ['Årstid', 'ARSTID'], ['Riksintresse', 'RIKSINTR'], ['Fast led', 'FAST_LED'], ['Aktualitet', 'AKTUALITET'], ['Signatur', 'SIGNATUR'], ['Ledlängd', 'geom_length', { fn: 'length' }], ], }, riks_ren: { title: 'Riksintresse rennäring', fields: [ ['Lagrum', 'LAGRUM'], ['Aktualitet', 'AKTUALITET'], ['Signatur', 'SIGNATUR'], ['Areal', 'geom_area', { fn: 'area' }], ], }, omr_riks: { title: '(Kärn)områden av riksintresse rennäring', fields: [ ['Områdes-ID', 'OMR_NR', { classes: ['feature-objid'] }], ['Länk', 'LANK'], ['Årets runt', 'ARET_RUNT'], ['Sameby', 'SAMEBY'], ['Ansvarig', 'ANSVARIG'], ['Aktualitet', 'AKTUALITET'], ['Signatur', 'SIGNATUR'], ['Areal', 'geom_area', { fn: 'area' }], ], }, }; layers.misc = { /* Documentation at * https://www.smhi.se/polopoly_fs/1.34541!/dammprod%202013_3%2C%20beskrivning%2C%20SVAR2012_2.pdf * */ dammar: { title: 'Damm', fields: [ ['Dammenhetens namn', 'DNamn'], ['Dammanläggningens namn', 'Namn'], ['Länsnr', 'LST_OBJID', { classes: ['feature-objid'] }], ['Status', 'Status', { fn: (v) => v === 1 ? 'Befintlig damm' : v === 2 ? 'Fd. damm' : '' }], //['Regleringstyp', 'Regleringstyp'], ['Byggår', 'ByggAr'], ['Dammhöjd', 'DammHojd', { unit: 'm' }], ['Krönlängd', 'KronLangd', { unit: 'm' }], ['Fiskväg', 'Fiskvag', { 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' : '' }], ['Huvudavrinningsområdesnummer', 'HARO', { classes: ['feature-objid'] } ], ['Vattendistrikt', 'Vattendistrikt', { classes: ['feature-objid'] } ], ['Verksamhet', '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' : '' }], ['Högsta dämningsgräns', 'DG', { unit: 'm' }], ['Lägsta sänkningsgräns', 'SG', { unit: 'm' }], ['Magasinsyta', 'MY', { unit: 'km²' }], ['Reglerbar volym', 'RV', { unit: 'Mm³' }], ['Kommentar', 'Kommentar'], ], }, gigafactories: { title: 'Stor industrisatsning', fields: [ ['Namn', 'Name'], ['Länk', 'Url', { fn: function(v) { if (v == null | v === '') { return; } const a = document.createElement('a'); a.href = v; a.target = '_blank'; const i = document.createElement('i'); i.classList.add('bi', 'bi-box-arrow-up-right'); a.appendChild(i); return a; }}], ], }, }; /* 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([desc, key, opts]) { const tr = document.createElement('tr'); tbody.appendChild(tr); const td1 = document.createElement('td'); tr.appendChild(td1); const textDesc = document.createTextNode(desc); td1.appendChild(textDesc); const td2 = document.createElement('td'); tr.appendChild(td2); const v = formatValue(properties[key], opts); if (v != null) { td2.appendChild(v); } opts?.classes?.forEach?.((c) => td2.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; }; let popupOverlay = null; export const initPopupOverLay = function(map, element) { popupOverlay = new Overlay({ stopEvent: true, element: element, }); map.addOverlay(popupOverlay); }; let featureOverlayLayer = null; let overlayAttributes = [], overlayAttrIdx = 0, mapSources = {}; const disposeFeatureOverlay = function() { if (featureOverlayLayer?.getVisible?.()) { featureOverlayLayer.setVisible(false); featureOverlayLayer.changed(); } /* clear the overlay list */ overlayAttributes = []; overlayAttrIdx = 0; mapSources = {}; } let popover = null; export const disposePopover = function() { disposeFeatureOverlay(); if (popover?.tip != null) { popover.dispose(); } }; export const initPopover = function(map) { 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) { 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) { if (event.button != 0) { return; } headerGrabbingArea.classList.remove('grabbing-area-grabbed'); document.onmousemove = null; document.onmouseup = null; }; }; 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); const featureOverlayStyle = new Style({ stroke: new Stroke({ color: 'rgba(0, 255, 255, .8)', width: 3, }), }); const updateFeatureOverlayLayer = 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(); }; const refreshPopover = function() { const attr = overlayAttributes[overlayAttrIdx]; updateFeatureOverlayLayer(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); }; 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; } 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); }; 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() { 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; } /* 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 */ 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]; updateFeatureOverlayLayer(attr.layer_group, attr.layer, attr.ogc_fid); popover = new Popover(popupOverlay.element, { template: '', 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() { document.body.classList.remove('inprogress'); }); }); };