Skip to content

Commit 6ade17f

Browse files
authored
Merge pull request #423 from geoadmin/feat-BGDIINF_SB-2979_add_3d_wmts_component
Add WMTS and WMS layer components for 3D
2 parents 2307ccf + c1f3b05 commit 6ade17f

13 files changed

+433
-101
lines changed

src/config.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,9 @@ export const TILEGRID_RESOLUTIONS = [
195195
]
196196

197197
/**
198-
* Map view's mininal resolution
199-
* Currently set so that OL scalebar displays 10 meters
200-
* Scalebar about 1" on screen, hence about 100px. So, 10 meters/100px = 0.1
201-
* Caveat: setting resolution (mininum and maximum) has the precedence over zoom (minimum/maximum)
198+
* Map view's mininal resolution Currently set so that OL scalebar displays 10 meters Scalebar about
199+
* 1" on screen, hence about 100px. So, 10 meters/100px = 0.1 Caveat: setting resolution (mininum
200+
* and maximum) has the precedence over zoom (minimum/maximum)
202201
*/
203202

204203
export const VIEW_MIN_RESOLUTION = 0.1 // meters/pixel
@@ -223,7 +222,14 @@ export const TILEGRID_EXTENT = [2420000, 1030000, 2900000, 1350000]
223222
*
224223
* @type {Number[]}
225224
*/
226-
export const LV95_EXTENT = [572215.44, 5684416.96, 1277662.37, 6145307.4]
225+
export const TILEGRID_EXTENT_EPSG_3857 = [572215.44, 5684416.96, 1277662.37, 6145307.4]
226+
227+
/**
228+
* TILEGRID_EXTENT (defined above) reprojected in EPSG:4326 through epsg.io website.
229+
*
230+
* @type {Number[]}
231+
*/
232+
export const TILEGRID_EXTENT_EPSG_4326 = [5.1402988, 45.3981222, 11.4774363, 48.230617]
227233

228234
/**
229235
* Map center default value is the center of switzerland LV:95 projection's extent (from
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<template>
2+
<div>
3+
<CesiumWMTSLayer
4+
v-if="layerConfig.type === LayerTypes.WMTS && !layerConfig.isExternal"
5+
:wmts-layer-config="layerConfig"
6+
:preview-year="previewYear"
7+
:projection="WEBMERCATOR"
8+
:z-index="zIndex"
9+
/>
10+
<CesiumWMSLayer
11+
v-if="layerConfig.type === LayerTypes.WMS && !layerConfig.isExternal"
12+
:wms-layer-config="layerConfig"
13+
:preview-year="previewYear"
14+
:projection="LV95"
15+
:z-index="zIndex"
16+
/>
17+
<slot />
18+
</div>
19+
</template>
20+
21+
<script>
22+
import AbstractLayer from '@/api/layers/AbstractLayer.class'
23+
import LayerTypes from '@/api/layers/LayerTypes.enum'
24+
import { LV95, WEBMERCATOR } from '@/utils/coordinateSystems'
25+
import CesiumWMTSLayer from './CesiumWMTSLayer.vue'
26+
import CesiumWMSLayer from './CesiumWMSLayer.vue'
27+
28+
/**
29+
* Transforms a layer config (metadata, structures can be found in api/layers/** files) into the
30+
* correct Cesium counterpart depending on the layer type.
31+
*/
32+
export default {
33+
components: {
34+
CesiumWMTSLayer,
35+
CesiumWMSLayer,
36+
},
37+
props: {
38+
layerConfig: {
39+
type: AbstractLayer,
40+
default: null,
41+
},
42+
zIndex: {
43+
type: Number,
44+
default: -1,
45+
},
46+
previewYear: {
47+
type: Number,
48+
default: null,
49+
},
50+
},
51+
data() {
52+
return {
53+
LayerTypes,
54+
LV95,
55+
WEBMERCATOR,
56+
}
57+
},
58+
}
59+
</script>

src/modules/map/components/cesium/CesiumMap.vue

