@eturnity/eturnity_3d 7.42.3 → 7.48.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.
- package/package.json +2 -2
- package/src/helper/ImageHelper.js +67 -0
- package/src/helper/customProvider.js +101 -61
- package/src/helper/render/roof.js +1 -1
- package/src/helper/render/tile.js +13 -3
- package/src/utils/constants.js +1 -1
- package/src/utils/layers.js +250 -213
- package/dist/assets/images/panels/longiSolarLR4_60HPH_350M.png +0 -0
- package/dist/assets/images/panels/longiSolarLR4_60HPH_370M.png +0 -0
- package/dist/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw copy.png +0 -0
- package/dist/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
- package/dist/assets/images/panels/uv.png +0 -0
- package/dist/assets/panels/longiSolarLR4_60HPH_350M.png +0 -0
- package/dist/assets/panels/longiSolarLR4_60HPH_370M.png +0 -0
- package/dist/assets/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
- package/dist/assets/panels/uv.png +0 -0
- package/dist/assets/theme.js +0 -43
- package/dist/assets/vue.svg +0 -1
- package/dist/main.es.js +0 -43662
- package/dist/main.umd.js +0 -3542
- package/dist/style.css +0 -1
- package/dist/vite.svg +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eturnity/eturnity_3d",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "7.
|
|
4
|
+
"version": "7.48.1",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
7
7
|
"src"
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"prettier": "prettier --write \"**/*.{js,vue}\""
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@eturnity/eturnity_maths": "7.
|
|
18
|
+
"@eturnity/eturnity_maths": "7.48.0",
|
|
19
19
|
"@originjs/vite-plugin-commonjs": "1.0.3",
|
|
20
20
|
"core-js": "3.30.2",
|
|
21
21
|
"cors": "2.8.5",
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
class ImageHelper {
|
|
2
|
+
/**
|
|
3
|
+
* Wrapper for image loading
|
|
4
|
+
* @param {String} src - source url
|
|
5
|
+
* @returns image
|
|
6
|
+
*/
|
|
7
|
+
static loadImage(src) {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
const image = new Image()
|
|
10
|
+
image.crossOrigin = 'Anonymous'
|
|
11
|
+
image.onload = () => {
|
|
12
|
+
resolve(image)
|
|
13
|
+
}
|
|
14
|
+
image.onerror = reject
|
|
15
|
+
image.src = src
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Overlays images on top of one another
|
|
21
|
+
* @param {Array<Images>} images
|
|
22
|
+
* @returns overlapped image
|
|
23
|
+
*/
|
|
24
|
+
static overlayImages(images = []) {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const canvas = document.createElement('canvas')
|
|
27
|
+
canvas.width = images[0].width
|
|
28
|
+
canvas.height = images[0].height
|
|
29
|
+
const ctx = canvas.getContext('2d')
|
|
30
|
+
|
|
31
|
+
// last element of the array will be the top most layer
|
|
32
|
+
images.forEach((image) => {
|
|
33
|
+
ctx.drawImage(image, 0, 0)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const newImage = new Image()
|
|
37
|
+
newImage.src = canvas.toDataURL('image/png')
|
|
38
|
+
newImage.onload = () => {
|
|
39
|
+
resolve(newImage)
|
|
40
|
+
}
|
|
41
|
+
newImage.onerror = reject
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Checks if an image is fully transparent
|
|
47
|
+
* @param {Image} image
|
|
48
|
+
* @returns Boolean
|
|
49
|
+
*/
|
|
50
|
+
static isFullyTransparent(image) {
|
|
51
|
+
const canvas = document.createElement('canvas')
|
|
52
|
+
canvas.width = image.width
|
|
53
|
+
canvas.height = image.height
|
|
54
|
+
const ctx = canvas.getContext('2d')
|
|
55
|
+
ctx.drawImage(image, 0, 0)
|
|
56
|
+
const imageData = ctx.getImageData(0, 0, image.width, image.height)
|
|
57
|
+
const pixels = imageData.data
|
|
58
|
+
for (let i = 3; i < pixels.length; i += 4) {
|
|
59
|
+
if (pixels[i] !== 0) {
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return true
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default ImageHelper
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { MapProvider } from 'geo-three'
|
|
2
2
|
import getLayers from '../utils/layers'
|
|
3
|
+
import ImageHelper from './ImageHelper'
|
|
4
|
+
import { MAP_LAYER_TYPE } from '../utils/constants'
|
|
5
|
+
|
|
3
6
|
export class CustomProvider extends MapProvider {
|
|
4
7
|
constructor(address, map_layer) {
|
|
5
8
|
super()
|
|
@@ -9,77 +12,114 @@ export class CustomProvider extends MapProvider {
|
|
|
9
12
|
this.mapLayer = map_layer
|
|
10
13
|
this.maxZoom = this.layer.layerData.options.maxNativeZoom || 20
|
|
11
14
|
this.minZoom = this.layer.layerData.options.minZoom || 17
|
|
12
|
-
|
|
13
|
-
this.defaultImage
|
|
14
|
-
this.defaultImage.crossOrigin = 'Anonymous'
|
|
15
|
+
const imgSrc = require('../assets/images/white_tile.png')
|
|
16
|
+
this.defaultImage = ImageHelper.loadImage(imgSrc.default || imgSrc)
|
|
15
17
|
this.url = layer
|
|
16
18
|
? layer.layerData._url
|
|
17
19
|
: 'https://a.tile.openstreetmap.org/{z}/{x}/{y}.png'
|
|
18
20
|
this.address = address
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
image.onload = function () {
|
|
31
|
-
image.style.backgroundColor = 'red'
|
|
32
|
-
resolve(image)
|
|
33
|
-
}
|
|
34
|
-
image.onerror = function () {
|
|
35
|
-
resolve(this.defaultImage)
|
|
36
|
-
}
|
|
23
|
+
getImageSrc(layerKey, layer, position) {
|
|
24
|
+
const { x, y, zoom } = position
|
|
25
|
+
let imageSrc = layer._url
|
|
26
|
+
if (layerKey == 'bkgHexagonGermanyLayer') {
|
|
27
|
+
const numTiles = Math.pow(2, zoom)
|
|
28
|
+
const tileX = x
|
|
29
|
+
const tileY = numTiles - 1 - y
|
|
30
|
+
const earthPerimeter = 6378137 * Math.PI * 2
|
|
31
|
+
const resolution_mPerTile = earthPerimeter / numTiles
|
|
37
32
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
33
|
+
const xMin = tileX * resolution_mPerTile - earthPerimeter / 2
|
|
34
|
+
const xMax = xMin + resolution_mPerTile
|
|
35
|
+
const yMin = tileY * resolution_mPerTile - earthPerimeter / 2
|
|
36
|
+
const yMax = yMin + resolution_mPerTile
|
|
37
|
+
const { kid, layers } = layer.options
|
|
38
|
+
imageSrc =
|
|
39
|
+
imageSrc +
|
|
40
|
+
'?service=WMS' +
|
|
41
|
+
'&request=GetMap' +
|
|
42
|
+
`&layers=${layers}` +
|
|
43
|
+
`&kid=${kid}` +
|
|
44
|
+
'&format=image%2Fpng' +
|
|
45
|
+
'&transparent=true' +
|
|
46
|
+
'&version=1.3.0' +
|
|
47
|
+
'&width=256' +
|
|
48
|
+
'&height=256' +
|
|
49
|
+
'&crs=EPSG%3A3857' +
|
|
50
|
+
`&bbox=${xMin},${yMin},${xMax},${yMax}`
|
|
51
|
+
} else if (layerKey == 'azureSatelliteLayer') {
|
|
52
|
+
const { apiVersion, tilesetId, subscriptionKey } = layer.options
|
|
53
|
+
imageSrc = imageSrc
|
|
54
|
+
.replace('{x}', x)
|
|
55
|
+
.replace('{y}', y)
|
|
56
|
+
.replace('{z}', zoom)
|
|
57
|
+
.replace('{apiVersion}', apiVersion)
|
|
58
|
+
.replace('{tilesetId}', tilesetId)
|
|
59
|
+
.replace('{subscriptionKey}', subscriptionKey)
|
|
60
|
+
imageSrc = imageSrc + `&no-cache=${Date.now()}`
|
|
61
|
+
} else {
|
|
62
|
+
imageSrc = imageSrc.replace('{x}', x)
|
|
63
|
+
imageSrc = imageSrc.replace('{y}', y)
|
|
64
|
+
imageSrc = imageSrc.replace('{z}', zoom)
|
|
65
|
+
if (layer.options.subdomains) {
|
|
66
|
+
const subDomain =
|
|
67
|
+
layer.options.subdomains[
|
|
68
|
+
Math.abs((x << zoom) + y) % layer.options.subdomains.length
|
|
69
|
+
]
|
|
70
|
+
imageSrc = imageSrc.replace('{s}', subDomain)
|
|
71
|
+
}
|
|
72
|
+
imageSrc = imageSrc.replace('{format}', 'image/jpeg')
|
|
73
|
+
imageSrc = imageSrc.replace('{tileMatrixSet}', 'PM')
|
|
74
|
+
}
|
|
75
|
+
return imageSrc
|
|
76
|
+
}
|
|
46
77
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
78
|
+
async fetchTile(zoom, x, y) {
|
|
79
|
+
try {
|
|
80
|
+
const minZoomLayer = this.layer.layerData.options.minZoom || 9
|
|
81
|
+
const position = {
|
|
82
|
+
x,
|
|
83
|
+
y,
|
|
84
|
+
zoom,
|
|
85
|
+
}
|
|
86
|
+
if (zoom < minZoomLayer) {
|
|
87
|
+
return this.defaultImage
|
|
88
|
+
} else if (this.layer.key === MAP_LAYER_TYPE.HEXAGON_SATELLITE) {
|
|
89
|
+
const layerGroup = this.layer.layerData
|
|
90
|
+
const layers = layerGroup
|
|
91
|
+
.getLayers()
|
|
92
|
+
.sort((a, b) => a.options.order - b.options.order)
|
|
51
93
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
} else {
|
|
65
|
-
imageSrc = imageSrc.replace('{x}', x)
|
|
66
|
-
imageSrc = imageSrc.replace('{y}', y)
|
|
67
|
-
imageSrc = imageSrc.replace('{z}', zoom)
|
|
68
|
-
//imageSrc = imageSrc.replace('{s}', 'a')
|
|
69
|
-
if (this.layer.layerData.options.subdomains) {
|
|
70
|
-
const subDomain =
|
|
71
|
-
this.layer.layerData.options.subdomains[
|
|
72
|
-
Math.abs((x << zoom) + y) %
|
|
73
|
-
this.layer.layerData.options.subdomains.length
|
|
74
|
-
]
|
|
75
|
-
imageSrc = imageSrc.replace('{s}', subDomain)
|
|
76
|
-
}
|
|
77
|
-
imageSrc = imageSrc.replace('{format}', 'image/jpeg')
|
|
78
|
-
//imageSrc = imageSrc.replace('{format}', 'image/png')
|
|
79
|
-
imageSrc = imageSrc.replace('{tileMatrixSet}', 'PM')
|
|
94
|
+
const promiseArray = layers.map((layer) => {
|
|
95
|
+
const imagePromise = ImageHelper.loadImage(
|
|
96
|
+
this.getImageSrc(this.layer.key, layer, position)
|
|
97
|
+
)
|
|
98
|
+
return imagePromise.catch((error) => error)
|
|
99
|
+
})
|
|
100
|
+
const images = await Promise.all(promiseArray)
|
|
101
|
+
const validImages = images.filter((image) => {
|
|
102
|
+
return image instanceof Image
|
|
103
|
+
})
|
|
104
|
+
if (!validImages.length) {
|
|
105
|
+
throw 'No valid image'
|
|
80
106
|
}
|
|
81
|
-
|
|
107
|
+
const result =
|
|
108
|
+
validImages.length === 1
|
|
109
|
+
? validImages[0]
|
|
110
|
+
: await ImageHelper.overlayImages(validImages)
|
|
111
|
+
return result
|
|
112
|
+
} else {
|
|
113
|
+
const imageSrc = this.getImageSrc(
|
|
114
|
+
this.layer.key,
|
|
115
|
+
this.layer.layerData,
|
|
116
|
+
position
|
|
117
|
+
)
|
|
118
|
+
const image = await ImageHelper.loadImage(imageSrc)
|
|
119
|
+
return image
|
|
82
120
|
}
|
|
83
|
-
})
|
|
121
|
+
} catch (error) {
|
|
122
|
+
return this.defaultImage
|
|
123
|
+
}
|
|
84
124
|
}
|
|
85
125
|
}
|
|
@@ -151,7 +151,7 @@ export default {
|
|
|
151
151
|
mesh.userData.version = roofPolygon.version
|
|
152
152
|
mesh.userData.type = 'flatRoofMeshes'
|
|
153
153
|
mesh.userData.meshId = roofPolygon.id
|
|
154
|
-
|
|
154
|
+
mesh.renderOrder = 10
|
|
155
155
|
mesh.visible = roofPolygon.maximumGap > maximumGapLimit
|
|
156
156
|
this.scene.add(mesh)
|
|
157
157
|
this.meshes.flatRoofMeshes[roofPolygon.id] = mesh
|
|
@@ -229,7 +229,16 @@ export default {
|
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
let mesh = this.meshes.tileMeshes[meshId]
|
|
232
|
-
|
|
232
|
+
const materialId =
|
|
233
|
+
'material_' + x + '_' + y + '_' + zoomLvl + '_' + mapLayer
|
|
234
|
+
const tileProjectionMaterial = this.material.projectionTiles.find(
|
|
235
|
+
(m) => m.userData.materialId === materialId
|
|
236
|
+
)
|
|
237
|
+
if (
|
|
238
|
+
mesh &&
|
|
239
|
+
this.provider.mapLayer == mesh.userData.mapLayer &&
|
|
240
|
+
(!isTileOnRoofBound || tileProjectionMaterial)
|
|
241
|
+
) {
|
|
233
242
|
resolve()
|
|
234
243
|
return
|
|
235
244
|
}
|
|
@@ -263,6 +272,8 @@ export default {
|
|
|
263
272
|
}
|
|
264
273
|
texture.generateMipmaps = false
|
|
265
274
|
texture.format = THREE.RGBAFormat
|
|
275
|
+
texture.encoding = THREE.sRGBEncoding
|
|
276
|
+
texture.colorSpace = THREE.SRGBColorSpace
|
|
266
277
|
texture.needsUpdate = true
|
|
267
278
|
let corners = tileToCorners(x, y, zoomLvl, latitude, longitude)
|
|
268
279
|
corners = corners.map((c) => {
|
|
@@ -284,8 +295,6 @@ export default {
|
|
|
284
295
|
mesh.castShadow = false
|
|
285
296
|
mesh.updateMatrix()
|
|
286
297
|
} else {
|
|
287
|
-
texture.encoding = THREE.sRGBEncoding
|
|
288
|
-
texture.colorSpace = THREE.SRGBColorSpace
|
|
289
298
|
material = new THREE.MeshPhongMaterial({
|
|
290
299
|
map: texture,
|
|
291
300
|
color: 0xffffff,
|
|
@@ -490,6 +499,7 @@ export default {
|
|
|
490
499
|
t.imagePromise.cancel()
|
|
491
500
|
return false
|
|
492
501
|
}
|
|
502
|
+
return true
|
|
493
503
|
})
|
|
494
504
|
},
|
|
495
505
|
},
|
package/src/utils/constants.js
CHANGED
|
@@ -11,6 +11,6 @@ export const MAP_LAYER_TYPE = {
|
|
|
11
11
|
BASEMAP_SATELLITE: 'baseMapLayerStreetNumber',
|
|
12
12
|
IGN_SATELLITE: 'ignSpainLayer_pnoa_image',
|
|
13
13
|
IGN_ROAD: 'ignSpainLayer_map',
|
|
14
|
-
|
|
14
|
+
HEXAGON_SATELLITE: 'bkgHexagonGermanyLayer',
|
|
15
15
|
GEOPORTAL_SATELLITE: 'geoportail_fr_wmts_ortho_layer',
|
|
16
16
|
}
|