@vcmap/core 6.3.0-rc.1 → 6.3.0-rc.2

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 (159) hide show
  1. package/dist/cesium.d.ts +12 -0
  2. package/dist/index.d.ts +10 -2
  3. package/dist/index.js +9 -2
  4. package/dist/index.js.map +1 -1
  5. package/dist/ol.d.ts +13 -2
  6. package/dist/src/cesium/cesium3DTileFeature.d.ts +1 -0
  7. package/dist/src/cesium/cesium3DTileFeature.js +16 -3
  8. package/dist/src/cesium/cesium3DTileFeature.js.map +1 -1
  9. package/dist/src/cesium/cesium3DTilePointFeature.js +2 -1
  10. package/dist/src/cesium/cesium3DTilePointFeature.js.map +1 -1
  11. package/dist/src/classRegistry.d.ts +7 -1
  12. package/dist/src/classRegistry.js.map +1 -1
  13. package/dist/src/featureProvider/abstractAttributeProvider.d.ts +62 -0
  14. package/dist/src/featureProvider/abstractAttributeProvider.js +129 -0
  15. package/dist/src/featureProvider/abstractAttributeProvider.js.map +1 -0
  16. package/dist/src/featureProvider/abstractFeatureProvider.d.ts +9 -18
  17. package/dist/src/featureProvider/abstractFeatureProvider.js +7 -38
  18. package/dist/src/featureProvider/abstractFeatureProvider.js.map +1 -1
  19. package/dist/src/featureProvider/compositeFeatureProvider.d.ts +27 -0
  20. package/dist/src/featureProvider/compositeFeatureProvider.js +53 -0
  21. package/dist/src/featureProvider/compositeFeatureProvider.js.map +1 -0
  22. package/dist/src/featureProvider/csvAttributeProvider.d.ts +41 -0
  23. package/dist/src/featureProvider/csvAttributeProvider.js +126 -0
  24. package/dist/src/featureProvider/csvAttributeProvider.js.map +1 -0
  25. package/dist/src/featureProvider/featureProviderFactory.d.ts +3 -0
  26. package/dist/src/featureProvider/featureProviderFactory.js +17 -0
  27. package/dist/src/featureProvider/featureProviderFactory.js.map +1 -0
  28. package/dist/src/featureProvider/i3sAttributeProvider.d.ts +7 -0
  29. package/dist/src/featureProvider/i3sAttributeProvider.js +43 -0
  30. package/dist/src/featureProvider/i3sAttributeProvider.js.map +1 -0
  31. package/dist/src/featureProvider/jsonAttributeProvider.d.ts +26 -0
  32. package/dist/src/featureProvider/jsonAttributeProvider.js +73 -0
  33. package/dist/src/featureProvider/jsonAttributeProvider.js.map +1 -0
  34. package/dist/src/featureProvider/tileProviderFeatureProvider.d.ts +4 -6
  35. package/dist/src/featureProvider/tileProviderFeatureProvider.js +9 -11
  36. package/dist/src/featureProvider/tileProviderFeatureProvider.js.map +1 -1
  37. package/dist/src/featureProvider/urlIdAttributeProvider.d.ts +28 -0
  38. package/dist/src/featureProvider/urlIdAttributeProvider.js +50 -0
  39. package/dist/src/featureProvider/urlIdAttributeProvider.js.map +1 -0
  40. package/dist/src/featureProvider/wmsFeatureProvider.d.ts +12 -3
  41. package/dist/src/featureProvider/wmsFeatureProvider.js +17 -6
  42. package/dist/src/featureProvider/wmsFeatureProvider.js.map +1 -1
  43. package/dist/src/interaction/featureAtPixelInteraction.d.ts +15 -3
  44. package/dist/src/interaction/featureAtPixelInteraction.js +41 -1
  45. package/dist/src/interaction/featureAtPixelInteraction.js.map +1 -1
  46. package/dist/src/interaction/featureProviderInteraction.js +42 -26
  47. package/dist/src/interaction/featureProviderInteraction.js.map +1 -1
  48. package/dist/src/layer/cesium/cesiumTilesetCesiumImpl.d.ts +14 -5
  49. package/dist/src/layer/cesium/cesiumTilesetCesiumImpl.js +243 -128
  50. package/dist/src/layer/cesium/cesiumTilesetCesiumImpl.js.map +1 -1
  51. package/dist/src/layer/cesium/i3sCesiumImpl.d.ts +33 -0
  52. package/dist/src/layer/cesium/i3sCesiumImpl.js +107 -0
  53. package/dist/src/layer/cesium/i3sCesiumImpl.js.map +1 -0
  54. package/dist/src/layer/cesium/vcsTile/vcsQuadtreeTileProvider.js +2 -1
  55. package/dist/src/layer/cesium/vcsTile/vcsQuadtreeTileProvider.js.map +1 -1
  56. package/dist/src/layer/cesium/vectorRasterTileCesiumImpl.js +7 -6
  57. package/dist/src/layer/cesium/vectorRasterTileCesiumImpl.js.map +1 -1
  58. package/dist/src/layer/cesium/vectorTileImageryProvider.js +2 -2
  59. package/dist/src/layer/cesium/vectorTileImageryProvider.js.map +1 -1
  60. package/dist/src/layer/cesiumTilesetLayer.d.ts +9 -0
  61. package/dist/src/layer/cesiumTilesetLayer.js +26 -1
  62. package/dist/src/layer/cesiumTilesetLayer.js.map +1 -1
  63. package/dist/src/layer/i3sLayer.d.ts +80 -0
  64. package/dist/src/layer/i3sLayer.js +242 -0
  65. package/dist/src/layer/i3sLayer.js.map +1 -0
  66. package/dist/src/layer/layer.d.ts +8 -3
  67. package/dist/src/layer/layer.js +7 -1
  68. package/dist/src/layer/layer.js.map +1 -1
  69. package/dist/src/layer/layerSymbols.d.ts +4 -0
  70. package/dist/src/layer/layerSymbols.js +4 -0
  71. package/dist/src/layer/layerSymbols.js.map +1 -1
  72. package/dist/src/layer/panoramaDatasetLayer.d.ts +2 -0
  73. package/dist/src/layer/panoramaDatasetLayer.js +33 -13
  74. package/dist/src/layer/panoramaDatasetLayer.js.map +1 -1
  75. package/dist/src/layer/tileProvider/flatGeobufTileProvider.js +3 -2
  76. package/dist/src/layer/tileProvider/flatGeobufTileProvider.js.map +1 -1
  77. package/dist/src/layer/tileProvider/mvtTileProvider.js +3 -2
  78. package/dist/src/layer/tileProvider/mvtTileProvider.js.map +1 -1
  79. package/dist/src/layer/tileProvider/tileProvider.d.ts +6 -0
  80. package/dist/src/layer/tileProvider/tileProvider.js +12 -1
  81. package/dist/src/layer/tileProvider/tileProvider.js.map +1 -1
  82. package/dist/src/layer/vectorLayer.js +2 -2
  83. package/dist/src/layer/vectorLayer.js.map +1 -1
  84. package/dist/src/layer/vectorProperties.js +10 -1
  85. package/dist/src/layer/vectorProperties.js.map +1 -1
  86. package/dist/src/layer/vectorTileLayer.d.ts +14 -5
  87. package/dist/src/layer/vectorTileLayer.js +78 -26
  88. package/dist/src/layer/vectorTileLayer.js.map +1 -1
  89. package/dist/src/layer/wmsLayer.d.ts +3 -0
  90. package/dist/src/layer/wmsLayer.js +62 -32
  91. package/dist/src/layer/wmsLayer.js.map +1 -1
  92. package/dist/src/map/baseCesiumMap.d.ts +4 -4
  93. package/dist/src/map/baseCesiumMap.js +12 -0
  94. package/dist/src/map/baseCesiumMap.js.map +1 -1
  95. package/dist/src/map/cesiumMap.js +0 -11
  96. package/dist/src/map/cesiumMap.js.map +1 -1
  97. package/dist/src/map/obliqueMap.js +11 -4
  98. package/dist/src/map/obliqueMap.js.map +1 -1
  99. package/dist/src/map/panoramaMap.js +1 -1
  100. package/dist/src/panorama/panoramaImage.js +6 -5
  101. package/dist/src/panorama/panoramaImage.js.map +1 -1
  102. package/dist/src/style/declarativeStyleItem.js +7 -8
  103. package/dist/src/style/declarativeStyleItem.js.map +1 -1
  104. package/dist/src/util/fetch.d.ts +7 -0
  105. package/dist/src/util/fetch.js +7 -0
  106. package/dist/src/util/fetch.js.map +1 -1
  107. package/dist/src/vcsApp.d.ts +2 -3
  108. package/dist/src/vcsApp.js.map +1 -1
  109. package/dist/src/vcsModuleHelpers.d.ts +5 -2
  110. package/dist/src/vcsModuleHelpers.js +27 -1
  111. package/dist/src/vcsModuleHelpers.js.map +1 -1
  112. package/dist/tests/unit/helpers/cesiumHelpers.js +7 -1
  113. package/dist/tests/unit/helpers/cesiumHelpers.js.map +1 -1
  114. package/index.ts +27 -0
  115. package/package.json +2 -2
  116. package/src/cesium/cesium.d.ts +12 -0
  117. package/src/cesium/cesium3DTileFeature.ts +25 -3
  118. package/src/cesium/cesium3DTilePointFeature.ts +3 -1
  119. package/src/classRegistry.ts +8 -3
  120. package/src/featureProvider/abstractAttributeProvider.ts +201 -0
  121. package/src/featureProvider/abstractFeatureProvider.ts +27 -47
  122. package/src/featureProvider/compositeFeatureProvider.ts +103 -0
  123. package/src/featureProvider/csvAttributeProvider.ts +186 -0
  124. package/src/featureProvider/featureProviderFactory.ts +31 -0
  125. package/src/featureProvider/i3sAttributeProvider.ts +60 -0
  126. package/src/featureProvider/jsonAttributeProvider.ts +109 -0
  127. package/src/featureProvider/tileProviderFeatureProvider.ts +13 -14
  128. package/src/featureProvider/urlIdAttributeProvider.ts +82 -0
  129. package/src/featureProvider/wmsFeatureProvider.ts +24 -7
  130. package/src/global.d.ts +2 -0
  131. package/src/interaction/featureAtPixelInteraction.ts +53 -3
  132. package/src/interaction/featureProviderInteraction.ts +59 -38
  133. package/src/layer/cesium/cesiumTilesetCesiumImpl.ts +296 -157
  134. package/src/layer/cesium/i3sCesiumImpl.ts +141 -0
  135. package/src/layer/cesium/vcsTile/vcsQuadtreeTileProvider.ts +4 -3
  136. package/src/layer/cesium/vectorRasterTileCesiumImpl.ts +7 -6
  137. package/src/layer/cesium/vectorTileImageryProvider.ts +2 -2
  138. package/src/layer/cesiumTilesetLayer.ts +51 -1
  139. package/src/layer/i3sLayer.ts +343 -0
  140. package/src/layer/layer.ts +30 -3
  141. package/src/layer/layerSymbols.ts +5 -0
  142. package/src/layer/panoramaDatasetLayer.ts +44 -13
  143. package/src/layer/tileProvider/flatGeobufTileProvider.ts +3 -2
  144. package/src/layer/tileProvider/mvtTileProvider.ts +3 -2
  145. package/src/layer/tileProvider/tileProvider.ts +13 -1
  146. package/src/layer/vectorLayer.ts +4 -2
  147. package/src/layer/vectorProperties.ts +10 -1
  148. package/src/layer/vectorTileLayer.ts +135 -47
  149. package/src/layer/wmsLayer.ts +77 -44
  150. package/src/map/baseCesiumMap.ts +29 -5
  151. package/src/map/cesiumMap.ts +0 -15
  152. package/src/map/obliqueMap.ts +13 -6
  153. package/src/map/panoramaMap.ts +1 -1
  154. package/src/ol/ol.d.ts +13 -2
  155. package/src/panorama/panoramaImage.ts +8 -5
  156. package/src/style/declarativeStyleItem.ts +7 -9
  157. package/src/util/fetch.ts +7 -0
  158. package/src/vcsApp.ts +7 -8
  159. package/src/vcsModuleHelpers.ts +62 -4
