Skip to content

Commit

Permalink
PB-995: group all background and visible layer into one component each
Browse files Browse the repository at this point in the history
like with OL, keeping all the logic for each group isolated from the main component
  • Loading branch information
pakb committed Nov 15, 2024
1 parent 335e335 commit 529c208
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 182 deletions.
26 changes: 26 additions & 0 deletions src/modules/map/components/cesium/CesiumBackgroundLayer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'
import CesiumInternalLayer from '@/modules/map/components/cesium/CesiumInternalLayer.vue'
const store = useStore()
const backgroundLayersFor3D = computed(() => store.getters.backgroundLayersFor3D)
const projection = computed(() => store.state.position.projection)
</script>

<template>
<!--
z-index can be set to zero for all, as only the WMTS
background layer is an imagery layer (and requires one), all other BG layer are
primitive layer and will ignore this prop
-->
<CesiumInternalLayer
v-for="(bgLayer, index) in backgroundLayersFor3D"
:key="bgLayer.id"
:layer-config="bgLayer"
:projection="projection"
:z-index="index"
/>
</template>
73 changes: 6 additions & 67 deletions src/modules/map/components/cesium/CesiumMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,8 @@
@touchcancel="clearLongPressTimer"
@contextmenu="onContextMenu"
>
<div v-if="viewerCreated">
<!--
Adding background layer, z-index can be set to zero for all, as only the WMTS
background layer is an imagery layer (and requires one), all other BG layer are
primitive layer and will ignore this prop
-->
<CesiumInternalLayer
v-for="bgLayer in backgroundLayersFor3D"
:key="bgLayer.id"
:layer-config="bgLayer"
:projection="projection"
:z-index="0"
/>
<!--
Adding all other layers
Layers split between imagery and primitive type for correct zIndex ordering.
Only imagery layers require a z-index, we start to count them at 1 because of the
background WMTS layer
-->
<CesiumInternalLayer
v-for="(layer, index) in visibleImageryLayers"
:key="layer.id"
:layer-config="layer"
:projection="projection"
:z-index="index + startingZIndexForImageryLayers"
:is-time-slider-active="isTimeSliderActive"
/>
<CesiumInternalLayer
v-for="layer in visiblePrimitiveLayers"
:key="layer.id"
:layer-config="layer"
:projection="projection"
/>
</div>
<CesiumBackgroundLayer v-if="viewerCreated" />
<CesiumVisibleLayers v-if="viewerCreated" />
<CesiumPopover
v-if="viewerCreated && showFeaturesPopover"
:coordinates="popoverCoordinates"
Expand Down Expand Up @@ -102,22 +70,18 @@ import proj4 from 'proj4'
import { mapActions, mapGetters, mapState } from 'vuex'
import { extractOlFeatureGeodesicCoordinates } from '@/api/features/features.api'
import ExternalLayer from '@/api/layers/ExternalLayer.class'
import GeoAdminAggregateLayer from '@/api/layers/GeoAdminAggregateLayer.class'
import GeoAdminGeoJsonLayer from '@/api/layers/GeoAdminGeoJsonLayer.class'
import GeoAdminWMSLayer from '@/api/layers/GeoAdminWMSLayer.class'
import GeoAdminWMTSLayer from '@/api/layers/GeoAdminWMTSLayer.class'
import GPXLayer from '@/api/layers/GPXLayer.class'
import KMLLayer from '@/api/layers/KMLLayer.class'
import LayerTypes from '@/api/layers/LayerTypes.enum'
import { get3dTilesBaseUrl, getWmsBaseUrl, getWmtsBaseUrl } from '@/config/baseUrl.config'
import { DEFAULT_PROJECTION } from '@/config/map.config'
import { IS_TESTING_WITH_CYPRESS } from '@/config/staging.config'
import FeatureEdit from '@/modules/infobox/components/FeatureEdit.vue'
import FeatureList from '@/modules/infobox/components/FeatureList.vue'
import CesiumBackgroundLayer from '@/modules/map/components/cesium/CesiumBackgroundLayer.vue'
import CesiumGeolocationFeedback from '@/modules/map/components/cesium/CesiumGeolocationFeedback.vue'
import CesiumInternalLayer from '@/modules/map/components/cesium/CesiumInternalLayer.vue'
import CesiumPopover from '@/modules/map/components/cesium/CesiumPopover.vue'
import CesiumVisibleLayers from '@/modules/map/components/cesium/CesiumVisibleLayers.vue'
import {
CAMERA_MAX_PITCH,
CAMERA_MAX_ZOOM_DISTANCE,
Expand Down Expand Up @@ -145,12 +109,13 @@ import { wrapDegrees } from '@/utils/numberUtils.js'
const dispatcher = { dispatcher: 'CesiumMap.vue' }
export default {
components: {
CesiumVisibleLayers,
CesiumBackgroundLayer,
CesiumGeolocationFeedback,
FontAwesomeIcon,
CesiumPopover,
FeatureEdit,
FeatureList,
CesiumInternalLayer,
},
provide() {
return {
Expand All @@ -172,7 +137,6 @@ export default {
cameraPosition: (state) => 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,
}),
Expand All @@ -182,7 +146,6 @@ export default {
'resolution',
'hasDevSiteWarning',
'visibleLayers',
'backgroundLayersFor3D',
'showFeatureInfoInTooltip',
]),
isProjectionWebMercator() {
Expand All @@ -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
},
Expand All @@ -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: {
Expand Down
21 changes: 5 additions & 16 deletions src/modules/map/components/cesium/CesiumVectorLayer.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<script setup>
import { computed, inject, onBeforeUnmount, onMounted, toRefs } from 'vue'
import { Cesium3DTileset } from 'cesium'
import { computed, inject, toRefs } from 'vue'
import GeoAdmin3DLayer from '@/api/layers/GeoAdmin3DLayer.class'
import { loadTileSetAndApplyStyle } from '@/modules/map/components/cesium/utils/primitiveLayerUtils'
import useAddPrimitiveLayer from '@/modules/map/components/cesium/utils/useAddPrimitiveLayer.composable'
const props = defineProps({
layerConfig: {
Expand All @@ -29,20 +30,8 @@ const url = computed(() => {
return `${baseUrl.value}${rootFolder}${layerId.value}${timeFolder}/tileset.json`
})
let layer
onMounted(async () => {
layer = getViewer().scene.primitives.add(
await loadTileSetAndApplyStyle(url.value, {
withEnhancedLabelStyle: layerId.value === 'ch.swisstopo.swissnames3d.3d',
})
)
})
onBeforeUnmount(() => {
const viewer = getViewer()
layer.show = false
viewer.scene.primitives.remove(layer)
viewer.scene.requestRender()
useAddPrimitiveLayer(getViewer(), Cesium3DTileset.fromUrl(url.value), {
withEnhancedLabelStyle: layerId.value === 'ch.swisstopo.swissnames3d.3d',
})
</script>

Expand Down
74 changes: 74 additions & 0 deletions src/modules/map/components/cesium/CesiumVisibleLayers.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'
import ExternalLayer from '@/api/layers/ExternalLayer.class'
import GeoAdminAggregateLayer from '@/api/layers/GeoAdminAggregateLayer.class'
import GeoAdminGeoJsonLayer from '@/api/layers/GeoAdminGeoJsonLayer.class'
import GeoAdminWMSLayer from '@/api/layers/GeoAdminWMSLayer.class'
import GeoAdminWMTSLayer from '@/api/layers/GeoAdminWMTSLayer.class'
import GPXLayer from '@/api/layers/GPXLayer.class'
import KMLLayer from '@/api/layers/KMLLayer.class'
import CesiumInternalLayer from '@/modules/map/components/cesium/CesiumInternalLayer.vue'
const store = useStore()
const visibleLayers = computed(() => store.getters.visibleLayers)
const layersConfig = computed(() => store.state.layers.config)
const projection = computed(() => store.state.position.projection)
const backgroundLayersFor3D = computed(() => store.getters.backgroundLayersFor3D)
const visibleImageryLayers = computed(() =>
visibleLayers.value.filter(isImageryLayer).map((imageryLayer) => {
if (imageryLayer.idIn3d) {
return (
layersConfig.value.find((layer) => layer.id === imageryLayer.idIn3d) ?? imageryLayer
)
}
return imageryLayer
})
)
const visiblePrimitiveLayers = computed(() => visibleLayers.value.filter(isPrimitiveLayer))
const startingZIndexForImageryLayers = computed(
() => backgroundLayersFor3D.value.filter(isImageryLayer).length
)
function isImageryLayer(layer) {
return (
layer instanceof GeoAdminWMTSLayer ||
layer instanceof GeoAdminWMSLayer ||
layer instanceof GeoAdminAggregateLayer ||
layer instanceof ExternalLayer
)
}
function isPrimitiveLayer(layer) {
return (
layer instanceof GeoAdminGeoJsonLayer ||
layer instanceof KMLLayer ||
layer instanceof GPXLayer
)
}
</script>
<template>
<!--
Layers split between imagery and primitive type for correct zIndex ordering.
Only imagery layers require a z-index, we start to count them at 1 or 0 depending on the
background WMTS layer
-->
<CesiumInternalLayer
v-for="(layer, index) in visibleImageryLayers"
:key="layer.id"
:layer-config="layer"
:projection="projection"
:z-index="index + startingZIndexForImageryLayers"
/>
<CesiumInternalLayer
v-for="layer in visiblePrimitiveLayers"
:key="layer.id"
:layer-config="layer"
:projection="projection"
/>
</template>
83 changes: 83 additions & 0 deletions src/modules/map/components/cesium/utils/enhanceLabelStyle.js
Original file line number Diff line number Diff line change
@@ -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)'],
],
},
})
Loading

0 comments on commit 529c208

Please sign in to comment.