@vcmap/core 6.3.0-rc.3 → 6.3.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 (80) hide show
  1. package/build/postinstall.js +16 -2
  2. package/dist/index.d.ts +3 -1
  3. package/dist/index.js +2 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/ol.d.ts +10 -1
  6. package/dist/src/featureProvider/abstractFeatureProvider.d.ts +8 -0
  7. package/dist/src/featureProvider/abstractFeatureProvider.js +10 -0
  8. package/dist/src/featureProvider/abstractFeatureProvider.js.map +1 -1
  9. package/dist/src/featureProvider/jsonAttributeProvider.d.ts +2 -1
  10. package/dist/src/featureProvider/jsonAttributeProvider.js +5 -2
  11. package/dist/src/featureProvider/jsonAttributeProvider.js.map +1 -1
  12. package/dist/src/featureProvider/mapboxFeatureProvider.d.ts +18 -0
  13. package/dist/src/featureProvider/mapboxFeatureProvider.js +49 -0
  14. package/dist/src/featureProvider/mapboxFeatureProvider.js.map +1 -0
  15. package/dist/src/featureProvider/wmsFeatureProvider.d.ts +11 -0
  16. package/dist/src/featureProvider/wmsFeatureProvider.js +19 -8
  17. package/dist/src/featureProvider/wmsFeatureProvider.js.map +1 -1
  18. package/dist/src/interaction/eventHandler.js +3 -1
  19. package/dist/src/interaction/eventHandler.js.map +1 -1
  20. package/dist/src/interaction/featureAtPixelInteraction.js +5 -0
  21. package/dist/src/interaction/featureAtPixelInteraction.js.map +1 -1
  22. package/dist/src/interaction/featureProviderInteraction.d.ts +10 -1
  23. package/dist/src/interaction/featureProviderInteraction.js +19 -3
  24. package/dist/src/interaction/featureProviderInteraction.js.map +1 -1
  25. package/dist/src/layer/cesium/mapboxStyleCesiumImpl.d.ts +25 -0
  26. package/dist/src/layer/cesium/mapboxStyleCesiumImpl.js +58 -0
  27. package/dist/src/layer/cesium/mapboxStyleCesiumImpl.js.map +1 -0
  28. package/dist/src/layer/cesium/mapboxStyleImageryProvider.d.ts +26 -0
  29. package/dist/src/layer/cesium/mapboxStyleImageryProvider.js +147 -0
  30. package/dist/src/layer/cesium/mapboxStyleImageryProvider.js.map +1 -0
  31. package/dist/src/layer/cesium/vectorTileImageryProvider.d.ts +1 -1
  32. package/dist/src/layer/cesium/vectorTileImageryProvider.js.map +1 -1
  33. package/dist/src/layer/mapboxStyleLayer.d.ts +55 -0
  34. package/dist/src/layer/mapboxStyleLayer.js +176 -0
  35. package/dist/src/layer/mapboxStyleLayer.js.map +1 -0
  36. package/dist/src/layer/openlayers/layerOpenlayersImpl.d.ts +3 -4
  37. package/dist/src/layer/openlayers/layerOpenlayersImpl.js +11 -3
  38. package/dist/src/layer/openlayers/layerOpenlayersImpl.js.map +1 -1
  39. package/dist/src/layer/openlayers/mapboxStyleOpenlayersImpl.d.ts +15 -0
  40. package/dist/src/layer/openlayers/mapboxStyleOpenlayersImpl.js +49 -0
  41. package/dist/src/layer/openlayers/mapboxStyleOpenlayersImpl.js.map +1 -0
  42. package/dist/src/layer/panoramaDatasetLayer.js +23 -6
  43. package/dist/src/layer/panoramaDatasetLayer.js.map +1 -1
  44. package/dist/src/map/baseCesiumMap.d.ts +17 -0
  45. package/dist/src/map/baseCesiumMap.js +36 -0
  46. package/dist/src/map/baseCesiumMap.js.map +1 -1
  47. package/dist/src/map/baseOLMap.d.ts +6 -4
  48. package/dist/src/map/baseOLMap.js +3 -2
  49. package/dist/src/map/baseOLMap.js.map +1 -1
  50. package/dist/src/map/cesiumMap.d.ts +3 -3
  51. package/dist/src/map/cesiumMap.js +2 -3
  52. package/dist/src/map/cesiumMap.js.map +1 -1
  53. package/dist/src/map/panoramaMap.d.ts +2 -2
  54. package/dist/src/map/panoramaMap.js +1 -2
  55. package/dist/src/map/panoramaMap.js.map +1 -1
  56. package/dist/src/map/vcsMap.d.ts +3 -3
  57. package/dist/src/map/vcsMap.js +11 -3
  58. package/dist/src/map/vcsMap.js.map +1 -1
  59. package/index.ts +3 -0
  60. package/package.json +4 -3
  61. package/src/featureProvider/abstractFeatureProvider.ts +12 -0
  62. package/src/featureProvider/jsonAttributeProvider.ts +10 -2
  63. package/src/featureProvider/mapboxFeatureProvider.ts +74 -0
  64. package/src/featureProvider/wmsFeatureProvider.ts +29 -8
  65. package/src/interaction/eventHandler.ts +3 -1
  66. package/src/interaction/featureAtPixelInteraction.ts +5 -0
  67. package/src/interaction/featureProviderInteraction.ts +37 -8
  68. package/src/layer/cesium/mapboxStyleCesiumImpl.ts +95 -0
  69. package/src/layer/cesium/mapboxStyleImageryProvider.ts +214 -0
  70. package/src/layer/cesium/vectorTileImageryProvider.ts +2 -1
  71. package/src/layer/mapboxStyleLayer.ts +244 -0
  72. package/src/layer/openlayers/layerOpenlayersImpl.ts +21 -10
  73. package/src/layer/openlayers/mapboxStyleOpenlayersImpl.ts +68 -0
  74. package/src/layer/panoramaDatasetLayer.ts +28 -8
  75. package/src/map/baseCesiumMap.ts +57 -0
  76. package/src/map/baseOLMap.ts +16 -14
  77. package/src/map/cesiumMap.ts +7 -6
  78. package/src/map/panoramaMap.ts +3 -3
  79. package/src/map/vcsMap.ts +16 -10
  80. package/src/ol/ol.d.ts +10 -1
