From 508e256d01e051e4ccd176d700701ff417612ebe Mon Sep 17 00:00:00 2001 From: Moritz Kirmse Date: Fri, 22 Sep 2023 19:22:03 +0200 Subject: [PATCH 01/29] improve layer exclusion: also deactivate BG layer if necessary --- bundle/lux.dist.mjs | 29 ++++++++--- bundle/lux.dist.umd.js | 29 ++++++++--- src/composables/layers/layers.composable.ts | 39 ++++++++++++--- src/stores/map.store.spec.ts | 55 +++++++++++++++++++++ 4 files changed, 132 insertions(+), 20 deletions(-) diff --git a/bundle/lux.dist.mjs b/bundle/lux.dist.mjs index 39261abf..cec47947 100644 --- a/bundle/lux.dist.mjs +++ b/bundle/lux.dist.mjs @@ -39765,10 +39765,8 @@ const themes = useThemes(); function useLayers() { function hasIntersect(exclusionA, exclusionB) { try { - const concat = JSON.parse(exclusionA).concat(JSON.parse(exclusionB)).sort((a, b) => a - b); - return concat.some( - (element, index2, array) => index2 && element === array[index2 - 1] - ); + const concat = JSON.parse(exclusionA).concat(JSON.parse(exclusionB)); + return new Set(concat).size < concat.length; } catch (e) { return false; } @@ -39795,17 +39793,17 @@ function useLayers() { ].join(LAYER_CURRENT_TIME_SEPARATOR); } function handleExclusionLayers(layer) { - var _a; + var _a, _b, _c, _d, _e; if (!((_a = layer.metadata) == null ? void 0 : _a.exclusion)) { return; } const mapStore = useMapStore(); const excludedLayers = mapStore.layers.filter( (_layer) => { - var _a2, _b; + var _a2, _b2; return hasIntersect( (_a2 = layer == null ? void 0 : layer.metadata) == null ? void 0 : _a2.exclusion, - (_b = _layer == null ? void 0 : _layer.metadata) == null ? void 0 : _b.exclusion + (_b2 = _layer == null ? void 0 : _layer.metadata) == null ? void 0 : _b2.exclusion ); } ); @@ -39823,6 +39821,23 @@ function useLayers() { ) ); } + if (layer.id !== ((_b = mapStore.bgLayer) == null ? void 0 : _b.id)) { + if (hasIntersect( + (_c = layer.metadata) == null ? void 0 : _c.exclusion, + (_e = (_d = mapStore.bgLayer) == null ? void 0 : _d.metadata) == null ? void 0 : _e.exclusion + )) { + mapStore.setBgLayer(null); + alert( + instance.t( + "Background has been deactivated because the layer {{layer}} cannot be displayed on top of it.", + { + layer: instance.t(layer.name, { ns: "client" }), + ns: "client" + } + ) + ); + } + } } function toggleLayer(id, show = true) { var _a; diff --git a/bundle/lux.dist.umd.js b/bundle/lux.dist.umd.js index 67881aa9..dfb09633 100644 --- a/bundle/lux.dist.umd.js +++ b/bundle/lux.dist.umd.js @@ -39779,10 +39779,8 @@ This will fail in production.`); function useLayers() { function hasIntersect(exclusionA, exclusionB) { try { - const concat = JSON.parse(exclusionA).concat(JSON.parse(exclusionB)).sort((a, b) => a - b); - return concat.some( - (element, index2, array) => index2 && element === array[index2 - 1] - ); + const concat = JSON.parse(exclusionA).concat(JSON.parse(exclusionB)); + return new Set(concat).size < concat.length; } catch (e) { return false; } @@ -39809,17 +39807,17 @@ This will fail in production.`); ].join(LAYER_CURRENT_TIME_SEPARATOR); } function handleExclusionLayers(layer) { - var _a; + var _a, _b, _c, _d, _e; if (!((_a = layer.metadata) == null ? void 0 : _a.exclusion)) { return; } const mapStore = useMapStore(); const excludedLayers = mapStore.layers.filter( (_layer) => { - var _a2, _b; + var _a2, _b2; return hasIntersect( (_a2 = layer == null ? void 0 : layer.metadata) == null ? void 0 : _a2.exclusion, - (_b = _layer == null ? void 0 : _layer.metadata) == null ? void 0 : _b.exclusion + (_b2 = _layer == null ? void 0 : _layer.metadata) == null ? void 0 : _b2.exclusion ); } ); @@ -39837,6 +39835,23 @@ This will fail in production.`); ) ); } + if (layer.id !== ((_b = mapStore.bgLayer) == null ? void 0 : _b.id)) { + if (hasIntersect( + (_c = layer.metadata) == null ? void 0 : _c.exclusion, + (_e = (_d = mapStore.bgLayer) == null ? void 0 : _d.metadata) == null ? void 0 : _e.exclusion + )) { + mapStore.setBgLayer(null); + alert( + instance.t( + "Background has been deactivated because the layer {{layer}} cannot be displayed on top of it.", + { + layer: instance.t(layer.name, { ns: "client" }), + ns: "client" + } + ) + ); + } + } } function toggleLayer(id, show = true) { var _a; diff --git a/src/composables/layers/layers.composable.ts b/src/composables/layers/layers.composable.ts index 3ac8bf2c..e1265194 100644 --- a/src/composables/layers/layers.composable.ts +++ b/src/composables/layers/layers.composable.ts @@ -14,13 +14,9 @@ const themes = useThemes() export default function useLayers() { function hasIntersect(exclusionA: string, exclusionB: string) { try { - const concat: number[] = JSON.parse(exclusionA) - .concat(JSON.parse(exclusionB)) - .sort((a: number, b: number) => a - b) + const concat = JSON.parse(exclusionA).concat(JSON.parse(exclusionB)) - return concat.some( - (element, index, array) => index && element === array[index - 1] - ) + return new Set(concat).size < concat.length } catch (e) { return false } @@ -96,12 +92,36 @@ export default function useLayers() { ) ) } + + if (layer.id !== mapStore.bgLayer?.id) { + if ( + hasIntersect( + layer.metadata?.exclusion as string, + mapStore.bgLayer?.metadata?.exclusion as string + ) + ) { + mapStore.setBgLayer(null) + alert( + i18next.t( + 'Background has been deactivated because ' + + 'the layer {{layer}} cannot be displayed on top of it.', + { + layer: i18next.t(layer.name, { ns: 'client' }), + ns: 'client', + } + ) + ) + } + } } function toggleLayer(id: LayerId, show = true) { const themeStore = useThemeStore() const mapStore = useMapStore() + // the cast from ThemeNodeModel | undefined to Layer might not be correct. + // in the themes fixture only WMS layers correspond to the Layer definition, + // whereas WMTS layers have "layer" property const layer = themes.findById(id, themeStore.theme) if (layer) { @@ -115,6 +135,13 @@ export default function useLayers() { mapStore.addLayers( initLayer(layer), ...linkedLayers.map(layerId => + // TODO: not sure if the layer exclusion is working correctly for linked layers? + // we might need somthing like the commented code below: + // { + // const newLinkedLayer = themes.findById(parseInt(layerId, 10)) as unknown as Layer + // handleExclusionLayers(newLinkedLayer) + // return initLayer(newLinkedLayer) + // } initLayer( themes.findById(parseInt(layerId, 10)) as unknown as Layer ) diff --git a/src/stores/map.store.spec.ts b/src/stores/map.store.spec.ts index 255cd5b9..77231686 100644 --- a/src/stores/map.store.spec.ts +++ b/src/stores/map.store.spec.ts @@ -1,5 +1,7 @@ import { setActivePinia, createPinia } from 'pinia' +import useBackgroundLayer from '../composables/background-layer/background-layer.composable' +import useLayers from '../composables/layers/layers.composable' import { useMapStore } from './map.store' import { Layer } from './map.store.model' @@ -25,6 +27,9 @@ const layer3: Layer = { layers: 'layer3_layers', type: 'WMTS', imageType: '', + metadata: { + exclusion: '["test_single1", "test_exclude"]', + }, } const layer4: Layer = { @@ -33,6 +38,9 @@ const layer4: Layer = { layers: 'layer4_layers', type: 'WMTS', imageType: '', + metadata: { + exclusion: '["test_single2", "test_exclude"]', + }, } const backgroundLayer: Layer = { @@ -41,6 +49,9 @@ const backgroundLayer: Layer = { layers: 'background_layers', type: 'BG WMTS', imageType: '', + metadata: { + exclusion: '["test_single3", "test_exclude"]', + }, } describe('Map Store', () => { @@ -174,5 +185,49 @@ describe('Map Store', () => { mapStore.setBgLayer(backgroundLayer) expect(mapStore.bgLayer).toStrictEqual(backgroundLayer) }) + vi.mock('../composables/themes/themes.composable', () => { + return { + default: () => { + return { + findById: (id: any, node?: any): any => { + expect(node).toBeUndefined() + if (id === 2) return layer2 + if (id === 3) return layer3 + if (id === 4) return layer4 + }, + } + }, + } + }) + vi.stubGlobal('alert', vi.fn()) + it('layer exclusion', () => { + const mapStore = useMapStore() + expect(mapStore.bgLayer).toBe(undefined) + mapStore.setBgLayer(backgroundLayer) + expect(mapStore.bgLayer).toStrictEqual(backgroundLayer) + useLayers().toggleLayer(2) + expect(mapStore.layers.length).toBe(1) + expect(window.alert).toHaveBeenCalledTimes(0) + useLayers().toggleLayer(3) + expect(window.alert).toHaveBeenCalledTimes(1) + expect(mapStore.layers.length).toBe(2) + expect(mapStore.bgLayer).toStrictEqual(null) + useLayers().toggleLayer(4) + expect(window.alert).toHaveBeenCalledTimes(2) + expect(mapStore.layers.length).toBe(2) + expect(mapStore.bgLayer).toStrictEqual(null) + }) + it('bg exclusion', () => { + const mapStore = useMapStore() + expect(mapStore.bgLayer).toBe(undefined) + mapStore.addLayers(layer2, layer3, layer4) + expect(mapStore.layers.length).toBe(3) + mapStore.setBgLayer(backgroundLayer) + expect(mapStore.layers.length).toBe(3) + useBackgroundLayer().setMapBackground(backgroundLayer) + expect(mapStore.layers.length).toBe(1) + expect(window.alert).toHaveBeenCalled() + expect(mapStore.bgLayer).toStrictEqual(backgroundLayer) + }) }) }) From 34d4512ed2718fe39f97a4f93fac06c4068eadf3 Mon Sep 17 00:00:00 2001 From: Moritz Kirmse Date: Sun, 24 Sep 2023 18:00:43 +0200 Subject: [PATCH 02/29] display 3d tree in catalog --- src/components/catalog/catalog-tree.vue | 41 +++++++++++++++---- .../layer-manager/layer-item/layer-item.vue | 4 ++ .../layer-manager/layer-manager.vue | 30 +++++++++++++- src/composables/layers/layers.composable.ts | 8 ++-- src/stores/config.store.ts | 11 +++++ src/stores/map.store.ts | 10 +++++ 6 files changed, 93 insertions(+), 11 deletions(-) diff --git a/src/components/catalog/catalog-tree.vue b/src/components/catalog/catalog-tree.vue index 576fa0ca..5c2f10de 100644 --- a/src/components/catalog/catalog-tree.vue +++ b/src/components/catalog/catalog-tree.vue @@ -1,5 +1,6 @@ diff --git a/src/components/layer-manager/layer-item/layer-item.vue b/src/components/layer-manager/layer-item/layer-item.vue index 57278eb3..81b10e7d 100644 --- a/src/components/layer-manager/layer-item/layer-item.vue +++ b/src/components/layer-manager/layer-item/layer-item.vue @@ -8,6 +8,7 @@ import LayerItemSub from './layer-item-sub.vue' import LayerTime from '../layer-time/layer-time.vue' const props = defineProps<{ + is3d: boolean layer: Layer draggableClassName: string isOpen: boolean @@ -52,6 +53,7 @@ function changeTime(dateStart?: string, dateEnd?: string) {