@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,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracks layer exclusivity, added to every {@link LayerCollection}.
|
|
3
|
+
* @class
|
|
4
|
+
* @api
|
|
5
|
+
*/
|
|
6
|
+
class ExclusiveManager {
|
|
7
|
+
constructor() {
|
|
8
|
+
/**
|
|
9
|
+
* The layers managed by this manager. The key is the group.
|
|
10
|
+
* @type {Map<(string|symbol), Set<import("@vcmap/core").Layer>>}
|
|
11
|
+
* @api
|
|
12
|
+
*/
|
|
13
|
+
this.layers = new Map();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* registers a Layer as Exclusive, the activation of a layer triggers the deactivation of all other exclusive Layers.
|
|
18
|
+
* The layer collection adds exclusive layers to the manager on adding the layer to the collection.
|
|
19
|
+
* @param {import("@vcmap/core").Layer} layer - layer to register
|
|
20
|
+
* @api
|
|
21
|
+
*/
|
|
22
|
+
registerLayer(layer) {
|
|
23
|
+
const { exclusiveGroups } = layer;
|
|
24
|
+
if (exclusiveGroups.length > 0) {
|
|
25
|
+
exclusiveGroups.forEach((group) => {
|
|
26
|
+
if (!this.layers.has(group)) {
|
|
27
|
+
this.layers.set(group, new Set());
|
|
28
|
+
}
|
|
29
|
+
const groupSet = this.layers.get(group);
|
|
30
|
+
groupSet.add(layer);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (layer.active) {
|
|
34
|
+
this.handleLayerActivated(layer);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Removes a layer from tracking. Layer collections remove the layer once they are removed from them.
|
|
41
|
+
* @param {import("@vcmap/core").Layer} layer - layer to unregister
|
|
42
|
+
* @api
|
|
43
|
+
*/
|
|
44
|
+
unregisterLayer(layer) {
|
|
45
|
+
const { exclusiveGroups } = layer;
|
|
46
|
+
if (exclusiveGroups.length > 0) {
|
|
47
|
+
exclusiveGroups.forEach((group) => {
|
|
48
|
+
this.layers.get(group).delete(layer);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @param {import("@vcmap/core").Layer} layer
|
|
55
|
+
*/
|
|
56
|
+
handleSplitDirectionChanged(layer) {
|
|
57
|
+
if (layer.active) {
|
|
58
|
+
this.handleLayerActivated(layer);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* handles the changing of a layer
|
|
64
|
+
* @param {import("@vcmap/core").Layer} layer
|
|
65
|
+
*/
|
|
66
|
+
handleLayerActivated(layer) {
|
|
67
|
+
const { exclusiveGroups } = layer;
|
|
68
|
+
if (exclusiveGroups.length > 0) {
|
|
69
|
+
const splitDirection = /** @type {SplitLayer} */ (layer).splitDirection || 0;
|
|
70
|
+
exclusiveGroups.forEach((group) => {
|
|
71
|
+
if (this.layers.has(group)) {
|
|
72
|
+
this.layers.get(group).forEach((groupLayer) => {
|
|
73
|
+
if (
|
|
74
|
+
groupLayer !== layer && !(
|
|
75
|
+
splitDirection &&
|
|
76
|
+
/** @type {SplitLayer} */ (groupLayer).splitDirection &&
|
|
77
|
+
/** @type {SplitLayer} */ (groupLayer).splitDirection !== splitDirection
|
|
78
|
+
)
|
|
79
|
+
) {
|
|
80
|
+
groupLayer.deactivate();
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @param {import("@vcmap/core").Layer} layer
|
|
90
|
+
*/
|
|
91
|
+
handleExclusiveGroupsChanged(layer) {
|
|
92
|
+
[...this.layers.values()].forEach((set) => {
|
|
93
|
+
set.delete(layer);
|
|
94
|
+
});
|
|
95
|
+
this.registerLayer(layer);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Gets all layers in the given group
|
|
100
|
+
* @param {string} group
|
|
101
|
+
* @returns {Array<import("@vcmap/core").Layer>}
|
|
102
|
+
* @api
|
|
103
|
+
*/
|
|
104
|
+
getActiveLayersForGroup(group) {
|
|
105
|
+
const layerGroup = this.layers.get(group);
|
|
106
|
+
if (layerGroup) {
|
|
107
|
+
const activeLayers = [];
|
|
108
|
+
layerGroup.forEach((groupLayer) => {
|
|
109
|
+
if (groupLayer.active) {
|
|
110
|
+
activeLayers.push(groupLayer);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
return activeLayers;
|
|
114
|
+
}
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Clears all layer groups
|
|
120
|
+
* @api
|
|
121
|
+
*/
|
|
122
|
+
clear() {
|
|
123
|
+
this.layers.clear();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Destroys the ExclusiveManager
|
|
128
|
+
* @api
|
|
129
|
+
*/
|
|
130
|
+
destroy() {
|
|
131
|
+
this.clear();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export default ExclusiveManager;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import Projection from './projection.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {ProjectionOptions} ExtentOptions
|
|
5
|
+
* @property {import("ol/extent").Extent|undefined} coordinates - if not specified, the extent of the projection is used
|
|
6
|
+
* @api
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* checks extent validity, point extent is also valid
|
|
11
|
+
* @param {import("ol/extent").Extent} extent
|
|
12
|
+
* @returns {boolean}
|
|
13
|
+
*/
|
|
14
|
+
function checkExtentValidity(extent) {
|
|
15
|
+
if (!extent || !Array.isArray(extent) || extent.length !== 4) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (
|
|
20
|
+
!Number.isFinite(extent[0]) ||
|
|
21
|
+
!Number.isFinite(extent[1]) ||
|
|
22
|
+
!Number.isFinite(extent[2]) ||
|
|
23
|
+
!Number.isFinite(extent[3])
|
|
24
|
+
) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return extent[0] <= extent[2] && extent[1] <= extent[3];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Extent Class
|
|
33
|
+
* @class
|
|
34
|
+
* @export
|
|
35
|
+
* @api
|
|
36
|
+
*/
|
|
37
|
+
class Extent {
|
|
38
|
+
/**
|
|
39
|
+
* @param {ExtentOptions=} options object
|
|
40
|
+
*/
|
|
41
|
+
constructor(options = {}) {
|
|
42
|
+
/** @type {Projection} */
|
|
43
|
+
this.projection = new Projection({
|
|
44
|
+
epsg: options.epsg,
|
|
45
|
+
proj4: options.proj4,
|
|
46
|
+
alias: options.alias,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
/** @type {import("ol/extent").Extent|null} */
|
|
50
|
+
this.extent = options.coordinates || this.projection.proj.getExtent();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @param {Projection} destination
|
|
55
|
+
* @param {import("ol/extent").Extent=} result
|
|
56
|
+
* @returns {import("ol/extent").Extent}
|
|
57
|
+
*/
|
|
58
|
+
getCoordinatesInProjection(destination, result) {
|
|
59
|
+
if (destination.epsg === this.projection.epsg) { // TODO aliases?!
|
|
60
|
+
const extent = result ? result.splice(0, 4, ...this.extent) : this.extent.slice();
|
|
61
|
+
return /** @type {import("ol/extent").Extent} */ (extent);
|
|
62
|
+
}
|
|
63
|
+
const transformer = Projection
|
|
64
|
+
.getTransformer(destination, this.projection);
|
|
65
|
+
const target = result || [];
|
|
66
|
+
transformer(this.extent, target, 2);
|
|
67
|
+
return /** @type {import("ol/extent").Extent} */ (target);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* only checks for null/nan numbers, does not check for spatial validity of the extent
|
|
72
|
+
* @returns {boolean} true if extent is valid
|
|
73
|
+
*/
|
|
74
|
+
isValid() {
|
|
75
|
+
return checkExtentValidity(this.extent);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @returns {ExtentOptions}
|
|
80
|
+
*/
|
|
81
|
+
getConfigObject() {
|
|
82
|
+
return { coordinates: this.extent.slice(), ...this.projection.getConfigObject() };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @returns {Extent}
|
|
87
|
+
*/
|
|
88
|
+
clone() {
|
|
89
|
+
return new Extent(this.getConfigObject());
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param {Extent} extent
|
|
94
|
+
* @returns {boolean}
|
|
95
|
+
*/
|
|
96
|
+
equals(extent) {
|
|
97
|
+
if (this === extent) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return this.isValid() &&
|
|
102
|
+
extent.isValid() &&
|
|
103
|
+
this.extent.every((c, i) => c === extent.extent[i]) &&
|
|
104
|
+
this.projection.equals(extent.projection);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* validates extent options, checks for valid projection and the geometry of the given coordinates.
|
|
109
|
+
* The Coordinate extent is also valid if its a point extent
|
|
110
|
+
* @param {ExtentOptions} options
|
|
111
|
+
* @returns {boolean}
|
|
112
|
+
* @api
|
|
113
|
+
*/
|
|
114
|
+
static validateOptions(options) {
|
|
115
|
+
return Projection.validateOptions(options) && checkExtentValidity(options.coordinates);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @type {import("ol/extent").Extent}
|
|
120
|
+
*/
|
|
121
|
+
static get WGS_84_EXTENT() { return [-180, -90, 180, 90]; }
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export default Extent;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
import { parseBoolean } from '@vcsuite/parsers';
|
|
3
|
+
import { vcsLayerName } from '../../layer/layerSymbols.js';
|
|
4
|
+
import VcsObject from '../../object.js';
|
|
5
|
+
import { getStyleOrDefaultStyle } from '../style/styleFactory.js';
|
|
6
|
+
import { defaultVectorStyle } from '../style/vectorStyleItem.js';
|
|
7
|
+
import VectorProperties from '../../layer/vectorProperties.js';
|
|
8
|
+
import { isProvidedFeature, showProvidedFeature } from './featureProviderSymbols.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @namespace featureProvider
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {VcsObjectOptions} AbstractFeatureProviderOptions
|
|
16
|
+
* @property {import("@vcmap/core").StyleItemOptions|import("@vcmap/core").StyleItem|undefined} style - the style to apply to features created by this feature provider
|
|
17
|
+
* @property {Object|undefined} genericFeatureProperties - generic properties to add to features created by this feature provider
|
|
18
|
+
* @property {import("@vcmap/core").VectorProperties|import("@vcmap/core").VectorPropertiesOptions|undefined} vectorProperties - the vector properties of the features. Allow picking is false by default.
|
|
19
|
+
* @property {boolean} [showGeometry=false] - show the resulting geometry in the map
|
|
20
|
+
* @property {Array<string>} [mapTypes=[]] - can be used to constrict the featureProvider to specific mapTypes empty array means no restriction
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* An abstract class providing features for {@link Layer}s which cannot provide features directly, but can provide features for
|
|
25
|
+
* a given location, e.g. WMS with a getFeatureInfo configuration. In this case, a feature provider can be created for this layer.
|
|
26
|
+
* @class
|
|
27
|
+
* @export
|
|
28
|
+
* @abstract
|
|
29
|
+
* @api
|
|
30
|
+
*/
|
|
31
|
+
class AbstractFeatureProvider extends VcsObject {
|
|
32
|
+
static get className() { return 'vcs.vcm.util.featureProvider.AbstractFeatureProvider'; }
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @returns {AbstractFeatureProviderOptions}
|
|
36
|
+
*/
|
|
37
|
+
static getDefaultOptions() {
|
|
38
|
+
return {
|
|
39
|
+
vectorProperties: {
|
|
40
|
+
allowPicking: false,
|
|
41
|
+
},
|
|
42
|
+
genericFeatureProperties: undefined,
|
|
43
|
+
showGeometry: false,
|
|
44
|
+
mapTypes: [],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {string} layerName
|
|
50
|
+
* @param {AbstractFeatureProviderOptions} options
|
|
51
|
+
*/
|
|
52
|
+
constructor(layerName, options) {
|
|
53
|
+
super(options);
|
|
54
|
+
const defaultOptions = AbstractFeatureProvider.getDefaultOptions();
|
|
55
|
+
/**
|
|
56
|
+
* The layer name of the associated layer
|
|
57
|
+
* @api
|
|
58
|
+
* @type {string}
|
|
59
|
+
*/
|
|
60
|
+
this.layerName = layerName;
|
|
61
|
+
/**
|
|
62
|
+
* The style set on features created by this provider
|
|
63
|
+
* @type {import("@vcmap/core").StyleItem|undefined}
|
|
64
|
+
* @api
|
|
65
|
+
*/
|
|
66
|
+
this.style = options.style ?
|
|
67
|
+
getStyleOrDefaultStyle(options.style, defaultVectorStyle.clone()) :
|
|
68
|
+
undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Whether to show the geometry on selection.
|
|
71
|
+
* @type {boolean}
|
|
72
|
+
* @api
|
|
73
|
+
*/
|
|
74
|
+
this.showGeometry = parseBoolean(options.showGeometry, defaultOptions.showGeometry);
|
|
75
|
+
/**
|
|
76
|
+
* The vector properties assigned to features created by this provider
|
|
77
|
+
* @type {import("@vcmap/core").VectorProperties}
|
|
78
|
+
* @api
|
|
79
|
+
*/
|
|
80
|
+
this.vectorProperties = options.vectorProperties instanceof VectorProperties ?
|
|
81
|
+
options.vectorProperties :
|
|
82
|
+
new VectorProperties({ ...defaultOptions.vectorProperties, ...options.vectorProperties });
|
|
83
|
+
/**
|
|
84
|
+
* An object of potential generic feature properties to add to all feature created by this provider
|
|
85
|
+
* @type {Object<string, *>|undefined}
|
|
86
|
+
* @api
|
|
87
|
+
*/
|
|
88
|
+
this.genericFeatureProperties = options.genericFeatureProperties || defaultOptions.genericFeatureProperties;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Map ClassNames Can be used to only apply this featureProvider to the specified maps
|
|
92
|
+
* @type {Array<string>}
|
|
93
|
+
* @api
|
|
94
|
+
*/
|
|
95
|
+
this.mapTypes = Array.isArray(options.mapTypes) ? options.mapTypes : defaultOptions.mapTypes;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* checks if the featureProvider is supported for provided Map
|
|
100
|
+
* @param {import("@vcmap/core").VcsMap} map
|
|
101
|
+
* @returns {boolean}
|
|
102
|
+
* @api stable
|
|
103
|
+
*/
|
|
104
|
+
isSupported(map) {
|
|
105
|
+
return map &&
|
|
106
|
+
(this.mapTypes.length === 0 || this.mapTypes.includes(map.className));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Ensures the feature has an ID, applies all vectorProperties and adds the generic properties, style and the vcsLayerName
|
|
111
|
+
* and isProvidedFeature symbols to the feature
|
|
112
|
+
* @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
|
|
113
|
+
* @returns {import("ol").Feature<import("ol/geom/Geometry").default>}
|
|
114
|
+
* @api
|
|
115
|
+
*/
|
|
116
|
+
getProviderFeature(feature) {
|
|
117
|
+
if (!feature.getId()) {
|
|
118
|
+
feature.setId(uuidv4());
|
|
119
|
+
}
|
|
120
|
+
if (this.style) {
|
|
121
|
+
feature.setStyle(this.style.style);
|
|
122
|
+
}
|
|
123
|
+
if (this.genericFeatureProperties) {
|
|
124
|
+
feature.setProperties(this.genericFeatureProperties);
|
|
125
|
+
}
|
|
126
|
+
feature[vcsLayerName] = this.layerName;
|
|
127
|
+
feature[isProvidedFeature] = true;
|
|
128
|
+
feature[showProvidedFeature] = this.showGeometry;
|
|
129
|
+
Object.entries(this.vectorProperties.getValues()).forEach(([key, value]) => {
|
|
130
|
+
const olcsKey = `olcs_${key}`;
|
|
131
|
+
if (feature.get(olcsKey) === undefined && value !== undefined) {
|
|
132
|
+
feature.set(olcsKey, value);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
return feature;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* This method must be overwritten by any implementations. Before returning the array of features, be sure to use the getProviderFeature
|
|
140
|
+
* on each feature to ensure all properties and symbols required by the VCM architecture
|
|
141
|
+
* to handle your feature is called: (e.g. <code>return features.map(f => this.getProviderFeature(f)</code>);
|
|
142
|
+
* @param {import("ol/coordinate").Coordinate} coordinate - in mercator
|
|
143
|
+
* @param {number} resolution - meters per pixel for the given location
|
|
144
|
+
* @returns {Promise<Array<import("ol").Feature<import("ol/geom/Geometry").default>>>}
|
|
145
|
+
* @api
|
|
146
|
+
*/
|
|
147
|
+
// eslint-disable-next-line no-unused-vars,class-methods-use-this
|
|
148
|
+
async getFeaturesByCoordinate(coordinate, resolution) {
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Returns the object required to configure this feature provider.
|
|
154
|
+
* @returns {AbstractFeatureProviderOptions}
|
|
155
|
+
* @api
|
|
156
|
+
*/
|
|
157
|
+
getConfigObject() {
|
|
158
|
+
const config =
|
|
159
|
+
/** @type {AbstractFeatureProviderOptions} */ (super.getConfigObject());
|
|
160
|
+
|
|
161
|
+
const defaultOptions = AbstractFeatureProvider.getDefaultOptions();
|
|
162
|
+
delete config.name; // the name is irrelevant, since its the layers name
|
|
163
|
+
|
|
164
|
+
if (this.showGeometry !== defaultOptions.showGeometry) {
|
|
165
|
+
config.showGeometry = this.showGeometry;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (this.genericFeatureProperties) {
|
|
169
|
+
config.genericFeatureProperties = { ...this.genericFeatureProperties };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (this.style) {
|
|
173
|
+
config.style = this.style.getOptions();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const vectorPropertiesConfig = this.vectorProperties
|
|
177
|
+
.getVcsMeta({ ...VectorProperties.getDefaultOptions(), ...defaultOptions.vectorProperties });
|
|
178
|
+
if (Object.keys(vectorPropertiesConfig).length > 0) {
|
|
179
|
+
config.vectorProperties = vectorPropertiesConfig;
|
|
180
|
+
}
|
|
181
|
+
return config;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Destroys this feature provider and detaches its resources
|
|
186
|
+
* @inheritDoc
|
|
187
|
+
*/
|
|
188
|
+
destroy() {
|
|
189
|
+
this.style = null;
|
|
190
|
+
this.vectorProperties.destroy();
|
|
191
|
+
this.genericFeatureProperties = undefined;
|
|
192
|
+
super.destroy();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export default AbstractFeatureProvider;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { getCenter } from 'ol/extent.js';
|
|
2
|
+
import Projection from '../projection.js';
|
|
3
|
+
import { createOrUpdateFromGeometry } from '../featureconverter/extent3d.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {VectorClickedObject} feature
|
|
7
|
+
* @param {import("@vcmap/core").Layer} layer
|
|
8
|
+
* @returns {?GenericFeature}
|
|
9
|
+
*/
|
|
10
|
+
// eslint-disable-next-line import/prefer-default-export
|
|
11
|
+
export function getGenericFeatureFromProvidedFeature(feature, layer) {
|
|
12
|
+
const attributes = feature.getProperties();
|
|
13
|
+
delete attributes[feature.getGeometryName()];
|
|
14
|
+
|
|
15
|
+
let { clickedPosition } = feature;
|
|
16
|
+
const geometry = feature.getGeometry();
|
|
17
|
+
const isModel = feature.get('olcs_modelUrl');
|
|
18
|
+
if (
|
|
19
|
+
geometry &&
|
|
20
|
+
(
|
|
21
|
+
(geometry.getType() === 'Point' && !isModel) ||
|
|
22
|
+
(clickedPosition && !clickedPosition.exactPosition) ||
|
|
23
|
+
(!clickedPosition && geometry)
|
|
24
|
+
)
|
|
25
|
+
) {
|
|
26
|
+
const center = getCenter(geometry.getExtent());
|
|
27
|
+
if (center) {
|
|
28
|
+
Projection.mercatorToWgs84(center, true);
|
|
29
|
+
clickedPosition = { longitude: center[0], latitude: center[1] };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let heightOffset = clickedPosition.height;
|
|
34
|
+
if (!isModel) {
|
|
35
|
+
const extent = createOrUpdateFromGeometry(geometry);
|
|
36
|
+
const max = Number.isFinite(extent[5]) ? extent[5] : 0;
|
|
37
|
+
heightOffset = max;
|
|
38
|
+
}
|
|
39
|
+
const relativeToGround = !isModel && feature.get('olcs_altitudeMode') === 'relativeToGround';
|
|
40
|
+
|
|
41
|
+
delete attributes.clickedPosition;
|
|
42
|
+
return {
|
|
43
|
+
layerName: layer.name,
|
|
44
|
+
layerClass: layer.className,
|
|
45
|
+
attributes,
|
|
46
|
+
longitude: clickedPosition.longitude,
|
|
47
|
+
latitude: clickedPosition.latitude,
|
|
48
|
+
height: heightOffset,
|
|
49
|
+
relativeToGround,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Added to ol.Feature, if they are not part of a layer, but provided by an {@link AbstractFeatureProvider}.
|
|
3
|
+
* @type {symbol}
|
|
4
|
+
*/
|
|
5
|
+
export const isProvidedFeature = Symbol('isProvidedFeature');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A boolean value, indicating whether {@link SelectBehavior} should add the feature to the selected item layer
|
|
9
|
+
* @type {symbol}
|
|
10
|
+
*/
|
|
11
|
+
export const showProvidedFeature = Symbol('showProvidedFeature');
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import AbstractFeatureProvider from './abstractFeatureProvider.js';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {AbstractFeatureProviderOptions} TileProviderFeatureProviderOptions
|
|
6
|
+
* @property {import("@vcmap/core").TileProvider} tileProvider
|
|
7
|
+
* @api
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @class
|
|
12
|
+
* @extends {AbstractFeatureProvider}
|
|
13
|
+
*/
|
|
14
|
+
class TileProviderFeatureProvider extends AbstractFeatureProvider {
|
|
15
|
+
static get className() { return 'vcs.vcm.util.featureProvider.TileProviderFeatureProvider'; }
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {string} layerName
|
|
19
|
+
* @param {TileProviderFeatureProviderOptions} options
|
|
20
|
+
*/
|
|
21
|
+
constructor(layerName, options) {
|
|
22
|
+
super(layerName, options);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Map ClassNames Can be used to only apply this featureProvider to the specified maps
|
|
26
|
+
* @type {Array<string>}
|
|
27
|
+
* @api
|
|
28
|
+
*/
|
|
29
|
+
this.mapTypes = ['vcs.vcm.maps.Cesium'];
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* TileProvider
|
|
33
|
+
* @type {import("@vcmap/core").TileProvider}
|
|
34
|
+
* @api
|
|
35
|
+
*/
|
|
36
|
+
this.tileProvider = options.tileProvider;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @inheritDoc
|
|
42
|
+
* @param {import("ol/coordinate").Coordinate} coordinate
|
|
43
|
+
* @param {number} resolution
|
|
44
|
+
* @returns {Promise<Array<import("ol").Feature<import("ol/geom/Geometry").default>>>}
|
|
45
|
+
*/
|
|
46
|
+
async getFeaturesByCoordinate(coordinate, resolution) {
|
|
47
|
+
const features = await this.tileProvider.getFeaturesByCoordinate(coordinate, resolution);
|
|
48
|
+
return features.filter((feature) => {
|
|
49
|
+
return this.vectorProperties.getAllowPicking(feature);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @inheritDoc
|
|
55
|
+
*/
|
|
56
|
+
destroy() {
|
|
57
|
+
this.tileProvider = undefined;
|
|
58
|
+
super.destroy();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default TileProviderFeatureProvider;
|