|
1 | 1 | <script setup>
|
2 | 2 | import { Tile as TileLayer } from 'ol/layer'
|
3 |
| -import { XYZ as XYZSource } from 'ol/source' |
4 |
| -import TileGrid from 'ol/tilegrid/TileGrid' |
| 3 | +import { WMTS as WMTSSource } from 'ol/source' |
| 4 | +import WMTSTileGrid from 'ol/tilegrid/WMTS' |
5 | 5 | import { computed, inject, toRefs, watch } from 'vue'
|
6 | 6 | import { useStore } from 'vuex'
|
7 | 7 |
|
8 | 8 | import GeoAdminWMTSLayer from '@/api/layers/GeoAdminWMTSLayer.class'
|
9 | 9 | import useAddLayerToMap from '@/modules/map/components/openlayers/utils/add-layers-to-map.composable'
|
10 |
| -import CustomCoordinateSystem from '@/utils/coordinates/CustomCoordinateSystem.class' |
11 | 10 | import { getTimestampFromConfig } from '@/utils/layerUtils'
|
12 | 11 |
|
13 | 12 | const props = defineProps({
|
@@ -44,43 +43,88 @@ const url = computed(() => {
|
44 | 43 | const layer = new TileLayer({
|
45 | 44 | id: layerId.value,
|
46 | 45 | opacity: opacity.value,
|
47 |
| - source: createXYZSourceForProjection(), |
| 46 | + source: createWMTSSourceForProjection(), |
48 | 47 | })
|
49 | 48 |
|
50 | 49 | // grabbing the map from the main OpenLayersMap component and use the composable that adds this layer to the map
|
51 | 50 | const olMap = inject('olMap', null)
|
52 | 51 | useAddLayerToMap(layer, olMap, zIndex)
|
53 | 52 |
|
54 | 53 | // reacting to changes accordingly
|
55 |
| -watch(url, (newUrl) => layer.getSource().setUrl(newUrl)) |
| 54 | +watch(url, (newUrl) => { |
| 55 | + layer.getSource().setUrl(getWMTSUrl(newUrl)) |
| 56 | +}) |
56 | 57 | watch(opacity, (newOpacity) => layer.setOpacity(newOpacity))
|
57 |
| -watch(projection, () => layer.setSource(createXYZSourceForProjection())) |
| 58 | +watch(projection, () => layer.setSource(createWMTSSourceForProjection())) |
| 59 | +
|
| 60 | +function getWMTSUrl(xyzUrl) { |
| 61 | + return xyzUrl |
| 62 | + .replace('{z}', '{TileMatrix}') |
| 63 | + .replace('{x}', '{TileCol}') |
| 64 | + .replace('{y}', '{TileRow}') |
| 65 | +} |
58 | 66 |
|
59 | 67 | /**
|
60 |
| - * Returns an OpenLayers XYZ source, with some customization depending on the projection being used. |
| 68 | + * Returns an OpenLayers WMTS source, with some customization depending on the projection being |
| 69 | + * used. |
61 | 70 | *
|
62 | 71 | * If the projection is a CustomCoordinateSystem, it will set the extent of this projection to a
|
63 | 72 | * dedicated TileGrid object, meaning that tiles outside the extent won't be requested.
|
64 | 73 | *
|
65 | 74 | * If the projection is not a CustomCoordinateSystem, it will default to a worldwide coverage,
|
66 | 75 | * meaning no limit where tiles shouldn't be requested.
|
67 | 76 | *
|
68 |
| - * @returns {XYZ} |
| 77 | + * @returns {WMTSSource} |
69 | 78 | */
|
70 |
| -function createXYZSourceForProjection() { |
71 |
| - let tileGrid = null |
72 |
| - if (projection.value instanceof CustomCoordinateSystem) { |
73 |
| - tileGrid = new TileGrid({ |
74 |
| - resolutions: projection.value.getResolutions(), |
75 |
| - extent: projection.value.bounds.flatten, |
76 |
| - origin: projection.value.getTileOrigin(), |
77 |
| - }) |
| 79 | +function createWMTSSourceForProjection() { |
| 80 | + const resolutions = projection.value.getResolutions() |
| 81 | + const origin = projection.value.getTileOrigin() |
| 82 | + const extent = projection.value.bounds.flatten |
| 83 | + const matrixIds = projection.value.getMatrixIds() |
| 84 | +
|
| 85 | + const tileGrid = new WMTSTileGrid({ |
| 86 | + resolutions: resolutions, |
| 87 | + origin: origin, |
| 88 | + matrixIds: matrixIds, |
| 89 | + extent: extent, |
| 90 | + }) |
| 91 | + let timestamp = getTimestampFromConfig(wmtsLayerConfig.value, previewYear.value) |
| 92 | + // Use "current" as the default timestamp if not defined in the layer config or |
| 93 | + timestamp = timestamp || wmtsLayerConfig.value.timeConfig.currentTimestamp || 'current' |
| 94 | +
|
| 95 | + // NOTE(IS): The following code is taken from the old geoadmin |
| 96 | + // For some obscure reasons, on iOS, displaying a base 64 image |
| 97 | + // in a tile with an existing crossOrigin attribute generates |
| 98 | + // CORS errors. |
| 99 | + // Currently crossOrigin definition is only used for mouse cursor |
| 100 | + // detection on desktop in TooltipDirective. |
| 101 | + let crossOrigin = 'anonymous' |
| 102 | + if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) { |
| 103 | + crossOrigin = undefined |
78 | 104 | }
|
79 |
| - return new XYZSource({ |
| 105 | + const wmtsSource = new WMTSSource({ |
| 106 | + dimensions: { |
| 107 | + Time: timestamp, |
| 108 | + }, |
| 109 | +
|
| 110 | + // Workaround: Set a cache size of zero when layer is |
| 111 | + // timeEnabled see: |
| 112 | + // https://github.com/geoadmin/mf-geoadmin3/issues/3491 |
| 113 | + cacheSize: wmtsLayerConfig.value.timeEnabled ? 0 : 2048, |
| 114 | + layer: layerId.value, |
| 115 | + format: wmtsLayerConfig.value.format, |
80 | 116 | projection: projection.value.epsg,
|
81 |
| - url: url.value, |
| 117 | + requestEncoding: 'REST', |
82 | 118 | tileGrid,
|
| 119 | + // tileLoadFunction: tileLoadFunction, |
| 120 | + url: getWMTSUrl(url.value), |
| 121 | + crossOrigin: crossOrigin, |
| 122 | + transition: 0, |
| 123 | + style: 'default', |
| 124 | + matrixSet: projection.value.epsg, |
| 125 | + attributions: wmtsLayerConfig.value.attribution, |
83 | 126 | })
|
| 127 | + return wmtsSource |
84 | 128 | }
|
85 | 129 | </script>
|
86 | 130 |
|
|
0 commit comments