diff options
author | Guilhem Moulin <guilhem@fripost.org> | 2025-06-15 13:26:30 +0200 |
---|---|---|
committer | Guilhem Moulin <guilhem@fripost.org> | 2025-06-15 13:49:27 +0200 |
commit | 0fc7bdd8bf374c36fa0ba27702d1fafed09277ac (patch) | |
tree | b8c81445d179725d0ae3ff6bff31963f06e5d456 | |
parent | d6981601de753dbb996f1808dcf34bcaab588d34 (diff) |
Factor out map setup into separate file.
This allows importing `map` in other modules, thereby eliminating the
need for creating and exporting functions that would be called only
once.
-rw-r--r-- | main.js | 105 | ||||
-rw-r--r-- | src/map.js | 103 | ||||
-rw-r--r-- | src/popover.js | 11 |
3 files changed, 118 insertions, 101 deletions
@@ -15,14 +15,8 @@ * 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 TileLayerGL from 'ol/layer/WebGLTile.js'; - -import WMTS from 'ol/source/WMTS.js'; import GeoTIFF from 'ol/source/GeoTIFF.js'; -import WMTSTileGrid from 'ol/tilegrid/WMTS.js'; import FullScreen from 'ol/control/FullScreen.js'; import ScaleLine from 'ol/control/ScaleLine.js'; @@ -42,82 +36,13 @@ import Point from 'ol/geom/Point.js'; import Fill from 'ol/style/Fill.js'; import Icon from 'ol/style/Icon.js'; -import proj4 from 'proj4'; -import { get as getProjection } from 'ol/proj.js'; -import { register as registerProjection } from 'ol/proj/proj4.js'; - import { Modal } from 'bootstrap'; +import { map, baseMapSource, extent, projection } from './src/map.js'; import { layers } from './src/layers.js'; -import { initPopupOverLay, initPopover, disposePopover } from './src/popover.js'; +import { disposePopover } from './src/popover.js'; import './src/style.css'; -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); -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. - */ -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 - */ -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, -}); - const age_filter_settings = { active: false, type: 'relative', @@ -183,11 +108,11 @@ let baseMapLayer = 'topowebb_nedtonad'; const x = parseFloat(params.get('x')); const y = parseFloat(params.get('y')); if (!isNaN(x) && !isNaN(y)) { - view.setCenter([x, y]); + map.getView().setCenter([x, y]); } const z = parseFloat(params.get('z')); if (!isNaN(z)) { - view.setZoom(z); + map.getView().setZoom(z); } if (!params.has('layers') || (!params.get('layers').match(/^\s*$/) && /* compat redirect/layer subst for old non-hierachical names */ @@ -263,17 +188,7 @@ let baseMapLayer = 'topowebb_nedtonad'; } })(); - -const map = new Map({ - controls: [], - view: view, - layers: [ - new TileLayer({ - source: baseMapSource - }), - ], - target: document.getElementById('map'), -}); +map.setTarget(document.getElementById('map')); /* move the control container to the viewport */ const container = document.getElementById('map-control-container'); @@ -368,12 +283,12 @@ if (window.location !== window.parent.location) { i.classList.add('bi', 'bi-box-arrow-up-right'); btn.onclick = function() { - const coordinates = view.getCenter(); + const coordinates = map.getView().getCenter(); const url = new URL(window.location.href); const searchParams = new URLSearchParams(url.hash.substring(1)); searchParams.set('x', coordinates[0].toFixed(2).replace(TRAILING_ZEROES, '')); searchParams.set('y', coordinates[1].toFixed(2).replace(TRAILING_ZEROES, '')); - searchParams.set('z', view.getZoom().toFixed(3).replace(TRAILING_ZEROES, '')); + searchParams.set('z', map.getView().getZoom().toFixed(3).replace(TRAILING_ZEROES, '')); url.hash = '#' + searchParams.toString(); return window.open(url.href, '_blank'); }; @@ -773,7 +688,8 @@ if (window.location === window.parent.location) { /* we're all set, show the control container now */ container.setAttribute('aria-hidden', 'false'); -view.on('change', function() { +map.getView().on('change', function(event) { + const view = event.target; disposePopover(); const coordinates = view.getCenter(); @@ -2197,6 +2113,3 @@ const infoMetadataAccordions = []; modal.show(); }; })(); - -initPopupOverLay(map, document.getElementById('popup')); -initPopover(map); diff --git a/src/map.js b/src/map.js new file mode 100644 index 0000000..5a751e6 --- /dev/null +++ b/src/map.js @@ -0,0 +1,103 @@ +/*********************************************************************** + * 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 index 74e79d6..7080711 100644 --- a/src/popover.js +++ b/src/popover.js @@ -23,6 +23,7 @@ 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'); @@ -989,13 +990,13 @@ const formatFeaturePropertiesToHTML = function(properties) { /* Initialize popup overlay with the give map and HTML element */ let popupOverlay = null; -export const initPopupOverLay = function(map, element) { +(function() { popupOverlay = new Overlay({ stopEvent: true, - element: element, + element: document.getElementById('popup'), }); map.addOverlay(popupOverlay); -}; +})(); let featureOverlayLayer = null; let overlayAttributes = [], @@ -1023,7 +1024,7 @@ export const disposePopover = function() { }; /* Initialize popover on the given map */ -export const initPopover = function(map) { +(function() { featureOverlayLayer = new VectorTileLayer({ zIndex: 65535, declutter: false, @@ -1344,4 +1345,4 @@ export const initPopover = function(map) { document.body.classList.remove('inprogress'); }); }); -}; +})(); |