aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2025-06-15 13:26:30 +0200
committerGuilhem Moulin <guilhem@fripost.org>2025-06-15 13:49:27 +0200
commit0fc7bdd8bf374c36fa0ba27702d1fafed09277ac (patch)
treeb8c81445d179725d0ae3ff6bff31963f06e5d456
parentd6981601de753dbb996f1808dcf34bcaab588d34 (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.js105
-rw-r--r--src/map.js103
-rw-r--r--src/popover.js11
3 files changed, 118 insertions, 101 deletions
diff --git a/main.js b/main.js
index c21392c..2cdc19a 100644
--- a/main.js
+++ b/main.js
@@ -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');
});
});
-};
+})();