@vcmap/core 5.0.0-rc.2 → 5.0.0-rc.5
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/index.d.ts +287 -95
- package/index.js +11 -3
- package/package.json +5 -10
- package/src/vcs/vcm/category/appBackedCategory.js +41 -0
- package/src/vcs/vcm/category/category.js +374 -0
- package/src/vcs/vcm/category/categoryCollection.js +145 -0
- package/src/vcs/vcm/context.js +73 -0
- package/src/vcs/vcm/interaction/coordinateAtPixel.js +1 -1
- package/src/vcs/vcm/layer/cesiumTileset.js +1 -1
- package/src/vcs/vcm/layer/featureStore.js +3 -3
- package/src/vcs/vcm/layer/featureStoreChanges.js +89 -73
- package/src/vcs/vcm/layer/geojson.js +3 -5
- package/src/vcs/vcm/layer/geojsonHelpers.js +3 -3
- package/src/vcs/vcm/layer/oblique/obliqueHelpers.js +2 -2
- package/src/vcs/vcm/layer/singleImage.js +2 -1
- package/src/vcs/vcm/layer/terrainHelpers.js +4 -8
- package/src/vcs/vcm/layer/tileProvider/mvtTileProvider.js +3 -3
- package/src/vcs/vcm/layer/tileProvider/staticGeojsonTileProvider.js +3 -3
- package/src/vcs/vcm/layer/tileProvider/urlTemplateTileProvider.js +3 -3
- package/src/vcs/vcm/layer/vector.js +1 -1
- package/src/vcs/vcm/layer/vectorHelpers.js +4 -4
- package/src/vcs/vcm/layer/wfs.js +5 -5
- package/src/vcs/vcm/maps/cameraLimiter.js +5 -5
- package/src/vcs/vcm/maps/map.js +26 -11
- package/src/vcs/vcm/maps/oblique.js +8 -8
- package/src/vcs/vcm/object.js +1 -1
- package/src/vcs/vcm/oblique/ObliqueCollection.js +83 -31
- package/src/vcs/vcm/oblique/ObliqueDataSet.js +67 -24
- package/src/vcs/vcm/oblique/ObliqueImage.js +1 -1
- package/src/vcs/vcm/oblique/ObliqueImageMeta.js +2 -2
- package/src/vcs/vcm/oblique/ObliqueProvider.js +10 -7
- package/src/vcs/vcm/oblique/helpers.js +12 -40
- package/src/vcs/vcm/oblique/parseImageJson.js +17 -9
- package/src/vcs/vcm/util/clipping/clippingPlaneHelper.js +4 -4
- package/src/vcs/vcm/util/extent.js +16 -9
- package/src/vcs/vcm/util/featureProvider/featureProviderHelpers.js +3 -4
- package/src/vcs/vcm/util/featureProvider/wmsFeatureProvider.js +11 -6
- package/src/vcs/vcm/util/featureconverter/extent3D.js +181 -0
- package/src/vcs/vcm/util/fetch.js +32 -0
- package/src/vcs/vcm/util/indexedCollection.js +23 -0
- package/src/vcs/vcm/util/layerCollection.js +10 -5
- package/src/vcs/vcm/util/overrideCollection.js +224 -0
- package/src/vcs/vcm/util/projection.js +37 -3
- package/src/vcs/vcm/util/style/declarativeStyleItem.js +2 -0
- package/src/vcs/vcm/util/style/styleFactory.js +1 -1
- package/src/vcs/vcm/util/style/styleItem.js +2 -0
- package/src/vcs/vcm/util/style/vectorStyleItem.js +2 -0
- package/src/vcs/vcm/util/viewpoint.js +3 -0
- package/src/vcs/vcm/vcsApp.js +360 -0
- package/src/vcs/vcm/vcsAppContextHelpers.js +108 -0
- package/src/vcs/vcm/util/featureconverter/extent3d.js +0 -154
|
@@ -3,12 +3,15 @@ import { register } from 'ol/proj/proj4.js';
|
|
|
3
3
|
import proj4 from 'proj4';
|
|
4
4
|
import { getLogger as getLoggerByName } from '@vcsuite/logger';
|
|
5
5
|
import { check } from '@vcsuite/check';
|
|
6
|
+
import { VcsClassRegistry } from '../classRegistry.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* @typedef {Object} ProjectionOptions
|
|
10
|
+
* @property {string} [type]
|
|
9
11
|
* @property {string|number} [epsg] - EPSG of the projection, for example: "EPSG:4326" if not specified, uses the framework projection
|
|
10
12
|
* @property {string|undefined|null} [proj4] - definition of the projection. See for example: {@link http://spatialreference.org/ref/epsg/4326/proj4/} proj4
|
|
11
13
|
* @property {Array<string>|undefined|null} [alias] - aliases to define
|
|
14
|
+
* @property {string|undefined} [prefix='EPSG:'] - an alternate prefix to use for custom projection
|
|
12
15
|
* @api stable
|
|
13
16
|
*/
|
|
14
17
|
|
|
@@ -36,7 +39,8 @@ let defaultProjectionOption = {
|
|
|
36
39
|
* @returns {string}
|
|
37
40
|
*/
|
|
38
41
|
function parseEPSGCode(value, prefix = 'EPSG:') {
|
|
39
|
-
const
|
|
42
|
+
const regex = new RegExp(`^(?:${prefix})?(\\d+)`, 'i');
|
|
43
|
+
const matches = `${value}`.match(regex);
|
|
40
44
|
if (matches && matches[1]) {
|
|
41
45
|
return `${prefix}${matches[1]}`;
|
|
42
46
|
}
|
|
@@ -73,9 +77,11 @@ function validateProjectionOptions(options) {
|
|
|
73
77
|
* @returns {ProjectionOptions} valid options
|
|
74
78
|
*/
|
|
75
79
|
function registerProjection(options) {
|
|
76
|
-
const saneOptions = {
|
|
80
|
+
const saneOptions = {
|
|
81
|
+
prefix: options.prefix,
|
|
82
|
+
};
|
|
77
83
|
if (options.epsg) {
|
|
78
|
-
saneOptions.epsg = parseEPSGCode(options.epsg);
|
|
84
|
+
saneOptions.epsg = parseEPSGCode(options.epsg, options.prefix);
|
|
79
85
|
if (saneOptions.epsg) {
|
|
80
86
|
if (options.proj4) {
|
|
81
87
|
saneOptions.proj4 = options.proj4;
|
|
@@ -123,6 +129,11 @@ export function setDefaultProjectionOptions(options) {
|
|
|
123
129
|
* @api stable
|
|
124
130
|
*/
|
|
125
131
|
class Projection {
|
|
132
|
+
/**
|
|
133
|
+
* @returns {string}
|
|
134
|
+
*/
|
|
135
|
+
static get className() { return 'vcs.vcm.util.Projection'; }
|
|
136
|
+
|
|
126
137
|
/**
|
|
127
138
|
* @param {ProjectionOptions} options
|
|
128
139
|
*/
|
|
@@ -143,6 +154,20 @@ class Projection {
|
|
|
143
154
|
if (!this.proj) {
|
|
144
155
|
this._epsg = Projection.parseEPSGCode(defaultProjectionOption.epsg);
|
|
145
156
|
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Cached for toJSON
|
|
160
|
+
* @type {Array<string>}
|
|
161
|
+
* @private
|
|
162
|
+
*/
|
|
163
|
+
this._alias = saneOptions.alias;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Cached for toJSON
|
|
167
|
+
* @type {string}
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
this._prefix = saneOptions.prefix;
|
|
146
171
|
}
|
|
147
172
|
|
|
148
173
|
/**
|
|
@@ -264,11 +289,18 @@ class Projection {
|
|
|
264
289
|
*/
|
|
265
290
|
toJSON() {
|
|
266
291
|
const configObject = {
|
|
292
|
+
type: Projection.className,
|
|
267
293
|
epsg: this.epsg,
|
|
268
294
|
};
|
|
269
295
|
if (this.proj4) {
|
|
270
296
|
configObject.proj4 = this.proj4;
|
|
271
297
|
}
|
|
298
|
+
if (Array.isArray(this._alias) && this._alias.length > 0) {
|
|
299
|
+
configObject.alias = this._alias.slice();
|
|
300
|
+
}
|
|
301
|
+
if (this._prefix) {
|
|
302
|
+
configObject.prefix = this._prefix;
|
|
303
|
+
}
|
|
272
304
|
return configObject;
|
|
273
305
|
}
|
|
274
306
|
|
|
@@ -346,3 +378,5 @@ export const wgs84Projection = new Projection({ epsg: 4326 });
|
|
|
346
378
|
* @export
|
|
347
379
|
*/
|
|
348
380
|
export const mercatorProjection = new Projection({ epsg: 3857 });
|
|
381
|
+
|
|
382
|
+
VcsClassRegistry.registerClass(Projection.className, Projection);
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
whiteColor,
|
|
15
15
|
} from './styleHelpers.js';
|
|
16
16
|
import { originalFeatureSymbol } from '../../layer/vectorSymbols.js';
|
|
17
|
+
import { VcsClassRegistry } from '../../classRegistry.js';
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* @typedef {Object} DeclarativeStyleItemConditions
|
|
@@ -558,6 +559,7 @@ class DeclarativeStyleItem extends StyleItem {
|
|
|
558
559
|
}
|
|
559
560
|
|
|
560
561
|
export default DeclarativeStyleItem;
|
|
562
|
+
VcsClassRegistry.registerClass(DeclarativeStyleItem.className, DeclarativeStyleItem);
|
|
561
563
|
|
|
562
564
|
/**
|
|
563
565
|
* @type {DeclarativeStyleItem}
|
|
@@ -13,7 +13,7 @@ function getLogger() {
|
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* @param {(Reference|DeclarativeStyleItemOptions|VectorStyleItemOptions|StyleItem|string)=} styleOptions
|
|
16
|
-
* @param {
|
|
16
|
+
* @param {StyleItem=} defaultStyle
|
|
17
17
|
* @returns {StyleItem}
|
|
18
18
|
*/
|
|
19
19
|
// eslint-disable-next-line import/prefer-default-export
|
|
@@ -4,6 +4,7 @@ import deepEqual from 'fast-deep-equal';
|
|
|
4
4
|
import { parseEnumValue } from '@vcsuite/parsers';
|
|
5
5
|
import VcsObject from '../../object.js';
|
|
6
6
|
import VcsEvent from '../../event/vcsEvent.js';
|
|
7
|
+
import { VcsClassRegistry } from '../../classRegistry.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* @namespace style
|
|
@@ -241,3 +242,4 @@ class StyleItem extends VcsObject {
|
|
|
241
242
|
}
|
|
242
243
|
|
|
243
244
|
export default StyleItem;
|
|
245
|
+
VcsClassRegistry.registerClass(StyleItem.className, StyleItem);
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
getDefaultVectorStyleItemOptions,
|
|
25
25
|
} from './styleHelpers.js';
|
|
26
26
|
import { getShapeFromOptions } from './shapesCategory.js';
|
|
27
|
+
import { VcsClassRegistry } from '../../classRegistry.js';
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* @typedef {Object} VectorStyleItemPattern
|
|
@@ -907,6 +908,7 @@ export default VectorStyleItem;
|
|
|
907
908
|
* @export
|
|
908
909
|
*/
|
|
909
910
|
export const defaultVectorStyle = new VectorStyleItem(getDefaultVectorStyleItemOptions());
|
|
911
|
+
VcsClassRegistry.registerClass(VectorStyleItem.className, VectorStyleItem);
|
|
910
912
|
|
|
911
913
|
/**
|
|
912
914
|
* @param {import("@vcmap/cesium").Color} cesiumColor
|
|
@@ -3,6 +3,7 @@ import { parseBoolean, parseNumber } from '@vcsuite/parsers';
|
|
|
3
3
|
import Projection, { wgs84Projection } from './projection.js';
|
|
4
4
|
import VcsObject from '../object.js';
|
|
5
5
|
import Extent from './extent.js';
|
|
6
|
+
import { VcsClassRegistry } from '../classRegistry.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* compares two numeric properties
|
|
@@ -331,3 +332,5 @@ class ViewPoint extends VcsObject {
|
|
|
331
332
|
}
|
|
332
333
|
|
|
333
334
|
export default ViewPoint;
|
|
335
|
+
|
|
336
|
+
VcsClassRegistry.registerClass(ViewPoint.className, ViewPoint);
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { getLogger as getLoggerByName } from '@vcsuite/logger';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { check } from '@vcsuite/check';
|
|
4
|
+
import Context from './context.js';
|
|
5
|
+
import {
|
|
6
|
+
contextIdSymbol,
|
|
7
|
+
destroyCollection,
|
|
8
|
+
getObjectFromOptions,
|
|
9
|
+
deserializeViewPoint,
|
|
10
|
+
deserializeMap,
|
|
11
|
+
getLayerIndex,
|
|
12
|
+
serializeLayer,
|
|
13
|
+
} from './vcsAppContextHelpers.js';
|
|
14
|
+
import makeOverrideCollection from './util/overrideCollection.js';
|
|
15
|
+
import CategoryCollection from './category/categoryCollection.js';
|
|
16
|
+
import MapCollection from './util/mapCollection.js';
|
|
17
|
+
import VcsMap from './maps/map.js';
|
|
18
|
+
import Layer from './layer/layer.js';
|
|
19
|
+
import Collection from './util/collection.js';
|
|
20
|
+
import ObliqueCollection from './oblique/ObliqueCollection.js';
|
|
21
|
+
import ViewPoint from './util/viewpoint.js';
|
|
22
|
+
import StyleItem from './util/style/styleItem.js';
|
|
23
|
+
import IndexedCollection from './util/indexedCollection.js';
|
|
24
|
+
import VcsEvent from './event/vcsEvent.js';
|
|
25
|
+
import { setDefaultProjectionOptions } from './util/projection.js';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @returns {import("@vcsuite/logger").Logger}
|
|
29
|
+
*/
|
|
30
|
+
function getLogger() {
|
|
31
|
+
return getLoggerByName('init');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @type {Map<string, VcsApp>}
|
|
36
|
+
*/
|
|
37
|
+
const vcsApps = new Map();
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @class
|
|
41
|
+
*/
|
|
42
|
+
class VcsApp {
|
|
43
|
+
constructor() {
|
|
44
|
+
/**
|
|
45
|
+
* @type {string}
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
this._id = uuidv4();
|
|
49
|
+
/**
|
|
50
|
+
* @type {Context}
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
this._defaultDynamicContext = new Context({ id: '_defaultDynamicContext' });
|
|
54
|
+
/**
|
|
55
|
+
* @type {Context}
|
|
56
|
+
* @private
|
|
57
|
+
*/
|
|
58
|
+
this._dynamicContext = this._defaultDynamicContext;
|
|
59
|
+
|
|
60
|
+
const getDynamicContextId = () => this._dynamicContext.id;
|
|
61
|
+
/**
|
|
62
|
+
* @type {OverrideMapCollection}
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
// @ts-ignore
|
|
66
|
+
this._maps = makeOverrideCollection(
|
|
67
|
+
new MapCollection(),
|
|
68
|
+
getDynamicContextId,
|
|
69
|
+
null,
|
|
70
|
+
deserializeMap.bind(null, this),
|
|
71
|
+
VcsMap,
|
|
72
|
+
);
|
|
73
|
+
/**
|
|
74
|
+
* @type {OverrideLayerCollection}
|
|
75
|
+
* @private
|
|
76
|
+
*/
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
this._layers = makeOverrideCollection(
|
|
79
|
+
this._maps.layerCollection,
|
|
80
|
+
getDynamicContextId,
|
|
81
|
+
serializeLayer.bind(null, this),
|
|
82
|
+
getObjectFromOptions,
|
|
83
|
+
Layer,
|
|
84
|
+
getLayerIndex,
|
|
85
|
+
);
|
|
86
|
+
/**
|
|
87
|
+
* @type {OverrideCollection<import("@vcmap/core").ObliqueCollection>}
|
|
88
|
+
* @private
|
|
89
|
+
*/
|
|
90
|
+
this._obliqueCollections = makeOverrideCollection(
|
|
91
|
+
new Collection(),
|
|
92
|
+
getDynamicContextId,
|
|
93
|
+
null,
|
|
94
|
+
getObjectFromOptions,
|
|
95
|
+
ObliqueCollection,
|
|
96
|
+
); // XXX there is a global for this collection in core.
|
|
97
|
+
/**
|
|
98
|
+
* @type {OverrideCollection<import("@vcmap/core").ViewPoint>}
|
|
99
|
+
* @private
|
|
100
|
+
*/
|
|
101
|
+
this._viewPoints = makeOverrideCollection(
|
|
102
|
+
new Collection(),
|
|
103
|
+
getDynamicContextId,
|
|
104
|
+
null,
|
|
105
|
+
deserializeViewPoint,
|
|
106
|
+
ViewPoint,
|
|
107
|
+
);
|
|
108
|
+
/**
|
|
109
|
+
* @type {OverrideCollection<import("@vcmap/core").StyleItem>}
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
this._styles = makeOverrideCollection(
|
|
113
|
+
new Collection(),
|
|
114
|
+
getDynamicContextId,
|
|
115
|
+
null,
|
|
116
|
+
getObjectFromOptions,
|
|
117
|
+
StyleItem,
|
|
118
|
+
); // XXX there is a global for this collection in core.
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @type {IndexedCollection<Context>}
|
|
122
|
+
* @private
|
|
123
|
+
*/
|
|
124
|
+
this._contexts = new IndexedCollection('id');
|
|
125
|
+
this._contexts.add(this._dynamicContext);
|
|
126
|
+
/**
|
|
127
|
+
* @type {CategoryCollection}
|
|
128
|
+
* @private
|
|
129
|
+
*/
|
|
130
|
+
this._categories = new CategoryCollection(this);
|
|
131
|
+
/**
|
|
132
|
+
* @type {import("@vcmap/core").VcsEvent<void>}
|
|
133
|
+
* @private
|
|
134
|
+
*/
|
|
135
|
+
this._destroyed = new VcsEvent();
|
|
136
|
+
/**
|
|
137
|
+
* @type {Promise<void>}
|
|
138
|
+
* @private
|
|
139
|
+
*/
|
|
140
|
+
this._contextMutationPromise = Promise.resolve();
|
|
141
|
+
vcsApps.set(this._id, this);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @type {string}
|
|
146
|
+
* @readonly
|
|
147
|
+
*/
|
|
148
|
+
get id() { return this._id; }
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @type {OverrideMapCollection}
|
|
152
|
+
* @readonly
|
|
153
|
+
*/
|
|
154
|
+
get maps() { return this._maps; }
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @type {OverrideLayerCollection}
|
|
158
|
+
* @readonly
|
|
159
|
+
*/
|
|
160
|
+
get layers() { return this._layers; }
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @type {OverrideCollection<import("@vcmap/core").ObliqueCollection>}
|
|
164
|
+
* @readonly
|
|
165
|
+
*/
|
|
166
|
+
get obliqueCollections() { return this._obliqueCollections; }
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @type {OverrideCollection<import("@vcmap/core").ViewPoint>}
|
|
170
|
+
* @readonly
|
|
171
|
+
*/
|
|
172
|
+
get viewPoints() { return this._viewPoints; }
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @type {OverrideCollection<import("@vcmap/core").StyleItem>}
|
|
176
|
+
* @readonly
|
|
177
|
+
*/
|
|
178
|
+
get styles() { return this._styles; }
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* @type {CategoryCollection}
|
|
182
|
+
* @readonly
|
|
183
|
+
*/
|
|
184
|
+
get categories() { return this._categories; }
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @type {VcsEvent<void>}
|
|
188
|
+
* @readonly
|
|
189
|
+
*/
|
|
190
|
+
get destroyed() { return this._destroyed; }
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* @returns {VcsEvent<Context>}
|
|
194
|
+
* @readonly
|
|
195
|
+
*/
|
|
196
|
+
get contextAdded() { return this._contexts.added; }
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @returns {VcsEvent<Context>}
|
|
200
|
+
* @readonly
|
|
201
|
+
*/
|
|
202
|
+
get contextRemoved() { return this._contexts.removed; }
|
|
203
|
+
|
|
204
|
+
get dynamicContextId() { return this._dynamicContext.id; }
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @param {string} id
|
|
208
|
+
* @returns {Context}
|
|
209
|
+
*/
|
|
210
|
+
getContextById(id) {
|
|
211
|
+
return this._contexts.getByKey(id);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @param {Context} context
|
|
216
|
+
* @returns {Promise<void>}
|
|
217
|
+
* @protected
|
|
218
|
+
*/
|
|
219
|
+
async _parseContext(context) {
|
|
220
|
+
const { config } = context;
|
|
221
|
+
if (config.projection) { // XXX this needs fixing. this should be _projections_ and there should be a `defaultProjection`
|
|
222
|
+
setDefaultProjectionOptions(config.projection);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
await this._styles.parseItems(config.styles, context.id);
|
|
226
|
+
await this._layers.parseItems(config.layers, context.id);
|
|
227
|
+
// TODO add flights & ade here
|
|
228
|
+
|
|
229
|
+
await this._obliqueCollections.parseItems(config.obliqueCollections, context.id);
|
|
230
|
+
await this._viewPoints.parseItems(config.viewpoints, context.id);
|
|
231
|
+
await this._maps.parseItems(config.maps, context.id);
|
|
232
|
+
|
|
233
|
+
if (Array.isArray(config.categories)) {
|
|
234
|
+
await Promise.all((config.categories).map(async ({ name, items }) => {
|
|
235
|
+
await this._categories.parseCategoryItems(name, items, context.id);
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* @param {Context} context
|
|
242
|
+
* @returns {Promise<void>}
|
|
243
|
+
* @protected
|
|
244
|
+
*/
|
|
245
|
+
async _setContextState(context) {
|
|
246
|
+
const { config } = context;
|
|
247
|
+
[...this._layers]
|
|
248
|
+
.filter(l => l[contextIdSymbol] === context.id)
|
|
249
|
+
.forEach((l) => {
|
|
250
|
+
if (l.activeOnStartup) {
|
|
251
|
+
l.activate()
|
|
252
|
+
.catch((err) => {
|
|
253
|
+
getLogger().error(`Failed to activate active on startup layer ${l.name}`);
|
|
254
|
+
getLogger().error(err);
|
|
255
|
+
this._layers.remove(l);
|
|
256
|
+
l.destroy();
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
if (config.startingMapName) {
|
|
262
|
+
await this._maps.setActiveMap(config.startingMapName);
|
|
263
|
+
} else if (!this._maps.activeMap && this._maps.size > 0) {
|
|
264
|
+
await this._maps.setActiveMap([...this._maps][0].name);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (config.startingViewPointName && this._maps.activeMap) {
|
|
268
|
+
const startViewPoint = this._viewPoints.getByKey(config.startingViewPointName);
|
|
269
|
+
if (startViewPoint) {
|
|
270
|
+
await this._maps.activeMap.gotoViewPoint(startViewPoint);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* @param {Context} context
|
|
277
|
+
* @returns {Promise<void>}
|
|
278
|
+
*/
|
|
279
|
+
addContext(context) {
|
|
280
|
+
check(context, Context);
|
|
281
|
+
|
|
282
|
+
this._contextMutationPromise = this._contextMutationPromise
|
|
283
|
+
.then(async () => {
|
|
284
|
+
if (this._contexts.has(context)) {
|
|
285
|
+
getLogger().info(`context with id ${context.id} already loaded`);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
await this._parseContext(context);
|
|
290
|
+
await this._setContextState(context);
|
|
291
|
+
this._contexts.add(context);
|
|
292
|
+
});
|
|
293
|
+
return this._contextMutationPromise;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* @param {string} contextId
|
|
298
|
+
* @returns {Promise<void>}
|
|
299
|
+
* @protected
|
|
300
|
+
*/
|
|
301
|
+
async _removeContext(contextId) {
|
|
302
|
+
await Promise.all([
|
|
303
|
+
this._maps.removeContext(contextId),
|
|
304
|
+
this._layers.removeContext(contextId),
|
|
305
|
+
this._viewPoints.removeContext(contextId),
|
|
306
|
+
this._styles.removeContext(contextId),
|
|
307
|
+
this._obliqueCollections.removeContext(contextId),
|
|
308
|
+
]);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* @param {string} contextId
|
|
313
|
+
* @returns {Promise<void>}
|
|
314
|
+
*/
|
|
315
|
+
removeContext(contextId) {
|
|
316
|
+
this._contextMutationPromise = this._contextMutationPromise
|
|
317
|
+
.then(async () => {
|
|
318
|
+
const context = this._contexts.getByKey(contextId);
|
|
319
|
+
if (!context) {
|
|
320
|
+
getLogger().info(`context with id ${contextId} has alread been removed`);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
await this._removeContext(contextId);
|
|
324
|
+
this._contexts.remove(context);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
return this._contextMutationPromise;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
destroy() {
|
|
331
|
+
Object.defineProperty(this, '_contextMutationPromise', {
|
|
332
|
+
get() {
|
|
333
|
+
throw new Error('VcsApp was destroyed');
|
|
334
|
+
},
|
|
335
|
+
});
|
|
336
|
+
vcsApps.delete(this._id);
|
|
337
|
+
destroyCollection(this._maps);
|
|
338
|
+
destroyCollection(this._layers);
|
|
339
|
+
destroyCollection(this._obliqueCollections);
|
|
340
|
+
destroyCollection(this._viewPoints);
|
|
341
|
+
destroyCollection(this._styles);
|
|
342
|
+
destroyCollection(this._contexts);
|
|
343
|
+
destroyCollection(this._categories);
|
|
344
|
+
this.destroyed.raiseEvent();
|
|
345
|
+
this.destroyed.destroy();
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* @param {string} id
|
|
351
|
+
* @returns {VcsApp}
|
|
352
|
+
*/
|
|
353
|
+
export function getVcsAppById(id) {
|
|
354
|
+
return vcsApps.get(id);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
window.vcs = window.vcs || {};
|
|
358
|
+
window.vcs.apps = vcsApps;
|
|
359
|
+
|
|
360
|
+
export default VcsApp;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { getLogger as getLoggerByName } from '@vcsuite/logger';
|
|
2
|
+
import { VcsClassRegistry } from './classRegistry.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @returns {import("@vcsuite/logger").Logger}
|
|
6
|
+
*/
|
|
7
|
+
function getLogger() {
|
|
8
|
+
return getLoggerByName('init');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @type {symbol}
|
|
13
|
+
*/
|
|
14
|
+
export const contextIdSymbol = Symbol('contextId');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* returns a constructor of a type.
|
|
18
|
+
* @api stable
|
|
19
|
+
* @export
|
|
20
|
+
* @param {Object} options
|
|
21
|
+
* @param {...*} args
|
|
22
|
+
* @returns {Promise<Object|null>}
|
|
23
|
+
*/
|
|
24
|
+
export async function getObjectFromOptions(options, ...args) {
|
|
25
|
+
if (!options.type) {
|
|
26
|
+
getLogger().warning(`ObjectCreation failed: could not find type in options ${options}`);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const ObjectConstructor = await VcsClassRegistry.getClass(options.type);
|
|
30
|
+
if (!ObjectConstructor) {
|
|
31
|
+
getLogger().warning(`ObjectCreation failed: could not find javascript class of type ${options.type}`);
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
let object;
|
|
35
|
+
try {
|
|
36
|
+
object = new ObjectConstructor(options, ...args);
|
|
37
|
+
} catch (ex) {
|
|
38
|
+
getLogger().warning(`Error: ${ex}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!object) {
|
|
42
|
+
getLogger().warning('ObjectCreation failed: could not create new Object');
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return object;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {import("@vcmap/core").VcsApp} vcsApp
|
|
50
|
+
* @param {VcsMapOptions} mapConfig
|
|
51
|
+
* @returns {Promise<import("@vcmap/core").VcsMap|null>}
|
|
52
|
+
*/
|
|
53
|
+
export async function deserializeMap(vcsApp, mapConfig) {
|
|
54
|
+
const map = await getObjectFromOptions(mapConfig);
|
|
55
|
+
if (map) {
|
|
56
|
+
map.layerCollection = vcsApp.layers;
|
|
57
|
+
}
|
|
58
|
+
return map;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {ViewPointOptions} viewPointObject
|
|
63
|
+
* @returns {Promise<null|import("@vcmap/core").ViewPoint>}
|
|
64
|
+
*/
|
|
65
|
+
export async function deserializeViewPoint(viewPointObject) {
|
|
66
|
+
const viewpoint = /** @type {import("@vcmap/core").ViewPoint} */ (await getObjectFromOptions(viewPointObject));
|
|
67
|
+
if (viewpoint && viewpoint.isValid()) {
|
|
68
|
+
return viewpoint;
|
|
69
|
+
}
|
|
70
|
+
getLogger().warning(`Viewpoint ${viewPointObject.name} is not valid`);
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @param {import("@vcmap/core").VcsApp} vcsApp
|
|
76
|
+
* @param {import("@vcmap/core").Layer} layer
|
|
77
|
+
* @returns {Promise<LayerOptions|null>}
|
|
78
|
+
*/
|
|
79
|
+
export async function serializeLayer(vcsApp, layer) {
|
|
80
|
+
const serializedLayer = layer.toJSON();
|
|
81
|
+
serializedLayer.zIndex = layer[vcsApp.layers.zIndexSymbol];
|
|
82
|
+
return serializedLayer;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @param {import("@vcmap/core").Layer} current
|
|
87
|
+
* @param {import("@vcmap/core").Layer} previous
|
|
88
|
+
* @param {number} currentIndex
|
|
89
|
+
* @returns {number|null}
|
|
90
|
+
*/
|
|
91
|
+
export function getLayerIndex(current, previous, currentIndex) {
|
|
92
|
+
if (current.zIndex !== previous.zIndex) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return currentIndex;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @param {import("@vcmap/core").Collection<*>} collection
|
|
100
|
+
*/
|
|
101
|
+
export function destroyCollection(collection) {
|
|
102
|
+
[...collection].forEach((i) => {
|
|
103
|
+
if (i.destroy && !i.isDestroyed) {
|
|
104
|
+
i.destroy();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
collection.destroy();
|
|
108
|
+
}
|