@eturnity/eturnity_3d 6.34.0 → 6.34.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/.editorconfig +5 -0
  2. package/package.json +8 -4
  3. package/src/App.vue +16 -16
  4. package/src/assets/theme.js +4 -4
  5. package/src/components/ThreeCanvasViewer.vue +56 -43
  6. package/src/config.js +139 -65
  7. package/src/helper/MapView.js +214 -241
  8. package/src/helper/UpdateRoofModuleFieldRelations.js +17 -23
  9. package/src/helper/UpdateRoofObstacleRelations.js +48 -41
  10. package/src/helper/cameraMixin.js +97 -93
  11. package/src/helper/customProvider.js +28 -28
  12. package/src/helper/materialMixin.js +86 -70
  13. package/src/helper/materials.js +64 -49
  14. package/src/helper/render/background.js +2 -5
  15. package/src/helper/render/base.js +43 -40
  16. package/src/helper/render/clear.js +96 -84
  17. package/src/helper/render/edge.js +59 -65
  18. package/src/helper/render/geometryHandler.js +166 -128
  19. package/src/helper/render/imageOverlay.js +157 -106
  20. package/src/helper/render/index.js +21 -3
  21. package/src/helper/render/loader.js +34 -34
  22. package/src/helper/render/mapProjection.js +88 -74
  23. package/src/helper/render/margin.js +46 -50
  24. package/src/helper/render/moduleField.js +26 -24
  25. package/src/helper/render/node.js +43 -43
  26. package/src/helper/render/obstacle.js +50 -48
  27. package/src/helper/render/panel.js +85 -79
  28. package/src/helper/render/projectionMaterial.js +58 -50
  29. package/src/helper/render/roof.js +136 -133
  30. package/src/helper/render/texture.js +17 -17
  31. package/src/helper/render/tile.js +291 -0
  32. package/src/helper/renderMixin.js +30 -37
  33. package/src/helper/threeMixin.js +40 -101
  34. package/src/main.js +22 -18
  35. package/src/store/AddMargin.js +87 -83
  36. package/src/store/hydrateData.js +40 -30
  37. package/src/store/nodesEdgesCreation.js +177 -160
  38. package/src/store/three-d-module.js +41 -27
  39. package/src/utils/cancellablePromise.js +23 -0
  40. package/.eslintrc.json +0 -18
  41. package/src/helper/geo-three.module.js +0 -1903
@@ -1,145 +1,148 @@
1
1
  import * as THREE from 'three'
2
- import {
3
- maximumGapLimit,
4
- } from '../../config'
2
+ import { maximumGapLimit } from '../../config'
5
3
  import {
6
4
  getBufferRoofGeometry,
7
- updateBufferRoofGeometry,
5
+ updateBufferRoofGeometry
8
6
  } from './geometryHandler'
9
- import { intersectOutlines, verticalProjectionOnPlane } from '@eturnity/eturnity_maths'
7
+ import {
8
+ intersectOutlines,
9
+ verticalProjectionOnPlane
10
+ } from '@eturnity/eturnity_maths'
10
11
 
