feat: improve map zoom controls

This commit is contained in:
2026-07-21 12:28:07 +01:00
parent 5851517a6b
commit f76b553fc4
2 changed files with 97 additions and 0 deletions
+44
View File
@@ -72,6 +72,7 @@ const map = new ol.Map({
controls: ol.control
.defaults.defaults({ rotate: false })
.extend([
createVisibleLayersExtentControl(),
new ol.control.Rotate({
autoHide: true,
label: createNorthPointerIcon(),
@@ -118,6 +119,21 @@ function createNorthPointerIcon() {
return icon;
}
function createVisibleLayersExtentControl() {
const element = document.createElement("div");
element.className = "ol-visible-layers-extent ol-unselectable ol-control";
const button = document.createElement("button");
button.type = "button";
button.title = "Zoom to visible layers";
button.setAttribute("aria-label", "Zoom to visible layers");
button.textContent = "⤢";
button.addEventListener("click", () => fitToVisibleLayers());
element.append(button);
return new ol.control.Control({ element });
}
async function searchParcela(event) {
event.preventDefault();
@@ -296,6 +312,34 @@ function fitToLayerExtent(layer) {
});
}
function fitToVisibleLayers() {
const visibleLayers = availableLayers.filter((layer) => selectedLayers.includes(layer.name));
const projectedExtents = visibleLayers
.filter((layer) => layer.extent && layer.extent.every(Number.isFinite))
.map((layer) => ol.proj.transformExtent(layer.extent, "EPSG:4326", "EPSG:3857"));
if (!projectedExtents.length) {
updateStatus("Select a layer with a published extent to zoom to it.", "error");
return;
}
const combinedExtent = projectedExtents.reduce(
(combined, extent) => [
Math.min(combined[0], extent[0]),
Math.min(combined[1], extent[1]),
Math.max(combined[2], extent[2]),
Math.max(combined[3], extent[3]),
],
[Infinity, Infinity, -Infinity, -Infinity],
);
map.getView().fit(combinedExtent, {
padding: [64, 64, 64, 64],
duration: 500,
maxZoom: 18,
});
}
function childElementsByName(node, localName) {
return [...(node?.children || [])].filter((child) => child.localName === localName);
}