diff options
author | Guilhem Moulin <guilhem@fripost.org> | 2024-01-11 18:07:19 +0100 |
---|---|---|
committer | Guilhem Moulin <guilhem@fripost.org> | 2024-01-12 05:00:33 +0100 |
commit | 22972d7c274e7941b9e18b794dfdb73afef3492a (patch) | |
tree | 329fdc40b7ef3577373141ee1523255ba2bc6c60 | |
parent | fe21d9d8ead10d6541382b55a237b9a4e3e7eb91 (diff) |
Add a simple dialog to switch between ‘topowebb’ and ‘topowebb_nedtonad’.
-rw-r--r-- | index.html | 11 | ||||
-rw-r--r-- | main.js | 104 | ||||
-rw-r--r-- | package-lock.json | 45 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | style.css | 21 | ||||
-rw-r--r-- | vite.config.js | 2 |
6 files changed, 151 insertions, 34 deletions
@@ -7,6 +7,17 @@ </head> <body> <div id="map"></div> + <div id="layer-selection-btn" class="ol-control ol-unselectable"> + <button type="button" aria-expanded="false" title="Byt kartlager"> + <i class="bi bi-stack"></i> + </button> + </div> + <div id="layer-selection-dialog" class="ol-control map-dialog map-dialog-hidden"> + <div class="form-check form-switch"> + <input class="form-check-input" type="checkbox" role="switch" id="layer-topowebb_nedtonad"> + <label class="form-check-label" for="layer-topowebb_nedtonad">Nedtonad bakgrund karta</label> + </div> + </div> <script type="module" src="./main.js"></script> </body> </html> @@ -22,6 +22,10 @@ import TileLayer from 'ol/layer/Tile.js'; import WMTS from 'ol/source/WMTS.js'; import WMTSTileGrid from 'ol/tilegrid/WMTS.js'; +import Zoom from 'ol/control/Zoom.js'; +import Attribution from 'ol/control/Attribution.js'; +import Control from 'ol/control/Control.js'; + import proj4 from 'proj4'; import {get as getProjection} from 'ol/proj.js'; import {register as registerProjection} from 'ol/proj/proj4.js'; @@ -49,7 +53,56 @@ const projection = getProjection('EPSG:3006'); */ 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/ + */ +const baseMapSource = new WMTS({ + // XXX the 'layer' parameter should be passed in the options + // dictionary (like style and version), but there is no setLayer() + // method to switch from/to the toned down map + url: 'https://minkarta.lantmateriet.se/map/topowebbcache?layer=topowebb', + 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_cache_v1.1.0.pdf + tileSize: 256, + origin: [-1200000, 8500000], + resolutions: [4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, .5], + matrixIds: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + }), + projection: projection, + wrapX: false, + crossOrigin: 'anonymous', + attributions: '© <a href="https://lantmateriet.se" target="_blank">Lantmäteriet</a>', +}); + + const map = new Map({ + controls: [ + new Zoom({ + zoomInTipLabel: 'Zooma in', + zoomOutTipLabel: 'Zooma ut', + }), + new Attribution({ + collapsible: true, + collapsed: true, + tipLabel: 'Information', + }), + ], view: new View({ projection: projection, extent: extent, @@ -63,41 +116,24 @@ const map = new Map({ }), layers: [ new TileLayer({ - /* 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/ - */ - source: new WMTS({ - url: 'https://minkarta.lantmateriet.se/map/topowebbcache', - version: '1.0.0', - layer: 'topowebb', - style: 'default', - matrixSet: '3006', - format: 'image/png', - tileGrid: new WMTSTileGrid({ - extent: extent, - // https://www.lantmateriet.se/globalassets/geodata/geodatatjanster/tb_twk_visning_cache_v1.1.0.pdf - tileSize: 256, - origin: [-1200000, 8500000], - resolutions: [4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, .5], - matrixIds: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - }), - projection: projection, - wrapX: false, - crossOrigin: 'anonymous', - attributions: '© <a href="https://lantmateriet.se" target="_blank">Lantmäteriet</a>', - }), + source: baseMapSource }), ], target: document.getElementById('map'), }); + +(function() { + const element = document.getElementById('layer-selection-btn'); + map.addControl(new Control({ + element: element, + })); + element.onclick = function(event) { + document.getElementById('layer-selection-dialog').classList.toggle('map-dialog-hidden'); + element.classList.toggle('map-dialog-expanded'); + }; +})(); + +document.getElementById('layer-topowebb_nedtonad').onchange = function(event) { + const layer = event.target.checked ? 'topowebb_nedtonad' : 'topowebb'; + baseMapSource.setUrl('https://minkarta.lantmateriet.se/map/topowebbcache?LAYER=' + layer); +} diff --git a/package-lock.json b/package-lock.json index 50f9d55..27ac98e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,8 @@ "version": "0.0.1", "license": "AGPL-3.0-or-later", "dependencies": { + "bootstrap": "5.3.x", + "bootstrap-icons": "1.11.x", "ol": "8.2.x", "proj4": "2.9.x" }, @@ -389,6 +391,16 @@ "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.4.tgz", "integrity": "sha512-kB+NJ5Br56ZhElKsf0pM7/PQfrDdDVMRz8f0JM6eVOGE+L89z9hwcst9QvWBBnazzuqGTGtPsJNZoQ1JdNiGSQ==" }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.9.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.4.tgz", @@ -564,6 +576,39 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/bootstrap": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz", + "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/bootstrap-icons": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz", + "integrity": "sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ] + }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", diff --git a/package.json b/package.json index bf89a66..02b0c8f 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "vite": "5.x" }, "dependencies": { + "bootstrap": "5.3.x", + "bootstrap-icons": "1.11.x", "ol": "8.2.x", "proj4": "2.9.x" } @@ -1,3 +1,5 @@ +@import "~bootstrap/dist/css/bootstrap.css"; +@import "~bootstrap-icons/font/bootstrap-icons.css"; @import "~ol/ol.css"; html, body { @@ -10,3 +12,22 @@ html, body { bottom: 0; width: 100%; } +#layer-selection-btn { + right: .5em; + top: .5em; +} +.map-dialog-hidden { + display: none; +} +.map-dialog { + top: .5em; + right: calc(.5em + 1.375em + 2px + .2em); + background: var(--ol-partial-background-color); + border: 1px solid var(--ol-subtle-background-color); + padding: 1ex; +} +@media screen and (max-width: 500px) { + #layer-selection-btn { + display: none; + } +} diff --git a/vite.config.js b/vite.config.js index 12d656b..668b49f 100644 --- a/vite.config.js +++ b/vite.config.js @@ -9,6 +9,8 @@ export default { }, resolve: { alias: { + "~bootstrap": "node_modules/bootstrap", + "~bootstrap-icons": "node_modules/bootstrap-icons", "~ol": "node_modules/ol", } }, |