Skip to content

Commit

Permalink
Merge pull request #849 from geoadmin/bug-PB-518-slider-smooth
Browse files Browse the repository at this point in the history
PB-518: Fix timeslider flickering and WMS time enabled layer update
  • Loading branch information
ltshb authored May 22, 2024
2 parents 05d4b03 + a3c9bb0 commit 5ee851a
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 39 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"hammerjs": "^2.0.8",
"jquery": "^3.7.1",
"liang-barsky": "^1.0.5",
"lodash": "^4.17.21",
"maplibre-gl": "^4.1.2",
"ol": "^9.1.0",
"pako": "^2.1.0",
Expand Down
11 changes: 5 additions & 6 deletions src/modules/map/components/cesium/CesiumWMTSLayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,11 @@ export default {
return this.wmtsLayerConfig.opacity || 1.0
},
url() {
return getWmtsXyzUrl(
this.wmtsLayerConfig,
this.projection,
this.previewYear,
this.isTimeSliderActive
)
return getWmtsXyzUrl(this.wmtsLayerConfig, this.projection, {
addTimestamp: true,
previewYear: this.previewYear,
isTimeSliderActive: this.isTimeSliderActive,
})
},
tileMatrixSet() {
const set =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup>
/** Renders a WMTS layer on the map by configuring it through a getCapabilities XML file */
import { cloneDeep } from 'lodash'
import { Tile as TileLayer } from 'ol/layer'
import WMTS from 'ol/source/WMTS'
import { computed, inject, onMounted, toRefs, watch } from 'vue'
Expand Down Expand Up @@ -37,22 +38,14 @@ const isTimeSliderActive = computed(() => store.state.ui.isTimeSliderActive)
const layerId = computed(() => externalWmtsLayerConfig.value.id)
const opacity = computed(() => parentLayerOpacity.value ?? externalWmtsLayerConfig.value.opacity)
const options = computed(() => {
const options = { ...externalWmtsLayerConfig.value.options }
options.dimensions = { ...options.dimensions }
if (timestamp.value) {
const timeDimension = Object.entries(options.dimensions ?? {}).find(
(e) => e[0].toLowerCase() === 'time'
)
if (timeDimension) {
options.dimensions[timeDimension[0]] = timestamp.value
} else {
if (!options.dimensions) {
options.dimensions = {}
}
options.dimensions.Time = timestamp.value
}
if (!externalWmtsLayerConfig.value.options) {
return null
}
const _options = cloneDeep(externalWmtsLayerConfig.value.options)
if (Object.hasOwn(_options, 'dimensions')) {
delete _options.dimensions
}
return options
return _options
})
// Use "current" as the default timestamp if not defined in the layer config (or no preview year)
const timestamp = computed(
Expand All @@ -63,6 +56,21 @@ const timestamp = computed(
isTimeSliderActive.value
) ?? 'current'
)
const dimensions = computed(() => {
if (!options.value) {
return null
}
const _dimensions = cloneDeep(options.value?.dimensions ?? {})
if (timestamp.value) {
const timeDimension = Object.entries(_dimensions).find((e) => e[0].toLowerCase() === 'time')
if (timeDimension) {
_dimensions[timeDimension[0]] = timestamp.value
} else {
_dimensions.Time = timestamp.value
}
}
return _dimensions
})
const layer = new TileLayer({
id: layerId.value,
Expand All @@ -75,6 +83,12 @@ useAddLayerToMap(layer, olMap, zIndex)
watch(opacity, (newOpacity) => layer.setOpacity(newOpacity))
watch(projection, setSourceForProjection)
watch(options, setSourceForProjection)
watch(dimensions, () => {
if (dimensions.value !== null) {
log.debug('Update wmts dimension', dimensions.value)
layer.getSource().updateDimensions(dimensions.value)
}
})
onMounted(() => {
setSourceForProjection()
Expand All @@ -94,7 +108,7 @@ function setSourceForProjection() {
)
// finally setting the source with the options drawn from the getCapabilities helper function
// the layer might be shown on the map a little later than all the others because of that
layer.setSource(new WMTS(options.value))
layer.setSource(new WMTS({ ...options.value, dimensions: dimensions.value }))
} else {
log.debug(`No WMTS options for layer ${layerId.value} available yet`)
}
Expand Down
21 changes: 11 additions & 10 deletions src/modules/map/components/openlayers/OpenLayersWMTSLayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useStore } from 'vuex'
import GeoAdminWMTSLayer from '@/api/layers/GeoAdminWMTSLayer.class'
import useAddLayerToMap from '@/modules/map/components/openlayers/utils/useAddLayerToMap.composable'
import { getTimestampFromConfig, getWmtsXyzUrl, indexOfMaxResolution } from '@/utils/layerUtils'
import log from '@/utils/logging'
const props = defineProps({
wmtsLayerConfig: {
Expand Down Expand Up @@ -45,9 +46,6 @@ const timestamp = computed(
)
const wmtsSourceConfig = computed(() => {
return {
dimensions: {
Time: timestamp.value,
},
// No local cache, so that our CloudFront cache is always used. Was creating an issue on mf-geoadmin3, see :
// https://github.com/geoadmin/mf-geoadmin3/issues/3491
cacheSize: 0,
Expand All @@ -62,6 +60,9 @@ const wmtsSourceConfig = computed(() => {
requestEncoding: 'REST',
}
})
const wmtsTimeConfig = computed(() => {
return { dimensions: { Time: timestamp.value } }
})
const layer = new TileLayer({
id: layerId.value,
Expand All @@ -77,14 +78,13 @@ useAddLayerToMap(layer, olMap, zIndex)
watch(opacity, (newOpacity) => layer.setOpacity(newOpacity))
watch(projection, () => layer.setSource(createWMTSSourceForProjection()))
watch(wmtsSourceConfig, () => layer.setSource(createWMTSSourceForProjection()), { deep: true })
watch(wmtsTimeConfig, () => {
log.debug('Update wmts dimension', wmtsTimeConfig.value)
layer.getSource().updateDimensions(wmtsTimeConfig.value.dimensions)
})
function getTransformedXYZUrl() {
return getWmtsXyzUrl(
wmtsLayerConfig.value,
projection.value,
previewYear.value,
isTimeSliderActive.value
)
return getWmtsXyzUrl(wmtsLayerConfig.value, projection.value)
.replace('{z}', '{TileMatrix}')
.replace('{x}', '{TileCol}')
.replace('{y}', '{TileRow}')
Expand Down Expand Up @@ -117,7 +117,8 @@ function createTileGridForProjection() {
* @returns {WMTSSource}
*/
function createWMTSSourceForProjection() {
return new WMTSSource(wmtsSourceConfig.value)
log.debug('Create new WMTS source for projection', wmtsSourceConfig.value, wmtsTimeConfig.value)
return new WMTSSource({ ...wmtsSourceConfig.value, ...wmtsTimeConfig.value })
}
</script>
Expand Down
18 changes: 13 additions & 5 deletions src/utils/layerUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,22 @@ export function getTimestampFromConfig(config, previewYear, isTimeSliderActive)
/**
* @param {GeoAdminWMTSLayer | ExternalWMTSLayer} wmtsLayerConfig
* @param {CoordinateSystem} projection
* @param {Number} previewYear
* @param {Boolean} isTimeSliderActive
* @param {Boolean} [options.addTimestamp=false] Add the timestamp from the time config or the
* timeslider to the ur. When false the timestamp is set to `{Time}` and need to processed later
* on. Default is `false`
* @param {Number | null} [options.previewYear=null] Default is `null`
* @param {Boolean | null} [options.isTimeSliderActive=false] Default is `false`
* @returns {String | null}
*/
export function getWmtsXyzUrl(wmtsLayerConfig, projection, previewYear, isTimeSliderActive) {
export function getWmtsXyzUrl(wmtsLayerConfig, projection, options = {}) {
const { addTimestamp = false, previewYear = null, isTimeSliderActive = false } = options ?? {}
if (wmtsLayerConfig?.type === LayerTypes.WMTS && projection) {
const timestamp =
getTimestampFromConfig(wmtsLayerConfig, previewYear, isTimeSliderActive) ?? 'current'
let timestamp = '{Time}'
if (addTimestamp) {
timestamp =
getTimestampFromConfig(wmtsLayerConfig, previewYear, isTimeSliderActive) ??
'current'
}

const layerId = wmtsLayerConfig.isExternal
? wmtsLayerConfig.id
Expand Down

0 comments on commit 5ee851a

Please sign in to comment.