Skip to content

Commit

Permalink
Merge pull request #1148 from geoadmin/feat-PB-1204-cesium-wms-compos…
Browse files Browse the repository at this point in the history
…able

PB-1204 Cesium WMS as composable and tested with Cypress
  • Loading branch information
pakb authored Dec 13, 2024
2 parents 2a21b44 + bb109a7 commit 6fbe6ad
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 136 deletions.
1 change: 1 addition & 0 deletions src/modules/infobox/components/FeatureList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ function loadMoreResultForLayer(layerId) {
}
&:not(.fluid) {
max-height: 33vh;
overflow-x: hidden;
overflow-y: auto;
display: grid;
grid-template-columns: repeat(auto-fit, minmax($overlay-width, 1fr));
Expand Down
4 changes: 0 additions & 4 deletions src/modules/map/components/cesium/CesiumInternalLayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,15 @@
v-if="layerConfig.type === LayerTypes.WMS"
:wms-layer-config="layerConfig"
:parent-layer-opacity="parentLayerOpacity"
:projection="projection"
:z-index="zIndex"
:is-time-slider-active="isTimeSliderActive"
/>
<div v-if="layerConfig.type === LayerTypes.GROUP">
<CesiumWMSLayer
v-for="(layer, index) in layerConfig.layers"
:key="`${layer.id}-${index}`"
:wms-layer-config="layer"
:projection="projection"
:parent-layer-opacity="parentLayerOpacity"
:z-index="zIndex + index"
:is-time-slider-active="isTimeSliderActive"
/>
</div>
<div v-if="layerConfig.type === LayerTypes.AGGREGATE">
Expand Down
188 changes: 80 additions & 108 deletions src/modules/map/components/cesium/CesiumWMSLayer.vue
Original file line number Diff line number Diff line change
@@ -1,125 +1,97 @@
<template>
<slot />
</template>

<script>
import { ImageryLayer, Rectangle, WebMapServiceImageryProvider } from 'cesium'
<script setup>
import { Rectangle, WebMapServiceImageryProvider } from 'cesium'
import { cloneDeep } from 'lodash'
import { mapState } from 'vuex'
import { computed, inject, toRef, toRefs, watch } from 'vue'
import { useStore } from 'vuex'
import ExternalWMSLayer from '@/api/layers/ExternalWMSLayer.class'
import GeoAdminWMSLayer from '@/api/layers/GeoAdminWMSLayer.class'
import { ALL_YEARS_TIMESTAMP } from '@/api/layers/LayerTimeConfigEntry.class'
import { getBaseUrlOverride } from '@/config/baseUrl.config'
import { DEFAULT_PROJECTION } from '@/config/map.config'
import addImageryLayerMixins from '@/modules/map/components/cesium/utils/addImageryLayer-mixins'
import CoordinateSystem from '@/utils/coordinates/CoordinateSystem.class'
import useAddImageryLayer from '@/modules/map/components/cesium/utils/useAddImageryLayer.composable'
import { WGS84 } from '@/utils/coordinates/coordinateSystems'
import { getTimestampFromConfig } from '@/utils/layerUtils'
const MAXIMUM_LEVEL_OF_DETAILS = 18
export default {
mixins: [addImageryLayerMixins],
props: {
wmsLayerConfig: {
type: [GeoAdminWMSLayer, ExternalWMSLayer],
required: true,
},
projection: {
type: CoordinateSystem,
required: true,
},
zIndex: {
type: Number,
default: -1,
},
isTimeSliderActive: {
type: Boolean,
default: false,
},
parentLayerOpacity: {
type: Number,
default: null,
},
const props = defineProps({
wmsLayerConfig: {
type: [GeoAdminWMSLayer, ExternalWMSLayer],
required: true,
},
computed: {
...mapState({
currentLang: (state) => state.i18n.lang,
}),
layerId() {
return this.wmsLayerConfig.technicalName ?? this.wmsLayerConfig.id
},
opacity() {
return this.parentLayerOpacity ?? this.wmsLayerConfig.opacity ?? 1.0
},
wmsVersion() {
return this.wmsLayerConfig.wmsVersion ?? '1.3.0'
},
format() {
return this.wmsLayerConfig.format ?? 'png'
},
url() {
return getBaseUrlOverride('wms') ?? this.wmsLayerConfig.baseUrl
},
timestamp() {
return getTimestampFromConfig(this.wmsLayerConfig)
},
customAttributes() {
return cloneDeep(this.wmsLayerConfig.customAttributes)
},
/**
* Definition of all relevant URL param for our WMS backends. Passes as parameters to
* https://cesium.com/learn/cesiumjs/ref-doc/WebMapServiceImageryProvider.html#.ConstructorOptions
*
* If we let the URL have all the param beforehand (sending all URL param through the url
* option), most of our wanted params will be doubled, resulting in longer and more
* difficult to read URLs
*
* @returns Object
*/
wmsUrlParams() {
let params = {
SERVICE: 'WMS',
REQUEST: 'GetMap',
TRANSPARENT: true,
LAYERS: this.layerId,
FORMAT: `image/${this.format}`,
LANG: this.currentLang,
VERSION: this.wmsVersion,
}
if (this.timestamp && this.timestamp !== ALL_YEARS_TIMESTAMP) {
params.TIME = this.timestamp
}
if (this.customAttributes) {
params = { ...params, ...this.customAttributes }
}
return params
},
zIndex: {
type: Number,
default: -1,
},
watch: {
wmsUrlParams() {
this.updateLayer()
},
},
methods: {
createImagery(url) {
return new ImageryLayer(
new WebMapServiceImageryProvider({
url: url,
parameters: this.wmsUrlParams,
layers: this.layerId,
maximumLevel: MAXIMUM_LEVEL_OF_DETAILS,
enablePickFeatures: false,
rectangle: Rectangle.fromDegrees(
...DEFAULT_PROJECTION.getBoundsAs(WGS84).flatten
),
}),
{
alpha: this.opacity,
}
)
},
parentLayerOpacity: {
type: Number,
default: null,
},
})
const { wmsLayerConfig, zIndex, parentLayerOpacity } = toRefs(props)
const getViewer = inject('getViewer')
const store = useStore()
const currentLang = computed(() => store.state.i18n.lang)
const layerId = computed(() => wmsLayerConfig.value.technicalName ?? wmsLayerConfig.value.id)
const opacity = computed(() => parentLayerOpacity.value ?? wmsLayerConfig.value.opacity ?? 1.0)
const wmsVersion = computed(() => wmsLayerConfig.value.wmsVersion ?? '1.3.0')
const format = computed(() => wmsLayerConfig.value.format ?? 'png')
const url = computed(() => getBaseUrlOverride('wms') ?? wmsLayerConfig.value.baseUrl)
const timestamp = computed(() => getTimestampFromConfig(wmsLayerConfig.value))
const customAttributes = computed(() => cloneDeep(wmsLayerConfig.value.customAttributes))
/**
* Definition of all relevant URL param for our WMS backends. Passes as parameters to
* https://cesium.com/learn/cesiumjs/ref-doc/WebMapServiceImageryProvider.html#.ConstructorOptions
*
* If we let the URL have all the param beforehand (sending all URL param through the url option),
* most of our wanted params will be doubled, resulting in longer and more difficult to read URLs
*
* @returns Object
*/
const wmsUrlParams = computed(() => {
let params = {
SERVICE: 'WMS',
REQUEST: 'GetMap',
TRANSPARENT: true,
LAYERS: layerId.value,
FORMAT: `image/${format.value}`,
LANG: currentLang.value,
VERSION: wmsVersion.value,
}
if (timestamp.value && timestamp.value !== ALL_YEARS_TIMESTAMP) {
params.TIME = timestamp.value
}
if (customAttributes.value) {
params = { ...params, ...customAttributes.value }
}
return params
})
watch(wmsUrlParams, () => refreshLayer(), { deep: true })
function createProvider() {
return new WebMapServiceImageryProvider({
url: url.value,
parameters: wmsUrlParams.value,
layers: layerId.value,
maximumLevel: MAXIMUM_LEVEL_OF_DETAILS,
enablePickFeatures: false,
rectangle: Rectangle.fromDegrees(...DEFAULT_PROJECTION.getBoundsAs(WGS84).flatten),
})
}
const { refreshLayer } = useAddImageryLayer(
getViewer(),
createProvider,
toRef(zIndex),
toRef(opacity)
)
</script>
<template>
<slot />
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { onBeforeUnmount, onMounted, toValue, watch } from 'vue'
* @param {Function<ImageryProvider>} createProvider
* @param {Ref<Number>} zIndex
* @param {Ref<Number>} opacity
* @returns {{ layer: ImageryLayer; refreshLayer: Function }}
* @returns {{ refreshLayer: Function }}
*/
export default function useAddImageryLayer(cesiumViewer, createProvider, zIndex, opacity) {
let layer
Expand All @@ -26,10 +26,7 @@ export default function useAddImageryLayer(cesiumViewer, createProvider, zIndex,
}
const provider = createProvider()
if (provider) {
layer = cesiumViewer.scene.imageryLayers.addImageryProvider(
createProvider(),
toValue(zIndex)
)
layer = cesiumViewer.scene.imageryLayers.addImageryProvider(provider, toValue(zIndex))
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/modules/menu/components/LayerCatalogueItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ function startLayerPreview() {
}
}
function stopLayerPreview() {
store.dispatch('setPreviewLayer', {
layer: null,
...dispatcher,
})
}
function addRemoveLayer() {
// if this is a group of a layer then simply add it to the map
const layers = store.getters.getActiveLayersById(
Expand All @@ -164,6 +171,7 @@ function addRemoveLayer() {
...dispatcher,
})
}
stopLayerPreview()
}
function onItemClick() {
Expand Down
Loading

0 comments on commit 6fbe6ad

Please sign in to comment.