From 529c2088e248b291d4ff47331c465eb330b8f3fa Mon Sep 17 00:00:00 2001 From: Pascal Barth Date: Mon, 4 Nov 2024 08:39:28 +0100 Subject: [PATCH] PB-995: group all background and visible layer into one component each like with OL, keeping all the logic for each group isolated from the main component --- .../cesium/CesiumBackgroundLayer.vue | 26 +++++ .../map/components/cesium/CesiumMap.vue | 73 ++------------ .../components/cesium/CesiumVectorLayer.vue | 21 +--- .../components/cesium/CesiumVisibleLayers.vue | 74 ++++++++++++++ .../cesium/utils/enhanceLabelStyle.js | 83 ++++++++++++++++ .../cesium/utils/primitiveLayerUtils.js | 99 ------------------- .../utils/useAddPrimitiveLayer.composable.js | 34 +++++++ 7 files changed, 228 insertions(+), 182 deletions(-) create mode 100644 src/modules/map/components/cesium/CesiumBackgroundLayer.vue create mode 100644 src/modules/map/components/cesium/CesiumVisibleLayers.vue create mode 100644 src/modules/map/components/cesium/utils/enhanceLabelStyle.js create mode 100644 src/modules/map/components/cesium/utils/useAddPrimitiveLayer.composable.js diff --git a/src/modules/map/components/cesium/CesiumBackgroundLayer.vue b/src/modules/map/components/cesium/CesiumBackgroundLayer.vue new file mode 100644 index 0000000000..ce169cbecf --- /dev/null +++ b/src/modules/map/components/cesium/CesiumBackgroundLayer.vue @@ -0,0 +1,26 @@ + + + diff --git a/src/modules/map/components/cesium/CesiumMap.vue b/src/modules/map/components/cesium/CesiumMap.vue index d59adc1839..1f8e3791f1 100644 --- a/src/modules/map/components/cesium/CesiumMap.vue +++ b/src/modules/map/components/cesium/CesiumMap.vue @@ -11,40 +11,8 @@ @touchcancel="clearLongPressTimer" @contextmenu="onContextMenu" > -
- - - - - -
+ + state.position.camera, uiMode: (state) => state.ui.mode, projection: (state) => state.position.projection, - isFullScreenMode: (state) => state.ui.fullscreenMode, isTimeSliderActive: (state) => state.ui.isTimeSliderActive, layersConfig: (state) => state.layers.config, }), @@ -182,7 +146,6 @@ export default { 'resolution', 'hasDevSiteWarning', 'visibleLayers', - 'backgroundLayersFor3D', 'showFeatureInfoInTooltip', ]), isProjectionWebMercator() { @@ -191,25 +154,6 @@ export default { isDesktopMode() { return this.uiMode === UIModes.DESKTOP }, - visibleImageryLayers() { - return this.visibleLayers - .filter( - (l) => - l instanceof GeoAdminWMTSLayer || - l instanceof GeoAdminWMSLayer || - l instanceof GeoAdminAggregateLayer || - l instanceof ExternalLayer - ) - .map((visibleLayer) => { - if (visibleLayer.idIn3d) { - return ( - this.layersConfig.find((layer) => layer.id === visibleLayer.idIn3d) ?? - visibleLayer - ) - } - return visibleLayer - }) - }, isFeatureInfoInTooltip() { return this.showFeatureInfoInTooltip }, @@ -227,11 +171,6 @@ export default { editFeature() { return this.selectedFeatures.find((feature) => feature.isEditable) }, - startingZIndexForImageryLayers() { - return this.backgroundLayersFor3D.find((layer) => layer.type === LayerTypes.WMTS) - ? 1 - : 0 - }, }, watch: { selectedFeatures: { diff --git a/src/modules/map/components/cesium/CesiumVectorLayer.vue b/src/modules/map/components/cesium/CesiumVectorLayer.vue index 333324506f..b5f9c231be 100644 --- a/src/modules/map/components/cesium/CesiumVectorLayer.vue +++ b/src/modules/map/components/cesium/CesiumVectorLayer.vue @@ -1,8 +1,9 @@ diff --git a/src/modules/map/components/cesium/CesiumVisibleLayers.vue b/src/modules/map/components/cesium/CesiumVisibleLayers.vue new file mode 100644 index 0000000000..5542aecdf4 --- /dev/null +++ b/src/modules/map/components/cesium/CesiumVisibleLayers.vue @@ -0,0 +1,74 @@ + + + diff --git a/src/modules/map/components/cesium/utils/enhanceLabelStyle.js b/src/modules/map/components/cesium/utils/enhanceLabelStyle.js new file mode 100644 index 0000000000..3535ed1620 --- /dev/null +++ b/src/modules/map/components/cesium/utils/enhanceLabelStyle.js @@ -0,0 +1,83 @@ +import { Cesium3DTileStyle } from 'cesium' + +/** + * Style to apply to our labels in 3D. It is a complete rip-off of + * https://github.com/geoadmin/mf-geoadmin3/blob/6a7b99a2cc9980eec27b394ee709305a239549f1/src/components/StylesService.js#L159-L233 + * + * @type {Cesium3DTileStyle} + */ +export default new Cesium3DTileStyle({ + show: true, + labelStyle: 2, + labelText: '${DISPLAY_TEXT}', + disableDepthTestDistance: Number.POSITIVE_INFINITY, + anchorLineEnabled: true, + anchorLineColor: "color('white')", + heightOffset: { + conditions: [ + ['${LOD} === "7"', 20], + ['${LOD} === "6"', 40], + ['${LOD} === "5"', 60], + ['${LOD} === "4"', 80], + ['${LOD} === "3"', 100], + ['${LOD} === "2"', 120], + ['${LOD} === "1"', 150], + ['${LOD} === "0"', 200], + ['true', '200'], + ], + }, + labelColor: { + conditions: [ + ['${OBJEKTART} === "See"', 'color("blue")'], + ['true', 'color("black")'], + ], + }, + labelOutlineColor: 'color("white", 1)', + labelOutlineWidth: 5, + font: { + conditions: [ + ['${OBJEKTART} === "See"', '"bold 32px arial"'], + ['${OBJEKTART} === "Alpiner Gipfel"', '"italic 32px arial"'], + ['true', '" 32px arial"'], + ], + }, + scaleByDistance: { + conditions: [ + ['${LOD} === "7"', 'vec4(1000, 1, 5000, 0.4)'], + ['${LOD} === "6"', 'vec4(1000, 1, 5000, 0.4)'], + ['${LOD} === "5"', 'vec4(1000, 1, 8000, 0.4)'], + ['${LOD} === "4"', 'vec4(1000, 1, 10000, 0.4)'], + ['${LOD} === "3"', 'vec4(1000, 1, 20000, 0.4)'], + ['${LOD} === "2"', 'vec4(1000, 1, 30000, 0.4)'], + ['${LOD} === "1"', 'vec4(1000, 1, 50000, 0.4)'], + ['${LOD} === "0"', 'vec4(1000, 1, 500000, 0.4)'], + ['true', 'vec4(1000, 1, 10000, 0.4)'], + ], + }, + translucencyByDistance: { + conditions: [ + ['${LOD} === "7"', 'vec4(5000, 1, 5001, 1)'], + ['${LOD} === "6"', 'vec4(5000, 1, 5001, 1)'], + ['${LOD} === "5"', 'vec4(5000, 1, 8000, 0.4)'], + ['${LOD} === "4"', 'vec4(5000, 1, 10000, 0.4)'], + ['${LOD} === "3"', 'vec4(5000, 1, 20000, 0.4)'], + ['${LOD} === "2"', 'vec4(5000, 1, 30000, 0.4)'], + ['${LOD} === "1"', 'vec4(5000, 1, 50000, 0.4)'], + ['${LOD} === "0"', 'vec4(5000, 1, 500000, 1)'], + ['true', 'vec4(5000, 1, 10000, 0.5)'], + ], + }, + distanceDisplayCondition: { + conditions: [ + ['${LOD} === "7"', 'vec2(0, 5000)'], + ['${LOD} === "6"', 'vec2(0, 5000)'], + ['${LOD} === "5"', 'vec2(0, 8000)'], + ['${LOD} === "4"', 'vec2(0, 10000)'], + ['${LOD} === "3"', 'vec2(0, 20000)'], + ['${LOD} === "2"', 'vec2(0, 30000)'], + ['${LOD} === "1"', 'vec2(0, 50000)'], + ['${LOD} === "0"', 'vec2(0, 500000)'], + ['${OBJEKTART} === "Alpiner Gipfel"', 'vec2(0, 100000)'], + ], + }, +}) diff --git a/src/modules/map/components/cesium/utils/primitiveLayerUtils.js b/src/modules/map/components/cesium/utils/primitiveLayerUtils.js index 1d18d12f26..396cfa7581 100644 --- a/src/modules/map/components/cesium/utils/primitiveLayerUtils.js +++ b/src/modules/map/components/cesium/utils/primitiveLayerUtils.js @@ -3,8 +3,6 @@ import { BillboardCollection, Cartesian2, Cartesian3, - Cesium3DTileset, - Cesium3DTileStyle, Color, GroundPolylinePrimitive, HeightReference, @@ -17,90 +15,6 @@ import { VerticalOrigin, } from 'cesium' -import log from '@/utils/logging' - -/** - * Style to apply to our labels in 3D. It is a complete rip-off of - * https://github.com/geoadmin/mf-geoadmin3/blob/6a7b99a2cc9980eec27b394ee709305a239549f1/src/components/StylesService.js#L159-L233 - * - * @type {module:cesium.Cesium3DTileStyle} - */ -const cesiumEnchancedLabelStzle = new Cesium3DTileStyle({ - show: true, - labelStyle: 2, - labelText: '${DISPLAY_TEXT}', - disableDepthTestDistance: 5000, - anchorLineEnabled: true, - anchorLineColor: "color('white')", - heightOffset: { - conditions: [ - ['${LOD} === "7"', 20], - ['${LOD} === "6"', 40], - ['${LOD} === "5"', 60], - ['${LOD} === "4"', 80], - ['${LOD} === "3"', 100], - ['${LOD} === "2"', 120], - ['${LOD} === "1"', 150], - ['${LOD} === "0"', 200], - ['true', '200'], - ], - }, - labelColor: { - conditions: [ - ['${OBJEKTART} === "See"', 'color("blue")'], - ['true', 'color("black")'], - ], - }, - labelOutlineColor: 'color("white", 1)', - labelOutlineWidth: 5, - font: { - conditions: [ - ['${OBJEKTART} === "See"', '"bold 32px arial"'], - ['${OBJEKTART} === "Alpiner Gipfel"', '"italic 32px arial"'], - ['true', '" 32px arial"'], - ], - }, - scaleByDistance: { - conditions: [ - ['${LOD} === "7"', 'vec4(1000, 1, 5000, 0.4)'], - ['${LOD} === "6"', 'vec4(1000, 1, 5000, 0.4)'], - ['${LOD} === "5"', 'vec4(1000, 1, 8000, 0.4)'], - ['${LOD} === "4"', 'vec4(1000, 1, 10000, 0.4)'], - ['${LOD} === "3"', 'vec4(1000, 1, 20000, 0.4)'], - ['${LOD} === "2"', 'vec4(1000, 1, 30000, 0.4)'], - ['${LOD} === "1"', 'vec4(1000, 1, 50000, 0.4)'], - ['${LOD} === "0"', 'vec4(1000, 1, 500000, 0.4)'], - ['true', 'vec4(1000, 1, 10000, 0.4)'], - ], - }, - translucencyByDistance: { - conditions: [ - ['${LOD} === "7"', 'vec4(5000, 1, 5001, 1)'], - ['${LOD} === "6"', 'vec4(5000, 1, 5001, 1)'], - ['${LOD} === "5"', 'vec4(5000, 1, 8000, 0.4)'], - ['${LOD} === "4"', 'vec4(5000, 1, 10000, 0.4)'], - ['${LOD} === "3"', 'vec4(5000, 1, 20000, 0.4)'], - ['${LOD} === "2"', 'vec4(5000, 1, 30000, 0.4)'], - ['${LOD} === "1"', 'vec4(5000, 1, 50000, 0.4)'], - ['${LOD} === "0"', 'vec4(5000, 1, 500000, 1)'], - ['true', 'vec4(5000, 1, 10000, 0.5)'], - ], - }, - distanceDisplayCondition: { - conditions: [ - ['${LOD} === "7"', 'vec2(0, 5000)'], - ['${LOD} === "6"', 'vec2(0, 5000)'], - ['${LOD} === "5"', 'vec2(0, 8000)'], - ['${LOD} === "4"', 'vec2(0, 10000)'], - ['${LOD} === "3"', 'vec2(0, 20000)'], - ['${LOD} === "2"', 'vec2(0, 30000)'], - ['${LOD} === "1"', 'vec2(0, 50000)'], - ['${LOD} === "0"', 'vec2(0, 500000)'], - ['${OBJEKTART} === "Alpiner Gipfel"', 'vec2(0, 100000)'], - ], - }, -}) - /** * This function goes throw the primitive collection and update passed properties * @@ -167,16 +81,3 @@ export function updateCollectionProperties(collection, properties) { } } } - -export async function loadTileSetAndApplyStyle(tileSetJsonURL, options) { - try { - const { withEnhancedLabelStyle = false } = options - const tileset = await Cesium3DTileset.fromUrl(tileSetJsonURL) - if (withEnhancedLabelStyle) { - tileset.style = cesiumEnchancedLabelStzle - } - return tileset - } catch (error) { - log.error('Error while loading tileset for', tileSetJsonURL, error) - } -} diff --git a/src/modules/map/components/cesium/utils/useAddPrimitiveLayer.composable.js b/src/modules/map/components/cesium/utils/useAddPrimitiveLayer.composable.js new file mode 100644 index 0000000000..8682a41f04 --- /dev/null +++ b/src/modules/map/components/cesium/utils/useAddPrimitiveLayer.composable.js @@ -0,0 +1,34 @@ +import { onBeforeUnmount, onMounted } from 'vue' + +import enhanceLabelStyle from '@/modules/map/components/cesium/utils/enhanceLabelStyle' +import log from '@/utils/logging' + +/** + * @param {Viewer} cesiumViewer + * @param {Promise | Cesium3DTileset} tileSet + */ +export default function useAddPrimitiveLayer(cesiumViewer, tileSet, options = {}) { + let layer + + const { withEnhancedLabelStyle = false } = options + + onMounted(async () => { + try { + const loadedTileSet = await tileSet + if (withEnhancedLabelStyle) { + loadedTileSet.style = enhanceLabelStyle + } + layer = cesiumViewer.scene.primitives.add(loadedTileSet) + } catch (error) { + log.error('Error while loading tileset for', tileSet, error) + } + }) + + onBeforeUnmount(() => { + if (layer) { + layer.show = false + cesiumViewer.scene.primitives.remove(layer) + cesiumViewer.scene.requestRender() + } + }) +}