Skip to content

Commit 8085e93

Browse files
committed
[POC] MapLibre layer
replaces all BG layers with a VectorTile equivalent switch to mercator as default projection to make it happen (not possible yet to mix projection systems, needs some work done on the geoblocks/ol-maplibre-layer library) fix INT staging URL : no sys service serves theses styles yet
1 parent ea12bde commit 8085e93

12 files changed

Lines changed: 76 additions & 65 deletions

.env.development

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ VITE_API_SERVICES_BASE_URL=https://sys-map.dev.bgdi.ch/api/
99
VITE_API_SERVICE_KML_BASE_URL=https://sys-public.dev.bgdi.ch/
1010
VITE_APP_API_SERVICE_SHORTLINK_BASE_URL=https://sys-s.dev.bgdi.ch/
1111
VITE_APP_3D_TILES_BASE_URL=https://sys-3d.dev.bgdi.ch/
12-
VITE_APP_VECTORTILES_BASE_URL=https://sys-verctortiles.dev.bgdi.ch/
12+
VITE_APP_VECTORTILES_BASE_URL=https://vectortiles.geo.admin.ch/
1313
VITE_APP_SERVICE_PROXY_BASE_URL=https://sys-proxy.dev.bgdi.ch/

.env.integration

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ VITE_API_SERVICES_BASE_URL=https://sys-map.int.bgdi.ch/api/
88
VITE_API_SERVICE_KML_BASE_URL=https://sys-public.int.bgdi.ch/
99
VITE_APP_API_SERVICE_SHORTLINK_BASE_URL=https://sys-s.int.bgdi.ch/
1010
VITE_APP_3D_TILES_BASE_URL=https://sys-3d.int.bgdi.ch/
11-
VITE_APP_VECTORTILES_BASE_URL=https://sys-verctortiles.int.bgdi.ch/
11+
VITE_APP_VECTORTILES_BASE_URL=https://vectortiles.geo.admin.ch/
1212
VITE_APP_SERVICE_PROXY_BASE_URL=https://sys-proxy.int.bgdi.ch/