@@ -0,0 +1,244 @@
1
+ import { SplitDirection } from '@vcmap-cesium/engine';
2
+ import { parseInteger } from '@vcsuite/parsers';
3
+ import { is } from '@vcsuite/check';
4
+ import Collection from 'ol/Collection.js';
5
+ import LayerGroup from 'ol/layer/Group.js';
6
+ import type BaseLayer from 'ol/layer/Base.js';
7
+ import { apply } from 'ol-mapbox-style';
8
+ import { layerClassRegistry } from '../classRegistry.js';
9
+ import AbstractAttributeProvider from '../featureProvider/abstractAttributeProvider.js';
10
+ import CompositeFeatureProvider from '../featureProvider/compositeFeatureProvider.js';
11
+ import MapboxFeatureProvider from '../featureProvider/mapboxFeatureProvider.js';
12
+ import type VcsMap from '../map/vcsMap.js';
13
+ import BaseCesiumMap from '../map/baseCesiumMap.js';
14
+ import CesiumMap from '../map/cesiumMap.js';
15
+ import ObliqueMap from '../map/obliqueMap.js';
16
+ import OpenlayersMap from '../map/openlayersMap.js';
17
+ import PanoramaMap from '../map/panoramaMap.js';
18
+ import VcsEvent from '../vcsEvent.js';
19
+ import MapboxVectorRasterTileCesiumImpl, {
20
+ type MapboxStyleLayerImplementationOptions,
21
+ } from './cesium/mapboxStyleCesiumImpl.js';
22
+ import Layer from './layer.js';
23
+ import type { LayerOptions, SplitLayer } from './layer.js';
24
+ import type LayerImplementation from './layerImplementation.js';
25
+ import MapboxVectorTileOpenlayersImpl from './openlayers/mapboxStyleOpenlayersImpl.js';
26
+ import { allowPicking, vcsLayerName } from './layerSymbols.js';
27
+
28
+ export type MapboxStyleOptions = LayerOptions & {
29
+ /** The sources from the Mapbox Style to use. If not provided, all sources from the style will be used. */
30
+ sources?: string[];
31
+ /** The Mapbox layers to exclude from picking. */
32
+ excludeLayerFromPicking?: string[];
33
+ /** either 'left' or 'right', none if omitted */
34
+ splitDirection?: string;
35
+ /** configures the visible level in the rendered map. Maps to Openlayers `minZoom` and Cesium `minimiumTerrainLevel` */
36
+ minRenderingLevel?: number;
37
+ /** configures the visible level in the rendered map. Maps to Openlayers `maxZoom` and Cesium `maximumTerrainLevel` */
38
+ maxRenderingLevel?: number;
39
+ };
40
+
41
+ export interface MaboxStyleImplementation extends LayerImplementation<VcsMap> {
42
+ updateSplitDirection(direction: SplitDirection): void;
43
+ }
44
+
45
+ /**
46
+ * Layer class for Mapbox Style layers.
47
+ * @group Layer
48
+ */
49
+ class MapboxStyleLayer
50
+ extends Layer<MaboxStyleImplementation>
51
+ implements SplitLayer
52
+ {
53
+ static get className(): string {
54
+ return 'MapboxStyleLayer';
55
+ }
56
+
57
+ static getDefaultOptions(): MapboxStyleOptions {
58
+ return {
59
+ ...Layer.getDefaultOptions(),
60
+ minRenderingLevel: undefined,
61
+ maxRenderingLevel: undefined,
62
+ };
63
+ }
64
+
65
+ protected _supportedMaps = [
66
+ CesiumMap.className,
67
+ ObliqueMap.className,
68
+ OpenlayersMap.className,
69
+ PanoramaMap.className,
70
+ ];
71
+ private _mapboxLayerGroup: LayerGroup;
72
+ private _sources?: string[];
73
+ private _excludeLayerFromPicking?: string[];
74
+ private _splitDirection: SplitDirection = SplitDirection.NONE;
75
+ splitDirectionChanged = new VcsEvent<SplitDirection>();
76
+ /**
77
+ * defines the visible level in the rendered map, maps to Openlayers `minZoom` and Cesium `minimiumTerrainLevel`.
78
+ * Changes requires calling layer.redraw() to take effect.
79
+ */
80
+ minRenderingLevel: number | undefined;
81
+ /**
82
+ * defines the visible level in the rendered map, maps to Openlayers `minZoom` and Cesium `minimiumTerrainLevel`.
83
+ * Changes requires calling layer.redraw() to take effect.
84
+ */
85
+ maxRenderingLevel: number | undefined;
86
+
87
+ constructor(options: MapboxStyleOptions) {
88
+ const defaultOptions = MapboxStyleLayer.getDefaultOptions();
89
+ super({ ...defaultOptions, ...options });
90
+
91
+ this._sources = options.sources;
92
+ this._excludeLayerFromPicking = options.excludeLayerFromPicking;
93
+ if (options.splitDirection) {
94
+ this._splitDirection =
95
+ options.splitDirection === 'left'
96
+ ? SplitDirection.LEFT
97
+ : SplitDirection.RIGHT;
98
+ }
99
+ this.minRenderingLevel = parseInteger(
100
+ options.minRenderingLevel,
101
+ defaultOptions.minRenderingLevel,
102
+ );
103
+ this.maxRenderingLevel = parseInteger(
104
+ options.maxRenderingLevel,
105
+ defaultOptions.maxRenderingLevel,
106
+ );
107
+
108
+ this._mapboxLayerGroup = new LayerGroup({
109
+ minZoom: this.minRenderingLevel,
110
+ maxZoom: this.maxRenderingLevel,
111
+ });
112
+ }
113
+
114
+ async initialize(): Promise<void> {
115
+ if (!this.initialized) {
116
+ await apply(this._mapboxLayerGroup, this.url);
117
+
118
+ const layers = this._mapboxLayerGroup.getLayersArray();
119
+ layers.forEach((layer) => {
120
+ layer[vcsLayerName] = this.name;
121
+ layer[allowPicking] = super.allowPicking;
122
+ });
123
+
124
+ if (this._sources && this._sources.length > 0) {
125
+ const filteredCollection = new Collection<BaseLayer>();
126
+ layers
127
+ .filter((layer) =>
128
+ this._sources!.includes(layer.get('mapbox-source') as string),
129
+ )
130
+ .forEach((layer) => {
131
+ filteredCollection.push(layer);
132
+ });
133
+
134
+ this._mapboxLayerGroup.setLayers(filteredCollection);
135
+ }
136
+ }
137
+
138
+ if (!this.featureProvider) {
139
+ this.featureProvider = new MapboxFeatureProvider({
140
+ styledMapboxLayerGroup: this._mapboxLayerGroup,
141
+ excludeLayerFromPicking: this._excludeLayerFromPicking,
142
+ });
143
+ } else if (is(this.featureProvider, AbstractAttributeProvider)) {
144
+ this.featureProvider = new CompositeFeatureProvider({
145
+ attributeProviders: [this.featureProvider],
146
+ featureProviders: [
147
+ new MapboxFeatureProvider({
148
+ styledMapboxLayerGroup: this._mapboxLayerGroup,
149
+ excludeLayerFromPicking: this._excludeLayerFromPicking,
150
+ }),
151
+ ],
152
+ });
153
+ }
154
+
155
+ await super.initialize();
156
+ }
157
+
158
+ get splitDirection(): SplitDirection {
159
+ return this._splitDirection;
160
+ }
161
+
162
+ set splitDirection(direction: SplitDirection) {
163
+ if (direction !== this._splitDirection) {
164
+ this._splitDirection = direction;
165
+ this.getImplementations().forEach((impl) => {
166
+ impl.updateSplitDirection(direction);
167
+ });
168
+ this.splitDirectionChanged.raiseEvent(this._splitDirection);
169
+ }
170
+ }
171
+
172
+ getImplementationOptions(): MapboxStyleLayerImplementationOptions {
173
+ return {
174
+ ...super.getImplementationOptions(),
175
+ styledMapboxLayerGroup: this._mapboxLayerGroup,
176
+ splitDirection: this._splitDirection,
177
+ minRenderingLevel: this.minRenderingLevel,
178
+ maxRenderingLevel: this.maxRenderingLevel,
179
+ };
180
+ }
181
+
182
+ createImplementationsForMap(map: VcsMap): MaboxStyleImplementation[] {
183
+ if (map instanceof BaseCesiumMap) {
184
+ return [
185
+ new MapboxVectorRasterTileCesiumImpl(
186
+ map,
187
+ this.getImplementationOptions(),
188
+ ),
189
+ ];
190
+ }
191
+
192
+ if (map instanceof OpenlayersMap) {
193
+ return [
194
+ new MapboxVectorTileOpenlayersImpl(
195
+ map,
196
+ this.getImplementationOptions(),
197
+ ),
198
+ ];
199
+ }
200
+ return super.createImplementationsForMap(map);
201
+ }
202
+
203
+ toJSON(
204
+ defaultOptions = MapboxStyleLayer.getDefaultOptions(),
205
+ ): MapboxStyleOptions {
206
+ const config: MapboxStyleOptions = { ...super.toJSON() };
207
+
208
+ if (this._sources && this._sources.length > 0) {
209
+ config.sources = this._sources.slice();
210
+ }
211
+
212
+ if (
213
+ this._excludeLayerFromPicking &&
214
+ this._excludeLayerFromPicking.length > 0
215
+ ) {
216
+ config.excludeLayerFromPicking = this._excludeLayerFromPicking.slice();
217
+ }
218
+
219
+ if (this._splitDirection !== SplitDirection.NONE) {
220
+ config.splitDirection =
221
+ this._splitDirection === SplitDirection.LEFT ? 'left' : 'right';
222
+ }
223
+
224
+ if (this.minRenderingLevel !== defaultOptions.minRenderingLevel) {
225
+ config.minRenderingLevel = this.minRenderingLevel;
226
+ }
227
+
228
+ if (this.maxRenderingLevel !== defaultOptions.maxRenderingLevel) {
229
+ config.maxRenderingLevel = this.maxRenderingLevel;
230
+ }
231
+
232
+ return config;
233
+ }
234
+
235
+ destroy(): void {
236
+ this.splitDirectionChanged.destroy();
237
+ this._mapboxLayerGroup.dispose();
238
+ this.featureProvider?.destroy();
239
+ super.destroy();
240
+ }
241
+ }
242
+
243
+ layerClassRegistry.registerClass(MapboxStyleLayer.className, MapboxStyleLayer);
244
+ export default MapboxStyleLayer;
@@ -1,10 +1,11 @@
1
1
  import { SplitDirection } from '@vcmap-cesium/engine';