+52-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
<template>
2-
<div id="cesium" ref="map" data-cy="cesium"></div>
2+
<div id="cesium" ref="viewer" data-cy="cesium">
3+
<div v-if="viewerCreated">
4+
<!-- Adding background layer -->
5+
<CesiumInternalLayer
6+
v-if="currentBackgroundLayer"
7+
:layer-config="currentBackgroundLayer"
8+
:z-index="0"
9+
/>
10+
<!-- Adding all other layers -->
11+
<CesiumInternalLayer
12+
v-for="(layer, index) in visibleLayers"
13+
:key="layer.getID()"
14+
:layer-config="layer"
15+
:preview-year="previewYear"
16+
:z-index="index + startingZIndexForVisibleLayers"
17+
/>
18+
</div>
19+
</div>
320
<cesium-compass v-show="isDesktopMode" ref="compass"></cesium-compass>
421
<slot />
522
</template>
@@ -13,31 +30,60 @@ import {
1330
Cartesian3,
1431
RequestScheduler,
1532
} from 'cesium'
16-
import { addSwisstopoWMTSLayer } from './utils/imageryLayerUtils'
1733
import { UIModes } from '@/store/modules/ui.store'
1834
import { mapGetters, mapState } from 'vuex'
1935
import { TERRAIN_URL } from './constants'
20-
import { IS_TESTING_WITH_CYPRESS } from '@/config'
36+
import { IS_TESTING_WITH_CYPRESS, WMTS_BASE_URL } from '@/config'
37+
import CesiumInternalLayer from './CesiumInternalLayer.vue'
38+
import GeoAdminWMTSLayer from '@/api/layers/GeoAdminWMTSLayer.class'
39+
import LayerTimeConfig from '@/api/layers/LayerTimeConfig.class'
40+
import { CURRENT_YEAR_WMTS_TIMESTAMP } from '@/api/layers/LayerTimeConfigEntry.class'
2141
import '@geoblocks/cesium-compass'
42+
2243
export default {
44+
components: { CesiumInternalLayer },
2345
provide() {
2446
return {
2547
// sharing cesium viewer object with children components
2648
getViewer: () => this.viewer,
2749
}
2850
},
51+
data() {
52+
return {
53+
viewerCreated: false,
54+
// todo just for testing, remove when 3d background switch will be implemented
55+
currentBackgroundLayer: new GeoAdminWMTSLayer(
56+
'ch.swisstopo.swisstlm3d-karte-farbe.3d',
57+
'ch.swisstopo.swisstlm3d-karte-farbe.3d',
58+
1,
59+
true,
60+
[],
61+
'jpeg',
62+
new LayerTimeConfig(CURRENT_YEAR_WMTS_TIMESTAMP, []),
63+
true,
64+
WMTS_BASE_URL,
65+
false,
66+
false,
67+
[]
68+
),
69+
}
70+
},
2971
computed: {
3072
...mapState({
3173
zoom: (state) => state.position.zoom,
3274
rotation: (state) => state.position.rotation,
3375
center: (state) => state.position.center,
3476
is3DActive: (state) => state.ui.showIn3d,
3577
uiMode: (state) => state.ui.mode,
78+
previewYear: (state) => state.layers.previewYear,
3679
}),
37-
...mapGetters(['centerEpsg4326', 'resolution', 'hasDevSiteWarning']),
80+
...mapGetters(['centerEpsg4326', 'resolution', 'hasDevSiteWarning', 'visibleLayers']),
3881
isDesktopMode() {
3982
return this.uiMode === UIModes.DESKTOP
4083
},
84+
startingZIndexForVisibleLayers() {
85+
return this.currentBackgroundLayer ? 1 : 0
86+
},
4187
},
4288
beforeCreate() {
4389
// Global variable required for Cesium and point to the URL where four static directories (see vite.config) are served
@@ -62,7 +108,7 @@ export default {
62108
rectangle: Rectangle.fromDegrees(0, 0, 1, 1), // the Rectangle dimensions are arbitrary
63109
})
64110
65-
this.viewer = new Viewer(this.$refs.map, {
111+
this.viewer = new Viewer(this.$refs.viewer, {
66112
contextOptions: {
67113
webgl: {
68114
powerPreference: 'high-performance',
@@ -113,14 +159,7 @@ export default {
113159
globe.undergroundColorAlphaByDistance.nearValue = 0.5
114160
globe.undergroundColorAlphaByDistance.farValue = 0.0
115161
116-
// todo move when the background layer switch is done
117-
const baseLayer = addSwisstopoWMTSLayer(
118-
this.viewer,
119-
'ch.swisstopo.swisstlm3d-karte-farbe.3d',
120-
'jpeg',
121-
20
122-
)
123-
baseLayer.show = true
162+
this.viewerCreated = true
124163
125164
this.flyToPosition()
126165
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<template>
2+
<div>
3+
<slot />
4+
</div>
5+
</template>
6+
7+
<script>
8+
import { CoordinateSystem, WEBMERCATOR } from '@/utils/coordinateSystems'
9+
import { ImageryLayer, Rectangle, WebMapServiceImageryProvider } from 'cesium'
10+
import { TILEGRID_EXTENT_EPSG_4326 } from '@/config'
11+
import { mapState } from 'vuex'
12+
import GeoAdminWMSLayer from '@/api/layers/GeoAdminWMSLayer.class'
13+
import addImageryLayerMixins from '@/modules/map/components/cesium/utils/addImageryLayer-mixins'
14+
15+
import { getTimestampFromConfig } from '@/utils/layerUtils'
16+
17+
const MAXIMUM_LEVEL_OF_DETAILS = 18
18+
19+
export default {
20+
mixins: [addImageryLayerMixins],
21+
props: {
22+
wmsLayerConfig: {
23+
type: GeoAdminWMSLayer,
24+
required: true,
25+
},
26+
previewYear: {
27+
type: Number,
28+
default: null,
29+
},
30+
projection: {
31+
type: CoordinateSystem,
32+
default: WEBMERCATOR.epsg,
33+
},
34+
zIndex: {
35+
type: Number,
36+
default: -1,
37+
},
38+
},
39+
computed: {
40+
...mapState({
41+
currentLang: (state) => state.i18n.lang,
42+
}),
43+
layerId() {
44+
return this.wmsLayerConfig.geoAdminID || this.wmsLayerConfig.externalLayerId
45+
},
46+
opacity() {
47+
return this.wmsLayerConfig.opacity || 1.0
48+
},
49+
wmsVersion() {
50+
return this.wmsLayerConfig.wmsVersion || '1.3.0'
51+
},
52+
format() {
53+
return this.wmsLayerConfig.format || 'png'
54+
},
55+
url() {
56+
return this.wmsLayerConfig.getURL()
57+
},
58+
timestamp() {
59+
return getTimestampFromConfig(this.wmsLayerConfig, this.previewYear)
60+
},
61+
/**
62+
* Definition of all relevant URL param for our WMS backends. Passes as parameters to
63+
* https://cesium.com/learn/cesiumjs/ref-doc/WebMapServiceImageryProvider.html#.ConstructorOptions
64+
*
65+
* If we let the URL have all the param beforehand (sending all URL param through the url
66+
* option), most of our wanted params will be doubled, resulting in longer and more
67+
* difficult to read URLs
68+
*
69+
* @returns Object
70+
*/
71+
wmsUrlParams() {
72+
return {
73+
SERVICE: 'WMS',
74+
REQUEST: 'GetMap',
75+
TRANSPARENT: true,
76+
LAYERS: this.layerId,
77+
FORMAT: `image/${this.format}`,
78+
LANG: this.currentLang,
79+
VERSION: this.wmsVersion,
80+
TIME: this.timestamp,
81+
}
82+
},
83+
},
84+
methods: {
85+
createImagery(url) {
86+
return new ImageryLayer(
87+
new WebMapServiceImageryProvider({
88+
url: url,
89+
parameters: this.wmsUrlParams,
90+
subdomains: '0123',
91+
layers: this.wmsLayerConfig.geoAdminID,
92+
maximumLevel: MAXIMUM_LEVEL_OF_DETAILS,
93+
rectangle: Rectangle.fromDegrees(...TILEGRID_EXTENT_EPSG_4326),
94+
}),
95+
{
96+
show: this.wmsLayerConfig.visible,
97+
alpha: this.opacity,
98+
}
99+
)
100+
},
101+
},
102+
}
103+
</script>
104+
105+
<style scoped lang="scss"></style>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<template>
2+
<div>
3+
<slot />
4+
</div>
5+
</template>
6+
7+
<script>
8+
import GeoAdminWMTSLayer from '@/api/layers/GeoAdminWMTSLayer.class'
9+
import { CoordinateSystem, WEBMERCATOR } from '@/utils/coordinateSystems'
10+
import { ImageryLayer, Rectangle, UrlTemplateImageryProvider } from 'cesium'
11+
import { TILEGRID_EXTENT_EPSG_4326 } from '@/config'
12+
import addImageryLayerMixins from './utils/addImageryLayer-mixins'
13+
14+
import { getTimestampFromConfig } from '@/utils/layerUtils'
15+
16+
const MAXIMUM_LEVEL_OF_DETAILS = 18
17+
18+
export default {
19+
mixins: [addImageryLayerMixins],
20+
props: {
21+
wmtsLayerConfig: {
22+
type: GeoAdminWMTSLayer,
23+
required: true,
24+
},
25+
previewYear: {
26+
type: Number,
27+
default: null,
28+
},
29+
projection: {
30+
type: CoordinateSystem,
31+
default: WEBMERCATOR,
32+
},
33+
zIndex: {
34+
type: Number,
35+
default: -1,
36+
},
37+
},
38+
computed: {
39+
layerId() {
40+
return this.wmtsLayerConfig.getID()
41+
},
42+
opacity() {
43+
return this.wmtsLayerConfig.opacity || 1.0
44+
},
45+
timestampForPreviewYear() {
46+
return getTimestampFromConfig(this.wmtsLayerConfig, this.previewYear)
47+
},
48+
url() {
49+
return this.wmtsLayerConfig.getURL(
50+
this.timestampForPreviewYear,
51+
this.projection.epsgNumber
52+
)
53+
},
54+
},
55+
methods: {
56+
createImagery(url) {
57+
return new ImageryLayer(
58+
new UrlTemplateImageryProvider({
59+
rectangle: Rectangle.fromDegrees(...TILEGRID_EXTENT_EPSG_4326),
60+
maximumLevel: MAXIMUM_LEVEL_OF_DETAILS,
61+
url: url,
62+
}),
63+
{
64+
show: this.wmtsLayerConfig.visible,
65+
alpha: this.opacity,
66+
}
67+
)
68+
},
69+
},
70+
}
71+
</script>
72+
73+
<style scoped lang="scss"></style>

0 commit comments

Comments
 (0)