From 9a7bf01513da1a425ab497c80aeca2deca90abd7 Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Fri, 11 Nov 2022 16:45:10 +0100 Subject: [PATCH 1/3] Separate printRenderMode for better labeling in printed maps --- src/controls/legend/overlay.js | 10 +++++--- src/controls/legend/overlays.js | 12 ++++----- src/controls/print/print-component.js | 34 ++++++++++++++++++++++-- src/map.js | 23 ++++++++--------- src/ui/component.js | 1 + src/viewer.js | 37 ++++++++++++++++++++------- 6 files changed, 82 insertions(+), 35 deletions(-) diff --git a/src/controls/legend/overlay.js b/src/controls/legend/overlay.js index 6b0a97ce9..66a9b7fec 100644 --- a/src/controls/legend/overlay.js +++ b/src/controls/legend/overlay.js @@ -295,14 +295,16 @@ const OverlayLayer = function OverlayLayer(options) { buttons.push(moreInfoButton); const ButtonsHtml = `${layerIcon.render()}${label.render()}${toggleButton.render()}${moreInfoButton.render()}`; - const removeOverlayMenuItem = function removeListeners() { - const popupMenuListEl = document.getElementById(popupMenuList.getId()); - if (popupMenuListEl) { popupMenuListEl.remove(); } + const removeOverlayMenuItem = function removeOverlayMenuItem() { + const popupMenuListEl = popupMenuList.getEl(); + if (popupMenuListEl) { + popupMenuListEl.remove(); + } }; const onRemove = function onRemove() { removeOverlayMenuItem(); - const el = document.getElementById(this.getId()); + const el = this.getEl(); el.remove(); }; diff --git a/src/controls/legend/overlays.js b/src/controls/legend/overlays.js index 1a8cd453a..40e3c194d 100644 --- a/src/controls/legend/overlays.js +++ b/src/controls/legend/overlays.js @@ -206,13 +206,11 @@ const Overlays = function Overlays(options) { const layer = evt.element; const layerName = layer.get('name'); const groupName = layer.get('group'); - if (groupName) { - const groupCmp = groupCmps.find((cmp) => cmp.name === groupName); - if (groupCmp) { - groupCmp.removeOverlay(layerName); - if (emptyGroupCheck(groupName)) { - document.getElementById(groupCmp.getId()).classList.add('hidden'); - } + const groupCmp = groupCmps.find((cmp) => cmp.name === groupName); + if (groupName && groupCmp) { + groupCmp.removeOverlay(layerName); + if (emptyGroupCheck(groupName)) { + document.getElementById(groupCmp.getId()).classList.add('hidden'); } } else { rootGroup.removeOverlay(layerName); diff --git a/src/controls/print/print-component.js b/src/controls/print/print-component.js index b9067cc75..da9efeb65 100644 --- a/src/controls/print/print-component.js +++ b/src/controls/print/print-component.js @@ -19,6 +19,7 @@ import { afterRender, beforeRender } from './download-callback'; import maputils from '../../maputils'; import PrintResize from './print-resize'; import { withLoading } from '../../loading'; + /** Backup of original OL function */ const original = PluggableMap.prototype.getEventPixel; @@ -459,10 +460,18 @@ const PrintComponent = function PrintComponent(options = {}) { printMapComponent.dispatch('change:togglePrintLegend', { showPrintLegend }); }, close() { + // GH-1537: remove layers temporarily added for print and unhide layers hidden for print + viewer.getLayersByProperty('added-for-print', true).forEach((l) => viewer.removeLayer(l)); + viewer.getLayersByProperty('hidden-for-print', true).forEach((l) => { + l.setVisible(true); + l.unset('hidden-for-print'); + }); + if (suppressNewDPIMethod === false) { printResize.resetLayers(); printResize.setResolution(150); } + // Restore monkey patch // WORKAROUND: Remove when OL supports transform: scale // See https://github.com/openlayers/openlayers/issues/13283 @@ -487,13 +496,12 @@ const PrintComponent = function PrintComponent(options = {}) { if (map.getView().getRotation() !== 0) { map.getView().setRotation(0); } - const printElement = document.getElementById(this.getId()); map.setTarget(viewerMapTarget); if (printInteractionToggle) { printInteractionToggle.restoreInteractions(); } this.restoreViewerControls(); - printElement.remove(); + this.getEl().remove(); }, async downloadPNG() { await withLoading(() => downloadPNG({ @@ -565,6 +573,28 @@ const PrintComponent = function PrintComponent(options = {}) { map.setTarget(printMapComponent.getId()); this.removeViewerControls(); await printMapComponent.addPrintControls(); + + // GH-1537: temporarily add layers for print and hide their original versions + viewer.getLayersByProperty('printRenderMode', 'image').forEach((layer) => { + if (layer.getVisible() && !layer.get('added-for-print') && !layer.get('hidden-for-print')) { + // hide the original, tiled, layer + layer.setVisible(false); + layer.set('hidden-for-print', true); + + // create a duplicate of the layer with a different renderMode + const { map: _, type, name, sourceName, ...properties } = layer.getProperties(); + const newLayer = viewer.addLayer({ + ...properties, + source: sourceName, + renderMode: 'image', + type: type === 'AGS_TILE' ? 'AGS_MAP' : type, + name: `${name}-forPrint`, + visible: true + }, layer); + newLayer.set('added-for-print', true); + } + }); + if (!supressResolutionsRecalculation) { updateResolutions(); } diff --git a/src/map.js b/src/map.js index d02277c3d..84cdeeb6e 100644 --- a/src/map.js +++ b/src/map.js @@ -2,16 +2,13 @@ import OlMap from 'ol/Map'; import OlView from 'ol/View'; import mapInteractions from './mapinteractions'; -const Map = (options = {}) => { - const interactions = mapInteractions({ target: options.target, mapInteractions: options.pageSettings && options.pageSettings.mapInteractions ? options.pageSettings.mapInteractions : {} }); - const mapOptions = Object.assign(options, { interactions }); - delete mapOptions.layers; - mapOptions.controls = []; - - const view = new OlView(options); - const map = new OlMap(Object.assign(mapOptions, { view })); - - return map; -}; - -export default Map; +export default class Map extends OlMap { + constructor(options = {}) { + const interactions = mapInteractions({ target: options.target, mapInteractions: options.pageSettings && options.pageSettings.mapInteractions ? options.pageSettings.mapInteractions : {} }); + const mapOptions = { ...options, interactions, controls: [] }; + delete mapOptions.layers; + + const view = new OlView(options); + super({ ...mapOptions, view }); + } +} diff --git a/src/ui/component.js b/src/ui/component.js index b48cc0ff7..8b4edc200 100644 --- a/src/ui/component.js +++ b/src/ui/component.js @@ -29,6 +29,7 @@ const Base = function Base() { }, getComponents: () => components, getId: () => id, + getEl: () => document.getElementById(id), removeComponent(component) { const index = components.indexOf(component); if (index > -1) { diff --git a/src/viewer.js b/src/viewer.js index 5e6c06025..4aa3dd9dd 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -19,6 +19,7 @@ import isEmbedded from './utils/isembedded'; import permalink from './permalink/permalink'; const Viewer = function Viewer(targetOption, options = {}) { + /** @type Map */ let map; let tileGrid; let featureinfo; @@ -189,7 +190,15 @@ const Viewer = function Viewer(targetOption, options = {}) { const getLayers = () => map.getLayers().getArray(); - const getLayersByProperty = function getLayersByProperty(key, val, byName) { + /** + * Returns layers that match a given property value + * + * @param {string} key + * @param {any} val + * @param {boolean} byName - Only returns layer names if true + * @returns {import("ol/layer/Base").default[]|string[]} + */ + const getLayersByProperty = function getLayersByProperty(key, val, byName = false) { const layers = map.getLayers().getArray().filter(layer => layer.get(key) && layer.get(key) === val); if (byName) { @@ -211,13 +220,11 @@ const Viewer = function Viewer(targetOption, options = {}) { }; const getQueryableLayers = function getQueryableLayers() { - const queryableLayers = getLayers().filter(layer => layer.get('queryable') && layer.getVisible()); - return queryableLayers; + return getLayers().filter(layer => layer.get('queryable') && layer.getVisible()); }; const getGroupLayers = function getGroupLayers() { - const groupLayers = getLayers().filter(layer => layer.get('type') === 'GROUP'); - return groupLayers; + return getLayers().filter(layer => layer.get('type') === 'GROUP'); }; const getSearchableLayers = function getSearchableLayers(searchableDefault) { @@ -356,6 +363,7 @@ const Viewer = function Viewer(targetOption, options = {}) { } }; + /** @param {Map} newMap */ const setMap = function setMap(newMap) { map = newMap; }; @@ -387,13 +395,23 @@ const Viewer = function Viewer(targetOption, options = {}) { } }; - const addLayer = function addLayer(layerProps) { + const addLayer = function addLayer(layerProps, insertBefore) { const layer = Layer(layerProps, this); addLayerStylePicker(layerProps); - map.addLayer(layer); - this.dispatch('addlayer', { + if (insertBefore) { + map.getLayers().insertAt(map.getLayers().getArray().indexOf(insertBefore), layer); + } else { + map.addLayer(layer); + } + this.dispatch('add:layer', { layerName: layerProps.name }); + return layer; + }; + + const removeLayer = function removeLayer(layer) { + this.dispatch('remove:layer', { layerName: layer.get('name') }); + map.removeLayer(layer); }; const addLayers = function addLayers(layersProps) { @@ -483,7 +501,7 @@ const Viewer = function Viewer(targetOption, options = {}) { tileGrid = maputils.tileGrid(tileGridSettings); - setMap(Map(Object.assign(options, { projection, center, zoom, target: this.getId() }))); + setMap(new Map({ ...options, projection, center, zoom, target: this.getId() })); mergeSavedLayerProps(layerOptions, urlParams.layers) .then(layerProps => { @@ -636,6 +654,7 @@ const Viewer = function Viewer(targetOption, options = {}) { getUrlParams, getViewerOptions, removeGroup, + removeLayer, removeOverlays, setStyle, zoomToExtent, From 592c15d4f0eb9853ccd465119dd26e1888b3337a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Thor=C3=A9n?= Date: Fri, 9 Dec 2022 10:33:12 +0100 Subject: [PATCH 2/3] fix: remove unrelated changes --- src/controls/legend/overlay.js | 10 ++++------ src/controls/legend/overlays.js | 12 +++++++----- src/controls/print/print-component.js | 3 ++- src/map.js | 23 +++++++++++++---------- src/ui/component.js | 1 - src/viewer.js | 8 +++----- 6 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/controls/legend/overlay.js b/src/controls/legend/overlay.js index 66a9b7fec..6b0a97ce9 100644 --- a/src/controls/legend/overlay.js +++ b/src/controls/legend/overlay.js @@ -295,16 +295,14 @@ const OverlayLayer = function OverlayLayer(options) { buttons.push(moreInfoButton); const ButtonsHtml = `${layerIcon.render()}${label.render()}${toggleButton.render()}${moreInfoButton.render()}`; - const removeOverlayMenuItem = function removeOverlayMenuItem() { - const popupMenuListEl = popupMenuList.getEl(); - if (popupMenuListEl) { - popupMenuListEl.remove(); - } + const removeOverlayMenuItem = function removeListeners() { + const popupMenuListEl = document.getElementById(popupMenuList.getId()); + if (popupMenuListEl) { popupMenuListEl.remove(); } }; const onRemove = function onRemove() { removeOverlayMenuItem(); - const el = this.getEl(); + const el = document.getElementById(this.getId()); el.remove(); }; diff --git a/src/controls/legend/overlays.js b/src/controls/legend/overlays.js index 40e3c194d..1a8cd453a 100644 --- a/src/controls/legend/overlays.js +++ b/src/controls/legend/overlays.js @@ -206,11 +206,13 @@ const Overlays = function Overlays(options) { const layer = evt.element; const layerName = layer.get('name'); const groupName = layer.get('group'); - const groupCmp = groupCmps.find((cmp) => cmp.name === groupName); - if (groupName && groupCmp) { - groupCmp.removeOverlay(layerName); - if (emptyGroupCheck(groupName)) { - document.getElementById(groupCmp.getId()).classList.add('hidden'); + if (groupName) { + const groupCmp = groupCmps.find((cmp) => cmp.name === groupName); + if (groupCmp) { + groupCmp.removeOverlay(layerName); + if (emptyGroupCheck(groupName)) { + document.getElementById(groupCmp.getId()).classList.add('hidden'); + } } } else { rootGroup.removeOverlay(layerName); diff --git a/src/controls/print/print-component.js b/src/controls/print/print-component.js index da9efeb65..2cedafe8e 100644 --- a/src/controls/print/print-component.js +++ b/src/controls/print/print-component.js @@ -496,12 +496,13 @@ const PrintComponent = function PrintComponent(options = {}) { if (map.getView().getRotation() !== 0) { map.getView().setRotation(0); } + const printElement = document.getElementById(this.getId()); map.setTarget(viewerMapTarget); if (printInteractionToggle) { printInteractionToggle.restoreInteractions(); } this.restoreViewerControls(); - this.getEl().remove(); + printElement.remove(); }, async downloadPNG() { await withLoading(() => downloadPNG({ diff --git a/src/map.js b/src/map.js index 84cdeeb6e..d02277c3d 100644 --- a/src/map.js +++ b/src/map.js @@ -2,13 +2,16 @@ import OlMap from 'ol/Map'; import OlView from 'ol/View'; import mapInteractions from './mapinteractions'; -export default class Map extends OlMap { - constructor(options = {}) { - const interactions = mapInteractions({ target: options.target, mapInteractions: options.pageSettings && options.pageSettings.mapInteractions ? options.pageSettings.mapInteractions : {} }); - const mapOptions = { ...options, interactions, controls: [] }; - delete mapOptions.layers; - - const view = new OlView(options); - super({ ...mapOptions, view }); - } -} +const Map = (options = {}) => { + const interactions = mapInteractions({ target: options.target, mapInteractions: options.pageSettings && options.pageSettings.mapInteractions ? options.pageSettings.mapInteractions : {} }); + const mapOptions = Object.assign(options, { interactions }); + delete mapOptions.layers; + mapOptions.controls = []; + + const view = new OlView(options); + const map = new OlMap(Object.assign(mapOptions, { view })); + + return map; +}; + +export default Map; diff --git a/src/ui/component.js b/src/ui/component.js index 8b4edc200..b48cc0ff7 100644 --- a/src/ui/component.js +++ b/src/ui/component.js @@ -29,7 +29,6 @@ const Base = function Base() { }, getComponents: () => components, getId: () => id, - getEl: () => document.getElementById(id), removeComponent(component) { const index = components.indexOf(component); if (index > -1) { diff --git a/src/viewer.js b/src/viewer.js index 4aa3dd9dd..2d4855e1c 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -19,7 +19,6 @@ import isEmbedded from './utils/isembedded'; import permalink from './permalink/permalink'; const Viewer = function Viewer(targetOption, options = {}) { - /** @type Map */ let map; let tileGrid; let featureinfo; @@ -363,7 +362,6 @@ const Viewer = function Viewer(targetOption, options = {}) { } }; - /** @param {Map} newMap */ const setMap = function setMap(newMap) { map = newMap; }; @@ -403,14 +401,14 @@ const Viewer = function Viewer(targetOption, options = {}) { } else { map.addLayer(layer); } - this.dispatch('add:layer', { + this.dispatch('addLayer', { layerName: layerProps.name }); return layer; }; const removeLayer = function removeLayer(layer) { - this.dispatch('remove:layer', { layerName: layer.get('name') }); + this.dispatch('removeLayer', { layerName: layer.get('name') }); map.removeLayer(layer); }; @@ -501,7 +499,7 @@ const Viewer = function Viewer(targetOption, options = {}) { tileGrid = maputils.tileGrid(tileGridSettings); - setMap(new Map({ ...options, projection, center, zoom, target: this.getId() })); + setMap(Map(Object.assign(options, { projection, center, zoom, target: this.getId() }))); mergeSavedLayerProps(layerOptions, urlParams.layers) .then(layerProps => { From 05eca1adf25cdfa22ad9a43f534de676cccb9d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Thor=C3=A9n?= Date: Mon, 12 Dec 2022 13:28:42 +0100 Subject: [PATCH 3/3] fix: undo changed functions and fix event names --- src/viewer.js | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/viewer.js b/src/viewer.js index 2d4855e1c..6ae05a1d4 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -189,15 +189,7 @@ const Viewer = function Viewer(targetOption, options = {}) { const getLayers = () => map.getLayers().getArray(); - /** - * Returns layers that match a given property value - * - * @param {string} key - * @param {any} val - * @param {boolean} byName - Only returns layer names if true - * @returns {import("ol/layer/Base").default[]|string[]} - */ - const getLayersByProperty = function getLayersByProperty(key, val, byName = false) { + const getLayersByProperty = function getLayersByProperty(key, val, byName) { const layers = map.getLayers().getArray().filter(layer => layer.get(key) && layer.get(key) === val); if (byName) { @@ -219,11 +211,13 @@ const Viewer = function Viewer(targetOption, options = {}) { }; const getQueryableLayers = function getQueryableLayers() { - return getLayers().filter(layer => layer.get('queryable') && layer.getVisible()); + const queryableLayers = getLayers().filter(layer => layer.get('queryable') && layer.getVisible()); + return queryableLayers; }; const getGroupLayers = function getGroupLayers() { - return getLayers().filter(layer => layer.get('type') === 'GROUP'); + const groupLayers = getLayers().filter(layer => layer.get('type') === 'GROUP'); + return groupLayers; }; const getSearchableLayers = function getSearchableLayers(searchableDefault) { @@ -401,14 +395,14 @@ const Viewer = function Viewer(targetOption, options = {}) { } else { map.addLayer(layer); } - this.dispatch('addLayer', { + this.dispatch('addlayer', { layerName: layerProps.name }); return layer; }; const removeLayer = function removeLayer(layer) { - this.dispatch('removeLayer', { layerName: layer.get('name') }); + this.dispatch('removelayer', { layerName: layer.get('name') }); map.removeLayer(layer); };