diff options
-rw-r--r-- | index.html | 3 | ||||
-rw-r--r-- | main.js | 116 |
2 files changed, 119 insertions, 0 deletions
@@ -24,6 +24,9 @@ på uppdrag av <a href="https://www.klimatanalysnorr.se" class="link-body-emphasis">Klimat Analys Norr projektet</a>.</p> <p class="mb-0">Källor och licensinformation:</p> <ul> + <li>Transmissionsnät för el från + <a href="https://www.svk.se" target="_blank" class="link-dark">Svenska Kraftnät</a>. + </li> <li>Bakgrund kartor från © <a href="https://lantmateriet.se" target="_blank" class="link-dark">Lantmäteriet</a>, CC0 (<a href="https://www.lantmateriet.se/sv/geodata/vara-produkter/oppna-data/#anchor-1" class="link-dark">öppna data</a>). @@ -27,6 +27,17 @@ import ScaleLine from 'ol/control/ScaleLine.js'; import Zoom from 'ol/control/Zoom.js'; import ZoomSlider from 'ol/control/ZoomSlider.js'; +import MVT from 'ol/format/MVT.js'; +import VectorTileLayer from 'ol/layer/VectorTile.js'; +import VectorTile from 'ol/source/VectorTile.js'; +import {createXYZ} from 'ol/tilegrid.js'; + +import CircleStyle from 'ol/style/Circle.js'; +import Fill from 'ol/style/Fill.js'; +import RegularShape from 'ol/style/RegularShape.js'; +import Stroke from 'ol/style/Stroke.js'; +import Style from 'ol/style/Style.js'; + import proj4 from 'proj4'; import { get as getProjection } from 'ol/proj.js'; import { register as registerProjection } from 'ol/proj/proj4.js'; @@ -432,6 +443,111 @@ view.on('change', function(event) { }); +const styles = { + 'svk_lines': + [1, 1.5, 2, 2, 2, 2, 3, 4, 5, 6, 8, 10].map(function(width) { + return new Style({ + zIndex: 2, + stroke: new Stroke({ + color: 'black', + width: width, + }), + }); + }), + 'svk_pylons': + [undefined, undefined, undefined, undefined, undefined] + .concat([3, 4, 5, 6, 8, 10, 15].map(function(radius) { + return new Style({ + zIndex: 1, + image: new CircleStyle({ + radius: radius, + fill: new Fill({ + color: 'black', + }), + }), + }); + })), + 'svk_stations': + [5, 6, 8, 8, 10].map(function(radius) { + return new Style({ + zIndex: 0, + image: new RegularShape({ + radius: radius, + points: 4, + angle: Math.PI/4, + fill: new Fill({ + color: 'black', + }), + }), + }); + }) + .concat([12, 15].map(function(radius) { + return new Style({ + zIndex: 0, + image: new RegularShape({ + radius: radius, + points: 4, + angle: Math.PI/4, + fill: new Fill({ + color: 'rgba(128, 128, 128, .85)', + }), + stroke: new Stroke({ + width: 1, + color: 'rgb(0, 0, 0)', + }), + }), + }); + })) + .concat([1, 1.5, 1.5, 2, 2].map(function(width) { + return new Style({ + zIndex: 0, + fill: new Fill({ + color: 'rgba(128, 128, 128, .7)', + }), + stroke: new Stroke({ + width: width, + color: 'rgb(0, 0, 0)', + }), + }); + })), +}; + +map.addLayer(new VectorTileLayer({ + source: new VectorTile({ + url: '/public/xyztiles/{z}/{x}/{y}.pbf', + format: new MVT({ + layers: Object.keys(styles), + }), + projection: projection, + wrapX: false, + transition: 0, + tileGrid: createXYZ({ + extent: extent, + tileSize: 1024, + maxResolution: 1024, /* = 1048576/1024 */ + minZoom: 0, + maxZoom: 9, + }), + }), + /* XXX switch to 'hybrid' if there are perf issues; but that seems to + * put lines above points regardless of their respective z-index */ + renderMode: 'vector', + declutter: false, + style: function(feature, resolution) { + const style = styles[feature.getProperties().layer]; + if (!Array.isArray(style)) { + return style; + } else { + const maxi = style.length - 1; + const z = resolutions.length - 2 - Math.log2(resolution); + /* use Math.floor() as VectorTile.js calls getZForResolution(resolution, 1) */ + const i = z <= 0 ? 0 : z >= maxi ? maxi : Math.floor(z); + // console.log(`resolution=${resolution}, z=${z}, i=${i}`); + return style[i]; + } + }, +})); + /* layer selection panel */ (function() { const modal = document.getElementById('layer-selection-panel'); |