2
2
  import { unByKey } from 'ol/Observable.js';
3
3
  import type { EventsKey } from 'ol/events.js';
4
- import type OLLayer from 'ol/layer/Layer.js';
4
+ import OLLayer from 'ol/layer/Layer.js';
5
5
  import type RenderEvent from 'ol/render/Event.js';
6
6
  import { vcsLayerName } from '../layerSymbols.js';
7
7
  import LayerImplementation from '../layerImplementation.js';
8
+ import type { OLLayerLike } from '../../map/baseOLMap.js';
8
9
  import type OpenlayersMap from '../../map/openlayersMap.js';
9
10
  import type { LayerImplementationOptions } from '../layer.js';
10
11
 
@@ -22,7 +23,7 @@ class LayerOpenlayersImpl extends LayerImplementation<OpenlayersMap> {
22
23
  return 'LayerOpenlayersImpl';
23
24
  }
24
25
 
25
- olLayer: OLLayer | null = null;
26
+ olLayer: OLLayerLike | null = null;
26
27
 
27
28
  splitDirection: SplitDirection;
28
29
 
@@ -62,10 +63,9 @@ class LayerOpenlayersImpl extends LayerImplementation<OpenlayersMap> {
62
63
 
63
64
  /**
64
65
  * returns the ol Layer
65
- * @returns {import("ol/layer").Layer<import("ol/source/Source").default>}
66
66
  */
67
67
  // eslint-disable-next-line class-methods-use-this
68
- getOLLayer(): OLLayer {
68
+ getOLLayer(): OLLayerLike {
69
69
  throw new Error();
70
70
  }
71
71
 
@@ -84,12 +84,23 @@ class LayerOpenlayersImpl extends LayerImplementation<OpenlayersMap> {
84
84
  !this._splitDirectionRenderListeners
85
85
  ) {
86
86
  this._splitDirectionRenderListeners = [];
87
- this._splitDirectionRenderListeners.push(
88
- this.olLayer!.on('prerender', this._splitPreRender.bind(this)),
89
- );
90
- this._splitDirectionRenderListeners.push(
91
- this.olLayer!.on('postrender', this._splitPostReder.bind(this)),
92
- );
87
+ if (this.olLayer instanceof OLLayer) {
88
+ this._splitDirectionRenderListeners.push(
89
+ this.olLayer.on('prerender', this._splitPreRender.bind(this)),
90
+ );
91
+ this._splitDirectionRenderListeners.push(
92
+ this.olLayer.on('postrender', this._splitPostReder.bind(this)),
93
+ );
94
+ } else {
95
+ this.olLayer!.getLayersArray().forEach((layer) => {
96
+ this._splitDirectionRenderListeners!.push(
97
+ layer.on('prerender', this._splitPreRender.bind(this)),
98
+ );
99
+ this._splitDirectionRenderListeners!.push(
100
+ layer.on('postrender', this._splitPostReder.bind(this)),
101
+ );
102
+ });
103
+ }
93
104
  this.olLayer!.changed();
94
105
  }
95
106
  }
@@ -0,0 +1,68 @@
1
+ import type LayerGroup from 'ol/layer/Group.js';
2
+ import { SplitDirection } from '@vcmap-cesium/engine';
3
+ import { unByKey } from 'ol/Observable.js';
4
+ import type { EventsKey } from 'ol/events.js';
5
+ import type OpenlayersMap from '../../map/openlayersMap.js';
6
+ import type { MapboxStyleLayerImplementationOptions } from '../cesium/mapboxStyleCesiumImpl.js';
7
+ import type { OLLayerLike } from '../../map/baseOLMap.js';
8
+ import LayerOpenlayersImpl from './layerOpenlayersImpl.js';
9
+
10
+ class MapboxVectorTileOpenlayersImpl extends LayerOpenlayersImpl {
11
+ static get className(): string {
12
+ return 'MapboxVectorTileOpenlayersImpl';
13
+ }
14
+
15
+ private _styledMapboxLayerGroup: LayerGroup;
16
+
17
+ private _removeChildLayerListeners: (() => void) | null = null;
18
+
19
+ constructor(
20
+ map: OpenlayersMap,
21
+ options: MapboxStyleLayerImplementationOptions,
22
+ ) {
23
+ super(map, options);
24
+ this._styledMapboxLayerGroup = options.styledMapboxLayerGroup;
25
+ }
26
+
27
+ getOLLayer(): OLLayerLike {
28
+ return this._styledMapboxLayerGroup as OLLayerLike;
29
+ }
30
+
31
+ updateSplitDirection(splitDirection: SplitDirection): void {
32
+ this.splitDirection = splitDirection;
33
+ if (this.initialized) {
34
+ this._removeChildLayerListeners?.();
35
+ this._removeChildLayerListeners = null;
36
+
37
+ if (splitDirection !== SplitDirection.NONE) {
38
+ const childLayers = this._styledMapboxLayerGroup.getLayersArray();
39
+ const listenerKeys: EventsKey[] = [];
40
+ childLayers.forEach((layer) => {
41
+ listenerKeys.push(
42
+ layer.on('prerender', this._splitPreRender.bind(this)),
43
+ );
44
+ listenerKeys.push(
45
+ layer.on('postrender', this._splitPostReder.bind(this)),
46
+ );
47
+ layer.changed();
48
+ });
49
+ this._removeChildLayerListeners = (): void => {
50
+ unByKey(listenerKeys);
51
+ };
52
+ } else {
53
+ const childLayers = this._styledMapboxLayerGroup.getLayersArray();
54
+ childLayers.forEach((layer) => {
55
+ layer.changed();
56
+ });
57
+ }
58
+ }
59
+ }
60
+
61
+ destroy(): void {
62
+ this._removeChildLayerListeners?.();
63
+ this._removeChildLayerListeners = null;
64
+ super.destroy();
65
+ }
66
+ }
67
+
68
+ export default MapboxVectorTileOpenlayersImpl;
@@ -140,9 +140,17 @@ export default class PanoramaDatasetLayer extends VectorTileLayer<PanoramaDatase
140
140
  defaultOptions.panoramaVectorProperties!,
141
141
  );
