aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--index.html3
-rw-r--r--main.js116
2 files changed, 119 insertions, 0 deletions
diff --git a/index.html b/index.html
index a43e291..d9323a2 100644
--- a/index.html
+++ b/index.html
@@ -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
&copy; <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>).
diff --git a/main.js b/main.js
index 90e059f..3e9cdb4 100644
--- a/main.js
+++ b/main.js
@@ -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');