@@ -1,7 +1,7 @@
1
1
  import type Feature from 'ol/Feature.js';
2
2
  import type { HttpReader } from 'flatgeobuf/lib/mjs/http-reader.js';
3
3
  import type { TileProviderOptions } from './tileProvider.js';
4
- import TileProvider, { rectangleToExtent } from './tileProvider.js';
4
+ import TileProvider from './tileProvider.js';
5
5
  import type { ProjectionOptions } from '../../util/projection.js';
6
6
  import Projection, {
7
7
  getDefaultProjection,
@@ -14,6 +14,7 @@ import {
14
14
  getRootNode,
15
15
  getValidReader,
16
16
  } from '../flatGeobufHelpers.js';
17
+ import { rectangleToMercatorExtent } from '../../util/math.js';
17
18
 
18
19
  export type FlatGeobufTileProviderOptions = Omit<
19
20
  TileProviderOptions,
@@ -81,7 +82,7 @@ export default class FlatGeobufTileProvider extends TileProvider {
81
82
 
82
83
  async loader(x: number, y: number, z: number): Promise<Feature[]> {
83
84
  const rectangle = this.tilingScheme.tileXYToRectangle(x, y, z);
84
- const extent = rectangleToExtent(rectangle);
85
+ const extent = rectangleToMercatorExtent(rectangle);
85
86
  const mercatorExtent = new Extent({
86
87
  coordinates: extent,
87
88
  projection: mercatorProjection,
@@ -3,10 +3,11 @@ import Feature from 'ol/Feature.js';
3
3
  import { getCenter } from 'ol/extent.js';
4
4
  import type { Geometry } from 'ol/geom.js';
5
5
  import type { TileProviderOptions } from './tileProvider.js';
6
- import TileProvider, { rectangleToExtent } from './tileProvider.js';
6
+ import TileProvider from './tileProvider.js';
7
7
  import { getURL } from './urlTemplateTileProvider.js';
8
8
  import { getInitForUrl, requestArrayBuffer } from '../../util/fetch.js';
9
9
  import { tileProviderClassRegistry } from '../../classRegistry.js';
10
+ import { rectangleToMercatorExtent } from '../../util/math.js';
10
11
 
11
12
  export type MVTTileProviderOptions = TileProviderOptions & {
12
13
  /**
@@ -66,7 +67,7 @@ class MVTTileProvider extends TileProvider {
66
67
  ): Promise<Feature[]> {
67
68
  const rectangle = this.tilingScheme.tileXYToRectangle(x, y, z);
68
69
  const url = getURL(this.url, x, y, z, rectangle, this.locale);
69
- const extent = rectangleToExtent(rectangle);
70
+ const extent = rectangleToMercatorExtent(rectangle);
70
71
  const center = getCenter(extent);
71
72
  const init = getInitForUrl(this.url, headers);
72
73
  const data = await requestArrayBuffer(url, init);
@@ -27,6 +27,7 @@ import VcsObject from '../../vcsObject.js';
27
27
  import VcsEvent from '../../vcsEvent.js';
28
28
  import { tileProviderClassRegistry } from '../../classRegistry.js';
29
29
  import type Extent from '../../util/extent.js';
30
+ import { rectangleToMercatorExtent } from '../../util/math.js';
30
31
 
31
32
  export type TileProviderRTreeEntry = {
32
33
  minX: number;
@@ -56,6 +57,7 @@ for (let i = 0; i < mercatorResolutionsToLevel.length; i++) {
56
57
  * transforms cesium geographic rectangle to mercator extent
57
58
  * @param rectangle in wgs84 radians
58
59
  * @returns extent in mercator
60
+ * @deprecated use rectangleToMercatorExtent
59
61
  */
60
62
  export function rectangleToExtent(rectangle: Rectangle): OLExtent {
61
63
  const baseSouthWestLevel = Rectangle.southwest(rectangle);
@@ -387,6 +389,16 @@ class TileProvider extends VcsObject {
387
389
  return `${level}/${x}/${y}`;
388
390
  }
389
391
 
392
+ // eslint-disable-next-line class-methods-use-this
393
+ parseCacheKey(key: string): { x: number; y: number; level: number } {
394
+ const parts = key.split('/');
395
+ return {
396
+ level: parseInt(parts[0], 10),
397
+ x: parseInt(parts[1], 10),
398
+ y: parseInt(parts[2], 10),
399
+ };
400
+ }
401
+
390
402
  private async _getRtreeForBaseTile(
391
403
  baseLevel: number,
392
404
  tileCenter: Cartographic,
@@ -506,7 +518,7 @@ class TileProvider extends VcsObject {
506
518
  if (level === baseLevel) {
507
519
  return rtree.all().map((item) => item.value);
508
520
  } else {
509
- const extent = rectangleToExtent(rectangle);
521
+ const extent = rectangleToMercatorExtent(rectangle);
510
522
  const features = rtree
511
523
  .search({
512
524
  minX: extent[0],
@@ -105,7 +105,7 @@ class VectorLayer
105
105
  dontUseTerrainForOblique: false,
106
106
  highlightStyle: undefined,
107
107
  isDynamic: false,
108
- vectorProperties: {}, // XXX or should we return VectorProperties default options?
108
+ vectorProperties: undefined, // XXX or should we return VectorProperties default options?
109
109
  vectorClusterGroup: undefined,
110
110
  ignoreMapLayerTypes: true,
111
111
  };
@@ -545,7 +545,9 @@ class VectorLayer
545
545
  config.isDynamic = this.isDynamic;
546
546
  }
547
547
 
548
- const vectorPropertiesConfig = this.vectorProperties.getVcsMeta();
548
+ const vectorPropertiesConfig = this.vectorProperties.getVcsMeta(
549
+ defaultOptions.vectorProperties,
550
+ );
549
551
  if (Object.keys(vectorPropertiesConfig).length > 0) {
550
552
  config.vectorProperties = vectorPropertiesConfig;
551
553
  }
@@ -347,8 +347,8 @@ class VectorProperties {
347
347
  modelRoll: 0,
348
348
  modelOptions: undefined,
349
349
  modelAutoScale: false,
350
- baseUrl: undefined,
351
350
  primitiveOptions: undefined,
351
+ baseUrl: undefined,
352
352
  };
353
353
  }
354
354
 
@@ -1683,6 +1683,15 @@ class VectorProperties {
1683
1683
  if (this.baseUrl !== defaultValues.baseUrl) {
1684
1684
  vcsMeta.baseUrl = this.baseUrl;
1685
1685
  }
1686
+ if (!deepEqual(this.modelOptions, defaultOptions?.modelOptions)) {
1687
+ vcsMeta.modelOptions = this.modelOptions;
1688
+ }
1689
+ if (this.modelAutoScale !== defaultValues.modelAutoScale) {
1690
+ vcsMeta.modelAutoScale = this.modelAutoScale;
1691
+ }
1692
+ if (!deepEqual(this.primitiveOptions, defaultOptions?.primitiveOptions)) {
1693
+ vcsMeta.primitiveOptions = this.primitiveOptions;
1694
+ }
1686
1695
  return vcsMeta;
1687
1696
  }
1688
1697
 
@@ -1,3 +1,4 @@
1
+ import { check, is, maybe, oneOf } from '@vcsuite/check';
1
2
  import Style, { type StyleFunction } from 'ol/style/Style.js';
2
3
  import type { Feature } from 'ol/index.js';
3
4
  import type { Size } from 'ol/size.js';
@@ -53,6 +54,14 @@ import VectorTileCesiumImpl from './cesium/vectorTileCesiumImpl.js';
53
54
  import VectorTilePanoramaImpl from './panorama/vectorTilePanoramaImpl.js';
54
55
  import PanoramaMap from '../map/panoramaMap.js';
55
56
  import type LayerImplementation from './layerImplementation.js';
57
+ import AbstractFeatureProvider from '../featureProvider/abstractFeatureProvider.js';
58
+ import AbstractAttributeProvider, {
59
+ type AbstractAttributeProviderOptions,
60
+ type AttributeProvider,
61
+ } from '../featureProvider/abstractAttributeProvider.js';
62
+ import CompositeFeatureProvider from '../featureProvider/compositeFeatureProvider.js';
63
+ import { rectangleToMercatorExtent } from '../util/math.js';
64
+ import { getProviderForOption } from '../featureProvider/featureProviderFactory.js';
56
65
 
57
66
  /**
58
67
  * synchronizes featureVisibility Symbols on the feature;
@@ -113,14 +122,18 @@ export type VectorTileOptions = FeatureLayerOptions & {
113
122
  declutter?: boolean;
114
123
  debug?: boolean;
115
124
  renderer?: VectorTileRenderer;
125
+ /**
126
+ * an optional attribute provider to provide custom attributes for the tileset features on load
127
+ */
128
+ attributeProvider?: AttributeProvider | AbstractAttributeProviderOptions;
116
129
  };
117
130
 
118
131
  export type VectorTileImplementationOptions =
119
132
  FeatureLayerImplementationOptions & {
120
133
  tileProvider: TileProvider;
121
134
  tileSize: Size;
122
- minLevel: number;
123
- maxLevel: number;
135
+ minLevel?: number;
136
+ maxLevel?: number;
124
137
  extent?: Extent;
125
138
  declutter: boolean;
126
139
  vectorProperties: VectorProperties;
@@ -163,6 +176,7 @@ class VectorTileLayer<
163
176
  declutter: true,
164
177
  debug: false,
165
178
  renderer: 'image',
179
+ attributeProvider: undefined,
166
180
  };
167
181
  }
168
182
 
@@ -177,9 +191,11 @@ class VectorTileLayer<
177
191
 
178
192
  tileProvider: TileProvider;
179
193
 
180
- private _maxLevel: number;
194
+ private _attributeProvider?: AttributeProvider;
195
+
196
+ private _maxLevel?: number;
181
197
 
182
- private _minLevel: number;
198
+ private _minLevel?: number;
183
199
 
184
200
  private _declutter: boolean;
185
201
 
@@ -200,6 +216,10 @@ class VectorTileLayer<
200
216
 
201
217
  private _renderer: VectorTileRenderer;
202
218
 
219
+ private _defaultFeatureProvider?:
220
+ | TileProviderFeatureProvider
221
+ | CompositeFeatureProvider;
222
+
203
223
  /**
204
224
  * @param options
205
225
  */
@@ -229,6 +249,7 @@ class VectorTileLayer<
229
249
  tileProviderClassRegistry,
230
250
  options.tileProvider ?? { type: TileProvider.className },
231
251
  ) as TileProvider);
252
+
232
253
  if (this.tileProvider) {
233
254
  this.tileProvider.locale = this.locale;
234
255
  }
@@ -242,6 +263,17 @@ class VectorTileLayer<
242
263
  vectorTileRenderers,
243
264
  defaultOptions.renderer,
244
265
  );
266
+
267
+ const attributeProvider = getProviderForOption(options.attributeProvider);
268
+
269
+ if (
270
+ is(
271
+ attributeProvider,
272
+ oneOf(CompositeFeatureProvider, AbstractAttributeProvider),
273
+ )
274
+ ) {
275
+ this._attributeProvider = attributeProvider;
276
+ }
245
277
  }
246
278
 
247
279
  /**
@@ -267,6 +299,26 @@ class VectorTileLayer<
267
299
  this.vectorProperties.allowPicking = allowPicking;
268
300
  }
269
301
 
302
+ get attributeProvider(): AttributeProvider | undefined {
303
+ return this._attributeProvider;
304
+ }
305
+
306
+ set attributeProvider(provider: AttributeProvider | undefined) {
307
+ check(
308
+ provider,
309
+ maybe(oneOf(AbstractAttributeProvider, CompositeFeatureProvider)),
310
+ );
311
+
312
+ if (this._attributeProvider !== provider) {
313
+ this._attributeProvider = provider;
314
+ this.forceRedraw().catch((e: unknown) => {
315
+ this.getLogger().error(
316
+ `Error forcing redraw after setting attribute provider: ${String(e)}`,
317
+ );
318
+ });
319
+ }
320
+ }
321
+
270
322
  async initialize(): Promise<void> {
271
323
  if (!this.initialized) {
272
324
  this._tileLoadEventListener =
@@ -279,14 +331,26 @@ class VectorTileLayer<
279
331
  void this.reload();
280
332
  });
281
333
 
282
- if (this._renderer === 'image') {
283
- // primitives dont need a feature provider
284
- this.featureProvider = new TileProviderFeatureProvider(this.name, {
285
- // XXX this overwrites
334
+ if (
335
+ this._renderer === 'image' &&
336
+ !(this.featureProvider instanceof AbstractFeatureProvider)
337
+ ) {
338
+ const defaultFeatureProvider = new TileProviderFeatureProvider({
286
339
  style: this.style,
287
340
  tileProvider: this.tileProvider,
288
341
  vectorProperties: this.vectorProperties,
289
342
  });
343
+
344
+ if (this.featureProvider instanceof AbstractAttributeProvider) {
345
+ const attributeProvider = this.featureProvider;
346
+ this._defaultFeatureProvider = new CompositeFeatureProvider({
347
+ featureProviders: [defaultFeatureProvider],
348
+ attributeProviders: [attributeProvider],
349
+ });
350
+ } else {
351
+ this._defaultFeatureProvider = defaultFeatureProvider;
352
+ }
353
+ this.featureProvider = this._defaultFeatureProvider;
290
354
  }
291
355
  }
292
356
  await super.initialize();
@@ -297,27 +361,40 @@ class VectorTileLayer<
297
361
  return this._styleZIndex;
298
362
  }
299
363
 
300
- private _handleTileLoaded({ rtree }: TileLoadedEvent): void {
301
- rtree
302
- .all()
303
- .map((item) => item.value)
304
- .forEach((feature) => {
305
- const featureStyle = feature.getStyle();
306
- if (featureStyle && featureStyle instanceof Style) {
307
- featureStyle.setZIndex(this._getNextStyleZIndex());
308
- }
309
- feature[vcsLayerName] = this.name;
310
- feature.getStyleFunction = (): StyleFunction => {
311
- return this._featureStyle.bind(this) as StyleFunction;
312
- };
313
- if (this.tileProvider.trackFeaturesToTiles && this.globalHider) {
314
- synchronizeFeatureVisibility(
315
- this.featureVisibility,
316
- this.globalHider,
317
- feature,
318
- );
319
- }
320
- });
364
+ private _handleTileLoaded({ rtree, tileId }: TileLoadedEvent): void {
365
+ const features = rtree.all().map((item) => {
366
+ const feature = item.value;
367
+ const featureStyle = feature.getStyle();
368
+ if (featureStyle && featureStyle instanceof Style) {
369
+ featureStyle.setZIndex(this._getNextStyleZIndex());
370
+ }
371
+ feature[vcsLayerName] = this.name;
372
+ feature.getStyleFunction = (): StyleFunction => {
373
+ return this._featureStyle.bind(this) as StyleFunction;
374
+ };
375
+ if (this.tileProvider.trackFeaturesToTiles && this.globalHider) {
376
+ synchronizeFeatureVisibility(
377
+ this.featureVisibility,
378
+ this.globalHider,
379
+ feature,
380
+ );
381
+ }
382
+ return feature;
383
+ });
384
+
385
+ if (this._attributeProvider) {
386
+ const { x, y, level } = this.tileProvider.parseCacheKey(tileId);
387
+ const rectangle = this.tileProvider.tilingScheme.tileXYToRectangle(
388
+ x,
389
+ y,
390
+ level,
391
+ );
392
+ this._attributeProvider
393
+ .augmentFeatures(features, rectangleToMercatorExtent(rectangle))
394
+ .catch((error: unknown) => {
395
+ this.getLogger().error(`Error augmenting features: ${String(error)}`);
396
+ });
397
+ }
321
398
  }
322
399
 
323
400
  setGlobalHider(globalHider: GlobalHider): void {
@@ -516,24 +593,6 @@ class VectorTileLayer<
516
593
  });
517
594
  }
518
595
 
519
- destroy(): void {
520
- this._featureVisibilityListeners.forEach((cb) => {
521
- cb();
522
- });
523
- super.destroy();
524
- this._tileLoadEventListener();
525
- if (this.featureProvider) {
526
- this.featureProvider.destroy();
527
- }
528
- if (this.tileProvider) {
529
- this.tileProvider.destroy();
530
- }
531
- this._vectorPropertiesChangedListener();
532
- if (this.vectorProperties) {
533
- this.vectorProperties.destroy();
534
- }
535
- }
536
-
537
596
  toJSON(
538
597
  defaultOptions = VectorTileLayer.getDefaultOptions(),
539
598
  ): VectorTileOptions {
@@ -572,8 +631,37 @@ class VectorTileLayer<
572
631
  config.debug = this._debug;
573
632
  }
574
633
 
634
+ if (this.featureProvider === this._defaultFeatureProvider) {
635
+ delete config.featureProvider;
636
+ if (this.featureProvider instanceof CompositeFeatureProvider) {
637
+ const { attributeProviders } = this.featureProvider.toJSON();
638
+ config.featureProvider = attributeProviders[0];
639
+ }
640
+ }
641
+
642
+ if (this._attributeProvider) {
643
+ config.attributeProvider = this._attributeProvider.toJSON();
644
+ }
645
+
575
646
  return config;
576
647
  }
648
+
649
+ destroy(): void {
650
+ this._featureVisibilityListeners.forEach((cb) => {
651
+ cb();
652
+ });
653
+ this.attributeProvider?.destroy();
654
+ this._defaultFeatureProvider?.destroy();
655
+ super.destroy();
656
+ this._tileLoadEventListener();
657
+ if (this.tileProvider) {
658
+ this.tileProvider.destroy();
659
+ }
660
+ this._vectorPropertiesChangedListener();
661
+ if (this.vectorProperties) {
662
+ this.vectorProperties.destroy();
663
+ }
664
+ }
577
665
  }
578
666
 
579
667
  layerClassRegistry.registerClass(VectorTileLayer.className, VectorTileLayer);
@@ -16,6 +16,10 @@ import WmsOpenlayersImpl from './openlayers/wmsOpenlayersImpl.js';
16
16
  import Extent from '../util/extent.js';
17
17
  import { layerClassRegistry } from '../classRegistry.js';
18
18
  import type VcsMap from '../map/vcsMap.js';
19
+ import AbstractAttributeProvider from '../featureProvider/abstractAttributeProvider.js';
20
+ import CompositeFeatureProvider, {
21
+ type CompositeFeatureProviderOptions,
22
+ } from '../featureProvider/compositeFeatureProvider.js';
19
23
 
20
24
  export type WMSImplementationOptions = RasterLayerImplementationOptions & {
21
25
  parameters: Record<string, string>;
@@ -39,9 +43,10 @@ export type WMSOptions = RasterLayerOptions & {
39
43
  * key value pair of additional WMS parameters, url query notation possible
40
44
  */
41
45
  parameters?: Record<string, string> | string;
42
-
43
46
  /**
44
47
  * whether this layer should send getFeatureInfo requests to the service when objects are clicked.
48
+ * do not provide this option AND a feature provider. this option will configure a
49
+ * layer specific WMSFeatureProvider. providing an attribute provider will create a composite feature provider.
45
50
  */
46
51
  featureInfo?: Partial<WMSFeatureProviderOptions>;
47
52
  /**
@@ -92,6 +97,8 @@ class WMSLayer extends RasterLayer<WmsCesiumImpl | WmsOpenlayersImpl> {
92
97
 
93
98
  private _featureInfoOptions: Partial<WMSFeatureProviderOptions> | undefined;
94
99
 
100
+ private _attributeProvider?: AbstractAttributeProvider;
101
+
95
102
  /**
96
103
  * @param options
97
104
  */
@@ -140,6 +147,10 @@ class WMSLayer extends RasterLayer<WmsCesiumImpl | WmsOpenlayersImpl> {
140
147
  options.singleImage2d,
141
148
  defaultOptions.singleImage2d,
142
149
  );
150
+
151
+ if (this.featureProvider instanceof AbstractAttributeProvider) {
152
+ this._attributeProvider = this.featureProvider;
153
+ }
143
154
  }
144
155
 
145
156
  initialize(): Promise<void> {
@@ -163,9 +174,19 @@ class WMSLayer extends RasterLayer<WmsCesiumImpl | WmsOpenlayersImpl> {
163
174
  extent: this.extent,
164
175
  parameters: this.parameters,
165
176
  version: this.version,
177
+ headers: this.headers,
166
178
  ...this._featureInfoOptions,
167
179
  };
168
- this.featureProvider = new WMSFeatureProvider(this.name, options);
180
+
181
+ const wmsFeatureProvider = new WMSFeatureProvider(options);
182
+ if (this._attributeProvider) {
183
+ this.featureProvider = new CompositeFeatureProvider({
184
+ featureProviders: [wmsFeatureProvider],
185
+ attributeProviders: [this._attributeProvider],
186
+ });
187
+ } else {
188
+ this.featureProvider = wmsFeatureProvider;
189
+ }
169
190
  }
170
191
  }
171
192
 
@@ -260,49 +281,61 @@ class WMSLayer extends RasterLayer<WmsCesiumImpl | WmsOpenlayersImpl> {
260
281
  config.singleImage2d = this.singleImage2d;
261
282
  }
262
283
 
263
- if (
264
- this.featureProvider &&
265
- this.featureProvider instanceof WMSFeatureProvider
266
- ) {
267
- const featureInfoConfig: Partial<WMSFeatureProviderOptions> =
268
- this.featureProvider.toJSON();
269
- if (
270
- this.tileSize[0] === featureInfoConfig?.tileSize?.[0] ||
271
- this.tileSize[1] === featureInfoConfig?.tileSize?.[1]
272
- ) {
273
- delete featureInfoConfig.tileSize;
274
- }
275
- if (
276
- Object.entries(this.parameters).every(
277
- ([key, value]) => featureInfoConfig?.parameters?.[key] === value,
278
- )
279
- ) {
280
- delete featureInfoConfig.parameters;
281
- }
282
- if (
283
- featureInfoConfig.extent &&
284
- new Extent(featureInfoConfig.extent).equals(this.extent)
285
- ) {
286
- delete featureInfoConfig.extent;
287
- }
288
- if (this.url === featureInfoConfig.url) {
289
- delete featureInfoConfig.url;
290
- }
291
- if (this.tilingSchema === featureInfoConfig.tilingSchema) {
292
- delete featureInfoConfig.tilingSchema;
293
- }
294
- if (this.version === featureInfoConfig.version) {
295
- delete featureInfoConfig.version;
296
- }
297
- if (this.minLevel === featureInfoConfig.minLevel) {
298
- delete featureInfoConfig.minLevel;
299
- }
300
- if (this.maxLevel === featureInfoConfig.maxLevel) {
301
- delete featureInfoConfig.maxLevel;
284
+ if (this._featureInfoOptions) {
285
+ delete config.featureProvider;
286
+ if (this.featureProvider) {
287
+ let featureInfoConfig: Partial<WMSFeatureProviderOptions>;
288
+ if (this._attributeProvider) {
289
+ const compositeInfo =
290
+ this.featureProvider.toJSON() as CompositeFeatureProviderOptions;
291
+ featureInfoConfig = compositeInfo.featureProviders[0];
292
+ config.featureProvider = this._attributeProvider.toJSON();
293
+ } else {
294
+ featureInfoConfig = this.featureProvider.toJSON();
295
+ }
296
+ if (
297
+ this.tileSize[0] === featureInfoConfig?.tileSize?.[0] ||
298
+ this.tileSize[1] === featureInfoConfig?.tileSize?.[1]
299
+ ) {
300
+ delete featureInfoConfig.tileSize;
301
+ }
302
+ if (
303
+ Object.entries(this.parameters).every(
304
+ ([key, value]) => featureInfoConfig?.parameters?.[key] === value,
305
+ )
306
+ ) {
307
+ delete featureInfoConfig.parameters;
308
+ }
309
+ if (
310
+ featureInfoConfig.extent &&
311
+ new Extent(featureInfoConfig.extent).equals(this.extent)
312
+ ) {
313
+ delete featureInfoConfig.extent;
314
+ }
315
+ if (this.url === featureInfoConfig.url) {
316
+ delete featureInfoConfig.url;
317
+ }
318
+ if (this.tilingSchema === featureInfoConfig.tilingSchema) {
319
+ delete featureInfoConfig.tilingSchema;
320
+ }
321
+ if (this.version === featureInfoConfig.version) {
322
+ delete featureInfoConfig.version;
323
+ }
324
+ if (this.minLevel === featureInfoConfig.minLevel) {
325
+ delete featureInfoConfig.minLevel;
326
+ }
327
+ if (this.maxLevel === featureInfoConfig.maxLevel) {
328
+ delete featureInfoConfig.maxLevel;
329
+ }
330
+
331
+ if (this._featureInfoOptions) {
332
+ delete featureInfoConfig.name;
333
+ delete featureInfoConfig.type;
334
+ }
335
+ config.featureInfo = featureInfoConfig;
336
+ } else {
337
+ config.featureInfo = this._featureInfoOptions;
302
338
  }
303
- config.featureInfo = featureInfoConfig;
304
- } else if (this._featureInfoOptions) {
305
- config.featureInfo = this._featureInfoOptions;
306
339
  }
307
340
 
308
341
  return config;
@@ -7,6 +7,7 @@ import {
7
7
  type CustomDataSource,
8
8
  type CzmlDataSource,
9
9
  Ellipsoid,
10
+ type I3SDataProvider,
10
11
  ImageryLayer,
11
12
  type ImageryLayerCollection,
12
13
  JulianDate,
@@ -47,7 +48,7 @@ function ensureInCollection<
47
48
  >(
48
49
  cesiumCollection: T,
49
50
  item: T extends PrimitiveCollection
50
- ? PrimitiveCollection | Cesium3DTileset
51
+ ? PrimitiveCollection | Cesium3DTileset | I3SDataProvider
51
52
  : ImageryLayer,
52
53
  layerCollection: LayerCollection,
53
54
  ): void {
@@ -62,7 +63,7 @@ function ensureInCollection<
62
63
  const collectionItem = cesiumCollection.get(
63
64
  i,
64
65
  ) as T extends PrimitiveCollection
65
- ? PrimitiveCollection | Cesium3DTileset
66
+ ? PrimitiveCollection | Cesium3DTileset | I3SDataProvider
66
67
  : ImageryLayer;
67
68
  if (
68
69
  (layerCollection.indexOfKey(collectionItem[vcsLayerName]) as number) >
@@ -139,7 +140,8 @@ export type CesiumVisualisationType =
139
140
  | CzmlDataSource
140
141
  | PrimitiveCollection
141
142
  | Cesium3DTileset
142
- | ImageryLayer;
143
+ | ImageryLayer
144
+ | I3SDataProvider;
143
145
 
144
146
  export default class BaseCesiumMap extends VcsMap<CesiumVisualisationType> {
145
147
  static get className(): string {
@@ -183,6 +185,22 @@ export default class BaseCesiumMap extends VcsMap<CesiumVisualisationType> {
183
185
  ),
184
186
  );
185
187
 
188
+ this._cesiumWidget.scene.frameState.creditDisplay.update = (): void => {};
189
+ this._cesiumWidget.scene.frameState.creditDisplay.beginFrame =
190
+ (): void => {};
191
+ this._cesiumWidget.scene.frameState.creditDisplay.endFrame = (): void => {};
192
+
193
+ // hide default cesium credits container
194
+ const creditsContainer = document.getElementsByClassName(
195
+ 'cesium-widget-credits',
196
+ );
197
+ if (creditsContainer) {
198
+ for (let i = 0; i < creditsContainer.length; i++) {
199
+ const element = creditsContainer[i] as HTMLElement;
200
+ element.style.display = 'none';
201
+ }
202
+ }
203
+
186
204
  this._listeners.push(
187
205
  this._cesiumWidget.scene.postRender.addEventListener(
188
206
  (eventScene: Scene, time: JulianDate) => {
@@ -465,7 +483,10 @@ export default class BaseCesiumMap extends VcsMap<CesiumVisualisationType> {
465
483
  * @param primitiveCollection
466
484
  */
467
485
  addPrimitiveCollection(
468
- primitiveCollection: PrimitiveCollection | Cesium3DTileset,
486
+ primitiveCollection:
487
+ | PrimitiveCollection
488
+ | Cesium3DTileset
489
+ | I3SDataProvider,
469
490
  ): void {
470
491
  if (!this._cesiumWidget) {
471
492
  throw new Error('Cannot add primitive to uninitialized map');
@@ -485,7 +506,10 @@ export default class BaseCesiumMap extends VcsMap<CesiumVisualisationType> {
485
506
  * @param primitiveCollection
486
507
  */
487
508
  removePrimitiveCollection(
488
- primitiveCollection: PrimitiveCollection | Cesium3DTileset,
509
+ primitiveCollection:
510
+ | PrimitiveCollection
511
+ | Cesium3DTileset
512
+ | I3SDataProvider,
489
513
  ): void {
490
514
  // XXX add destroy as boolean?
491
515
  this.removeVisualization(primitiveCollection);