142
142
  if (options.panoramaVectorProperties) {
143
- this._panoramaVectorProperties.setValues(
144
- options.panoramaVectorProperties,
145
- );
143
+ const panoramaVectorPropertiesOptions =
144
+ options.panoramaVectorProperties.primitiveOptions == null
145
+ ? options.panoramaVectorProperties
146
+ : {
147
+ ...options.panoramaVectorProperties,
148
+ primitiveOptions: {
149
+ offset: [0, 0, this.cameraOffset],
150
+ ...options.panoramaVectorProperties.primitiveOptions,
151
+ },
152
+ };
153
+ this._panoramaVectorProperties.setValues(panoramaVectorPropertiesOptions);
146
154
  }
147
155
 
148
156
  this._supportedMaps.push(PanoramaMap.className);
@@ -289,16 +297,28 @@ export default class PanoramaDatasetLayer extends VectorTileLayer<PanoramaDatase
289
297
  delete config.zIndex;
290
298
  }
291
299
 
292
- defaultOptions.panoramaVectorProperties!.primitiveOptions!.offset = [
293
- 0,
294
- 0,
295
- this.cameraOffset,
296
- ];
300
+ const defaultPanoramaPrimitiveOptions =
301
+ defaultOptions.panoramaVectorProperties!.primitiveOptions!;
297
302
  const vectorPropertiesConfig = this._panoramaVectorProperties.getVcsMeta({
298
303
  ...VectorProperties.getDefaultOptions(),
299
304
  ...defaultOptions.panoramaVectorProperties,
305
+ primitiveOptions: {
306
+ offset: [0, 0, this.cameraOffset],
307
+ ...defaultPanoramaPrimitiveOptions,
308
+ },
300
309
  });
