@eturnity/eturnity_3d 7.48.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_3d",
3
3
  "private": false,
4
- "version": "7.48.0",
4
+ "version": "7.48.1",
5
5
  "files": [
6
6
  "dist",
7
7
  "src"
@@ -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
- this.defaultImage = document.createElement('img')
13
- this.defaultImage.src = require('../assets/images/white_tile.png')
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
- fetchTile(zoom, x, y) {
22
- const minZoomLayer = this.layer.layerData.options.minZoom || 9
23
- const maxZoomLayer = this.layer.layerData.options.maxNativeZoom || 20
24
- return new Promise((resolve, reject) => {
25
- if (zoom < minZoomLayer) {
26
- resolve(this.defaultImage)
27
- } else {
28
- const image = document.createElement('img')
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
- image.crossOrigin = 'Anonymous'
39
- let imageSrc = this.url
40
- if (this.layer.key == 'bkgHexagonGermanyLayer') {
41
- const numTiles = Math.pow(2, zoom)
42
- const tileX = x
43
- const tileY = numTiles - 1 - y
44
- const earthPerimeter = 6378137 * Math.PI * 2
45
- const resolution_mPerTile = earthPerimeter / numTiles
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
- const xMin = tileX * resolution_mPerTile - earthPerimeter / 2
48
- const xMax = xMin + resolution_mPerTile
49
- const yMin = tileY * resolution_mPerTile - earthPerimeter / 2
50
- const yMax = yMin + resolution_mPerTile
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
- imageSrc += `&service=WMS&request=GetMap&layers=rgb&styles=&format=image%2Fjpeg&transparent=false&version=1.1.1&id=bkg_image&layerTypeAPI=bkgHexagonGermanyLayer&width=256&height=256&srs=EPSG%3A3857&bbox=${xMin},${yMin},${xMax},${yMax}`
53
- } else if (this.layer.key == 'azureSatelliteLayer') {
54
- const { apiVersion, tilesetId, subscriptionKey } =
55
- this.layer.layerData.options
56
- imageSrc = imageSrc
57
- .replace('{x}', x)
58
- .replace('{y}', y)
59
- .replace('{z}', zoom)
60
- .replace('{apiVersion}', apiVersion)
61
- .replace('{tilesetId}', tilesetId)
62
- .replace('{subscriptionKey}', subscriptionKey)
63
- imageSrc = imageSrc + `&no-cache=${Date.now()}`
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
- image.src = imageSrc
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
  }
@@ -229,7 +229,16 @@ export default {
229
229
  }
230
230
 
231
231
  let mesh = this.meshes.tileMeshes[meshId]
232
- if (mesh && this.provider.mapLayer == mesh.userData.mapLayer) {
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
  },
@@ -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
- BKG_SATELLITE: 'bkgHexagonGermanyLayer',
14
+ HEXAGON_SATELLITE: 'bkgHexagonGermanyLayer',
15
15
  GEOPORTAL_SATELLITE: 'geoportail_fr_wmts_ortho_layer',
16
16
  }
@@ -2,216 +2,253 @@ import * as L from 'leaflet'
2
2
  import 'leaflet.gridlayer.googlemutant/dist/Leaflet.GoogleMutant.js'
3
3
  import { leafletMapLayersConfig } from './leaflet-config.service'
4
4
 
5
- function getLayers() {
6
- const googleLayer = L.gridLayer.googleMutant({
7
- type: 'hybrid',
8
- layerTypeAPI: 'googleLayer',
9
- maxNativeZoom: 25,
10
- maxZoom: 25,
11
- })
12
- const googleLayerRoadmap = L.gridLayer.googleMutant({
13
- type: 'roadmap',
14
- layerTypeAPI: 'googleLayerRoadmap',
15
- maxNativeZoom: 25,
16
- maxZoom: 25,
17
- })
18
- const googleLayerTerrain = L.gridLayer.googleMutant({
19
- type: 'terrain',
20
- layerTypeAPI: 'googleLayerTerrain',
21
- maxNativeZoom: 25,
22
- maxZoom: 25,
23
- })
24
- // TODO activate for different users
25
- const baseMapLayer = L.tileLayer(
26
- 'https://mapsneu.wien.gv.at/basemap/geolandbasemap/normal/google3857/{z}/{y}/{x}.png',
27
- {
28
- id: 'basemap',
29
- subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
30
- attribution:
31
- 'Datenquelle: <a href="http://www.basemap.at/">basemap.at</a>',
32
- // TODO not defined
33
- minZoom: leafletMapLayersConfig['baseMapLayer']['minZoom'],
34
- maxZoom: leafletMapLayersConfig['baseMapLayer']['maxZoom'],
35
- maxNativeZoom: leafletMapLayersConfig['baseMapLayer']['maxNativeZoom'],
36
- layerTypeAPI: 'baseMapLayer',
37
- }
38
- )
39
- const baseMapLayerStreetNumber = L.tileLayer(
40
- 'https://mapsneu.wien.gv.at/basemap/bmaporthofoto30cm/normal/google3857/{z}/{y}/{x}.jpeg',
41
- {
42
- id: 'basemap_bmaporthofoto30cm',
43
- subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
44
- attribution:
45
- 'Datenquelle: <a href="http://www.basemap.at/">basemap.at</a>',
46
- // TODO not defined
47
- minZoom: leafletMapLayersConfig['baseMapLayerStreetNumber']['minZoom'],
48
- maxZoom: leafletMapLayersConfig['baseMapLayerStreetNumber']['maxZoom'],
49
- maxNativeZoom:
50
- leafletMapLayersConfig['baseMapLayerStreetNumber']['maxNativeZoom'],
51
- layerTypeAPI: 'baseMapLayerStreetNumber',
52
- }
53
- )
54
- const swisstopoLayer_swissimage = L.tileLayer(
55
- 'https://wmts10.geo.admin.ch/1.0.0/ch.swisstopo.swissimage/default/current/3857/{z}/{x}/{y}.jpeg',
56
- {
57
- id: 'swisstopo_swissimage',
58
- subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
59
- attribution:
60
- 'Datenquelle: <a href="https://www.geo.admin.ch">geo.admin.ch</a>',
61
- maxZoom: leafletMapLayersConfig['swisstopoLayer_swissimage']['maxZoom'],
62
- maxNativeZoom:
63
- leafletMapLayersConfig['swisstopoLayer_swissimage']['maxNativeZoom'],
64
- layerTypeAPI: 'swisstopoLayer_swissimage',
65
- }
66
- )
67
- const swisstopoLayer_pixelkarte = L.tileLayer(
68
- 'https://wmts10.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/3857/{z}/{x}/{y}.jpeg',
69
- {
70
- id: 'swisstopo_pixelkarte',
71
- subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
72
- attribution:
73
- 'Datenquelle: <a href="https://www.geo.admin.ch">geo.admin.ch</a>',
74
- maxZoom: leafletMapLayersConfig['swisstopoLayer_pixelkarte']['maxZoom'],
75
- maxNativeZoom:
76
- leafletMapLayersConfig['swisstopoLayer_pixelkarte']['maxNativeZoom'],
77
- layerTypeAPI: 'swisstopoLayer_pixelkarte',
78
- }
79
- )
80
- const swisstopoLayer_solarenergie_fassade = L.tileLayer(
81
- 'https://wmts10.geo.admin.ch/1.0.0/ch.bfe.solarenergie-eignung-fassaden/default/current/3857/{z}/{x}/{y}.png',
82
- {
83
- id: 'swisstopo_solarenergie_fassade',
84
- // subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
85
- attribution:
86
- 'Datenquelle: <a href="https://www.geo.admin.ch">geo.admin.ch</a>',
87
- maxZoom:
88
- leafletMapLayersConfig['swisstopoLayer_solarenergie_fassade'][
89
- 'maxZoom'
90
- ],
91
- maxNativeZoom:
92
- leafletMapLayersConfig['swisstopoLayer_solarenergie_fassade'][
93
- 'maxNativeZoom'
94
- ],
95
- layerTypeAPI: 'swisstopoLayer_solarenergie_fassade',
96
- }
97
- )
98
- const swisstopoLayer_solarenergie_roof = L.tileLayer(
99
- 'https://wmts10.geo.admin.ch/1.0.0/ch.bfe.solarenergie-eignung-daecher/default/current/3857/{z}/{x}/{y}.png',
100
- {
101
- id: 'swisstopo_solarenergie_roof',
102
- // subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
103
- attribution:
104
- 'Datenquelle: <a href="https://www.geo.admin.ch">geo.admin.ch</a>',
105
- maxZoom:
106
- leafletMapLayersConfig['swisstopoLayer_solarenergie_roof']['maxZoom'],
107
- maxNativeZoom:
108
- leafletMapLayersConfig['swisstopoLayer_solarenergie_roof'][
109
- 'maxNativeZoom'
110
- ],
111
- layerTypeAPI: 'swisstopoLayer_solarenergie_roof',
112
- }
113
- )
114
- const openStreetMapLayer = L.tileLayer(
115
- 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
116
- {
117
- id: 'osm',
118
- attribution:
119
- '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
120
- minZoom: leafletMapLayersConfig['openStreetMapLayer']['minZoom'],
121
- maxZoom: leafletMapLayersConfig['openStreetMapLayer']['maxZoom'],
122
- maxNativeZoom:
123
- leafletMapLayersConfig['openStreetMapLayer']['maxNativeZoom'],
124
- layerTypeAPI: 'openStreetMapLayer',
125
- }
126
- )
127
- const ignLayerPNOAImage = L.tileLayer(
128
- 'https://www.ign.es/wmts/pnoa-ma?layer={layer}&tilematrixset={tilematrixset}&Service=WMTS&Request=GetTile&Version=1.0.0&Format={format}&TileMatrix={z}&TileCol={x}&TileRow={y}',
129
- {
130
- layer: 'OI.OrthoimageCoverage',
131
- tilematrixset: 'EPSG:3857',
132
- format: 'image/jpeg',
133
- id: 'ign_pnoa',
134
- attribution:
135
- '&copy; <a href="https://pnoa.ign.es" target="_blank">PNOA</a>',
136
- maxZoom: leafletMapLayersConfig['ignSpainLayer_pnoa_image']['maxZoom'],
137
- maxNativeZoom:
138
- leafletMapLayersConfig['ignSpainLayer_pnoa_image']['maxNativeZoom'],
139
- layerTypeAPI: 'ignSpainLayer_pnoa_image',
140
- }
141
- )
142
- const ignLayerMap = L.tileLayer(
143
- 'https://www.ign.es/wmts/ign-base?layer={layer}&tilematrixset={tilematrixset}&Service=WMTS&Request=GetTile&Version=1.0.0&Format={format}&TileMatrix={z}&TileCol={x}&TileRow={y}',
144
- {
145
- layer: 'IGNBaseTodo',
146
- tilematrixset: 'EPSG:3857',
147
- format: 'image/jpeg',
148
- id: 'ign_map',
149
- attribution:
150
- '&copy; <a href="https://www.ign.es/web/ign/portal" target="_blank">IGN</a>',
151
- maxZoom: leafletMapLayersConfig['ignSpainLayer_map']['maxZoom'],
152
- maxNativeZoom:
153
- leafletMapLayersConfig['ignSpainLayer_map']['maxNativeZoom'],
154
- layerTypeAPI: 'ignSpainLayer_map',
155
- }
156
- )
157
- const bkgHexagonImage = L.tileLayer.wms(
158
- 'https://terramapserver.org/Proxy/geoserver/BKG/wms?kid=eag20.1',
159
- {
160
- layers: 'rgb',
161
- id: 'bkg_image',
162
- attribution:
163
- '&copy; <a href="https://www.bkg.bund.de" target="_blank">Bundesamt für Kartographie und Geodäsie</a>',
164
- maxZoom: leafletMapLayersConfig['bkgHexagonGermanyLayer']['maxZoom'],
165
- maxNativeZoom:
166
- leafletMapLayersConfig['bkgHexagonGermanyLayer']['maxNativeZoom'],
167
- layerTypeAPI: 'bkgHexagonGermanyLayer',
168
- }
169
- )
170
- const GeoLayer_HR = L.tileLayer(
171
- 'https://data.geopf.fr/wmts?' +
172
- '&REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0' +
173
- '&STYLE=normal' +
174
- '&TILEMATRIXSET=PM' +
175
- '&FORMAT=image/jpeg' +
176
- '&LAYER=HR.ORTHOIMAGERY.ORTHOPHOTOS' +
177
- '&TILEMATRIX={z}' +
178
- '&TILEROW={y}' +
179
- '&TILECOL={x}',
180
- {
181
- layers: 'HR.ORTHOIMAGERY.ORTHOPHOTOS',
182
- id: 'HR.ORTHOIMAGERY.ORTHOPHOTOS',
183
- attribution: '© IGN-F/Geoportail France',
184
- minZoom: leafletMapLayersConfig['GeoPortal']['minZoom'],
185
- maxZoom: leafletMapLayersConfig['GeoPortal']['maxZoom'],
186
- maxNativeZoom: leafletMapLayersConfig['GeoPortal']['maxNativeZoom'],
187
- tileSize: 256,
188
- layerTypeAPI: 'geoportail_fr_wmts_ortho_layer',
189
- }
190
- )
5
+ const googleLayer = L.gridLayer.googleMutant({
6
+ type: 'hybrid',
7
+ layerTypeAPI: 'googleLayer',
8
+ maxNativeZoom: 25,
9
+ maxZoom: 25,
10
+ })
191
11
 
192
- const azureSatelliteLayer = L.tileLayer(
193
- 'https://atlas.microsoft.com/map/tile?' +
194
- 'api-version={apiVersion}' +
195
- '&tilesetId={tilesetId}' +
196
- '&subscription-key={subscriptionKey}' +
197
- '&zoom={z}' +
198
- '&x={x}' +
199
- '&y={y}',
200
- {
201
- layerTypeAPI: 'azureSatelliteLayer',
202
- id: 'azure_satellite',
203
- attribution: `\u00A9 ${new Date().getFullYear()} EarthStar Geographics, Microsoft`,
204
- minZoom: leafletMapLayersConfig['azureSatelliteLayer']['minZoom'],
205
- maxZoom: leafletMapLayersConfig['azureSatelliteLayer']['maxZoom'],
206
- maxNativeZoom:
207
- leafletMapLayersConfig['azureSatelliteLayer']['maxNativeZoom'],
208
- // query parameters
209
- apiVersion: '2022-08-01',
210
- tilesetId: 'microsoft.imagery',
211
- subscriptionKey: process.env.VUE_APP_AZURE_MAP_SUBSCRIPTION_KEY,
212
- }
213
- )
12
+ const googleLayerRoadmap = L.gridLayer.googleMutant({
13
+ type: 'roadmap',
14
+ layerTypeAPI: 'googleLayerRoadmap',
15
+ maxNativeZoom: 25,
16
+ maxZoom: 25,
17
+ })
18
+
19
+ const googleLayerTerrain = L.gridLayer.googleMutant({
20
+ type: 'terrain',
21
+ layerTypeAPI: 'googleLayerTerrain',
22
+ maxNativeZoom: 25,
23
+ maxZoom: 25,
24
+ })
25
+
26
+ const baseMapLayer = L.tileLayer(
27
+ 'https://mapsneu.wien.gv.at/basemap/geolandbasemap/normal/google3857/{z}/{y}/{x}.png',
28
+ {
29
+ id: 'basemap',
30
+ subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
31
+ attribution: 'Datenquelle: <a href="http://www.basemap.at/">basemap.at</a>',
32
+ minZoom: leafletMapLayersConfig['baseMapLayer']['minZoom'],
33
+ maxZoom: leafletMapLayersConfig['baseMapLayer']['maxZoom'],
34
+ maxNativeZoom: leafletMapLayersConfig['baseMapLayer']['maxNativeZoom'],
35
+ layerTypeAPI: 'baseMapLayer',
36
+ }
37
+ )
38
+
39
+ const baseMapLayerStreetNumber = L.tileLayer(
40
+ 'https://mapsneu.wien.gv.at/basemap/bmaporthofoto30cm/normal/google3857/{z}/{y}/{x}.jpeg',
41
+ {
42
+ id: 'basemap_bmaporthofoto30cm',
43
+ subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
44
+ attribution: 'Datenquelle: <a href="http://www.basemap.at/">basemap.at</a>',
45
+ // TODO not defined
46
+ minZoom: leafletMapLayersConfig['baseMapLayerStreetNumber']['minZoom'],
47
+ maxZoom: leafletMapLayersConfig['baseMapLayerStreetNumber']['maxZoom'],
48
+ maxNativeZoom:
49
+ leafletMapLayersConfig['baseMapLayerStreetNumber']['maxNativeZoom'],
50
+ layerTypeAPI: 'baseMapLayerStreetNumber',
51
+ }
52
+ )
53
+
54
+ const swisstopoLayer_swissimage = L.tileLayer(
55
+ 'https://wmts10.geo.admin.ch/1.0.0/ch.swisstopo.swissimage/default/current/3857/{z}/{x}/{y}.jpeg',
56
+ {
57
+ id: 'swisstopo_swissimage',
58
+ subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
59
+ attribution:
60
+ 'Datenquelle: <a href="https://www.geo.admin.ch">geo.admin.ch</a>',
61
+ maxZoom: leafletMapLayersConfig['swisstopoLayer_swissimage']['maxZoom'],
62
+ maxNativeZoom:
63
+ leafletMapLayersConfig['swisstopoLayer_swissimage']['maxNativeZoom'],
64
+ layerTypeAPI: 'swisstopoLayer_swissimage',
65
+ }
66
+ )
67
+
68
+ const swisstopoLayer_pixelkarte = L.tileLayer(
69
+ 'https://wmts10.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/3857/{z}/{x}/{y}.jpeg',
70
+ {
71
+ id: 'swisstopo_pixelkarte',
72
+ subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
73
+ attribution:
74
+ 'Datenquelle: <a href="https://www.geo.admin.ch">geo.admin.ch</a>',
75
+ maxZoom: leafletMapLayersConfig['swisstopoLayer_pixelkarte']['maxZoom'],
76
+ maxNativeZoom:
77
+ leafletMapLayersConfig['swisstopoLayer_pixelkarte']['maxNativeZoom'],
78
+ layerTypeAPI: 'swisstopoLayer_pixelkarte',
79
+ }
80
+ )
81
+
82
+ const swisstopoLayer_solarenergie_fassade = L.tileLayer(
83
+ 'https://wmts10.geo.admin.ch/1.0.0/ch.bfe.solarenergie-eignung-fassaden/default/current/3857/{z}/{x}/{y}.png',
84
+ {
85
+ id: 'swisstopo_solarenergie_fassade',
86
+ // subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
87
+ attribution:
88
+ 'Datenquelle: <a href="https://www.geo.admin.ch">geo.admin.ch</a>',
89
+ maxZoom:
90
+ leafletMapLayersConfig['swisstopoLayer_solarenergie_fassade']['maxZoom'],
91
+ maxNativeZoom:
92
+ leafletMapLayersConfig['swisstopoLayer_solarenergie_fassade'][
93
+ 'maxNativeZoom'
94
+ ],
95
+ layerTypeAPI: 'swisstopoLayer_solarenergie_fassade',
96
+ }
97
+ )
214
98
 
99
+ const swisstopoLayer_solarenergie_roof = L.tileLayer(
100
+ 'https://wmts10.geo.admin.ch/1.0.0/ch.bfe.solarenergie-eignung-daecher/default/current/3857/{z}/{x}/{y}.png',
101
+ {
102
+ id: 'swisstopo_solarenergie_roof',
103
+ // subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
104
+ attribution:
105
+ 'Datenquelle: <a href="https://www.geo.admin.ch">geo.admin.ch</a>',
106
+ maxZoom:
107
+ leafletMapLayersConfig['swisstopoLayer_solarenergie_roof']['maxZoom'],
108
+ maxNativeZoom:
109
+ leafletMapLayersConfig['swisstopoLayer_solarenergie_roof'][
110
+ 'maxNativeZoom'
111
+ ],
112
+ layerTypeAPI: 'swisstopoLayer_solarenergie_roof',
113
+ }
114
+ )
115
+
116
+ const openStreetMapLayer = L.tileLayer(
117
+ 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
118
+ {
119
+ id: 'osm',
120
+ attribution:
121
+ '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
122
+ minZoom: leafletMapLayersConfig['openStreetMapLayer']['minZoom'],
123
+ maxZoom: leafletMapLayersConfig['openStreetMapLayer']['maxZoom'],
124
+ maxNativeZoom:
125
+ leafletMapLayersConfig['openStreetMapLayer']['maxNativeZoom'],
126
+ layerTypeAPI: 'openStreetMapLayer',
127
+ }
128
+ )
129
+
130
+ const ignLayerPNOAImage = L.tileLayer(
131
+ 'https://www.ign.es/wmts/pnoa-ma?layer={layer}&tilematrixset={tilematrixset}&Service=WMTS&Request=GetTile&Version=1.0.0&Format={format}&TileMatrix={z}&TileCol={x}&TileRow={y}',
132
+ {
133
+ layer: 'OI.OrthoimageCoverage',
134
+ tilematrixset: 'EPSG:3857',
135
+ format: 'image/jpeg',
136
+ id: 'ign_pnoa',
137
+ attribution:
138
+ '&copy; <a href="https://pnoa.ign.es" target="_blank">PNOA</a>',
139
+ maxZoom: leafletMapLayersConfig['ignSpainLayer_pnoa_image']['maxZoom'],
140
+ maxNativeZoom:
141
+ leafletMapLayersConfig['ignSpainLayer_pnoa_image']['maxNativeZoom'],
142
+ layerTypeAPI: 'ignSpainLayer_pnoa_image',
143
+ }
144
+ )
145
+
146
+ const ignLayerMap = L.tileLayer(
147
+ 'https://www.ign.es/wmts/ign-base?layer={layer}&tilematrixset={tilematrixset}&Service=WMTS&Request=GetTile&Version=1.0.0&Format={format}&TileMatrix={z}&TileCol={x}&TileRow={y}',
148
+ {
149
+ layer: 'IGNBaseTodo',
150
+ tilematrixset: 'EPSG:3857',
151
+ format: 'image/jpeg',
152
+ id: 'ign_map',
153
+ attribution:
154
+ '&copy; <a href="https://www.ign.es/web/ign/portal" target="_blank">IGN</a>',
155
+ maxZoom: leafletMapLayersConfig['ignSpainLayer_map']['maxZoom'],
156
+ maxNativeZoom: leafletMapLayersConfig['ignSpainLayer_map']['maxNativeZoom'],
157
+ layerTypeAPI: 'ignSpainLayer_map',
158
+ }
159
+ )
160
+
161
+ const getHexagonLayer = (url, params) => {
162
+ const options = {
163
+ kid: params.kid,
164
+ format: 'image/png',
165
+ transparent: true,
166
+ maxZoom: leafletMapLayersConfig['bkgHexagonGermanyLayer']['maxZoom'],
167
+ maxNativeZoom:
168
+ leafletMapLayersConfig['bkgHexagonGermanyLayer']['maxNativeZoom'],
169
+ id: `bkg_hexagon_${params.layers}`,
170
+ layerTypeAPI: 'bkgHexagonGermanyLayer',
171
+ layers: params.layers,
172
+ order: params.order,
173
+ version: '1.3.0',
174
+ crs: L.CRS.EPSG3857,
175
+ attribution: `&copy; GeoBasis-DE/BKG ${new Date().getFullYear()}, powered by HxGN`,
176
+ }
177
+ return L.tileLayer.wms(url, options)
178
+ }
179
+
180
+ const hexagonImageDop20 = getHexagonLayer(
181
+ 'https://geodaten-vertrieb.de/Proxy/DOP20/wms',
182
+ {
183
+ layers: 'DOP20',
184
+ kid: 'ET_expert_qlN7AQXKu3jTw',
185
+ order: 1,
186
+ }
187
+ )
188
+
189
+ const hexagonImageDop10 = getHexagonLayer(
190
+ 'https://geodaten-vertrieb.de/Proxy/DOP10/wms',
191
+ {
192
+ layers: 'DOP10',
193
+ kid: 'ET_expert_qlN7AQXKu3jTw',
194
+ order: 2,
195
+ }
196
+ )
197
+
198
+ const hexagonLayerGroup = L.layerGroup([hexagonImageDop20, hexagonImageDop10], {
199
+ attribution: `© GeoBasis-DE/BKG ${new Date().getFullYear()}, powered by HxGN`,
200
+ maxZoom: leafletMapLayersConfig['bkgHexagonGermanyLayer']['maxZoom'],
201
+ maxNativeZoom:
202
+ leafletMapLayersConfig['bkgHexagonGermanyLayer']['maxNativeZoom'],
203
+ layerTypeAPI: 'bkgHexagonGermanyLayer',
204
+ })
205
+
206
+ const GeoLayer_HR = L.tileLayer(
207
+ 'https://data.geopf.fr/wmts?' +
208
+ '&REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0' +
209
+ '&STYLE=normal' +
210
+ '&TILEMATRIXSET=PM' +
211
+ '&FORMAT=image/jpeg' +
212
+ '&LAYER=HR.ORTHOIMAGERY.ORTHOPHOTOS' +
213
+ '&TILEMATRIX={z}' +
214
+ '&TILEROW={y}' +
215
+ '&TILECOL={x}',
216
+ {
217
+ layers: 'HR.ORTHOIMAGERY.ORTHOPHOTOS',
218
+ id: 'HR.ORTHOIMAGERY.ORTHOPHOTOS',
219
+ attribution: '&copy; IGN-F/Geoportail France',
220
+ minZoom: leafletMapLayersConfig['GeoPortal']['minZoom'],
221
+ maxZoom: leafletMapLayersConfig['GeoPortal']['maxZoom'],
222
+ maxNativeZoom: leafletMapLayersConfig['GeoPortal']['maxNativeZoom'],
223
+ tileSize: 256,
224
+ layerTypeAPI: 'geoportail_fr_wmts_ortho_layer',
225
+ }
226
+ )
227
+
228
+ const azureSatelliteLayer = L.tileLayer(
229
+ 'https://atlas.microsoft.com/map/tile?' +
230
+ 'api-version={apiVersion}' +
231
+ '&tilesetId={tilesetId}' +
232
+ '&subscription-key={subscriptionKey}' +
233
+ '&zoom={z}' +
234
+ '&x={x}' +
235
+ '&y={y}',
236
+ {
237
+ layerTypeAPI: 'azureSatelliteLayer',
238
+ id: 'azure_satellite',
239
+ attribution: `\u00A9 ${new Date().getFullYear()} EarthStar Geographics, Microsoft`,
240
+ minZoom: leafletMapLayersConfig['azureSatelliteLayer']['minZoom'],
241
+ maxZoom: leafletMapLayersConfig['azureSatelliteLayer']['maxZoom'],
242
+ maxNativeZoom:
243
+ leafletMapLayersConfig['azureSatelliteLayer']['maxNativeZoom'],
244
+ // query parameters
245
+ apiVersion: '2022-08-01',
246
+ tilesetId: 'microsoft.imagery',
247
+ subscriptionKey: process.env.VUE_APP_AZURE_MAP_SUBSCRIPTION_KEY,
248
+ }
249
+ )
250
+
251
+ function getLayers() {
215
252
  return [
216
253
  {
217
254
  name: 'SwissTopo (satellite)',
@@ -273,11 +310,6 @@ function getLayers() {
273
310
  key: 'ignSpainLayer_map',
274
311
  layerData: ignLayerMap,
275
312
  },
276
- {
277
- name: 'BKG satellite image',
278
- key: 'bkgHexagonGermanyLayer',
279
- layerData: bkgHexagonImage,
280
- },
281
313
  {
282
314
  name: 'GeoPortal France (satellite)',
283
315
  key: 'geoportail_fr_wmts_ortho_layer',
@@ -288,6 +320,11 @@ function getLayers() {
288
320
  key: 'azureSatelliteLayer',
289
321
  layerData: azureSatelliteLayer,
290
322
  },
323
+ {
324
+ name: 'BKG (satellite)',
325
+ key: 'bkgHexagonGermanyLayer',
326
+ layerData: hexagonLayerGroup,
327
+ },
291
328
  ]
292
329
  }
293
330
  export default getLayers