@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,536 @@
|
|
|
1
|
+
import { boundingExtent, containsXY } from 'ol/extent.js';
|
|
2
|
+
import { get as getProjection, getTransform, transform, transformExtent } from 'ol/proj.js';
|
|
3
|
+
import { check } from '@vcsuite/check';
|
|
4
|
+
import { parseBoolean, parseNumber } from '@vcsuite/parsers';
|
|
5
|
+
import Extent from '../util/extent.js';
|
|
6
|
+
import { mercatorProjection, wgs84Projection } from '../util/projection.js';
|
|
7
|
+
import { getResolutionOptions, getZoom } from '../layer/oblique/obliqueHelpers.js';
|
|
8
|
+
import ViewPoint from '../util/viewpoint.js';
|
|
9
|
+
import BaseOLMap from './baseOLMap.js';
|
|
10
|
+
import VcsMap from './map.js';
|
|
11
|
+
import VcsEvent from '../event/vcsEvent.js';
|
|
12
|
+
import { obliqueCollectionCollection } from '../globalCollections.js';
|
|
13
|
+
import { ObliqueViewDirection as ViewDirection } from '../oblique/ObliqueViewDirection.js';
|
|
14
|
+
import ObliqueProvider from '../oblique/ObliqueProvider.js';
|
|
15
|
+
import ObliqueCollection from '../oblique/ObliqueCollection.js';
|
|
16
|
+
import { transformFromImage } from '../oblique/helpers.js';
|
|
17
|
+
import { VcsClassRegistry } from '../classRegistry.js';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {Object} ObliqueClickParameters
|
|
21
|
+
* @property {import("ol/pixel").Pixel} pixel
|
|
22
|
+
* @property {boolean|undefined} estimate
|
|
23
|
+
* @api stable
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {VcsMapOptions} ObliqueOptions
|
|
28
|
+
* @property {boolean} [changeOnMoveEnd=false]
|
|
29
|
+
* @property {number} [switchThreshold=0]
|
|
30
|
+
* @property {boolean} [switchOnEdge=true]
|
|
31
|
+
* @property {string|undefined} defaultCollectionName
|
|
32
|
+
* @api
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
const defaultHeadings = {
|
|
36
|
+
[ViewDirection.NORTH]: 0,
|
|
37
|
+
[ViewDirection.EAST]: 90,
|
|
38
|
+
[ViewDirection.SOUTH]: 180,
|
|
39
|
+
[ViewDirection.WEST]: 270,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* returns the direction which matches the heading of the viewpoint
|
|
44
|
+
* @param {ViewPoint} viewpoint
|
|
45
|
+
* @returns {import("@vcmap/core").ObliqueViewDirection}
|
|
46
|
+
*/
|
|
47
|
+
export function getViewDirectionFromViewPoint(viewpoint) {
|
|
48
|
+
const { heading } = viewpoint;
|
|
49
|
+
let direction = ViewDirection.NORTH;
|
|
50
|
+
if (heading >= 45 && heading < 135) {
|
|
51
|
+
direction = ViewDirection.EAST;
|
|
52
|
+
} else if (heading >= 135 && heading < 225) {
|
|
53
|
+
direction = ViewDirection.SOUTH;
|
|
54
|
+
} else if (heading >= 225 && heading < 315) {
|
|
55
|
+
direction = ViewDirection.WEST;
|
|
56
|
+
}
|
|
57
|
+
return direction;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {ViewPoint} viewpoint
|
|
62
|
+
* @returns {import("ol/coordinate").Coordinate}
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
export function getMercatorViewpointCenter(viewpoint) {
|
|
66
|
+
const gpWGS84 = viewpoint.groundPosition || viewpoint.cameraPosition;
|
|
67
|
+
return transform(
|
|
68
|
+
gpWGS84,
|
|
69
|
+
wgs84Projection.proj,
|
|
70
|
+
mercatorProjection.proj,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Oblique Map Class (2D map with oblique imagery)
|
|
76
|
+
*
|
|
77
|
+
* @class
|
|
78
|
+
* @export
|
|
79
|
+
* @extends {BaseOLMap}
|
|
80
|
+
* @api stable
|
|
81
|
+
*/
|
|
82
|
+
class Oblique extends BaseOLMap {
|
|
83
|
+
static get className() { return 'vcs.vcm.maps.Oblique'; }
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @returns {ObliqueOptions}
|
|
87
|
+
*/
|
|
88
|
+
static getDefaultOptions() {
|
|
89
|
+
return {
|
|
90
|
+
...VcsMap.getDefaultOptions(),
|
|
91
|
+
changeOnMoveEnd: false,
|
|
92
|
+
switchThreshold: 0,
|
|
93
|
+
switchOnEdge: true,
|
|
94
|
+
defaultCollectionName: undefined,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @param {ObliqueOptions} options
|
|
100
|
+
*/
|
|
101
|
+
constructor(options) {
|
|
102
|
+
super(options);
|
|
103
|
+
const defaultOptions = Oblique.getDefaultOptions();
|
|
104
|
+
/**
|
|
105
|
+
* @type {string|undefined}
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
this._defaultCollectionName = options.defaultCollectionName || defaultOptions.defaultCollectionName;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @type {ObliqueCollection|null}
|
|
112
|
+
* @private
|
|
113
|
+
*/
|
|
114
|
+
this._loadingCollection = null;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @type {string}
|
|
118
|
+
* @private
|
|
119
|
+
*/
|
|
120
|
+
this._mapChangeEvent = options.changeOnMoveEnd ? 'moveend' : 'postrender';
|
|
121
|
+
|
|
122
|
+
/** @type {number} */
|
|
123
|
+
this._switchThreshold = parseNumber(options.switchThreshold, defaultOptions.switchThreshold);
|
|
124
|
+
if (this._switchThreshold > 1) {
|
|
125
|
+
this._switchThreshold = 0.2;
|
|
126
|
+
} else if (this._switchThreshold < 0) {
|
|
127
|
+
this._switchThreshold = 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @type {boolean}
|
|
132
|
+
* @private
|
|
133
|
+
*/
|
|
134
|
+
this._switchEnabled = parseBoolean(options.switchOnEdge, defaultOptions.switchOnEdge);
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* An event raise, when the collection changes. Is passed the collection as its only argument.
|
|
138
|
+
* @type {VcsEvent<ObliqueCollection>}
|
|
139
|
+
* @api
|
|
140
|
+
*/
|
|
141
|
+
this.collectionChanged = new VcsEvent();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Whether the post render handler should switch on image edge. Setting
|
|
146
|
+
* this to false will suspend all post render handler switches.
|
|
147
|
+
* @type {boolean}
|
|
148
|
+
* @api
|
|
149
|
+
*/
|
|
150
|
+
get switchEnabled() {
|
|
151
|
+
return this._switchEnabled;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @param {boolean} switchEnabled
|
|
156
|
+
*/
|
|
157
|
+
set switchEnabled(switchEnabled) {
|
|
158
|
+
this._switchEnabled = switchEnabled;
|
|
159
|
+
if (this._obliqueProvider) {
|
|
160
|
+
this._obliqueProvider.switchEnabled = switchEnabled;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Threshold from 0 to 1 to define when to start switching to other images. Where 0 indicates
|
|
166
|
+
* to only switch, when the view center is outside of the image and 1 to always switch. 0.2 would start switching
|
|
167
|
+
* if the view center is within the outer 20% of the image.
|
|
168
|
+
* @type {number}
|
|
169
|
+
* @api
|
|
170
|
+
*/
|
|
171
|
+
get switchThreshold() {
|
|
172
|
+
return this._switchThreshold;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @param {number} threshold
|
|
177
|
+
*/
|
|
178
|
+
set switchThreshold(threshold) {
|
|
179
|
+
check(threshold, Number);
|
|
180
|
+
this._switchThreshold = threshold;
|
|
181
|
+
if (this._switchThreshold > 1) {
|
|
182
|
+
this._switchThreshold = 0.2;
|
|
183
|
+
} else if (this._switchThreshold < 0) {
|
|
184
|
+
this._switchThreshold = 0;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (this._obliqueProvider) {
|
|
188
|
+
this._obliqueProvider.switchThreshold = this._switchThreshold;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* @type {string}
|
|
194
|
+
*/
|
|
195
|
+
get mapChangeEvent() {
|
|
196
|
+
return this._mapChangeEvent;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @returns {Promise<void>}
|
|
201
|
+
*/
|
|
202
|
+
async initialize() {
|
|
203
|
+
if (!this.initializedPromise) {
|
|
204
|
+
this.initializedPromise = super.initialize()
|
|
205
|
+
.then(async () => {
|
|
206
|
+
this._obliqueProvider = new ObliqueProvider(this.olMap);
|
|
207
|
+
this.mapChangeEvent = this._mapChangeEvent;
|
|
208
|
+
this.switchThreshold = this._switchThreshold;
|
|
209
|
+
this.switchEnabled = this._switchEnabled;
|
|
210
|
+
let collectionToLoad = this._loadingCollection;
|
|
211
|
+
if (!collectionToLoad) {
|
|
212
|
+
collectionToLoad = this._defaultCollectionName ?
|
|
213
|
+
obliqueCollectionCollection.getByKey(this._defaultCollectionName) :
|
|
214
|
+
[...obliqueCollectionCollection][0];
|
|
215
|
+
}
|
|
216
|
+
if (collectionToLoad) {
|
|
217
|
+
await this._setCollection(collectionToLoad);
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
.then(() => {
|
|
221
|
+
this.initialized = true;
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
await this.initializedPromise;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @param {string} eventType
|
|
229
|
+
*/
|
|
230
|
+
set mapChangeEvent(eventType) {
|
|
231
|
+
check(eventType, String);
|
|
232
|
+
this._mapChangeEvent = eventType;
|
|
233
|
+
if (this._obliqueProvider) {
|
|
234
|
+
this._obliqueProvider.mapChangeEvent = eventType;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* @type {ObliqueCollection}
|
|
240
|
+
* @readonly
|
|
241
|
+
* @api
|
|
242
|
+
*/
|
|
243
|
+
get collection() { return this._obliqueProvider.collection; }
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* @type {import("@vcmap/cesium").Event}
|
|
247
|
+
* @readonly
|
|
248
|
+
* @api
|
|
249
|
+
*/
|
|
250
|
+
get imageChanged() {
|
|
251
|
+
return this._obliqueProvider ? this._obliqueProvider.imageChanged : null;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* @type {import("@vcmap/core").ObliqueImage|null}
|
|
256
|
+
* @api
|
|
257
|
+
* @readonly
|
|
258
|
+
*/
|
|
259
|
+
get currentImage() {
|
|
260
|
+
return this._obliqueProvider ? this._obliqueProvider.currentImage : null;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* @param {ViewPoint} viewpoint
|
|
265
|
+
* @returns {Promise<boolean>}
|
|
266
|
+
* @api
|
|
267
|
+
*/
|
|
268
|
+
async canShowViewpoint(viewpoint) {
|
|
269
|
+
await this.initialize();
|
|
270
|
+
if (this.collection) {
|
|
271
|
+
const viewDirection = getViewDirectionFromViewPoint(viewpoint);
|
|
272
|
+
const mercatorCoordinates = getMercatorViewpointCenter(viewpoint);
|
|
273
|
+
return this.collection.hasImageAtCoordinate(mercatorCoordinates, viewDirection);
|
|
274
|
+
}
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* @inheritDoc
|
|
280
|
+
* @returns {Promise<void>}
|
|
281
|
+
*/
|
|
282
|
+
async activate() {
|
|
283
|
+
await super.activate();
|
|
284
|
+
if (this.active) {
|
|
285
|
+
this._obliqueProvider.activate();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* @returns {Extent}
|
|
291
|
+
*/
|
|
292
|
+
getExtentOfCurrentImage() {
|
|
293
|
+
const image = this.currentImage;
|
|
294
|
+
if (image) {
|
|
295
|
+
const coords = boundingExtent(image.groundCoordinates);
|
|
296
|
+
return new Extent({
|
|
297
|
+
coordinates: transformExtent(coords, image.meta.projection, mercatorProjection.proj),
|
|
298
|
+
epsg: 'EPSG:3857',
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
return new Extent({
|
|
302
|
+
coordinates: [-18924313.4349, -15538711.0963, 18924313.4349, 15538711.0963],
|
|
303
|
+
epsg: 'EPSG:3857',
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* @returns {import("@vcmap/core").ObliqueImage}
|
|
309
|
+
* @api
|
|
310
|
+
* @deprecated 4.0
|
|
311
|
+
*/
|
|
312
|
+
getCurrentImage() {
|
|
313
|
+
this.getLogger().deprecate('getCurrentImage', 'access the currentImage property');
|
|
314
|
+
return this._obliqueProvider ? this._obliqueProvider.currentImage : null;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
deactivate() {
|
|
318
|
+
super.deactivate();
|
|
319
|
+
this._obliqueProvider.deactivate();
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Sets a new oblique collection
|
|
324
|
+
* @param {ObliqueCollection} obliqueCollection
|
|
325
|
+
* @param {ViewPoint=} viewpoint
|
|
326
|
+
* @returns {Promise<void>}
|
|
327
|
+
* @api
|
|
328
|
+
*/
|
|
329
|
+
async setCollection(obliqueCollection, viewpoint) {
|
|
330
|
+
check(obliqueCollection, ObliqueCollection);
|
|
331
|
+
|
|
332
|
+
if (this.movementDisabled) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (!this.initializedPromise) { // TODO add collection to obliqueCollections?
|
|
337
|
+
this._defaultCollectionName = obliqueCollection.name;
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
this._loadingCollection = obliqueCollection;
|
|
341
|
+
await this.initializedPromise;
|
|
342
|
+
if (this._loadingCollection !== obliqueCollection) {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
await this._setCollection(obliqueCollection, viewpoint);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Sets a new oblique collection
|
|
350
|
+
* @param {ObliqueCollection} obliqueCollection
|
|
351
|
+
* @param {ViewPoint=} viewpoint
|
|
352
|
+
* @returns {Promise<void>}
|
|
353
|
+
* @private
|
|
354
|
+
*/
|
|
355
|
+
async _setCollection(obliqueCollection, viewpoint) {
|
|
356
|
+
this._loadingCollection = obliqueCollection;
|
|
357
|
+
await obliqueCollection.load();
|
|
358
|
+
const vp = viewpoint || await this.getViewPoint();
|
|
359
|
+
if (this._loadingCollection !== obliqueCollection) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
this._obliqueProvider.setCollection(obliqueCollection);
|
|
363
|
+
this.collectionChanged.raiseEvent(obliqueCollection);
|
|
364
|
+
if (vp) {
|
|
365
|
+
await this.gotoViewPoint(vp);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Sets an image by its name on the map
|
|
371
|
+
* @param {string} imageName
|
|
372
|
+
* @param {import("ol/coordinate").Coordinate=} optCenter
|
|
373
|
+
* @returns {Promise<void>}
|
|
374
|
+
* @api
|
|
375
|
+
*/
|
|
376
|
+
async setImageByName(imageName, optCenter) {
|
|
377
|
+
if (this.movementDisabled || !this.initializedPromise) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
await this.initializedPromise;
|
|
381
|
+
const image = this._obliqueProvider.collection.getImageByName(imageName);
|
|
382
|
+
if (image) {
|
|
383
|
+
await this._obliqueProvider.setImage(image, optCenter);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* @returns {Promise<ViewPoint|null>}
|
|
389
|
+
* @inheritDoc
|
|
390
|
+
*/
|
|
391
|
+
async getViewPoint() {
|
|
392
|
+
const image = this.currentImage;
|
|
393
|
+
if (!image) {
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
// if we dont have an image, we may not have a map, thus two if clauses
|
|
397
|
+
const viewCenter = this.olMap.getView().getCenter();
|
|
398
|
+
if (!viewCenter) {
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const transformationOptions = { dataProjection: getProjection('EPSG:4326') };
|
|
403
|
+
const { coords } = await transformFromImage(image, viewCenter, transformationOptions);
|
|
404
|
+
return this._computeViewpointInternal(coords);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* @inheritDoc
|
|
409
|
+
* @returns {ViewPoint|null}
|
|
410
|
+
*/
|
|
411
|
+
getViewPointSync() {
|
|
412
|
+
const image = this.currentImage;
|
|
413
|
+
if (!image) {
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const gpImageCoordinates = this.olMap.getView().getCenter();
|
|
418
|
+
if (!gpImageCoordinates) {
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const gpInternalProjection = image.transformImage2RealWorld(gpImageCoordinates, image.averageHeight);
|
|
423
|
+
|
|
424
|
+
const transfrom = getTransform(image.meta.projection, wgs84Projection.proj);
|
|
425
|
+
const gpWGS84 = transfrom(gpInternalProjection.slice(0, 2));
|
|
426
|
+
return this._computeViewpointInternal(gpWGS84);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* @param {import("ol/coordinate").Coordinate} groundPosition
|
|
431
|
+
* @returns {ViewPoint}
|
|
432
|
+
* @private
|
|
433
|
+
*/
|
|
434
|
+
_computeViewpointInternal(groundPosition) {
|
|
435
|
+
const image = this.currentImage;
|
|
436
|
+
const { size, fovy, metersPerUnit } = getResolutionOptions(this.olMap, image);
|
|
437
|
+
|
|
438
|
+
const view = this.olMap.getView();
|
|
439
|
+
const resolution = view.getResolution() || 1;
|
|
440
|
+
const visibleMapUnits = resolution * size.height;
|
|
441
|
+
const visibleMeters = visibleMapUnits * metersPerUnit;
|
|
442
|
+
const height = Math.abs((visibleMeters / 2) / Math.tan(fovy / 2));
|
|
443
|
+
|
|
444
|
+
const avgHeight = groundPosition[2] || image.averageHeight;
|
|
445
|
+
const cameraHeight = height + avgHeight;
|
|
446
|
+
|
|
447
|
+
return new ViewPoint({
|
|
448
|
+
cameraPosition: [groundPosition[0], groundPosition[1], cameraHeight],
|
|
449
|
+
groundPosition,
|
|
450
|
+
heading: defaultHeadings[image.viewDirection],
|
|
451
|
+
pitch: -90,
|
|
452
|
+
roll: 0,
|
|
453
|
+
distance: height,
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* @param {ViewPoint} viewpoint
|
|
459
|
+
* @returns {Promise<void>}
|
|
460
|
+
* @inheritDoc
|
|
461
|
+
*/
|
|
462
|
+
async gotoViewPoint(viewpoint) {
|
|
463
|
+
if (this.movementDisabled || !this._obliqueProvider || !viewpoint.isValid()) {
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const viewDirection = getViewDirectionFromViewPoint(viewpoint);
|
|
468
|
+
const mercatorCoordinates = getMercatorViewpointCenter(viewpoint);
|
|
469
|
+
const { distance } = viewpoint;
|
|
470
|
+
await this._obliqueProvider.setView(mercatorCoordinates, viewDirection);
|
|
471
|
+
if (this._obliqueProvider.currentImage) {
|
|
472
|
+
const zoom = getZoom(this.olMap, this._obliqueProvider.currentImage, distance);
|
|
473
|
+
this.olMap.getView().setZoom(zoom);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* @param {import("ol/coordinate").Coordinate} coords in WGS84 degrees
|
|
479
|
+
* @returns {boolean}
|
|
480
|
+
* @api
|
|
481
|
+
*/
|
|
482
|
+
pointIsVisible(coords) {
|
|
483
|
+
const image = this.currentImage;
|
|
484
|
+
if (!image || !this.active) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
const view = this.olMap.getView();
|
|
488
|
+
const extent = view.calculateExtent(this.olMap.getSize());
|
|
489
|
+
const bl = image.transformImage2RealWorld([extent[0], extent[1]]);
|
|
490
|
+
const ur = image.transformImage2RealWorld([extent[2], extent[3]]);
|
|
491
|
+
const bbox = [bl[0], bl[1], ur[0], ur[1]];
|
|
492
|
+
const transformedBbox = transformExtent(bbox, image.meta.projection, wgs84Projection.proj);
|
|
493
|
+
return containsXY(transformedBbox, coords[0], coords[1]);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* @returns {ObliqueOptions}
|
|
498
|
+
* @api
|
|
499
|
+
*/
|
|
500
|
+
getConfigObject() {
|
|
501
|
+
const config = /** @type {ObliqueOptions} */ (super.getConfigObject());
|
|
502
|
+
const defaultOptions = Oblique.getDefaultOptions();
|
|
503
|
+
|
|
504
|
+
if (this.mapChangeEvent === 'movened') {
|
|
505
|
+
config.changeOnMoveEnd = true;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
if (this.switchThreshold !== defaultOptions.switchThreshold) {
|
|
509
|
+
config.switchThreshold = this.switchThreshold;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
if (this.switchEnabled !== defaultOptions.switchOnEdge) {
|
|
513
|
+
config.switchOnEdge = this.switchEnabled;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (this._defaultCollectionName !== defaultOptions.defaultCollectionName) {
|
|
517
|
+
config.defaultCollectionName = this._defaultCollectionName;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
return config;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* @api
|
|
525
|
+
*/
|
|
526
|
+
destroy() {
|
|
527
|
+
if (this._obliqueProvider) {
|
|
528
|
+
this._obliqueProvider.destroy();
|
|
529
|
+
}
|
|
530
|
+
this.collectionChanged.destroy();
|
|
531
|
+
super.destroy();
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
VcsClassRegistry.registerClass(Oblique.className, Oblique);
|
|
536
|
+
export default Oblique;
|