301
310
 
311
+ if (
312
+ vectorPropertiesConfig.primitiveOptions?.offset?.[0] === 0 &&
313
+ vectorPropertiesConfig.primitiveOptions?.offset?.[1] === 0 &&
314
+ vectorPropertiesConfig.primitiveOptions?.offset?.[2] === this.cameraOffset
315
+ ) {
316
+ delete vectorPropertiesConfig.primitiveOptions.offset;
317
+ if (Object.keys(vectorPropertiesConfig.primitiveOptions).length === 0) {
318
+ delete vectorPropertiesConfig.primitiveOptions;
319
+ }
320
+ }
321
+
302
322
  if (Object.keys(vectorPropertiesConfig).length > 0) {
303
323
  config.panoramaVectorProperties = vectorPropertiesConfig;
304
324
  }
@@ -21,7 +21,9 @@ import {
21
21
  ScreenSpaceEventType,
22
22
  type TerrainProvider,
23
23
  } from '@vcmap-cesium/engine';
24
+ import { parseBoolean } from '@vcsuite/parsers';
24
25
  import type { Coordinate } from 'ol/coordinate.js';
26
+ import type { VcsMapOptions } from './vcsMap.js';
25
27
  import VcsMap from './vcsMap.js';
26
28
  import type Layer from '../layer/layer.js';