src/api/layers/GeoAdminLayer.class.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ export default class GeoAdminLayer extends AbstractLayer {
2222
* layer
2323
* @param {String | null} layerData.idIn3d The layer ID to be used as substitute for this layer
2424
* when we are showing the 3D map. Will be using the same layer if this is set to null.
25+
* @param {String | null} layerData.idInVectorTile The layer ID to be used as substitute for
26+
* this layer when we are showing the map with vector tiles. Will be using the same layer if
27+
* this is set to null.
2528
* @param {String} layerData.technicalName The ID/name to use when requesting the WMS/WMTS
2629
* backend, this might be different than id, and many layers (with different id) can in fact
2730
* request the same layer, through the same technical name, in the end)
@@ -75,6 +78,7 @@ export default class GeoAdminLayer extends AbstractLayer {
7578
type = null,
7679
id = null,
7780
idIn3d = null,
81+
idInVectorTile = null,
7882
technicalName = null,
7983
opacity = 1.0,
8084
visible = true,
@@ -128,6 +132,7 @@ export default class GeoAdminLayer extends AbstractLayer {
128132
this.isHighlightable = isHighlightable
129133
this.topics = topics
130134
this.idIn3d = idIn3d
135+
this.idInVectorTile = idInVectorTile
131136
this.isSpecificFor3D = id.toLowerCase().endsWith('_3d')
132137
this.searchable = searchable
133138
}

src/api/layers/GeoAdminVectorLayer.class.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,26 @@ import { getVectorTilesBaseUrl } from '@/config/baseUrl.config'
1616
*/
1717
export default class GeoAdminVectorLayer extends GeoAdminLayer {
1818
/**
19-
* @param {string} layerId The ID of this layer
20-
* @param {LayerAttribution[]} extraAttributions Extra attribution in case this vector layer is
21-
* a mix of many sources
19+
* @param {string} vtLayerConfig.id The ID of this layer
20+
* @param {string} vtLayerConfig.vectorStyleId The ID of the style in the VT backend
21+
* @param {LayerAttribution[]} vtLayerConfig.extraAttributions Extra attribution in case this
22+
* vector layer is a mix of many sources
2223
*/
23-
constructor(layerId, extraAttributions = []) {
24+
constructor(vtLayerConfig = {}) {
25+
const { id, vectorStyleId = null, extraAttributions = [] } = vtLayerConfig
2426
super({
25-
name: layerId,
27+
id,
28+
name: id,
2629
type: LayerTypes.VECTOR,
2730
baseUrl: getVectorTilesBaseUrl(),
28-
id: layerId,
29-
technicalName: layerId,
31+
technicalName: id,
3032
attributions: [
3133
...extraAttributions,
3234
new LayerAttribution('swisstopo', 'https://www.swisstopo.admin.ch/en/home.html'),
3335
],
3436
isBackground: true,
3537
hasLegend: false,
3638
})
39+
this.vectorStyleId = vectorStyleId
3740
}
3841
}

src/api/layers/GeoAdminWMSLayer.class.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export default class GeoAdminWMSLayer extends GeoAdminLayer {
2121
* @param {String} layerData.id The unique ID of this layer
2222
* @param {String | null} layerData.idIn3d The layer ID to be used as substitute for this layer
2323
* when we are showing the 3D map. Will be using the same layer if this is set to null.
24+
* @param {String | null} layerData.idInVectorTile The layer ID to be used as substitute for
25+
* this layer when we are showing the map with vector tiles. Will be using the same layer if
26+
* this is set to null.
2427
* @param {String} layerData.technicalName The ID/name to use when requesting the WMS backend,
2528
* this might be different than id, and many layers (with different id) can in fact request
2629
* the same layer, through the same technical name, in the end)
@@ -69,6 +72,7 @@ export default class GeoAdminWMSLayer extends GeoAdminLayer {
6972
name = null,
7073
id = null,
7174
idIn3d = null,
75+
idInVectorTile = null,
7276
technicalName = null,
7377
opacity = 1.0,
7478
visible = true,
@@ -91,6 +95,7 @@ export default class GeoAdminWMSLayer extends GeoAdminLayer {
9195
type: LayerTypes.WMS,
9296
id,
9397
idIn3d,
98+
idInVectorTile,
9499
technicalName,
95100
opacity,
96101
visible,

src/api/layers/GeoAdminWMTSLayer.class.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ export default class GeoAdminWMTSLayer extends GeoAdminLayer {
2222
* @param {String} layerData.id Unique layer ID
2323
* @param {String | null} layerData.idIn3d The layer ID to be used as substitute for this layer
2424
* when we are showing the 3D map. Will be using the same layer if this is set to null.
25+
* @param {String | null} layerData.idInVectorTile The layer ID to be used as substitute for
26+
* this layer when we are showing the map with vector tiles. Will be using the same layer if
27+
* this is set to null.
2528
* @param {String} layerData.technicalName ID to be used in our backend (can be different from
2629
* the id)
2730
* @param {Number} [layerData.opacity=1.0] Opacity value between 0.0 (transparent) and 1.0
@@ -63,6 +66,7 @@ export default class GeoAdminWMTSLayer extends GeoAdminLayer {
6366
name = null,
6467
id = null,
6568
idIn3d = null,
69+
idInVectorTile = null,
6670
technicalName = null,
6771
opacity = 1.0,
6872
visible = true,
@@ -89,6 +93,7 @@ export default class GeoAdminWMTSLayer extends GeoAdminLayer {
8993
type: LayerTypes.WMTS,
9094
id,
9195
idIn3d,
96+
idInVectorTile,
9297
technicalName,
9398
opacity,
9499
visible,

src/config/map.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { LV95 } from '@/utils/coordinates/coordinateSystems'
1+
import { WEBMERCATOR } from '@/utils/coordinates/coordinateSystems'
22

33
/**
44
* Default projection to be used throughout the application
55
*
66
* @type {CoordinateSystem}
77
*/
8-
export const DEFAULT_PROJECTION = LV95
8+
export const DEFAULT_PROJECTION = WEBMERCATOR
99

1010
/**
1111
* Default tile size to use when requesting WMS tiles with our internal WMSs (512px)

src/modules/map/components/openlayers/OpenLayersBackgroundLayer.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@ import { useLayerZIndexCalculation } from '@/modules/map/components/common/z-ind
66
import OpenLayersInternalLayer from '@/modules/map/components/openlayers/OpenLayersInternalLayer.vue'
77
88
const store = useStore()
9+
const layersConfig = computed(() => store.state.layers.config)
910
const currentBackgroundLayer = computed(() => store.state.layers.currentBackgroundLayer)
11+
const vectorTileCounterpart = computed(() =>
12+
layersConfig.value.find((layer) => layer.id === currentBackgroundLayer.value.idInVectorTile)
13+
)
1014
1115
const { getZIndexForLayer } = useLayerZIndexCalculation()
1216
</script>
1317

1418
<template>
1519
<OpenLayersInternalLayer
1620
v-if="currentBackgroundLayer"
17-
:layer-config="currentBackgroundLayer"
21+
:layer-config="vectorTileCounterpart ?? currentBackgroundLayer"
1822
:z-index="getZIndexForLayer(currentBackgroundLayer)"
1923
/>
2024
</template>

src/modules/map/components/openlayers/OpenLayersInternalLayer.vue

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import OpenLayersKMLLayer from '@/modules/map/components/openlayers/OpenLayersKM
1616
import OpenLayersVectorLayer from '@/modules/map/components/openlayers/OpenLayersVectorLayer.vue'
1717
import OpenLayersWMSLayer from '@/modules/map/components/openlayers/OpenLayersWMSLayer.vue'
1818
import OpenLayersWMTSLayer from '@/modules/map/components/openlayers/OpenLayersWMTSLayer.vue'
19-
import { WEBMERCATOR } from '@/utils/coordinates/coordinateSystems'
2019
2120
const props = defineProps({
2221
layerConfig: {
@@ -35,7 +34,6 @@ const props = defineProps({
3534
const { layerConfig, parentLayerOpacity, zIndex } = toRefs(props)
3635
3736
const store = useStore()
38-
const projection = computed(() => store.state.position.projection)
3937
const resolution = computed(() => store.getters.resolution)
4038
4139
function shouldAggregateSubLayerBeVisible(subLayer) {
@@ -56,7 +54,7 @@ function shouldAggregateSubLayerBeVisible(subLayer) {
5654
(see OpenLayersMap main component)
5755
-->
5856
<OpenLayersVectorLayer
59-
v-if="projection.epsg === WEBMERCATOR.epsg && layerConfig.type === LayerTypes.VECTOR"
57+
v-if="layerConfig.type === LayerTypes.VECTOR"
6058
:vector-layer-config="layerConfig"
6159
:parent-layer-opacity="parentLayerOpacity"
6260
:z-index="zIndex"

src/modules/map/components/openlayers/OpenLayersVectorLayer.vue

Lines changed: 9 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@
1010
*/
1111
1212
import { MapLibreLayer } from '@geoblocks/ol-maplibre-layer'
13-
import axios from 'axios'
13+
import { Source } from 'ol/source'
1414
import { computed, inject, toRefs, watch } from 'vue'
1515
1616
import GeoAdminVectorLayer from '@/api/layers/GeoAdminVectorLayer.class'
17-
import { VECTOR_TILES_IMAGERY_STYLE_ID } from '@/config/vectortiles.config'
1817
import useAddLayerToMap from '@/modules/map/components/openlayers/utils/useAddLayerToMap.composable'
19-
import log from '@/utils/logging'
2018
2119
const props = defineProps({
2220
vectorLayerConfig: {
@@ -35,65 +33,27 @@ const props = defineProps({
3533
const { vectorLayerConfig, parentLayerOpacity, zIndex } = toRefs(props)
3634
3735
// extracting useful info from what we've linked so far
38-
const layerId = computed(() => vectorLayerConfig.value.id)
36+
const layerId = computed(() => vectorLayerConfig.value.vectorStyleId)
3937
const opacity = computed(() => parentLayerOpacity.value ?? vectorLayerConfig.value.opacity)
4038
const styleUrl = computed(
4139
() => `${vectorLayerConfig.value.baseUrl}styles/${layerId.value}/style.json`
4240
)
4341
4442
const layer = new MapLibreLayer({
45-
id: layerId.value,
4643
opacity: opacity.value,
44+
mapLibreOptions: {
45+
style: styleUrl.value,
46+
},
47+
source: new Source({
48+
attribution: [vectorLayerConfig.value.attribution],
49+
}),
4750
})
48-
setMapLibreStyle(styleUrl.value)
4951
5052
const olMap = inject('olMap')
5153
useAddLayerToMap(layer, olMap, zIndex)
5254
5355
watch(opacity, (newOpacity) => layer.setOpacity(newOpacity))
54-
watch(styleUrl, (newStyleUrl) => setMapLibreStyle(newStyleUrl))
55-
function setMapLibreStyle(styleUrl) {
56-
if (!layer?.maplibreMap) {
57-
log.error('MapLibre instance is not attached to the layer')
58-
return
59-
}
60-
// most of this methods will be edited while doing https://jira.swisstopo.ch/browse/BGDIINF_SB-2741
61-
if (layerId.value === VECTOR_TILES_IMAGERY_STYLE_ID) {
62-
// special case here, as the imagery is only over Switzerland (for now)
63-
// we inject a fair-use WMTS that covers the globe under our aerial images
64-
axios
65-
.get(styleUrl)
66-
.then((response) => {
67-
const vectorStyle = response.data
68-
// settings SwissImage to use the tiled WMS instead
69-
// otherwise it covers the whole world with white tiles (when no data is present)
70-
vectorStyle.sources.swissimage_wmts.tiles = [
71-
'https://wms.geo.admin.ch/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=ch.swisstopo.swissimage&LANG=en&WIDTH=256&HEIGHT=256&CRS=EPSG%3A3857&STYLES=&BBOX={bbox-epsg-3857}',
72-
]
73-
// setting up Sentinel2 WMTS to cover the globe outside of Switzerland
74-
vectorStyle.sources['sentinel2_wmts'] = {
75-
minzoom: 0,
76-
maxzoom: 22,
77-
tileSize: 256,
78-
type: 'raster',
79-
tiles: [
80-
'https://tiles.maps.eox.at/wmts?layer=s2cloudless-2020_3857&style=default&tilematrixset=g&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fjpeg&TileMatrix={z}&TileCol={x}&TileRow={y}',
81-
],
82-
}
83-
vectorStyle.layers.splice(1, 0, {
84-
id: 'sentinel2',
85-
source: 'sentinel2_wmts',
86-
type: 'raster',
87-
})
88-
layer.maplibreMap.setStyle(vectorStyle)
89-
})
90-
.catch((err) => {
91-
log.error('Error while fetching MapLibre style', styleUrl, err)
92-
})
93-
} else {
94-
layer.maplibreMap.setStyle(styleUrl)
95-
}
96-
}
56+
watch(styleUrl, (newStyleUrl) => layer.mapLibreMap?.setStyle(newStyleUrl))
9757
</script>
9858
9959
<template>

0 commit comments

Comments
 (0)