11<script setup lang="ts">
2- import { ref , onMounted } from ' vue'
2+ import { ref , onMounted , computed } from ' vue'
3+ import { storeToRefs } from ' pinia'
34import { useTranslation } from ' i18next-vue'
45import { CLASS_CONTROL , CLASS_UNSELECTABLE } from ' ol/css'
56import Control from ' ol/control/Control'
67import { Options } from ' ol/control/Control'
8+ import { toLonLat } from ' ol/proj'
79
810import useControl from ' @/composables/control/control.composable'
911import { useMapStore } from ' @/stores/map.store'
1012
13+ const LUX_VCS_URL = import .meta .env .VITE_LUX_VCS_URL
14+ const LUX_VCS_COORDINATES = [6.13 , 49.61 ]
15+ const LUX_VCS_MODULES = [' catalogConfig' , ' LuxConfig' ]
16+ const zoomToCesiumAltitude = {
17+ 9 : 350000 ,
18+ 10 : 180000 ,
19+ 11 : 100000 ,
20+ 12 : 40000 ,
21+ 13 : 25000 ,
22+ 14 : 9000 ,
23+ 15 : 6000 ,
24+ 16 : 3500 ,
25+ 17 : 1900 ,
26+ 18 : 900 ,
27+ 19 : 600 ,
28+ }
29+
1130const mapStore = useMapStore ()
1231const { t } = useTranslation ()
1332const props = withDefaults (
@@ -18,33 +37,77 @@ const props = withDefaults(
1837 }>(),
1938 {
2039 className: ' map-3d-button' ,
21- label: ' \ue057 ' ,
22- tipLabel: ' 3d ' ,
40+ label: ' 3D ' ,
41+ tipLabel: ' 3D ' ,
2342 }
2443)
44+ const { x, y, zoom, layers } = storeToRefs (mapStore )
2545const controlElement = ref (null )
46+ const linkTo3dMap = computed (() => {
47+ // Example pattern for VCS state
48+ // [[[6.131935,49.611622,5000],[6.131935,49.611622,50],300,0,-90,0],"cesium",["moduleName"],[["addresses",1,0],["communes",1,0]],[],0]
49+
50+ const [lon, lat] = getLonLatFromXY (x .value , y .value )
51+ const altitude = getAltFromZoom (zoom .value ?? 12 )
52+ const selectedLayers = layers .value .map (l => JSON .stringify ([l .name , 1 , 0 ]))
53+ const state = ` [[[${[lon , lat , altitude ].join (' ,' )}],[${[
54+ lon ,
55+ lat ,
56+ altitude ,
57+ ].join (' ,' )}],300,0,-90,0],"cesium",["${LUX_VCS_MODULES .join (
58+ ' ","'
59+ )}"],[${selectedLayers .join (' ,' )}],[],0] `
60+
61+ return ` ${LUX_VCS_URL }?state=${encodeURIComponent (state )} `
62+ })
2663
2764onMounted (() =>
2865 useControl (Control , {
2966 ... props ,
30- ... { target: controlElement } ,
67+ target: controlElement ,
3168 } as unknown as Options )
3269)
3370
34- const toggle3d = () => {
35- mapStore .setIs3dActive (! mapStore .is3dActive )
71+ function getLonLatFromXY(
72+ x : number | undefined | null ,
73+ y : number | undefined | null
74+ ) {
75+ return x && y ? toLonLat ([x , y ]) : LUX_VCS_COORDINATES
76+ }
77+
78+ function getAltFromZoom(zoom : number ) {
79+ const minZoom = 9
80+ const maxZoom = 19
81+
82+ const clampedZoom = Math .max (
83+ minZoom ,
84+ Math .min (maxZoom , Math .round (zoom ))
85+ ) as keyof typeof zoomToCesiumAltitude
86+
87+ return zoomToCesiumAltitude [clampedZoom ]
3688}
3789 </script >
3890
3991<template >
4092 <div
93+ data-cy =" 3dViewerLink"
4194 ref =" controlElement"
42- :class =" `${props.className} ${CLASS_UNSELECTABLE} ${CLASS_CONTROL} ${
43- mapStore.is3dActive ? 'active' : ''
44- }`"
95+ :class =" `${props.className} ${CLASS_UNSELECTABLE} ${CLASS_CONTROL}`"
4596 >
46- <button :title =" t(props.tipLabel)" @click =" toggle3d" >
47- {{ props.label }}
48- </button >
97+ <a
98+ type =" button"
99+ target =" lux3d"
100+ :href =" linkTo3dMap"
101+ :title =" t(props.tipLabel)"
102+ >3D</a
103+ >
49104 </div >
50105</template >
106+
107+ <style lang="css" scoped>
108+ .ol-control a [type = ' button' ] {
109+ font-family : ' DINNextLTPro-Condensed' , Arial , sans-serif ;
110+ font-size : 1.5em ;
111+ line-height : 2.5rem ;
112+ }
113+ </style >
0 commit comments