@vcmap/core 6.0.7 → 6.1.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.
- package/dist/cesium.d.ts +3 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/ol.d.ts +8 -1
- package/dist/src/featureProvider/featureProviderSymbols.d.ts +5 -0
- package/dist/src/featureProvider/featureProviderSymbols.js +5 -1
- package/dist/src/featureProvider/featureProviderSymbols.js.map +1 -1
- package/dist/src/interaction/featureAtPixelInteraction.js +58 -62
- package/dist/src/interaction/featureAtPixelInteraction.js.map +1 -1
- package/dist/src/interaction/featureProviderInteraction.js +25 -13
- package/dist/src/interaction/featureProviderInteraction.js.map +1 -1
- package/dist/src/layer/cesium/sourceVectorContextSync.d.ts +27 -0
- package/dist/src/layer/cesium/sourceVectorContextSync.js +94 -0
- package/dist/src/layer/cesium/sourceVectorContextSync.js.map +1 -0
- package/dist/src/layer/cesium/vectorCesiumImpl.d.ts +4 -27
- package/dist/src/layer/cesium/vectorCesiumImpl.js +15 -107
- package/dist/src/layer/cesium/vectorCesiumImpl.js.map +1 -1
- package/dist/src/layer/cesium/vectorContext.d.ts +12 -1
- package/dist/src/layer/cesium/vectorContext.js +6 -0
- package/dist/src/layer/cesium/vectorContext.js.map +1 -1
- package/dist/src/layer/layerSymbols.js +1 -1
- package/dist/src/layer/layerSymbols.js.map +1 -1
- package/dist/src/layer/oblique/sourceObliqueSync.d.ts +18 -0
- package/dist/src/layer/oblique/sourceObliqueSync.js +319 -0
- package/dist/src/layer/oblique/sourceObliqueSync.js.map +1 -0
- package/dist/src/layer/oblique/vectorObliqueImpl.d.ts +2 -40
- package/dist/src/layer/oblique/vectorObliqueImpl.js +8 -283
- package/dist/src/layer/oblique/vectorObliqueImpl.js.map +1 -1
- package/dist/src/layer/vectorLayer.d.ts +10 -1
- package/dist/src/layer/vectorLayer.js +23 -1
- package/dist/src/layer/vectorLayer.js.map +1 -1
- package/dist/src/map/baseOLMap.js +8 -1
- package/dist/src/map/baseOLMap.js.map +1 -1
- package/dist/src/map/cesiumMap.d.ts +2 -0
- package/dist/src/map/cesiumMap.js +26 -1
- package/dist/src/map/cesiumMap.js.map +1 -1
- package/dist/src/map/vcsMap.d.ts +24 -12
- package/dist/src/map/vcsMap.js +92 -38
- package/dist/src/map/vcsMap.js.map +1 -1
- package/dist/src/ol/source/ClusterEnhancedVectorSource.d.ts +6 -4
- package/dist/src/ol/source/ClusterEnhancedVectorSource.js +4 -9
- package/dist/src/ol/source/ClusterEnhancedVectorSource.js.map +1 -1
- package/dist/src/ol/source/VcsCluster.d.ts +10 -10
- package/dist/src/ol/source/VcsCluster.js +23 -7
- package/dist/src/ol/source/VcsCluster.js.map +1 -1
- package/dist/src/util/clipping/clippingPolygonHelper.d.ts +7 -0
- package/dist/src/util/clipping/clippingPolygonHelper.js +53 -0
- package/dist/src/util/clipping/clippingPolygonHelper.js.map +1 -0
- package/dist/src/util/clipping/clippingPolygonObject.d.ts +59 -0
- package/dist/src/util/clipping/clippingPolygonObject.js +158 -0
- package/dist/src/util/clipping/clippingPolygonObject.js.map +1 -0
- package/dist/src/util/clipping/clippingPolygonObjectCollection.d.ts +18 -0
- package/dist/src/util/clipping/clippingPolygonObjectCollection.js +167 -0
- package/dist/src/util/clipping/clippingPolygonObjectCollection.js.map +1 -0
- package/dist/src/util/layerCollection.d.ts +11 -1
- package/dist/src/util/layerCollection.js +67 -12
- package/dist/src/util/layerCollection.js.map +1 -1
- package/dist/src/util/mapCollection.d.ts +16 -1
- package/dist/src/util/mapCollection.js +37 -3
- package/dist/src/util/mapCollection.js.map +1 -1
- package/dist/src/util/renderScreenshot.d.ts +9 -0
- package/dist/src/util/renderScreenshot.js +162 -0
- package/dist/src/util/renderScreenshot.js.map +1 -0
- package/dist/src/util/rotation.d.ts +30 -0
- package/dist/src/util/rotation.js +145 -0
- package/dist/src/util/rotation.js.map +1 -0
- package/dist/src/util/vcsTemplate.d.ts +7 -0
- package/dist/src/util/vcsTemplate.js +248 -0
- package/dist/src/util/vcsTemplate.js.map +1 -0
- package/dist/src/vcsApp.d.ts +7 -0
- package/dist/src/vcsApp.js +29 -0
- package/dist/src/vcsApp.js.map +1 -1
- package/dist/src/vcsModule.d.ts +6 -2
- package/dist/src/vcsModule.js.map +1 -1
- package/dist/src/vectorCluster/vectorClusterCesiumContext.d.ts +18 -0
- package/dist/src/{layer/cesium/clusterContext.js → vectorCluster/vectorClusterCesiumContext.js} +28 -42
- package/dist/src/vectorCluster/vectorClusterCesiumContext.js.map +1 -0
- package/dist/src/vectorCluster/vectorClusterGroup.d.ts +96 -0
- package/dist/src/vectorCluster/vectorClusterGroup.js +320 -0
- package/dist/src/vectorCluster/vectorClusterGroup.js.map +1 -0
- package/dist/src/vectorCluster/vectorClusterGroupCesiumImpl.d.ts +20 -0
- package/dist/src/vectorCluster/vectorClusterGroupCesiumImpl.js +115 -0
- package/dist/src/vectorCluster/vectorClusterGroupCesiumImpl.js.map +1 -0
- package/dist/src/vectorCluster/vectorClusterGroupCollection.d.ts +19 -0
- package/dist/src/vectorCluster/vectorClusterGroupCollection.js +37 -0
- package/dist/src/vectorCluster/vectorClusterGroupCollection.js.map +1 -0
- package/dist/src/vectorCluster/vectorClusterGroupImpl.d.ts +31 -0
- package/dist/src/vectorCluster/vectorClusterGroupImpl.js +76 -0
- package/dist/src/vectorCluster/vectorClusterGroupImpl.js.map +1 -0
- package/dist/src/vectorCluster/vectorClusterGroupObliqueImpl.d.ts +17 -0
- package/dist/src/vectorCluster/vectorClusterGroupObliqueImpl.js +62 -0
- package/dist/src/vectorCluster/vectorClusterGroupObliqueImpl.js.map +1 -0
- package/dist/src/vectorCluster/vectorClusterGroupOpenlayersImpl.d.ts +17 -0
- package/dist/src/vectorCluster/vectorClusterGroupOpenlayersImpl.js +62 -0
- package/dist/src/vectorCluster/vectorClusterGroupOpenlayersImpl.js.map +1 -0
- package/dist/src/vectorCluster/vectorClusterStyleItem.d.ts +110 -0
- package/dist/src/vectorCluster/vectorClusterStyleItem.js +374 -0
- package/dist/src/vectorCluster/vectorClusterStyleItem.js.map +1 -0
- package/dist/src/vectorCluster/vectorClusterSymbols.d.ts +1 -0
- package/dist/src/vectorCluster/vectorClusterSymbols.js +3 -0
- package/dist/src/vectorCluster/vectorClusterSymbols.js.map +1 -0
- package/index.ts +42 -1
- package/package.json +3 -1
- package/src/cesium/cesium.d.ts +3 -0
- package/src/featureProvider/featureProviderSymbols.ts +6 -1
- package/src/interaction/featureAtPixelInteraction.ts +109 -84
- package/src/interaction/featureProviderInteraction.ts +42 -28
- package/src/layer/cesium/sourceVectorContextSync.ts +134 -0
- package/src/layer/cesium/vcsTile/vcsDebugTile.ts +1 -1
- package/src/layer/cesium/vcsTile/vcsVectorTile.ts +1 -1
- package/src/layer/cesium/vectorCesiumImpl.ts +30 -144
- package/src/layer/cesium/vectorContext.ts +17 -1
- package/src/layer/layerSymbols.ts +1 -1
- package/src/layer/oblique/sourceObliqueSync.ts +436 -0
- package/src/layer/oblique/vectorObliqueImpl.ts +11 -397
- package/src/layer/vectorLayer.ts +35 -2
- package/src/map/baseOLMap.ts +8 -1
- package/src/map/cesiumMap.ts +36 -3
- package/src/map/vcsMap.ts +121 -47
- package/src/ol/ol.d.ts +8 -1
- package/src/ol/source/{ClusterEnhancedVectorSource.js → ClusterEnhancedVectorSource.ts} +7 -10
- package/src/ol/source/VcsCluster.ts +58 -0
- package/src/util/clipping/clippingPolygonHelper.ts +86 -0
- package/src/util/clipping/clippingPolygonObject.ts +223 -0
- package/src/util/clipping/clippingPolygonObjectCollection.ts +249 -0
- package/src/util/layerCollection.ts +90 -12
- package/src/util/mapCollection.ts +53 -2
- package/src/util/renderScreenshot.ts +193 -0
- package/src/util/rotation.ts +215 -0
- package/src/util/vcsTemplate.ts +373 -0
- package/src/vcsApp.ts +65 -0
- package/src/vcsModule.ts +6 -2
- package/src/vectorCluster/vectorClusterCesiumContext.ts +123 -0
- package/src/vectorCluster/vectorClusterGroup.ts +463 -0
- package/src/vectorCluster/vectorClusterGroupCesiumImpl.ts +176 -0
- package/src/vectorCluster/vectorClusterGroupCollection.ts +43 -0
- package/src/vectorCluster/vectorClusterGroupImpl.ts +107 -0
- package/src/vectorCluster/vectorClusterGroupObliqueImpl.ts +84 -0
- package/src/vectorCluster/vectorClusterGroupOpenlayersImpl.ts +81 -0
- package/src/vectorCluster/vectorClusterStyleItem.ts +490 -0
- package/src/vectorCluster/vectorClusterSymbols.ts +2 -0
- package/dist/src/layer/cesium/clusterContext.d.ts +0 -20
- package/dist/src/layer/cesium/clusterContext.js.map +0 -1
- package/src/layer/cesium/clusterContext.ts +0 -140
- package/src/ol/source/VcsCluster.js +0 -37
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import deepEqual from 'fast-deep-equal';
|
|
2
|
+
import { Coordinate } from 'ol/coordinate.js';
|
|
3
|
+
import { Feature } from 'ol';
|
|
4
|
+
import { Polygon } from 'ol/geom.js';
|
|
5
|
+
import { check, oneOf } from '@vcsuite/check';
|
|
6
|
+
import { parseBoolean } from '@vcsuite/parsers';
|
|
7
|
+
import { getLogger } from '@vcsuite/logger';
|
|
8
|
+
import { Cartesian3, ClippingPolygon } from '@vcmap-cesium/engine';
|
|
9
|
+
import VcsObject, { VcsObjectOptions } from '../../vcsObject.js';
|
|
10
|
+
import VcsEvent from '../../vcsEvent.js';
|
|
11
|
+
|
|
12
|
+
export enum ClippingPolygonObjectState {
|
|
13
|
+
INACTIVE = 1,
|
|
14
|
+
ACTIVE = 2,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type ClippingPolygonObjectOptions = VcsObjectOptions & {
|
|
18
|
+
layerNames?: string[] | 'all';
|
|
19
|
+
terrain?: boolean;
|
|
20
|
+
activeOnStartup?: boolean;
|
|
21
|
+
coordinates: Array<Coordinate>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
function getLayerNamesClone(layerNames: string[] | 'all'): string[] | 'all' {
|
|
25
|
+
return Array.isArray(layerNames) ? layerNames.slice() : layerNames;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
class ClippingPolygonObject extends VcsObject {
|
|
29
|
+
static get className(): string {
|
|
30
|
+
return 'ClippingPolygonObject';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static getDefaultOptions(): ClippingPolygonObjectOptions {
|
|
34
|
+
return {
|
|
35
|
+
activeOnStartup: false,
|
|
36
|
+
layerNames: 'all',
|
|
37
|
+
terrain: false,
|
|
38
|
+
coordinates: [],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static fromFeature(feature: Feature<Polygon>): ClippingPolygonObject | null {
|
|
43
|
+
const geometry = feature.getGeometry();
|
|
44
|
+
if (geometry instanceof Polygon) {
|
|
45
|
+
return ClippingPolygonObject.fromGeometry(geometry);
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static fromGeometry(geometry: Polygon): ClippingPolygonObject {
|
|
51
|
+
check(geometry, Polygon);
|
|
52
|
+
const ring = geometry.getLinearRing(0)!;
|
|
53
|
+
const coordinates = ring.getCoordinates();
|
|
54
|
+
return new ClippingPolygonObject({ coordinates });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
activeOnStartup: boolean;
|
|
58
|
+
|
|
59
|
+
private _state: ClippingPolygonObjectState;
|
|
60
|
+
|
|
61
|
+
stateChanged = new VcsEvent<ClippingPolygonObjectState>();
|
|
62
|
+
|
|
63
|
+
private _layerNames: string[] | 'all';
|
|
64
|
+
|
|
65
|
+
private _terrain: boolean;
|
|
66
|
+
|
|
67
|
+
private _coordinates: Array<Coordinate> = [];
|
|
68
|
+
|
|
69
|
+
private _clippingPolygon: ClippingPolygon | undefined = undefined;
|
|
70
|
+
|
|
71
|
+
clippingPolygonChanged = new VcsEvent<{
|
|
72
|
+
newValue: ClippingPolygon;
|
|
73
|
+
oldValue: ClippingPolygon | undefined;
|
|
74
|
+
}>();
|
|
75
|
+
|
|
76
|
+
layersChanged = new VcsEvent<{
|
|
77
|
+
newValue: string[] | 'all';
|
|
78
|
+
oldValue: string[] | 'all';
|
|
79
|
+
}>();
|
|
80
|
+
|
|
81
|
+
terrainChanged = new VcsEvent<boolean>();
|
|
82
|
+
|
|
83
|
+
constructor(options: ClippingPolygonObjectOptions) {
|
|
84
|
+
super(options);
|
|
85
|
+
const defaultOptions = ClippingPolygonObject.getDefaultOptions();
|
|
86
|
+
|
|
87
|
+
this.activeOnStartup = parseBoolean(
|
|
88
|
+
options.activeOnStartup,
|
|
89
|
+
defaultOptions.activeOnStartup,
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
this._state = ClippingPolygonObjectState.INACTIVE;
|
|
93
|
+
|
|
94
|
+
this._layerNames = options.layerNames || defaultOptions.layerNames!;
|
|
95
|
+
|
|
96
|
+
this._terrain = parseBoolean(options.terrain, defaultOptions.terrain);
|
|
97
|
+
|
|
98
|
+
this.setCoordinates(options.coordinates || defaultOptions.coordinates);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Whether the clipping polygon object is active or not
|
|
103
|
+
*/
|
|
104
|
+
get active(): boolean {
|
|
105
|
+
return this._state === ClippingPolygonObjectState.ACTIVE;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
get layerNames(): string[] | 'all' {
|
|
109
|
+
return this._layerNames;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
get terrain(): boolean {
|
|
113
|
+
return this._terrain;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
set terrain(terrain: boolean) {
|
|
117
|
+
check(terrain, Boolean);
|
|
118
|
+
|
|
119
|
+
if (this._terrain !== terrain) {
|
|
120
|
+
this._terrain = terrain;
|
|
121
|
+
this.terrainChanged.raiseEvent(this._terrain);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
get clippingPolygon(): ClippingPolygon | undefined {
|
|
126
|
+
return this._clippingPolygon;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
get coordinates(): readonly Readonly<Coordinate>[] {
|
|
130
|
+
return this._coordinates;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Set polygon coordinates from an array of geographic wgs84 coordinates
|
|
135
|
+
* @param coordinates
|
|
136
|
+
*/
|
|
137
|
+
setCoordinates(coordinates: Coordinate[]): void {
|
|
138
|
+
check(coordinates, [[Number]]);
|
|
139
|
+
|
|
140
|
+
if (coordinates.length < 3) {
|
|
141
|
+
getLogger('ClippingPolygonObject').error(
|
|
142
|
+
'At least 3 coordinates are required!',
|
|
143
|
+
);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (deepEqual(this._coordinates, coordinates)) {
|
|
148
|
+
getLogger('ClippingPolygonObject').error(
|
|
149
|
+
'The provided coordinates are already set!',
|
|
150
|
+
);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const positions = coordinates.map((c) => {
|
|
155
|
+
return Cartesian3.fromDegrees(c[0], c[1], c[2]);
|
|
156
|
+
});
|
|
157
|
+
this._coordinates = structuredClone(coordinates);
|
|
158
|
+
|
|
159
|
+
const oldValue = this._clippingPolygon;
|
|
160
|
+
const newValue = new ClippingPolygon({ positions });
|
|
161
|
+
this._clippingPolygon = newValue;
|
|
162
|
+
this.clippingPolygonChanged.raiseEvent({ oldValue, newValue });
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
setLayerNames(layerNames: string[] | 'all'): void {
|
|
166
|
+
check(layerNames, oneOf([String], 'all'));
|
|
167
|
+
|
|
168
|
+
if (!deepEqual(this._layerNames, layerNames)) {
|
|
169
|
+
const oldValue = this._layerNames;
|
|
170
|
+
this._layerNames = getLayerNamesClone(layerNames);
|
|
171
|
+
this.layersChanged.raiseEvent({
|
|
172
|
+
newValue: layerNames,
|
|
173
|
+
oldValue,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
activate(): void {
|
|
179
|
+
if (this._state === ClippingPolygonObjectState.INACTIVE) {
|
|
180
|
+
this._state = ClippingPolygonObjectState.ACTIVE;
|
|
181
|
+
this.stateChanged.raiseEvent(this._state);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
deactivate(): void {
|
|
186
|
+
if (this._state === ClippingPolygonObjectState.ACTIVE) {
|
|
187
|
+
this._state = ClippingPolygonObjectState.INACTIVE;
|
|
188
|
+
this.stateChanged.raiseEvent(this._state);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
toJSON(): ClippingPolygonObjectOptions {
|
|
193
|
+
const config: ClippingPolygonObjectOptions = {
|
|
194
|
+
...super.toJSON(),
|
|
195
|
+
coordinates: structuredClone(this._coordinates),
|
|
196
|
+
};
|
|
197
|
+
const defaultOptions = ClippingPolygonObject.getDefaultOptions();
|
|
198
|
+
|
|
199
|
+
if (!deepEqual(this._layerNames, defaultOptions.layerNames)) {
|
|
200
|
+
config.layerNames = getLayerNamesClone(this._layerNames);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (this._terrain !== defaultOptions.terrain) {
|
|
204
|
+
config.terrain = this._terrain;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (this.activeOnStartup !== defaultOptions.activeOnStartup) {
|
|
208
|
+
config.activeOnStartup = this.activeOnStartup;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return config;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
destroy(): void {
|
|
215
|
+
this.stateChanged.destroy();
|
|
216
|
+
this.clippingPolygonChanged.destroy();
|
|
217
|
+
this.layersChanged.destroy();
|
|
218
|
+
this.terrainChanged.destroy();
|
|
219
|
+
super.destroy();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export default ClippingPolygonObject;
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { Cesium3DTileset } from '@vcmap-cesium/engine';
|
|
2
|
+
import Collection from '../collection.js';
|
|
3
|
+
import VcsEvent from '../../vcsEvent.js';
|
|
4
|
+
import type VcsApp from '../../vcsApp.js';
|
|
5
|
+
import type ClippingPolygonObject from './clippingPolygonObject.js';
|
|
6
|
+
import {
|
|
7
|
+
addClippingPolygon,
|
|
8
|
+
addClippingPolygonObjectToMap,
|
|
9
|
+
getTargetTilesets,
|
|
10
|
+
removeClippingPolygon,
|
|
11
|
+
removeClippingPolygonFromMap,
|
|
12
|
+
} from './clippingPolygonHelper.js';
|
|
13
|
+
import { vcsLayerName } from '../../layer/layerSymbols.js';
|
|
14
|
+
import CesiumMap from '../../map/cesiumMap.js';
|
|
15
|
+
import MapState from '../../map/mapState.js';
|
|
16
|
+
|
|
17
|
+
class ClippingPolygonObjectCollection extends Collection<ClippingPolygonObject> {
|
|
18
|
+
private _app: VcsApp;
|
|
19
|
+
|
|
20
|
+
private _listener: Array<() => void>;
|
|
21
|
+
|
|
22
|
+
private _mapListener: Map<string, () => void> = new Map();
|
|
23
|
+
|
|
24
|
+
private _itemListener: Map<string, () => void> = new Map();
|
|
25
|
+
|
|
26
|
+
stateChanged: VcsEvent<ClippingPolygonObject> = new VcsEvent();
|
|
27
|
+
|
|
28
|
+
constructor(app: VcsApp) {
|
|
29
|
+
super();
|
|
30
|
+
|
|
31
|
+
this._app = app;
|
|
32
|
+
|
|
33
|
+
this._listener = [
|
|
34
|
+
this.added.addEventListener((item) => {
|
|
35
|
+
this._itemListener.set(item.name, this._setItemListener(item));
|
|
36
|
+
if (item.activeOnStartup) {
|
|
37
|
+
item.activate();
|
|
38
|
+
}
|
|
39
|
+
}),
|
|
40
|
+
this.removed.addEventListener((item) => {
|
|
41
|
+
if (item.active) {
|
|
42
|
+
const maps = this._getActiveCesiumMaps();
|
|
43
|
+
maps.forEach((map) => {
|
|
44
|
+
removeClippingPolygonFromMap(
|
|
45
|
+
map,
|
|
46
|
+
item.clippingPolygon,
|
|
47
|
+
item.terrain,
|
|
48
|
+
item.layerNames,
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (this._itemListener.has(item.name)) {
|
|
53
|
+
this._itemListener.get(item.name)?.();
|
|
54
|
+
this._itemListener.delete(item.name);
|
|
55
|
+
}
|
|
56
|
+
}),
|
|
57
|
+
this._app.maps.added.addEventListener((map) => {
|
|
58
|
+
if (map instanceof CesiumMap) {
|
|
59
|
+
this._mapListener.set(map.name, this._setMapListener(map));
|
|
60
|
+
}
|
|
61
|
+
}),
|
|
62
|
+
this._app.maps.removed.addEventListener((map) => {
|
|
63
|
+
if (map instanceof CesiumMap) {
|
|
64
|
+
this._array.forEach((item) => {
|
|
65
|
+
removeClippingPolygonFromMap(
|
|
66
|
+
map,
|
|
67
|
+
item.clippingPolygon,
|
|
68
|
+
item.terrain,
|
|
69
|
+
item.layerNames,
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
if (this._mapListener.has(map.name)) {
|
|
73
|
+
this._mapListener.get(map.name)?.();
|
|
74
|
+
this._mapListener.delete(map.name);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}),
|
|
78
|
+
this._app.maps.replaced.addEventListener(({ old }) => {
|
|
79
|
+
if (old instanceof CesiumMap) {
|
|
80
|
+
this._array.forEach((item) => {
|
|
81
|
+
removeClippingPolygonFromMap(
|
|
82
|
+
old,
|
|
83
|
+
item.clippingPolygon,
|
|
84
|
+
item.terrain,
|
|
85
|
+
item.layerNames,
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
if (this._mapListener.has(old.name)) {
|
|
89
|
+
this._mapListener.get(old.name)?.();
|
|
90
|
+
this._mapListener.delete(old.name);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}),
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_getActiveCesiumMaps(): CesiumMap[] {
|
|
98
|
+
return this._app.maps
|
|
99
|
+
.getByType(CesiumMap.className)
|
|
100
|
+
.filter((map) => map.active) as CesiumMap[];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
_setMapListener(map: CesiumMap): () => void {
|
|
104
|
+
const listener = [
|
|
105
|
+
map.stateChanged.addEventListener((state) => {
|
|
106
|
+
if (state === MapState.INACTIVE) {
|
|
107
|
+
this._array.forEach((item) => {
|
|
108
|
+
removeClippingPolygonFromMap(
|
|
109
|
+
map,
|
|
110
|
+
item.clippingPolygon,
|
|
111
|
+
item.terrain,
|
|
112
|
+
item.layerNames,
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
} else if (state === MapState.ACTIVE) {
|
|
116
|
+
this._array
|
|
117
|
+
.filter((item) => item.active)
|
|
118
|
+
.forEach((item) => {
|
|
119
|
+
addClippingPolygonObjectToMap(
|
|
120
|
+
map,
|
|
121
|
+
item.clippingPolygon,
|
|
122
|
+
item.terrain,
|
|
123
|
+
item.layerNames,
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}),
|
|
128
|
+
map.visualizationAdded.addEventListener((v) => {
|
|
129
|
+
if (v instanceof Cesium3DTileset) {
|
|
130
|
+
this._array
|
|
131
|
+
.filter(
|
|
132
|
+
(item) =>
|
|
133
|
+
item.active &&
|
|
134
|
+
(item.layerNames === 'all' ||
|
|
135
|
+
item.layerNames.includes(v[vcsLayerName])),
|
|
136
|
+
)
|
|
137
|
+
.forEach((item) => {
|
|
138
|
+
addClippingPolygon(v, item.clippingPolygon);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}),
|
|
142
|
+
map.visualizationRemoved.addEventListener((v) => {
|
|
143
|
+
if (v instanceof Cesium3DTileset) {
|
|
144
|
+
this._array
|
|
145
|
+
.filter(
|
|
146
|
+
(item) =>
|
|
147
|
+
item.layerNames === 'all' ||
|
|
148
|
+
item.layerNames.includes(v[vcsLayerName]),
|
|
149
|
+
)
|
|
150
|
+
.forEach((item) => {
|
|
151
|
+
removeClippingPolygon(v, item.clippingPolygon);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}),
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
return () => listener.forEach((cb) => cb());
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
_setItemListener(item: ClippingPolygonObject): () => void {
|
|
161
|
+
const listener = [
|
|
162
|
+
item.stateChanged.addEventListener(() => {
|
|
163
|
+
const maps = this._getActiveCesiumMaps();
|
|
164
|
+
if (item.active) {
|
|
165
|
+
maps.forEach((map) =>
|
|
166
|
+
addClippingPolygonObjectToMap(
|
|
167
|
+
map,
|
|
168
|
+
item.clippingPolygon,
|
|
169
|
+
item.terrain,
|
|
170
|
+
item.layerNames,
|
|
171
|
+
),
|
|
172
|
+
);
|
|
173
|
+
} else {
|
|
174
|
+
maps.forEach((map) =>
|
|
175
|
+
removeClippingPolygonFromMap(
|
|
176
|
+
map,
|
|
177
|
+
item.clippingPolygon,
|
|
178
|
+
item.terrain,
|
|
179
|
+
item.layerNames,
|
|
180
|
+
),
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
}),
|
|
184
|
+
item.clippingPolygonChanged.addEventListener(({ oldValue, newValue }) => {
|
|
185
|
+
if (item.active) {
|
|
186
|
+
const maps = this._getActiveCesiumMaps();
|
|
187
|
+
maps.forEach((map) =>
|
|
188
|
+
removeClippingPolygonFromMap(
|
|
189
|
+
map,
|
|
190
|
+
oldValue,
|
|
191
|
+
item.terrain,
|
|
192
|
+
item.layerNames,
|
|
193
|
+
),
|
|
194
|
+
);
|
|
195
|
+
maps.forEach((map) =>
|
|
196
|
+
addClippingPolygonObjectToMap(
|
|
197
|
+
map,
|
|
198
|
+
newValue,
|
|
199
|
+
item.terrain,
|
|
200
|
+
item.layerNames,
|
|
201
|
+
),
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
}),
|
|
205
|
+
item.terrainChanged.addEventListener(() => {
|
|
206
|
+
if (item.active) {
|
|
207
|
+
const globes = this._getActiveCesiumMaps()
|
|
208
|
+
.map((map) => map.getScene()?.globe)
|
|
209
|
+
.filter((g) => !!g);
|
|
210
|
+
if (item.terrain) {
|
|
211
|
+
globes.forEach((g) => addClippingPolygon(g, item.clippingPolygon));
|
|
212
|
+
} else {
|
|
213
|
+
globes.forEach((g) =>
|
|
214
|
+
removeClippingPolygon(g, item.clippingPolygon),
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}),
|
|
219
|
+
item.layersChanged.addEventListener(({ newValue, oldValue }) => {
|
|
220
|
+
const maps = this._getActiveCesiumMaps();
|
|
221
|
+
maps.forEach((map) => {
|
|
222
|
+
const old = getTargetTilesets(map, oldValue);
|
|
223
|
+
const tilesets = getTargetTilesets(map, newValue);
|
|
224
|
+
|
|
225
|
+
const added = tilesets.filter((i) => !old.includes(i));
|
|
226
|
+
const removed = old.filter((i) => !tilesets.includes(i));
|
|
227
|
+
|
|
228
|
+
removed.forEach((tileset) => {
|
|
229
|
+
removeClippingPolygon(tileset, item.clippingPolygon);
|
|
230
|
+
});
|
|
231
|
+
added.forEach((tileset) => {
|
|
232
|
+
addClippingPolygon(tileset, item.clippingPolygon);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
}),
|
|
236
|
+
];
|
|
237
|
+
|
|
238
|
+
return () => listener.forEach((cb) => cb());
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
destroy(): void {
|
|
242
|
+
this._listener.forEach((cb) => cb());
|
|
243
|
+
this._mapListener.forEach((cb) => cb());
|
|
244
|
+
this._itemListener.forEach((cb) => cb());
|
|
245
|
+
super.destroy();
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export default ClippingPolygonObjectCollection;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { parseBoolean } from '@vcsuite/parsers';
|
|
2
2
|
import { check } from '@vcsuite/check';
|
|
3
3
|
import IndexedCollection from './indexedCollection.js';
|
|
4
4
|
import ExclusiveManager from './exclusiveManager.js';
|
|
@@ -7,6 +7,9 @@ import VcsEvent from '../vcsEvent.js';
|
|
|
7
7
|
import GlobalHider from '../layer/globalHider.js';
|
|
8
8
|
// eslint-disable-next-line import/no-named-default
|
|
9
9
|
import type { default as Layer, SplitLayer } from '../layer/layer.js';
|
|
10
|
+
import VectorClusterGroupCollection from '../vectorCluster/vectorClusterGroupCollection.js';
|
|
11
|
+
import type VectorLayer from '../layer/vectorLayer.js';
|
|
12
|
+
import { destroyCollection } from '../vcsModuleHelpers.js';
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* The largest integer zindex which can be safely assigned to a layer (equal to Number.MAX_SAFE_INTEGER)
|
|
@@ -14,6 +17,11 @@ import type { default as Layer, SplitLayer } from '../layer/layer.js';
|
|
|
14
17
|
*/
|
|
15
18
|
export const maxZIndex = Number.MAX_SAFE_INTEGER;
|
|
16
19
|
|
|
20
|
+
export type LayerCollectionOptions = {
|
|
21
|
+
vectorClusterGroupCollection?: VectorClusterGroupCollection;
|
|
22
|
+
destroyVectorClusterGroupCollection?: boolean;
|
|
23
|
+
};
|
|
24
|
+
|
|
17
25
|
/**
|
|
18
26
|
* A collection of layers. Manages rendering order and layer exclusivity. Emits state changes for convenience. Passed to
|
|
19
27
|
* {@link Map} for layers available to said map. Layers must have unique names.
|
|
@@ -57,6 +65,8 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
57
65
|
*/
|
|
58
66
|
private _globalHider: GlobalHider;
|
|
59
67
|
|
|
68
|
+
private _vectorClusterGroups: VectorClusterGroupCollection;
|
|
69
|
+
|
|
60
70
|
/**
|
|
61
71
|
* Locale for this layerCollection, will be synchronized by the vcsApp, if part of an vcsApp.
|
|
62
72
|
* This Locale will be set on all Member Layers. On setting the Locale this will trigger a reload of all locale
|
|
@@ -64,7 +74,11 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
64
74
|
*/
|
|
65
75
|
private _locale: string;
|
|
66
76
|
|
|
67
|
-
|
|
77
|
+
private _vectorClusterGroupListeners: (() => void) | undefined;
|
|
78
|
+
|
|
79
|
+
destroyVectorClusterGroupCollection: boolean;
|
|
80
|
+
|
|
81
|
+
constructor(options: LayerCollectionOptions = {}) {
|
|
68
82
|
super();
|
|
69
83
|
|
|
70
84
|
this._layerEventListeners = {};
|
|
@@ -73,6 +87,18 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
73
87
|
this.exclusiveManager = new ExclusiveManager();
|
|
74
88
|
this._globalHider = new GlobalHider();
|
|
75
89
|
this._locale = 'en';
|
|
90
|
+
if (options.vectorClusterGroupCollection) {
|
|
91
|
+
this._vectorClusterGroups = options.vectorClusterGroupCollection;
|
|
92
|
+
} else {
|
|
93
|
+
this._vectorClusterGroups = new VectorClusterGroupCollection(
|
|
94
|
+
this._globalHider,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
this.destroyVectorClusterGroupCollection = parseBoolean(
|
|
98
|
+
options.destroyVectorClusterGroupCollection,
|
|
99
|
+
!options.vectorClusterGroupCollection,
|
|
100
|
+
);
|
|
101
|
+
this._setupVectorClusterGroupListeners();
|
|
76
102
|
}
|
|
77
103
|
|
|
78
104
|
/**
|
|
@@ -102,6 +128,7 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
102
128
|
this._array.forEach((layer) => {
|
|
103
129
|
layer.setGlobalHider(this._globalHider);
|
|
104
130
|
});
|
|
131
|
+
this.vectorClusterGroups.globalHider = this._globalHider;
|
|
105
132
|
}
|
|
106
133
|
|
|
107
134
|
get locale(): string {
|
|
@@ -119,6 +146,10 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
119
146
|
}
|
|
120
147
|
}
|
|
121
148
|
|
|
149
|
+
get vectorClusterGroups(): VectorClusterGroupCollection {
|
|
150
|
+
return this._vectorClusterGroups;
|
|
151
|
+
}
|
|
152
|
+
|
|
122
153
|
private _listenToLayerEvents(layer: Layer): void {
|
|
123
154
|
const stateListener = layer.stateChanged.addEventListener(
|
|
124
155
|
(state: LayerState) => {
|
|
@@ -148,6 +179,25 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
148
179
|
),
|
|
149
180
|
);
|
|
150
181
|
}
|
|
182
|
+
|
|
183
|
+
if ((layer as VectorLayer).vectorClusterGroupChanged) {
|
|
184
|
+
listeners.push(
|
|
185
|
+
(layer as VectorLayer).vectorClusterGroupChanged.addEventListener(
|
|
186
|
+
({ newGroup, oldGroup }) => {
|
|
187
|
+
if (oldGroup) {
|
|
188
|
+
this._vectorClusterGroups
|
|
189
|
+
.getByKey(oldGroup)
|
|
190
|
+
?.removeLayer(layer as VectorLayer);
|
|
191
|
+
}
|
|
192
|
+
if (newGroup) {
|
|
193
|
+
this._vectorClusterGroups
|
|
194
|
+
.getByKey(newGroup)
|
|
195
|
+
?.addLayer(layer as VectorLayer);
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
),
|
|
199
|
+
);
|
|
200
|
+
}
|
|
151
201
|
this._layerEventListeners[layer.name] = listeners;
|
|
152
202
|
}
|
|
153
203
|
|
|
@@ -158,7 +208,7 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
158
208
|
*/
|
|
159
209
|
private _findZIndexPosition(zIndex: number): number | null {
|
|
160
210
|
const usedIndex = this._array.findIndex(
|
|
161
|
-
// @ts-
|
|
211
|
+
// @ts-expect-error: z index is undefined
|
|
162
212
|
(l) => l[this._zIndexSymbol] > zIndex,
|
|
163
213
|
);
|
|
164
214
|
return usedIndex > -1 ? usedIndex : null;
|
|
@@ -173,7 +223,7 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
173
223
|
private _zIndexChanged(layer: Layer): void {
|
|
174
224
|
const currentIndex = this.indexOf(layer);
|
|
175
225
|
if (currentIndex > -1) {
|
|
176
|
-
// @ts-
|
|
226
|
+
// @ts-expect-error: z index is undefined
|
|
177
227
|
layer[this._zIndexSymbol] = layer.zIndex;
|
|
178
228
|
let zIndexPosition = this._findZIndexPosition(layer.zIndex);
|
|
179
229
|
if (
|
|
@@ -197,29 +247,43 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
197
247
|
*/
|
|
198
248
|
private _ensureLocalZIndex(layer: Layer): void {
|
|
199
249
|
const currentIndex = this.indexOf(layer);
|
|
200
|
-
// @ts-
|
|
250
|
+
// @ts-expect-error: z index is undefined
|
|
201
251
|
const currentLayerZIndex = layer[this._zIndexSymbol] as number;
|
|
202
252
|
if (currentIndex > 0) {
|
|
203
|
-
// @ts-
|
|
253
|
+
// @ts-expect-error: z index is undefined
|
|
204
254
|
const below: number = this._array[currentIndex - 1][
|
|
205
255
|
this._zIndexSymbol
|
|
206
256
|
] as number;
|
|
207
257
|
if (below > currentLayerZIndex) {
|
|
208
|
-
// @ts-
|
|
258
|
+
// @ts-expect-error: z index is undefined
|
|
209
259
|
layer[this._zIndexSymbol] = below;
|
|
210
260
|
}
|
|
211
261
|
}
|
|
212
262
|
|
|
213
263
|
if (currentIndex < this._array.length - 1) {
|
|
214
|
-
// @ts-
|
|
264
|
+
// @ts-expect-error: z index is undefined
|
|
215
265
|
const above = this._array[currentIndex + 1][this._zIndexSymbol] as number;
|
|
216
266
|
if (above < currentLayerZIndex) {
|
|
217
|
-
// @ts-
|
|
267
|
+
// @ts-expect-error: z index is undefined
|
|
218
268
|
layer[this._zIndexSymbol] = above;
|
|
219
269
|
}
|
|
220
270
|
}
|
|
221
271
|
}
|
|
222
272
|
|
|
273
|
+
private _setupVectorClusterGroupListeners(): void {
|
|
274
|
+
this._vectorClusterGroupListeners =
|
|
275
|
+
this._vectorClusterGroups.added.addEventListener((collection) => {
|
|
276
|
+
this._array
|
|
277
|
+
.filter(
|
|
278
|
+
(layer) =>
|
|
279
|
+
(layer as VectorLayer).vectorClusterGroup === collection.name,
|
|
280
|
+
)
|
|
281
|
+
.forEach((layer) => {
|
|
282
|
+
collection.addLayer(layer as VectorLayer);
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
223
287
|
/**
|
|
224
288
|
* Adds a layer to the collection. Can optionally be passed an index at which to insert the layer.
|
|
225
289
|
* The layer locale will be set to the same locale of the layerCollection. This will trigger a forceRedraw
|
|
@@ -235,13 +299,18 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
235
299
|
}
|
|
236
300
|
const insertedAt = super.add(layer, usedIndex);
|
|
237
301
|
if (insertedAt != null) {
|
|
238
|
-
// @ts-
|
|
302
|
+
// @ts-expect-error: z index is undefined
|
|
239
303
|
layer[this._zIndexSymbol] = layer.zIndex;
|
|
240
304
|
layer.setGlobalHider(this._globalHider);
|
|
241
305
|
layer.locale = this.locale;
|
|
242
306
|
this._ensureLocalZIndex(layer);
|
|
243
307
|
this._listenToLayerEvents(layer);
|
|
244
308
|
this.exclusiveManager.registerLayer(layer);
|
|
309
|
+
if ((layer as VectorLayer).vectorClusterGroup) {
|
|
310
|
+
this._vectorClusterGroups
|
|
311
|
+
.getByKey((layer as VectorLayer).vectorClusterGroup)
|
|
312
|
+
?.addLayer(layer as VectorLayer);
|
|
313
|
+
}
|
|
245
314
|
}
|
|
246
315
|
return insertedAt;
|
|
247
316
|
}
|
|
@@ -253,10 +322,15 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
253
322
|
});
|
|
254
323
|
delete this._layerEventListeners[layer.name];
|
|
255
324
|
}
|
|
256
|
-
// @ts-
|
|
325
|
+
// @ts-expect-error: z index is undefined
|
|
257
326
|
delete layer[this._zIndexSymbol];
|
|
258
327
|
layer.setGlobalHider();
|
|
259
328
|
this.exclusiveManager.unregisterLayer(layer);
|
|
329
|
+
if ((layer as VectorLayer).vectorClusterGroup) {
|
|
330
|
+
this._vectorClusterGroups
|
|
331
|
+
.getByKey((layer as VectorLayer).vectorClusterGroup)
|
|
332
|
+
?.removeLayer(layer as VectorLayer);
|
|
333
|
+
}
|
|
260
334
|
return super._remove(layer);
|
|
261
335
|
}
|
|
262
336
|
|
|
@@ -267,7 +341,7 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
267
341
|
r();
|
|
268
342
|
});
|
|
269
343
|
this._array.forEach((l) => {
|
|
270
|
-
// @ts-
|
|
344
|
+
// @ts-expect-error: z index is undefined
|
|
271
345
|
delete l[this._zIndexSymbol];
|
|
272
346
|
});
|
|
273
347
|
|
|
@@ -286,6 +360,10 @@ class LayerCollection extends IndexedCollection<Layer> {
|
|
|
286
360
|
this._layerEventListeners = {};
|
|
287
361
|
this.exclusiveManager.destroy();
|
|
288
362
|
this._globalHider.destroy();
|
|
363
|
+
this._vectorClusterGroupListeners?.();
|
|
364
|
+
if (this.destroyVectorClusterGroupCollection) {
|
|
365
|
+
destroyCollection(this._vectorClusterGroups);
|
|
366
|
+
}
|
|
289
367
|
super.destroy();
|
|
290
368
|
}
|
|
291
369
|
}
|