@vcmap/core 5.0.0-rc.0
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/LICENSE.md +21 -0
- package/README.md +44 -0
- package/build/postinstall.js +44 -0
- package/index.js +139 -0
- package/package.json +92 -0
- package/src/cesium/cesium3DTileFeature.js +9 -0
- package/src/cesium/cesium3DTilePointFeature.js +9 -0
- package/src/cesium/cesiumVcsCameraPrimitive.js +146 -0
- package/src/cesium/wallpaperMaterial.js +64 -0
- package/src/ol/feature.js +47 -0
- package/src/ol/geom/circle.js +24 -0
- package/src/ol/geom/geometryCollection.js +33 -0
- package/src/ol/render/canvas/canvasTileRenderer.js +179 -0
- package/src/ol/source/ClusterEnhancedVectorSource.js +39 -0
- package/src/ol/source/VcsCluster.js +37 -0
- package/src/vcs/vcm/classRegistry.js +106 -0
- package/src/vcs/vcm/event/vcsEvent.js +89 -0
- package/src/vcs/vcm/globalCollections.js +11 -0
- package/src/vcs/vcm/interaction/abstractInteraction.js +149 -0
- package/src/vcs/vcm/interaction/coordinateAtPixel.js +102 -0
- package/src/vcs/vcm/interaction/eventHandler.js +425 -0
- package/src/vcs/vcm/interaction/featureAtPixelInteraction.js +286 -0
- package/src/vcs/vcm/interaction/featureProviderInteraction.js +54 -0
- package/src/vcs/vcm/interaction/interactionChain.js +124 -0
- package/src/vcs/vcm/interaction/interactionType.js +114 -0
- package/src/vcs/vcm/layer/buildings.js +17 -0
- package/src/vcs/vcm/layer/cesium/cesiumTilesetCesium.js +359 -0
- package/src/vcs/vcm/layer/cesium/clusterContext.js +95 -0
- package/src/vcs/vcm/layer/cesium/dataSourceCesium.js +171 -0
- package/src/vcs/vcm/layer/cesium/openStreetMapCesium.js +29 -0
- package/src/vcs/vcm/layer/cesium/pointCloudCesium.js +58 -0
- package/src/vcs/vcm/layer/cesium/rasterLayerCesium.js +110 -0
- package/src/vcs/vcm/layer/cesium/singleImageCesium.js +49 -0
- package/src/vcs/vcm/layer/cesium/terrainCesium.js +80 -0
- package/src/vcs/vcm/layer/cesium/tmsCesium.js +54 -0
- package/src/vcs/vcm/layer/cesium/vectorCesium.js +255 -0
- package/src/vcs/vcm/layer/cesium/vectorContext.js +167 -0
- package/src/vcs/vcm/layer/cesium/vectorRasterTileCesium.js +116 -0
- package/src/vcs/vcm/layer/cesium/vectorTileImageryProvider.js +246 -0
- package/src/vcs/vcm/layer/cesium/wmsCesium.js +71 -0
- package/src/vcs/vcm/layer/cesium/wmtsCesium.js +101 -0
- package/src/vcs/vcm/layer/cesium/x3dmHelper.js +22 -0
- package/src/vcs/vcm/layer/cesiumTileset.js +376 -0
- package/src/vcs/vcm/layer/czml.js +141 -0
- package/src/vcs/vcm/layer/dataSource.js +259 -0
- package/src/vcs/vcm/layer/featureLayer.js +261 -0
- package/src/vcs/vcm/layer/featureStore.js +647 -0
- package/src/vcs/vcm/layer/featureStoreChanges.js +360 -0
- package/src/vcs/vcm/layer/featureStoreState.js +19 -0
- package/src/vcs/vcm/layer/featureVisibility.js +435 -0
- package/src/vcs/vcm/layer/geojson.js +185 -0
- package/src/vcs/vcm/layer/geojsonHelpers.js +450 -0
- package/src/vcs/vcm/layer/globalHider.js +157 -0
- package/src/vcs/vcm/layer/layer.js +752 -0
- package/src/vcs/vcm/layer/layerImplementation.js +102 -0
- package/src/vcs/vcm/layer/layerState.js +17 -0
- package/src/vcs/vcm/layer/layerSymbols.js +6 -0
- package/src/vcs/vcm/layer/oblique/layerOblique.js +76 -0
- package/src/vcs/vcm/layer/oblique/obliqueHelpers.js +175 -0
- package/src/vcs/vcm/layer/oblique/vectorOblique.js +469 -0
- package/src/vcs/vcm/layer/openStreetMap.js +194 -0
- package/src/vcs/vcm/layer/openlayers/layerOpenlayers.js +79 -0
- package/src/vcs/vcm/layer/openlayers/openStreetMapOpenlayers.js +27 -0
- package/src/vcs/vcm/layer/openlayers/rasterLayerOpenlayers.js +121 -0
- package/src/vcs/vcm/layer/openlayers/singleImageOpenlayers.js +49 -0
- package/src/vcs/vcm/layer/openlayers/tileDebugOpenlayers.js +39 -0
- package/src/vcs/vcm/layer/openlayers/tmsOpenlayers.js +62 -0
- package/src/vcs/vcm/layer/openlayers/vectorOpenlayers.js +118 -0
- package/src/vcs/vcm/layer/openlayers/vectorTileOpenlayers.js +177 -0
- package/src/vcs/vcm/layer/openlayers/wmsOpenlayers.js +55 -0
- package/src/vcs/vcm/layer/openlayers/wmtsOpenlayers.js +141 -0
- package/src/vcs/vcm/layer/pointCloud.js +162 -0
- package/src/vcs/vcm/layer/rasterLayer.js +294 -0
- package/src/vcs/vcm/layer/singleImage.js +119 -0
- package/src/vcs/vcm/layer/terrain.js +122 -0
- package/src/vcs/vcm/layer/terrainHelpers.js +123 -0
- package/src/vcs/vcm/layer/tileLoadedHelper.js +72 -0
- package/src/vcs/vcm/layer/tileProvider/mvtTileProvider.js +104 -0
- package/src/vcs/vcm/layer/tileProvider/staticGeojsonTileProvider.js +67 -0
- package/src/vcs/vcm/layer/tileProvider/tileProvider.js +584 -0
- package/src/vcs/vcm/layer/tileProvider/tileProviderFactory.js +28 -0
- package/src/vcs/vcm/layer/tileProvider/urlTemplateTileProvider.js +106 -0
- package/src/vcs/vcm/layer/tms.js +121 -0
- package/src/vcs/vcm/layer/vector.js +632 -0
- package/src/vcs/vcm/layer/vectorHelpers.js +206 -0
- package/src/vcs/vcm/layer/vectorProperties.js +1391 -0
- package/src/vcs/vcm/layer/vectorSymbols.js +40 -0
- package/src/vcs/vcm/layer/vectorTile.js +480 -0
- package/src/vcs/vcm/layer/wfs.js +165 -0
- package/src/vcs/vcm/layer/wms.js +270 -0
- package/src/vcs/vcm/layer/wmsHelpers.js +65 -0
- package/src/vcs/vcm/layer/wmts.js +235 -0
- package/src/vcs/vcm/maps/baseOLMap.js +257 -0
- package/src/vcs/vcm/maps/cameraLimiter.js +219 -0
- package/src/vcs/vcm/maps/cesium.js +1192 -0
- package/src/vcs/vcm/maps/map.js +511 -0
- package/src/vcs/vcm/maps/mapState.js +17 -0
- package/src/vcs/vcm/maps/oblique.js +536 -0
- package/src/vcs/vcm/maps/openlayers.js +205 -0
- package/src/vcs/vcm/object.js +92 -0
- package/src/vcs/vcm/oblique/ObliqueCollection.js +572 -0
- package/src/vcs/vcm/oblique/ObliqueDataSet.js +357 -0
- package/src/vcs/vcm/oblique/ObliqueImage.js +247 -0
- package/src/vcs/vcm/oblique/ObliqueImageMeta.js +126 -0
- package/src/vcs/vcm/oblique/ObliqueProvider.js +433 -0
- package/src/vcs/vcm/oblique/ObliqueView.js +130 -0
- package/src/vcs/vcm/oblique/ObliqueViewDirection.js +40 -0
- package/src/vcs/vcm/oblique/helpers.js +483 -0
- package/src/vcs/vcm/oblique/parseImageJson.js +248 -0
- package/src/vcs/vcm/util/clipping/clippingObject.js +386 -0
- package/src/vcs/vcm/util/clipping/clippingObjectManager.js +312 -0
- package/src/vcs/vcm/util/clipping/clippingPlaneHelper.js +413 -0
- package/src/vcs/vcm/util/collection.js +193 -0
- package/src/vcs/vcm/util/dateTime.js +60 -0
- package/src/vcs/vcm/util/exclusiveManager.js +135 -0
- package/src/vcs/vcm/util/extent.js +124 -0
- package/src/vcs/vcm/util/featureProvider/abstractFeatureProvider.js +196 -0
- package/src/vcs/vcm/util/featureProvider/featureProviderHelpers.js +51 -0
- package/src/vcs/vcm/util/featureProvider/featureProviderSymbols.js +11 -0
- package/src/vcs/vcm/util/featureProvider/tileProviderFeatureProvider.js +62 -0
- package/src/vcs/vcm/util/featureProvider/wmsFeatureProvider.js +280 -0
- package/src/vcs/vcm/util/featureconverter/circleToCesium.js +215 -0
- package/src/vcs/vcm/util/featureconverter/convert.js +83 -0
- package/src/vcs/vcm/util/featureconverter/extent3d.js +154 -0
- package/src/vcs/vcm/util/featureconverter/featureconverterHelper.js +591 -0
- package/src/vcs/vcm/util/featureconverter/lineStringToCesium.js +171 -0
- package/src/vcs/vcm/util/featureconverter/pointToCesium.js +359 -0
- package/src/vcs/vcm/util/featureconverter/polygonToCesium.js +229 -0
- package/src/vcs/vcm/util/geometryHelpers.js +172 -0
- package/src/vcs/vcm/util/indexedCollection.js +158 -0
- package/src/vcs/vcm/util/isMobile.js +12 -0
- package/src/vcs/vcm/util/layerCollection.js +216 -0
- package/src/vcs/vcm/util/locale.js +53 -0
- package/src/vcs/vcm/util/mapCollection.js +363 -0
- package/src/vcs/vcm/util/math.js +71 -0
- package/src/vcs/vcm/util/projection.js +348 -0
- package/src/vcs/vcm/util/splitScreen.js +233 -0
- package/src/vcs/vcm/util/style/declarativeStyleItem.js +631 -0
- package/src/vcs/vcm/util/style/shapesCategory.js +67 -0
- package/src/vcs/vcm/util/style/styleFactory.js +48 -0
- package/src/vcs/vcm/util/style/styleHelpers.js +555 -0
- package/src/vcs/vcm/util/style/styleItem.js +226 -0
- package/src/vcs/vcm/util/style/vectorStyleItem.js +927 -0
- package/src/vcs/vcm/util/style/writeStyle.js +48 -0
- package/src/vcs/vcm/util/urlHelpers.js +16 -0
- package/src/vcs/vcm/util/viewpoint.js +333 -0
|
@@ -0,0 +1,752 @@
|
|
|
1
|
+
import { check } from '@vcsuite/check';
|
|
2
|
+
import { parseBoolean, parseInteger } from '@vcsuite/parsers';
|
|
3
|
+
import VcsObject from '../object.js';
|
|
4
|
+
import Extent from '../util/extent.js';
|
|
5
|
+
import { getGlobalHider } from './globalHider.js';
|
|
6
|
+
import { vcsLayerName } from './layerSymbols.js';
|
|
7
|
+
import LayerState from './layerState.js';
|
|
8
|
+
import VcsEvent from '../event/vcsEvent.js';
|
|
9
|
+
import { getCurrentLocale, getLocaleChangedEvent } from '../util/locale.js';
|
|
10
|
+
import { VcsClassRegistry } from '../classRegistry.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {Object} GenericFeature
|
|
14
|
+
* @property {number} longitude
|
|
15
|
+
* @property {number} latitude
|
|
16
|
+
* @property {number} height
|
|
17
|
+
* @property {string} layerName
|
|
18
|
+
* @property {string} layerClass
|
|
19
|
+
* @property {any} attributes
|
|
20
|
+
* @property {boolean} relativeToGround
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {import("@vcmap/core").Layer} SplitLayer
|
|
25
|
+
* @property {import("@vcmap/cesium").ImagerySplitDirection} splitDirection
|
|
26
|
+
* @property {VcsEvent<import("@vcmap/cesium").ImagerySplitDirection>} splitDirectionChanged
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {Object} CopyrightOptions
|
|
31
|
+
* @property {string|undefined} provider
|
|
32
|
+
* @property {string|undefined} url
|
|
33
|
+
* @property {string|undefined} year
|
|
34
|
+
* @api
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
// TODO add flight options if flight is moved to core
|
|
38
|
+
/**
|
|
39
|
+
* @typedef {VectorPropertiesOptions} VcsMeta
|
|
40
|
+
* @property {string|undefined} version - the version of the vcsMeta schema
|
|
41
|
+
* @property {VectorStyleItemOptions|DeclarativeStyleItemOptions|Reference|undefined} style
|
|
42
|
+
* @property {Array<string>|undefined} embeddedIcons
|
|
43
|
+
* @property {number|undefined} screenSpaceError
|
|
44
|
+
* @property {*|undefined} flightOptions
|
|
45
|
+
* @property {string|undefined} baseUrl
|
|
46
|
+
* @api
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @typedef {VcsObjectOptions} LayerOptions
|
|
51
|
+
* @property {string|undefined} name - the name of the layer, used to retrieve the layer from the framework. if not specified, a uuid is generated
|
|
52
|
+
* @property {boolean} [activeOnStartup=false] - if true the layer will be activated on initialization
|
|
53
|
+
* @property {boolean} [allowPicking=true] - whether to allow picking on this layer
|
|
54
|
+
* @property {number|undefined} zIndex - zIndex of this layer
|
|
55
|
+
* @property {ExtentOptions|undefined} extent - metadata on the data extent of the layer.
|
|
56
|
+
* @property {Array<string|symbol>|undefined} [exclusiveGroups=[]] -
|
|
57
|
+
* @property {Array<string>|undefined} mapNames - the map names on which this layer is shown, all if empty
|
|
58
|
+
* @property {string|Object|undefined} url - for most layers, a resource url will be needed
|
|
59
|
+
* @property {Array<string>|undefined} hiddenObjectIds - an array of building ids which should be hidden if this layer is active
|
|
60
|
+
* @property {CopyrightOptions|undefined} copyright
|
|
61
|
+
* @api
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The options passed to a layer implementation.
|
|
66
|
+
* @typedef {Object} LayerImplementationOptions
|
|
67
|
+
* @property {string} name
|
|
68
|
+
* @property {string} url
|
|
69
|
+
* @api
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Layer implementations for the {@link CesiumMap} map
|
|
74
|
+
* @namespace cesium
|
|
75
|
+
* @api stable
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Layer implementations for the {@link Oblique} map
|
|
80
|
+
* @namespace oblique
|
|
81
|
+
* @api stable
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Layer implementations for the {@link Openlayers} map
|
|
86
|
+
* @namespace openlayers
|
|
87
|
+
* @api stable
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The version of vcsMeta schema being written by this helper
|
|
92
|
+
* @type {string}
|
|
93
|
+
* @const
|
|
94
|
+
*/
|
|
95
|
+
export const vcsMetaVersion = '2.0';
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Abstract base class for Layers.
|
|
99
|
+
* To create a layer Implementation the function `createImplementationsForMap` has to be implemented.
|
|
100
|
+
* To receive implementation options, implement `geImplementationOptions`
|
|
101
|
+
* @abstract
|
|
102
|
+
* @class
|
|
103
|
+
* @export
|
|
104
|
+
* @extends {VcsObject}
|
|
105
|
+
* @api stable
|
|
106
|
+
*/
|
|
107
|
+
class Layer extends VcsObject {
|
|
108
|
+
/** @type {string} */
|
|
109
|
+
static get className() { return 'vcs.vcm.layer.Layer'; }
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Symbol to declare a layers name on its visualizations, e.g. ol.layer.Layer, Cesium.Cesium3DTileset
|
|
113
|
+
* @type {symbol}
|
|
114
|
+
* @api
|
|
115
|
+
*/
|
|
116
|
+
static get vcsLayerNameSymbol() { return vcsLayerName; }
|
|
117
|
+
|
|
118
|
+
/** @returns {LayerOptions} */
|
|
119
|
+
static getDefaultOptions() {
|
|
120
|
+
return {
|
|
121
|
+
name: undefined,
|
|
122
|
+
extent: undefined,
|
|
123
|
+
activeOnStartup: false,
|
|
124
|
+
allowPicking: true,
|
|
125
|
+
exclusiveGroups: [],
|
|
126
|
+
mapNames: [],
|
|
127
|
+
url: undefined,
|
|
128
|
+
hiddenObjectIds: [],
|
|
129
|
+
copyright: undefined,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @param {LayerOptions} options
|
|
135
|
+
*/
|
|
136
|
+
constructor(options) {
|
|
137
|
+
super(options);
|
|
138
|
+
const defaultOptions = Layer.getDefaultOptions();
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Metadata on the extent of the data in this layer. Depending on the implementation, data is only requested
|
|
142
|
+
* for this extent (e.g. {@see RasterLayer})
|
|
143
|
+
* @type {Extent|null}
|
|
144
|
+
* @api
|
|
145
|
+
*/
|
|
146
|
+
this.extent = options.extent ? new Extent(options.extent) : null;
|
|
147
|
+
/**
|
|
148
|
+
* Whether this layer should be active on startup or not. Relevant for creating links.
|
|
149
|
+
* @type {boolean}
|
|
150
|
+
* @api
|
|
151
|
+
*/
|
|
152
|
+
this.activeOnStartup = parseBoolean(options.activeOnStartup, defaultOptions.activeOnStartup);
|
|
153
|
+
/**
|
|
154
|
+
* @type {boolean}
|
|
155
|
+
* @private
|
|
156
|
+
*/
|
|
157
|
+
this._allowPicking = parseBoolean(options.allowPicking, defaultOptions.allowPicking);
|
|
158
|
+
/**
|
|
159
|
+
* @type {LayerState}
|
|
160
|
+
* @private
|
|
161
|
+
*/
|
|
162
|
+
this._state = LayerState.INACTIVE;
|
|
163
|
+
/**
|
|
164
|
+
* @type {Promise<void>|null}
|
|
165
|
+
* @private
|
|
166
|
+
*/
|
|
167
|
+
this._loadingPromise = null;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* @type {boolean}
|
|
171
|
+
* @private
|
|
172
|
+
*/
|
|
173
|
+
this._initialized = false;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* the names of the maps this layer is shown, all if empty
|
|
177
|
+
* @type {Array.<string>}
|
|
178
|
+
*/
|
|
179
|
+
this.mapNames = options.mapNames || defaultOptions.mapNames;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* The class names of the supported maps.
|
|
183
|
+
* @type {Array<string>}
|
|
184
|
+
* @protected
|
|
185
|
+
* @api
|
|
186
|
+
*/
|
|
187
|
+
this._supportedMaps = [];
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @type {string|Object}
|
|
191
|
+
* @private
|
|
192
|
+
*/
|
|
193
|
+
this._url = options.url;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @type {Function}
|
|
197
|
+
* @private
|
|
198
|
+
*/
|
|
199
|
+
this._localeChangedListener = null;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* @type {number}
|
|
203
|
+
* @private
|
|
204
|
+
*/
|
|
205
|
+
this._zIndex = parseInteger(options.zIndex, 0);
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Called when the zIndex of this layer is changed. Is passed the new zIndex as its only argument.
|
|
209
|
+
* @type {VcsEvent<number>}
|
|
210
|
+
* @api
|
|
211
|
+
*/
|
|
212
|
+
this.zIndexChanged = new VcsEvent();
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* array of object Ids which should be hidden within the context of the layers layerCollection, if this layer is active
|
|
216
|
+
* @type {Array.<string>}
|
|
217
|
+
* @api
|
|
218
|
+
*/
|
|
219
|
+
this.hiddenObjectIds = Array.isArray(options.hiddenObjectIds) ?
|
|
220
|
+
options.hiddenObjectIds :
|
|
221
|
+
defaultOptions.hiddenObjectIds;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* @type {Array<string|symbol>}
|
|
225
|
+
* @private
|
|
226
|
+
*/
|
|
227
|
+
this._exclusiveGroups = Array.isArray(options.exclusiveGroups) ?
|
|
228
|
+
options.exclusiveGroups.slice() :
|
|
229
|
+
defaultOptions.exclusiveGroups;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* event raised if the exclusives group of the layer changes. is passed the array of exclusive groups as its only argument
|
|
233
|
+
* @type {VcsEvent<Array<string|symbol>>}
|
|
234
|
+
* @api
|
|
235
|
+
*/
|
|
236
|
+
this.exclusiveGroupsChanged = new VcsEvent();
|
|
237
|
+
|
|
238
|
+
/** @type {import("@vcmap/core").GlobalHider} */
|
|
239
|
+
this.globalHider = getGlobalHider();
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* @type {CopyrightOptions|undefined}
|
|
243
|
+
*/
|
|
244
|
+
this.copyright = options.copyright || defaultOptions.copyright;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* @type {Map<import("@vcmap/core").VcsMap, Array<import("@vcmap/core").LayerImplementation>>}
|
|
248
|
+
* @private
|
|
249
|
+
*/
|
|
250
|
+
this._implementations = new Map();
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* @type {Set<import("@vcmap/core").VcsMap>}
|
|
254
|
+
* @private
|
|
255
|
+
*/
|
|
256
|
+
this._activeMaps = new Set();
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Event raised, if the layers state changes. Is passed the LayerState as its only parameter
|
|
260
|
+
* @type {VcsEvent<LayerState>}
|
|
261
|
+
* @api
|
|
262
|
+
*/
|
|
263
|
+
this.stateChanged = new VcsEvent();
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* An optional feature provider to provider features based on click events.
|
|
267
|
+
* @type {import("@vcmap/core").AbstractFeatureProvider}
|
|
268
|
+
* @api
|
|
269
|
+
*/
|
|
270
|
+
this.featureProvider = undefined;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* True if this layer has been initialized, typically after its first activation.
|
|
275
|
+
* @type {boolean}
|
|
276
|
+
* @readonly
|
|
277
|
+
* @api
|
|
278
|
+
*/
|
|
279
|
+
get initialized() {
|
|
280
|
+
return this._initialized;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* @api
|
|
285
|
+
* @type {boolean}
|
|
286
|
+
* @readonly
|
|
287
|
+
*/
|
|
288
|
+
get active() {
|
|
289
|
+
return this._state === LayerState.ACTIVE;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* @api
|
|
294
|
+
* @type {boolean}
|
|
295
|
+
* @readonly
|
|
296
|
+
*/
|
|
297
|
+
get loading() {
|
|
298
|
+
return !!(this._state & LayerState.LOADING);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* @api
|
|
303
|
+
* @type {LayerState}
|
|
304
|
+
* @readonly
|
|
305
|
+
*/
|
|
306
|
+
get state() {
|
|
307
|
+
return this._state;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* @api
|
|
312
|
+
* @type {boolean}
|
|
313
|
+
*/
|
|
314
|
+
get allowPicking() {
|
|
315
|
+
return this._allowPicking;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* @param {boolean} allowPicking
|
|
320
|
+
*/
|
|
321
|
+
set allowPicking(allowPicking) {
|
|
322
|
+
this._allowPicking = allowPicking;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* A layers url, should on be configured, else an empty string
|
|
327
|
+
* @type {string}
|
|
328
|
+
* @api
|
|
329
|
+
*/
|
|
330
|
+
get url() {
|
|
331
|
+
if (this._url) {
|
|
332
|
+
if (typeof this._url === 'string') {
|
|
333
|
+
return this._url;
|
|
334
|
+
}
|
|
335
|
+
const locale = getCurrentLocale();
|
|
336
|
+
if (this._url[locale]) {
|
|
337
|
+
return this._url[locale];
|
|
338
|
+
}
|
|
339
|
+
return Object.values(this._url)[0];
|
|
340
|
+
}
|
|
341
|
+
return '';
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* @param {string|Object} url
|
|
346
|
+
*/
|
|
347
|
+
set url(url) {
|
|
348
|
+
check(url, [String, Object]);
|
|
349
|
+
|
|
350
|
+
if (this._url !== url) {
|
|
351
|
+
this._url = url;
|
|
352
|
+
this.reload();
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Indicates, that this layer is part of an exclusiveGroup
|
|
358
|
+
* @api
|
|
359
|
+
* @type {boolean}
|
|
360
|
+
* @readonly
|
|
361
|
+
*/
|
|
362
|
+
get exclusive() {
|
|
363
|
+
return this._exclusiveGroups.length > 0;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* An array of arbitrary exclusive groups
|
|
368
|
+
* @returns {Array<string|symbol>}
|
|
369
|
+
* @readonly
|
|
370
|
+
* @api
|
|
371
|
+
*/
|
|
372
|
+
get exclusiveGroups() {
|
|
373
|
+
return this._exclusiveGroups.slice();
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* @param {Array<string|symbol>} groups
|
|
378
|
+
*/
|
|
379
|
+
set exclusiveGroups(groups) {
|
|
380
|
+
check(groups, [[String, Symbol]]);
|
|
381
|
+
|
|
382
|
+
if (
|
|
383
|
+
groups.length !== this._exclusiveGroups.length ||
|
|
384
|
+
!groups.every(g => this._exclusiveGroups.includes(g))
|
|
385
|
+
) {
|
|
386
|
+
this._exclusiveGroups = groups.slice();
|
|
387
|
+
this.exclusiveGroupsChanged.raiseEvent(groups);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* @type {number}
|
|
393
|
+
* @api
|
|
394
|
+
*/
|
|
395
|
+
get zIndex() { return this._zIndex; }
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* @param {number} index
|
|
399
|
+
*/
|
|
400
|
+
set zIndex(index) {
|
|
401
|
+
check(index, Number);
|
|
402
|
+
|
|
403
|
+
if (this._zIndex !== index) {
|
|
404
|
+
this._zIndex = index;
|
|
405
|
+
this.zIndexChanged.raiseEvent(index);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* creates an array of layer implementations for the given map.
|
|
411
|
+
* @param {import("@vcmap/core").VcsMap} map Map
|
|
412
|
+
* @returns {Array<import("@vcmap/core").LayerImplementation<import("@vcmap/core").VcsMap>>} return the specific implementation
|
|
413
|
+
*/
|
|
414
|
+
// eslint-disable-next-line class-methods-use-this,no-unused-vars
|
|
415
|
+
createImplementationsForMap(map) {
|
|
416
|
+
return [];
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* creates or returns a cached array of layer implementations for the given map.
|
|
421
|
+
* @param {import("@vcmap/core").VcsMap} map initialized Map
|
|
422
|
+
* @returns {Array<import("@vcmap/core").LayerImplementation<import("@vcmap/core").VcsMap>>} return the specific implementation
|
|
423
|
+
* @api
|
|
424
|
+
*/
|
|
425
|
+
getImplementationsForMap(map) {
|
|
426
|
+
if (!this._implementations.has(map)) {
|
|
427
|
+
if (this.isSupported(map)) {
|
|
428
|
+
this._implementations.set(map, this.createImplementationsForMap(map));
|
|
429
|
+
} else {
|
|
430
|
+
this._implementations.set(map, []);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return this._implementations.get(map);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Returns all implementation of this layer for all maps
|
|
438
|
+
* @returns {Array<import("@vcmap/core").LayerImplementation<import("@vcmap/core").VcsMap>>}
|
|
439
|
+
* @api
|
|
440
|
+
*/
|
|
441
|
+
getImplementations() {
|
|
442
|
+
return [...this._implementations.values()].flat();
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* @returns {LayerImplementationOptions}
|
|
447
|
+
*/
|
|
448
|
+
getImplementationOptions() {
|
|
449
|
+
return {
|
|
450
|
+
name: this.name,
|
|
451
|
+
url: this.url,
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Reloads all the data loaded and forces a redraw
|
|
457
|
+
* @returns {Promise<void>}
|
|
458
|
+
* @api
|
|
459
|
+
*/
|
|
460
|
+
reload() {
|
|
461
|
+
return this.forceRedraw();
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* destroys all current implementations and recreates the ones which have an active map.
|
|
466
|
+
* called for instance when the URL for a layer changes
|
|
467
|
+
* @returns {Promise<void>}
|
|
468
|
+
* @api
|
|
469
|
+
*/
|
|
470
|
+
async forceRedraw() {
|
|
471
|
+
const maps = [...this._implementations.keys()];
|
|
472
|
+
|
|
473
|
+
const promises = maps.map((map) => {
|
|
474
|
+
this.removedFromMap(map);
|
|
475
|
+
if (map.active) {
|
|
476
|
+
return this.mapActivated(map);
|
|
477
|
+
}
|
|
478
|
+
return Promise.resolve();
|
|
479
|
+
});
|
|
480
|
+
await Promise.all(promises);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* returns the Extent of this layer
|
|
485
|
+
* @returns {Extent}
|
|
486
|
+
* @api stable
|
|
487
|
+
*/
|
|
488
|
+
getExtent() {
|
|
489
|
+
return this.extent;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* returns the Extent of this layer or null, if the layers extent was not defined or cannot be established
|
|
494
|
+
* @returns {Extent|null}
|
|
495
|
+
* @api stable
|
|
496
|
+
*/
|
|
497
|
+
getZoomToExtent() {
|
|
498
|
+
if (this.extent && this.extent.isValid()) {
|
|
499
|
+
return this.extent;
|
|
500
|
+
}
|
|
501
|
+
return null;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* recreates the implementations on locale change, if the url of this layer is an Object
|
|
506
|
+
* @param {string} locale
|
|
507
|
+
* @private
|
|
508
|
+
*/
|
|
509
|
+
_handleLocaleChange(locale) {
|
|
510
|
+
if (this._url && typeof this._url === 'object' && this._url[locale]) {
|
|
511
|
+
this.reload();
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* initializes the layer, can be used to defer loading
|
|
517
|
+
* @returns {Promise<void>}
|
|
518
|
+
*/
|
|
519
|
+
initialize() {
|
|
520
|
+
if (!this.initialized) {
|
|
521
|
+
this._localeChangedListener = getLocaleChangedEvent().addEventListener(this._handleLocaleChange.bind(this));
|
|
522
|
+
}
|
|
523
|
+
this._initialized = true;
|
|
524
|
+
return Promise.resolve();
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* is called from the map when the map is activated, and this layer is in the layerCollection of the map.
|
|
529
|
+
* Will create an implementation if it does not exits and will forward the activation call to the implementation.
|
|
530
|
+
* @param {import("@vcmap/core").VcsMap} map
|
|
531
|
+
* @returns {Promise<void>}
|
|
532
|
+
*/
|
|
533
|
+
async mapActivated(map) {
|
|
534
|
+
this.getLogger().debug(`Layer: ${this.name} mapActivated is called from Map: ${map.name}`);
|
|
535
|
+
this._activeMaps.add(map);
|
|
536
|
+
if (this.active || (this.loading && this.initialized)) {
|
|
537
|
+
await this._activateImplsForMap(map);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* is called from the map when the map is deactivated, and this layer is in the layerCollection of the map.
|
|
543
|
+
* will forward deactivation call to the map specific implementation
|
|
544
|
+
* @param {import("@vcmap/core").VcsMap} map
|
|
545
|
+
*/
|
|
546
|
+
mapDeactivated(map) {
|
|
547
|
+
this.getLogger().debug(`Layer: ${this.name} mapDeactivated is called from Map: ${map.name}`);
|
|
548
|
+
this._activeMaps.delete(map);
|
|
549
|
+
if (this.active || this.loading) {
|
|
550
|
+
this.getImplementationsForMap(map)
|
|
551
|
+
.forEach((impl) => {
|
|
552
|
+
impl.deactivate();
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* is called when a layer is removed from the layer collection of a map or said map is destroyed.
|
|
559
|
+
* destroys the associated implementation.
|
|
560
|
+
* @param {import("@vcmap/core").VcsMap} map
|
|
561
|
+
*/
|
|
562
|
+
removedFromMap(map) {
|
|
563
|
+
this._activeMaps.delete(map);
|
|
564
|
+
this.getImplementationsForMap(map)
|
|
565
|
+
.forEach((impl) => {
|
|
566
|
+
impl.destroy();
|
|
567
|
+
});
|
|
568
|
+
this._implementations.delete(map);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* checks if the currently active map supports this layer
|
|
573
|
+
* @param {import("@vcmap/core").VcsMap} map
|
|
574
|
+
* @returns {boolean}
|
|
575
|
+
* @api stable
|
|
576
|
+
*/
|
|
577
|
+
isSupported(map) {
|
|
578
|
+
return map &&
|
|
579
|
+
this._supportedMaps.includes(map.className) &&
|
|
580
|
+
(this.mapNames.length === 0 || this.mapNames.indexOf(map.name) >= 0);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* @param {import("@vcmap/core").VcsMap} map
|
|
585
|
+
* @returns {Promise<void>}
|
|
586
|
+
* @private
|
|
587
|
+
*/
|
|
588
|
+
async _activateImplsForMap(map) {
|
|
589
|
+
const impls = this.getImplementationsForMap(map);
|
|
590
|
+
try {
|
|
591
|
+
await Promise.all(impls.map(i => i.activate()));
|
|
592
|
+
} catch (err) {
|
|
593
|
+
this.getLogger().error(`Layer ${this.name} could not activate impl for map ${map.name}`);
|
|
594
|
+
this.getLogger().error(err);
|
|
595
|
+
this._implementations.set(map, []);
|
|
596
|
+
impls.forEach((i) => { i.destroy(); });
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* @returns {Promise<void>}
|
|
602
|
+
* @private
|
|
603
|
+
*/
|
|
604
|
+
async _activate() {
|
|
605
|
+
this._state = LayerState.LOADING;
|
|
606
|
+
try {
|
|
607
|
+
this.stateChanged.raiseEvent(LayerState.LOADING);
|
|
608
|
+
} catch (e) {
|
|
609
|
+
this.getLogger().debug(`Error on raising LayerState.LOADING event for layer ${this.name} : ${e.message}`);
|
|
610
|
+
}
|
|
611
|
+
await this.initialize();
|
|
612
|
+
if (this._state !== LayerState.LOADING) {
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
await Promise.all([...this._activeMaps].map(m => this._activateImplsForMap(m)));
|
|
617
|
+
if (this._state !== LayerState.LOADING) {
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
this.globalHider.hideObjects(this.hiddenObjectIds);
|
|
621
|
+
this._state = LayerState.ACTIVE;
|
|
622
|
+
try {
|
|
623
|
+
this.stateChanged.raiseEvent(LayerState.ACTIVE);
|
|
624
|
+
} catch (e) {
|
|
625
|
+
this.getLogger().debug(`Error on raising LayerState.ACTIVE event for layer ${this.name} : ${e.message}`);
|
|
626
|
+
}
|
|
627
|
+
this._loadingPromise = null;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Activates this layer object, i.e. changes its internal view state
|
|
632
|
+
* and updates the map. The returned promise resolves, once the layer & any _implementations are initialized
|
|
633
|
+
* and all data is loaded.
|
|
634
|
+
* Once the promise resolves, the layer can still be inactive, if deactivate was called while initializing the layer.
|
|
635
|
+
* @returns {Promise<void>}
|
|
636
|
+
* @api stable
|
|
637
|
+
*/
|
|
638
|
+
activate() {
|
|
639
|
+
if (this._loadingPromise) {
|
|
640
|
+
return this._loadingPromise;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (this._state === LayerState.INACTIVE) {
|
|
644
|
+
this._loadingPromise = this._activate()
|
|
645
|
+
.catch((err) => {
|
|
646
|
+
this._state = LayerState.INACTIVE;
|
|
647
|
+
return Promise.reject(err);
|
|
648
|
+
});
|
|
649
|
+
return this._loadingPromise;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
return Promise.resolve();
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Deactivates a layer, changing the internal view state
|
|
657
|
+
* @api
|
|
658
|
+
*/
|
|
659
|
+
deactivate() {
|
|
660
|
+
if (this._loadingPromise) {
|
|
661
|
+
this._loadingPromise = null;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
if (this._state !== LayerState.INACTIVE) {
|
|
665
|
+
this.getImplementations().forEach((impl) => {
|
|
666
|
+
if (impl.loading || impl.active) {
|
|
667
|
+
impl.deactivate();
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
this.globalHider.showObjects(this.hiddenObjectIds);
|
|
671
|
+
this._state = LayerState.INACTIVE;
|
|
672
|
+
try {
|
|
673
|
+
this.stateChanged.raiseEvent(LayerState.INACTIVE);
|
|
674
|
+
} catch (e) {
|
|
675
|
+
this.getLogger().debug(`Error on raising LayerState.INACTIVE event for layer ${this.name} : ${e.message}`);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* @returns {LayerOptions}
|
|
682
|
+
*/
|
|
683
|
+
getConfigObject() {
|
|
684
|
+
/** @type {LayerOptions} */
|
|
685
|
+
const config = super.getConfigObject();
|
|
686
|
+
const defaultOptions = Layer.getDefaultOptions();
|
|
687
|
+
|
|
688
|
+
if (this.activeOnStartup !== defaultOptions.activeOnStartup) {
|
|
689
|
+
config.activeOnStartup = this.activeOnStartup;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
if (this.allowPicking !== defaultOptions.allowPicking) {
|
|
693
|
+
config.allowPicking = this.allowPicking;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
if (this.mapNames.length > 0) {
|
|
697
|
+
config.mapNames = this.mapNames.slice();
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
if (this.hiddenObjectIds.length > 0) {
|
|
701
|
+
config.hiddenObjectIds = this.hiddenObjectIds.slice();
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
if (this._url) {
|
|
705
|
+
config.url = this._url;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
if (this.extent && this.extent.isValid()) {
|
|
709
|
+
config.extent = this.extent.getConfigObject();
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
if (this._exclusiveGroups.length > 0) {
|
|
713
|
+
config.exclusiveGroups = this._exclusiveGroups.slice();
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
if (this.copyright !== defaultOptions.copyright) {
|
|
717
|
+
config.copyright = { ...this.copyright };
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
return config;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* disposes of this layer, removes instances from the current maps and the framework
|
|
725
|
+
* @api stable
|
|
726
|
+
*/
|
|
727
|
+
destroy() {
|
|
728
|
+
super.destroy();
|
|
729
|
+
if (this.featureProvider) {
|
|
730
|
+
this.featureProvider.destroy();
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
this._activeMaps.clear();
|
|
734
|
+
this.getImplementations()
|
|
735
|
+
.forEach((impl) => {
|
|
736
|
+
impl.destroy();
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
if (this._localeChangedListener) {
|
|
740
|
+
this._localeChangedListener();
|
|
741
|
+
this._localeChangedListener = null;
|
|
742
|
+
}
|
|
743
|
+
this._initialized = false;
|
|
744
|
+
this._implementations.clear();
|
|
745
|
+
this.stateChanged.destroy();
|
|
746
|
+
this.zIndexChanged.destroy();
|
|
747
|
+
this.exclusiveGroupsChanged.destroy();
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
VcsClassRegistry.registerClass(Layer.className, Layer);
|
|
752
|
+
export default Layer;
|