27
29
  import type LayerCollection from '../util/layerCollection.js';
@@ -36,6 +38,13 @@ import Projection from '../util/projection.js';
36
38
 
37
39
  RequestScheduler.maximumRequestsPerServer = 12;
38
40
 
41
+ export type BaseCesiumMapOptions = VcsMapOptions & {
42
+ /**
43
+ * If true, ancestors will be preloaded
44
+ */
45
+ preloadAncestors?: boolean;
46
+ };
47
+
39
48
  /**
40
49
  * Ensures, a primitive/imageryLayer/entity is part of a collection and placed at the correct location
41
50
  * @param cesiumCollection
@@ -148,18 +157,48 @@ export default class BaseCesiumMap extends VcsMap<CesiumVisualisationType> {
148
157
  return 'BaseCesiumMap';
149
158
  }
150
159
 
160
+ static getDefaultOptions(): BaseCesiumMapOptions {
161
+ return {
162
+ ...VcsMap.getDefaultOptions(),
163
+ preloadAncestors: false,
164
+ };
165
+ }
166
+
151
167
  protected _cesiumWidget: CesiumWidget | null = null;
152
168
 
153
169
  protected _terrainProvider: TerrainProvider | null | undefined = null;
154
170
 
155
171
  private _screenSpaceListener: (() => void) | undefined;
156
172
 
173
+ private _preloadAncestors = false;
174
+
157
175
  screenSpaceEventHandler: ScreenSpaceEventHandler | null = null;
158
176
 
159
177
  defaultTerrainProvider: TerrainProvider | null = null;
160
178
 
161
179
  protected _listeners: (() => void)[] = [];
162
180
 
181
+ constructor(options: BaseCesiumMapOptions) {
182
+ const defaultOptions = BaseCesiumMap.getDefaultOptions();
183
+ super({ ...defaultOptions, ...options });
184
+
185
+ this._preloadAncestors = parseBoolean(
186
+ options.preloadAncestors,
187
+ defaultOptions.preloadAncestors,
188
+ );
189
+ }
190
+
191
+ get preloadAncestors(): boolean {
192
+ return this._preloadAncestors;
193
+ }
194
+
195
+ set preloadAncestors(value: boolean) {
196
+ this._preloadAncestors = value;
197
+ if (this._cesiumWidget) {
198
+ this._cesiumWidget.scene.globe.preloadAncestors = value;
199
+ }
200
+ }
201
+
163
202
  get terrainProvider(): TerrainProvider | null | undefined {
164
203
  return this._terrainProvider;
165
204
  }
@@ -185,6 +224,7 @@ export default class BaseCesiumMap extends VcsMap<CesiumVisualisationType> {
185
224
  ),
186
225
  );
187
226
 
227
+ this._cesiumWidget.scene.globe.preloadAncestors = this.preloadAncestors;
188
228
  this._cesiumWidget.scene.frameState.creditDisplay.update = (): void => {};
189
229
  this._cesiumWidget.scene.frameState.creditDisplay.beginFrame =
190
230
  (): void => {};
@@ -453,6 +493,13 @@ export default class BaseCesiumMap extends VcsMap<CesiumVisualisationType> {
453
493
  return this._cesiumWidget?.scene;
454
494
  }
455
495
 
496
+ /**
497
+ * defines whether ancestors are preloaded or not
498
+ */
499
+ setPreloadAncestors(value: boolean): void {
500
+ this.preloadAncestors = value;
501
+ }
502
+
456
503
  protected _indexChangedOnVisualization(vis: CesiumVisualisationType): void {
457
504
  if (vis instanceof PrimitiveCollection) {
458
505
  indexChangedOnPrimitive(
@@ -579,6 +626,16 @@ export default class BaseCesiumMap extends VcsMap<CesiumVisualisationType> {
579
626
  }
580
627
  }
581
628
 
629
+ toJSON(
630
+ defaultOptions = BaseCesiumMap.getDefaultOptions(),
631
+ ): BaseCesiumMapOptions {
632
+ const config: BaseCesiumMapOptions = super.toJSON(defaultOptions);
633
+ if (this.preloadAncestors !== defaultOptions.preloadAncestors) {
634
+ config.preloadAncestors = this.preloadAncestors;
635
+ }
636
+ return config;
637
+ }
638
+
582
639
  override destroy(): void {
583
640
  this._listeners.forEach((cb) => {
584
641
  cb();
@@ -1,12 +1,12 @@
1
1
  import { Cartesian2 } from '@vcmap-cesium/engine';
2
2
  import { unByKey } from 'ol/Observable.js';
3
3
  import OLMap from 'ol/Map.js';
4
+ import type OLLayer from 'ol/layer/Layer.js';
5
+ import type OLLayerGroup from 'ol/layer/Group.js';
4
6
  import { defaults as defaultInteractions } from 'ol/interaction.js';
5
7
  import type { Collection as OLCollection, MapBrowserEvent } from 'ol';
6
- import type { Layer as OLLayer } from 'ol/layer.js';
7
8
  import type { EventsKey } from 'ol/events.js';
8
9
  import type { Coordinate } from 'ol/coordinate.js';
9
-
10
10
  import VcsMap from './vcsMap.js';
11
11
  import { vcsLayerName } from '../layer/layerSymbols.js';
12
12
  import {
@@ -20,22 +20,24 @@ import type Layer from '../layer/layer.js';
20
20
  import type { DisableMapControlOptions } from '../util/mapCollection.js';
21
21
  import { vectorClusterGroupName } from '../vectorCluster/vectorClusterSymbols.js';
22
22
 
23
+ export type OLLayerLike = OLLayer | OLLayerGroup;
24
+
23
25
  function ensureLayerInCollection(
24
- layers: OLCollection<OLLayer>,
25
- layer: OLLayer,
26
+ layers: OLCollection<OLLayerLike>,
27
+ layer: OLLayerLike,
26
28
  layerCollection: LayerCollection,
27
29
  ): void {
28
30
  const sortedVectorClusterGroups = [
29
31
  ...layerCollection.vectorClusterGroups,
30
32
  ].sort((a, b) => a.zIndex - b.zIndex);
31
33
 
32
- const getIndexOfOlLayer = (olL: OLLayer): number => {
34
+ const getIndexOfOlLayer = (olL: OLLayerLike): number => {
33
35
  let layerIndex;
34
36
  let clusterIndex = 0;
35
- if (olL[vectorClusterGroupName]) {
36
- const clusterGroup = layerCollection.vectorClusterGroups.getByKey(
37
- olL[vectorClusterGroupName],
38
- )!;
37
+ const clusterName = (olL as OLLayer)[vectorClusterGroupName];
38
+ if (clusterName) {
39
+ const clusterGroup =
40
+ layerCollection.vectorClusterGroups.getByKey(clusterName)!;
39
41
  layerIndex = layerCollection.findIndex(
40
42
  (l) => l.zIndex > clusterGroup.zIndex,
41
43
  );
@@ -90,7 +92,7 @@ function getPointerKeyType(button?: number): PointerKeyType {
90
92
  /**
91
93
  * @group Map
92
94
  */
93
- class BaseOLMap extends VcsMap<OLLayer> {
95
+ class BaseOLMap extends VcsMap<OLLayerLike> {
94
96
  static get className(): string {
95
97
  return 'BaseOLMap';
96
98
  }
@@ -214,7 +216,7 @@ class BaseOLMap extends VcsMap<OLLayer> {
214
216
  const layers = (this._olMap as OLMap).getLayers();
215
217
  layers.remove(olLayer);
216
218
  ensureLayerInCollection(
217
- layers as OLCollection<OLLayer>,
219
+ layers as OLCollection<OLLayerLike>,
218
220
  olLayer,
219
221
  this.layerCollection,
220
222
  );
@@ -226,11 +228,11 @@ class BaseOLMap extends VcsMap<OLLayer> {
226
228
  * Internal API for registering representations.
227
229
  * @param olLayer
228
230
  */
229
- addOLLayer(olLayer: OLLayer): void {
231
+ addOLLayer(olLayer: OLLayerLike): void {
230
232
  if (this.validateVisualization(olLayer)) {
231
233
  this.addVisualization(olLayer);
232
234
  ensureLayerInCollection(
233
- (this._olMap as OLMap).getLayers() as OLCollection<OLLayer>,
235
+ (this._olMap as OLMap).getLayers() as OLCollection<OLLayerLike>,
234
236
  olLayer,
235
237
  this.layerCollection,
236
238
  );
@@ -240,7 +242,7 @@ class BaseOLMap extends VcsMap<OLLayer> {
240
242
  /**
241
243
  * Internal API for deregistering representations.
242
244
  */
243
- removeOLLayer(olLayer: OLLayer): void {
245
+ removeOLLayer(olLayer: OLLayerLike): void {
244
246
  this.removeVisualization(olLayer);
245
247
  if (this._olMap) {
246
248
  this._olMap.getLayers().remove(olLayer);
@@ -29,7 +29,11 @@ import {
29
29
  import type { Coordinate } from 'ol/coordinate.js';
30
30
  import { check, maybe } from '@vcsuite/check';
31
31
  import { parseBoolean, parseInteger, parseNumber } from '@vcsuite/parsers';
32
- import VcsMap, { type VcsMapOptions } from './vcsMap.js';
32
+ import type {
33
+ BaseCesiumMapOptions,
34
+ CesiumVisualisationType,
35
+ } from './baseCesiumMap.js';
36
+ import BaseCesiumMap from './baseCesiumMap.js';
33
37
  import type Viewpoint from '../util/viewpoint.js';
34
38
  import Projection, { mercatorProjection } from '../util/projection.js';
35
39
  import { getHeightFromTerrainProvider } from '../layer/terrainHelpers.js';
@@ -41,9 +45,6 @@ import type LayerCollection from '../util/layerCollection.js';
41
45
  import VcsEvent from '../vcsEvent.js';
42
46
  import type { DisableMapControlOptions } from '../util/mapCollection.js';
43
47
  import { vectorClusterGroupName } from '../vectorCluster/vectorClusterSymbols.js';
44
- import BaseCesiumMap, {
45
- type CesiumVisualisationType,
46
- } from './baseCesiumMap.js';
47
48
 
48
49
  /**
49
50
  * @param dataSourceCollection
@@ -120,7 +121,7 @@ function indexChangedOnDataSource(
120
121
  );
121
122
  }
122
123
 
123
- export type CesiumMapOptions = VcsMapOptions & {
124
+ export type CesiumMapOptions = BaseCesiumMapOptions & {
124
125
  /**
125
126
  * if true, lighting will be activated.
126
127
  */
@@ -203,7 +204,7 @@ class CesiumMap extends BaseCesiumMap {
203
204
 
204
205
  static getDefaultOptions(): CesiumMapOptions {
205
206
  return {
206
- ...VcsMap.getDefaultOptions(),
207
+ ...BaseCesiumMap.getDefaultOptions(),
207
208
  enableLightning: true,
208
209
  tileCacheSize: 1,
209
210
  webGLaa: false,