11
12
  export default {
12
- methods:{
13
- updateRoofGeometry(geometry, roofPolygon) {
14
- const roofOutline = roofPolygon.outline
15
- let cropedHolesOutline = roofPolygon.holes
16
- .filter((h) => h.layer == 'obstacle')
17
- .map((h) => {
18
- //let's crop obstacle with roof outline
19
- const cropedHoleOutline =
20
- intersectOutlines(h.outline, roofPolygon.outline)[0] || []
21
- const outline = cropedHoleOutline.map((p) => {
22
- return {
23
- x: p.x,
24
- y: p.y,
25
- z: verticalProjectionOnPlane(
26
- p,
27
- roofPolygon.normalVector,
28
- roofPolygon.flatOutline[0]
29
- ).z
30
- }
31
- })
32
- return outline
33
- })
13
+ methods: {
14
+ updateRoofGeometry(geometry, roofPolygon) {
15
+ const roofOutline = roofPolygon.outline
16
+ let cropedHolesOutline = roofPolygon.holes
17
+ .filter((h) => h.layer == 'obstacle')
18
+ .map((h) => {
19
+ //let's crop obstacle with roof outline
20
+ const cropedHoleOutline =
21
+ intersectOutlines(h.outline, roofPolygon.outline)[0] || []
22
+ const outline = cropedHoleOutline.map((p) => {
23
+ return {
24
+ x: p.x,
25
+ y: p.y,
26
+ z: verticalProjectionOnPlane(
27
+ p,
28
+ roofPolygon.normalVector,
29
+ roofPolygon.flatOutline[0]
30
+ ).z
31
+ }
32
+ })
33
+ return outline
34
+ })
35
+
36
+ cropedHolesOutline = cropedHolesOutline.filter((outline) => !!outline)
37
+ geometry = updateBufferRoofGeometry(
38
+ roofOutline,
39
+ cropedHolesOutline,
40
+ geometry
41
+ )
42
+
43
+ return geometry
44
+ },
45
+ createRoofGeometry(roofPolygon) {
46
+ const roofOutline = roofPolygon.outline
47
+ let cropedHolesOutline = roofPolygon.holes
48
+ .filter((h) => h.layer == 'obstacle')
49
+ .map((h) => {
50
+ //let's crop obstacle with roof outline
51
+ const cropedHoleOutline =
52
+ intersectOutlines(h.outline, roofPolygon.outline)[0] || []
53
+ const outline = cropedHoleOutline.map((p) => {
54
+ return {
55
+ x: p.x,
56
+ y: p.y,
57
+ z: verticalProjectionOnPlane(
58
+ p,
59
+ roofPolygon.normalVector,
60
+ roofPolygon.flatOutline[0]
61
+ ).z
62
+ }
63
+ })
64
+ return outline
65
+ })
66
+
67
+ cropedHolesOutline = cropedHolesOutline.filter((outline) => !!outline)
68
+ let geometry = getBufferRoofGeometry(roofOutline, cropedHolesOutline)
34
69
 
35
- cropedHolesOutline = cropedHolesOutline.filter((outline) => !!outline)
36
- geometry = updateBufferRoofGeometry(
37
- roofOutline,
38
- cropedHolesOutline,
39
- geometry
40
- )
70
+ return geometry
71
+ },
41
72
 
42
- return geometry
43
- },
44
- createRoofGeometry(roofPolygon) {
45
- const roofOutline = roofPolygon.outline
46
- let cropedHolesOutline = roofPolygon.holes
47
- .filter((h) => h.layer == 'obstacle')
48
- .map((h) => {
49
- //let's crop obstacle with roof outline
50
- const cropedHoleOutline =
51
- intersectOutlines(h.outline, roofPolygon.outline)[0] || []
52
- const outline = cropedHoleOutline.map((p) => {
53
- return {
54
- x: p.x,
55
- y: p.y,
56
- z: verticalProjectionOnPlane(
57
- p,
58
- roofPolygon.normalVector,
59
- roofPolygon.flatOutline[0]
60
- ).z
61
- }
62
- })
63
- return outline
64
- })
73
+ applyTextureOnRoofs() {
74
+ this.roofs.forEach((roof) => {
75
+ //roofs
76
+ let mesh = this.meshes.roofMeshes[roof.id]
77
+ this.applyTextureOnMesh(this.material.roof, mesh)
78
+ //obstacle on roof
79
+ roof.holes
80
+ .filter((p) => p.layer == 'obstacle')
81
+ .forEach((obstacle) => {
82
+ let meshObstacle =
83
+ this.meshes.obstacleMeshes[obstacle.id + '-' + roof.id + '_top']
84
+ this.applyTextureOnMesh(this.material.roof, meshObstacle)
85
+ })
86
+ })
87
+ },
88
+ renderRoofs() {
89
+ this.clearRemovedOnes('roofMeshes')
90
+ this.roofs.forEach((roofPolygon) => {
91
+ let mesh
92
+ let geometry
93
+ if (
94
+ this.meshes.roofMeshes[roofPolygon.id] &&
95
+ this.meshes.roofMeshes[roofPolygon.id].userData.version <
96
+ roofPolygon.version
97
+ ) {
98
+ //update mesh
99
+ mesh = this.meshes.roofMeshes[roofPolygon.id]
100
+ geometry = mesh.geometry
101
+ geometry = this.updateRoofGeometry(geometry, roofPolygon)
102
+ //in order to be able to render multiple material on it (background and image overlay)
65
103
 
66
- cropedHolesOutline = cropedHolesOutline.filter((outline) => !!outline)
67
- let geometry = getBufferRoofGeometry(roofOutline, cropedHolesOutline)
104
+ mesh.geometry = geometry
105
+ this.applyTextureOnMesh(this.material.roof, mesh)
106
+ mesh.frustumCulled = false
107
+ mesh.updateMatrix()
108
+ }
109
+ if (!this.meshes.roofMeshes[roofPolygon.id]) {
110
+ //create
111
+ geometry = this.createRoofGeometry(roofPolygon)
68
112
 
69
- return geometry
70
- },
71
-
72
- applyTextureOnRoofs(){
73
- this.roofs.forEach(roof=>{
74
- //roofs
75
- let mesh=this.meshes.roofMeshes[roof.id]
76
- this.applyTextureOnMesh(this.material.roof,mesh)
77
- //obstacle on roof
78
- roof.holes.filter(p=>p.layer=="obstacle").forEach(obstacle=>{
79
- let meshObstacle=this.meshes.obstacleMeshes[obstacle.id + '-' + roof.id + '_top']
80
- this.applyTextureOnMesh(this.material.roof,meshObstacle)
81
- })
82
- })
83
- },
84
- renderRoofs() {
85
- this.clearRemovedOnes('roofMeshes')
86
- this.roofs.forEach((roofPolygon) => {
87
- let mesh
88
- let geometry
89
- if (
90
- this.meshes.roofMeshes[roofPolygon.id] &&
91
- this.meshes.roofMeshes[roofPolygon.id].userData.version <
92
- roofPolygon.version
93
- ) {
94
- //update mesh
95
- mesh = this.meshes.roofMeshes[roofPolygon.id]
96
- geometry = mesh.geometry
97
- geometry = this.updateRoofGeometry(geometry, roofPolygon)
98
- //in order to be able to render multiple material on it (background and image overlay)
99
-
100
- mesh.geometry = geometry
101
- this.applyTextureOnMesh(this.material.roof,mesh)
102
-
113
+ if (geometry) {
114
+ mesh = new THREE.Mesh(geometry, this.material.roof)
115
+ mesh.userData.version = roofPolygon.version
116
+ mesh.userData.type = 'roofMeshes'
117
+ mesh.userData.meshId = roofPolygon.id
118
+ mesh.userData.polygonId = roofPolygon.id
119
+ mesh.matrixAutoUpdate = false
120
+ this.scene.add(mesh)
121
+ this.applyTextureOnMesh(this.material.roof, mesh)
103
122
  mesh.frustumCulled = false
104
- mesh.updateMatrix()
105
- }
106
- if (!this.meshes.roofMeshes[roofPolygon.id]) {
107
- //create
108
- geometry = this.createRoofGeometry(roofPolygon)
109
-
110
- if (geometry) {
111
- mesh = new THREE.Mesh(geometry, this.material.roof)
112
- mesh.userData.version = roofPolygon.version
113
- mesh.userData.type = 'roofMeshes'
114
- mesh.userData.meshId = roofPolygon.id
115
- mesh.userData.polygonId = roofPolygon.id
116
- mesh.matrixAutoUpdate = false
117
- this.scene.add(mesh)
118
- this.applyTextureOnMesh(this.material.roof,mesh)
119
- mesh.frustumCulled = false
120
- this.meshes.roofMeshes[roofPolygon.id] = mesh
121
- }
122
- }
123
- })
124
- },
125
- renderFlatRoofs() {
126
- //this.clearRemovedOnes('flatRoofMeshes')
127
- this.clearByType('flatRoofMeshes')
128
- this.roofs.forEach((roofPolygon) => {
129
- //if(this.meshes.flatRoofMeshes[roofPolygon.id])
130
- if(roofPolygon.maximumGap < maximumGapLimit) return
131
- let geometry = getBufferRoofGeometry(roofPolygon.flatOutline)
132
- if (geometry) {
133
- const material =this.material.curvedRoof
134
- const mesh = new THREE.Mesh(geometry, material)
135
- geometry.dispose()
136
- geometry = null
137
- mesh.itemData = roofPolygon
138
- mesh.frustumCulled = false
139
- this.scene.add(mesh)
140
- this.meshes.flatRoofMeshes[roofPolygon.id] = mesh
141
- }
142
- })
143
- },
123
+ this.meshes.roofMeshes[roofPolygon.id] = mesh
124
+ }
125
+ }
126
+ })
127
+ },
128
+ renderFlatRoofs() {
129
+ //this.clearRemovedOnes('flatRoofMeshes')
130
+ this.clearByType('flatRoofMeshes')
131
+ this.roofs.forEach((roofPolygon) => {
132
+ //if(this.meshes.flatRoofMeshes[roofPolygon.id])
133
+ if (roofPolygon.maximumGap < maximumGapLimit) return
134
+ let geometry = getBufferRoofGeometry(roofPolygon.flatOutline)
135
+ if (geometry) {
136
+ const material = this.material.curvedRoof
137
+ const mesh = new THREE.Mesh(geometry, material)
138
+ geometry.dispose()
139
+ geometry = null
140
+ mesh.itemData = roofPolygon
141
+ mesh.frustumCulled = false
142
+ this.scene.add(mesh)
143
+ this.meshes.flatRoofMeshes[roofPolygon.id] = mesh
144
+ }
145
+ })
144
146
  }
145
- }
147
+ }
148
+ }
@@ -1,19 +1,19 @@
1
1
  export default {
2
- methods:{
3
- applyTextureOnMesh(materials,mesh){
4
- if(materials && materials.length>0){
5
- let geometry=mesh.geometry
6
- geometry.clearGroups();
7
- for(let k=0;k<materials.length;k++){
8
- geometry.addGroup( 0, Infinity, k )
9
- }
10
- mesh.material=materials
11
- for(let m=0;m<materials.length;m++){
12
- if(materials[m].project) {
13
- materials[m].project(mesh)
14
- }
15
- }
16
- }
17
- },
2
+ methods: {
3
+ applyTextureOnMesh(materials, mesh) {
4
+ if (materials && materials.length > 0) {
5
+ let geometry = mesh.geometry
6
+ geometry.clearGroups()
7
+ for (let k = 0; k < materials.length; k++) {
8
+ geometry.addGroup(0, Infinity, k)
9
+ }
10
+ mesh.material = materials
11
+ for (let m = 0; m < materials.length; m++) {
12
+ if (materials[m].project) {
13
+ materials[m].project(mesh)
14
+ }
15
+ }
16
+ }
18
17
  }
19
- }
18
+ }
19
+ }
@@ -0,0 +1,291 @@
1
+ import * as THREE from 'three'
2
+ import {
3
+ getBufferRoofGeometry,
4
+ updateBufferRoofGeometry
5
+ } from './geometryHandler'
6
+ import {
7
+ distanceToDeltaLatLng,
8
+ latLngToTileXY,
9
+ tileToCorners
10
+ } from '@eturnity/eturnity_maths'
11
+
12
+ import {cancellablePromise} from '../../utils/cancellablePromise'
13
+
14
+ export default {
15
+ data() {
16
+ return {
17
+ pendingTiles: [],
18
+ }
19
+ },
20
+ methods: {
21
+ async renderTiles() {
22
+ if (
23
+ !this.selectedMapLayer ||
24
+ ['googleLayerRoadmap', 'googleLayer', 'googleLayerTerrain'].includes(
25
+ this.selectedMapLayer.key
26
+ )
27
+ ) {
28
+ this.renderGoogleTiles()
29
+ } else {
30
+ this.renderProviderTiles()
31
+ }
32
+ },
33
+ removeUnusedTiles(tileToRender) {
34
+ let tileToRenderIds = tileToRender.map(
35
+ (tileParam) =>
36
+ 'tile_' +
37
+ tileParam.xTile +
38
+ '_' +
39
+ tileParam.yTile +
40
+ '_' +
41
+ tileParam.zoomLvl
42
+ )
43
+ let idsToRemove = Object.keys(this.meshes.tileMeshes).filter((id) => {
44
+ return !tileToRenderIds.includes(id)
45
+ })
46
+ for (let id of idsToRemove) {
47
+ this.clearMesh(this.meshes.tileMeshes[id])
48
+ }
49
+ },
50
+ async renderProviderTiles() {
51
+ if (this.backgroundMap) {
52
+ this.backgroundMap.clear()
53
+ this.scene.remove(this.backgroundMap)
54
+ this.clearThreeObjects(this.backgroundMap)
55
+ }
56
+ this.backgroundMap = new THREE.Group()
57
+
58
+ let zoomLvl = this.provider.maxZoom
59
+ const latitude = this.layoutSettings.layout_latitude
60
+ const longitude = this.layoutSettings.layout_longitude
61
+ let { xMin, xMax, yMin, yMax } = this.roofsBounds
62
+ if (xMin == Infinity) {
63
+ xMin = 0
64
+ yMin = 0
65
+ xMax = 0
66
+ yMax = 0
67
+ }
68
+ let { lat: latMin, lng: lngMin } = distanceToDeltaLatLng(
69
+ xMin,
70
+ yMin,
71
+ latitude
72
+ )
73
+ let { lat: latMax, lng: lngMax } = distanceToDeltaLatLng(
74
+ xMax,
75
+ yMax,
76
+ latitude
77
+ )
78
+ let { x: xTileMin, y: yTileMax } = latLngToTileXY(
79
+ latitude + latMin,
80
+ longitude + lngMin,
81
+ zoomLvl
82
+ )
83
+ let { x: xTileMax, y: yTileMin } = latLngToTileXY(
84
+ latitude + latMax,
85
+ longitude + lngMax,
86
+ zoomLvl
87
+ )
88
+ xTileMin = xTileMin - (xTileMin % 2)
89
+ xTileMax = xTileMax + 1 - (xTileMax % 2)
90
+ yTileMin = yTileMin - (yTileMin % 2)
91
+ yTileMax = yTileMax + 1 - (yTileMax % 2)
92
+ let tileToRender = []
93
+ for (let xTile = xTileMin; xTile <= xTileMax; xTile++) {
94
+ for (let yTile = yTileMin; yTile <= yTileMax; yTile++) {
95
+ tileToRender.push({ xTile, yTile, zoomLvl })
96
+ }
97
+ }
98
+
99
+ for (let k = 0; k < 3; k++) {
100
+ xTileMin = xTileMin / 2 - 1
101
+ xTileMax = (xTileMax + 1) / 2
102
+ yTileMin = yTileMin / 2 - 1
103
+ yTileMax = (yTileMax + 1) / 2
104
+ //Make sure Mins are even and Maxs are odd to join tiles without overlapping
105
+ let xMinOdd = xTileMin % 2
106
+ let yMinOdd = yTileMin % 2
107
+ let xMaxEven = 1 - (xTileMax % 2)
108
+ let yMaxEven = 1 - (yTileMax % 2)
109
+ xTileMin = xTileMin - (xTileMin % 2)
110
+ xTileMax = xTileMax + 1 - (xTileMax % 2)
111
+ yTileMin = yTileMin - (yTileMin % 2)
112
+ yTileMax = yTileMax + 1 - (yTileMax % 2)
113
+ zoomLvl -= 1
114
+ for (let xTile = xTileMin; xTile <= xTileMax; xTile++) {
115
+ for (let yTile = yTileMin; yTile <= yTileMax; yTile++) {
116
+ if (
117
+ xTile - xTileMin <= xMinOdd ||
118
+ xTileMax - xTile <= xMaxEven ||
119
+ yTile - yTileMin <= yMinOdd ||
120
+ yTileMax - yTile <= yMaxEven
121
+ ) {
122
+ tileToRender.push({ xTile, yTile, zoomLvl })
123
+ }
124
+ }
125
+ }
126
+ }
127
+ await this.removeUnusedTiles(tileToRender)
128
+ for (let k in tileToRender) {
129
+ let xTile = tileToRender[k].xTile
130
+ let yTile = tileToRender[k].yTile
131
+ zoomLvl = tileToRender[k].zoomLvl
132
+ this.renderTile(xTile, yTile, zoomLvl)
133
+ }
134
+ },
135
+ removeTileFromPending(meshId,mapLayer){
136
+ this.pendingTiles = this.pendingTiles.filter(
137
+ (t) => t.meshId != meshId || t.mapLayer != mapLayer
138
+ )
139
+ },
140
+ async renderTile(x, y, zoomLvl) {
141
+ const meshId = 'tile_' + x + '_' + y + '_' + zoomLvl
142
+ const mapLayer = this.provider.mapLayer
143
+ if (
144
+ this.pendingTiles.find(t=>t.meshId==meshId && t.mapLayer==mapLayer)
145
+ ) {
146
+ return
147
+ }
148
+
149
+ let mesh = this.meshes.tileMeshes[meshId]
150
+ if (mesh && this.provider.mapLayer == mesh.userData.mapLayer) {
151
+ return
152
+ }
153
+
154
+ const latitude = this.layoutSettings.layout_latitude
155
+ const longitude = this.layoutSettings.layout_longitude
156
+ let geometry, material
157
+ const imagePromise=cancellablePromise(this.provider.fetchTile(zoomLvl, x, y))
158
+ this.pendingTiles.push({ x, y, zoomLvl, mapLayer, meshId, imagePromise})
159
+ imagePromise.then((image) =>{
160
+
161
+ if (!image) {
162
+ this.removeTileFromPending(meshId,mapLayer)
163
+ return
164
+ }
165
+ const texture = new THREE.Texture(image)
166
+ texture.generateMipmaps = false
167
+ texture.format = THREE.RGBAFormat
168
+ texture.magFilter = THREE.LinearFilter
169
+ texture.minFilter = THREE.LinearFilter
170
+ texture.needsUpdate = true
171
+ let corners = tileToCorners(x, y, zoomLvl, latitude, longitude)
172
+ corners = corners.map((c) => {
173
+ return { ...c, z: -100 }
174
+ })
175
+ if (mesh) {
176
+ geometry = mesh.geometry
177
+ material = mesh.material
178
+ geometry = updateBufferRoofGeometry(corners, [], geometry)
179
+ mesh.geometry = geometry
180
+ material.map = texture
181
+ material.needsUpdate = true
182
+ mesh.userData.mapLayer = this.provider.mapLayer
183
+ mesh.userData.type = 'tileMeshes'
184
+ mesh.userData.meshId = meshId
185
+ mesh.frustumCulled = false
186
+ mesh.needsUpdate = true
187
+ mesh.updateMatrix()
188
+ } else {
189
+ material = new THREE.MeshBasicMaterial({
190
+ map: texture,
191
+ color: 0xffffff,
192
+ side: THREE.FrontSide,
193
+ transparent: true
194
+ })
195
+ material.map = texture
196
+ material.needsUpdate = true
197
+ geometry = getBufferRoofGeometry(corners)
198
+ if (geometry) {
199
+ mesh = new THREE.Mesh(geometry, material)
200
+ mesh.userData.type = 'tileMeshes'
201
+ mesh.userData.meshId = meshId
202
+ mesh.userData.mapLayer = this.provider.mapLayer
203
+ this.meshes.tileMeshes[meshId] = mesh
204
+ this.scene.add(mesh)
205
+ }
206
+ }
207
+ //image.parentNode.removeChild(image);
208
+ this.removeTileFromPending(meshId,mapLayer)
209
+ })
210
+ },
211
+ renderGoogleTiles() {
212
+ this.clearByType('tileMeshes')
213
+ if (this.backgroundMap) {
214
+ this.backgroundMap.clear()
215
+ this.scene.remove(this.backgroundMap)
216
+ this.clearThreeObjects(this.backgroundMap)
217
+ }
218
+ this.backgroundMap = new THREE.Group()
219
+
220
+ let googleMapType = 'satellite'
221
+ switch (this.selectedMapLayer.key) {
222
+ case 'googleLayerRoadmap':
223
+ googleMapType = 'roadmap'
224
+ break
225
+ case 'googleLayer':
226
+ googleMapType = 'satellite'
227
+ break
228
+ case 'googleLayerTerrain':
229
+ googleMapType = 'terrain'
230
+ break
231
+ }
232
+
233
+ let apiKey = process.env.VUE_APP_GOOGLE_MAP_API_KEY
234
+ let backgroundPlane = []
235
+ let size = 640
236
+ let planeGeometry = []
237
+ let planeMaterial = []
238
+ let texture = []
239
+ let zoomLevels = [19, 16]
240
+ for (
241
+ let indexGoogleBackground = 0;
242
+ indexGoogleBackground < zoomLevels.length;
243
+ indexGoogleBackground++
244
+ ) {
245
+ let zoomLevel = zoomLevels[indexGoogleBackground]
246
+ let groundResolution =
247
+ (Math.cos((this.layoutSettings.layout_latitude * Math.PI) / 180) *
248
+ 2 *
249
+ Math.PI *
250
+ 6378137) /
251
+ (256 * Math.pow(2, zoomLevel))
252
+ let sizeInMeter = groundResolution * size
253
+ planeGeometry[indexGoogleBackground] = new THREE.PlaneGeometry(
254
+ sizeInMeter,
255
+ sizeInMeter
256
+ )
257
+ let googleBackgroundUrl = `https://maps.googleapis.com/maps/api/staticmap?center=${
258
+ this.layoutSettings.layout_latitude +
259
+ ',' +
260
+ this.layoutSettings.layout_longitude
261
+ }&maptype=${googleMapType}&zoom=${zoomLevel}&size=${size}x${size}&key=${apiKey}`
262
+
263
+ texture[indexGoogleBackground] = this.loader.load(googleBackgroundUrl)
264
+ planeMaterial[indexGoogleBackground] = new THREE.MeshBasicMaterial({
265
+ map: texture[indexGoogleBackground],
266
+ side: THREE.DoubleSide
267
+ })
268
+ backgroundPlane[indexGoogleBackground] = new THREE.Mesh(
269
+ planeGeometry[indexGoogleBackground],
270
+ planeMaterial[indexGoogleBackground]
271
+ )
272
+ backgroundPlane[indexGoogleBackground].position.z =
273
+ -indexGoogleBackground / 2
274
+ this.backgroundMap.add(backgroundPlane[indexGoogleBackground])
275
+ }
276
+ this.scene.add(this.backgroundMap)
277
+ }
278
+ },
279
+ watch:{
280
+ selectedMapLayer(newMapLayer){
281
+ this.pendingTiles = this.pendingTiles.filter(
282
+ (t) => {
283
+ if(t.mapLayer != newMapLayer.key){
284
+ t.imagePromise.cancel()
285
+ return false
286
+ }
287
+ }
288
+ )
289
+ }
290
+ }
291
+ }