@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.
Files changed (146) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +44 -0
  3. package/build/postinstall.js +44 -0
  4. package/index.js +139 -0
  5. package/package.json +92 -0
  6. package/src/cesium/cesium3DTileFeature.js +9 -0
  7. package/src/cesium/cesium3DTilePointFeature.js +9 -0
  8. package/src/cesium/cesiumVcsCameraPrimitive.js +146 -0
  9. package/src/cesium/wallpaperMaterial.js +64 -0
  10. package/src/ol/feature.js +47 -0
  11. package/src/ol/geom/circle.js +24 -0
  12. package/src/ol/geom/geometryCollection.js +33 -0
  13. package/src/ol/render/canvas/canvasTileRenderer.js +179 -0
  14. package/src/ol/source/ClusterEnhancedVectorSource.js +39 -0
  15. package/src/ol/source/VcsCluster.js +37 -0
  16. package/src/vcs/vcm/classRegistry.js +106 -0
  17. package/src/vcs/vcm/event/vcsEvent.js +89 -0
  18. package/src/vcs/vcm/globalCollections.js +11 -0
  19. package/src/vcs/vcm/interaction/abstractInteraction.js +149 -0
  20. package/src/vcs/vcm/interaction/coordinateAtPixel.js +102 -0
  21. package/src/vcs/vcm/interaction/eventHandler.js +425 -0
  22. package/src/vcs/vcm/interaction/featureAtPixelInteraction.js +286 -0
  23. package/src/vcs/vcm/interaction/featureProviderInteraction.js +54 -0
  24. package/src/vcs/vcm/interaction/interactionChain.js +124 -0
  25. package/src/vcs/vcm/interaction/interactionType.js +114 -0
  26. package/src/vcs/vcm/layer/buildings.js +17 -0
  27. package/src/vcs/vcm/layer/cesium/cesiumTilesetCesium.js +359 -0
  28. package/src/vcs/vcm/layer/cesium/clusterContext.js +95 -0
  29. package/src/vcs/vcm/layer/cesium/dataSourceCesium.js +171 -0
  30. package/src/vcs/vcm/layer/cesium/openStreetMapCesium.js +29 -0
  31. package/src/vcs/vcm/layer/cesium/pointCloudCesium.js +58 -0
  32. package/src/vcs/vcm/layer/cesium/rasterLayerCesium.js +110 -0
  33. package/src/vcs/vcm/layer/cesium/singleImageCesium.js +49 -0
  34. package/src/vcs/vcm/layer/cesium/terrainCesium.js +80 -0
  35. package/src/vcs/vcm/layer/cesium/tmsCesium.js +54 -0
  36. package/src/vcs/vcm/layer/cesium/vectorCesium.js +255 -0
  37. package/src/vcs/vcm/layer/cesium/vectorContext.js +167 -0
  38. package/src/vcs/vcm/layer/cesium/vectorRasterTileCesium.js +116 -0
  39. package/src/vcs/vcm/layer/cesium/vectorTileImageryProvider.js +246 -0
  40. package/src/vcs/vcm/layer/cesium/wmsCesium.js +71 -0
  41. package/src/vcs/vcm/layer/cesium/wmtsCesium.js +101 -0
  42. package/src/vcs/vcm/layer/cesium/x3dmHelper.js +22 -0
  43. package/src/vcs/vcm/layer/cesiumTileset.js +376 -0
  44. package/src/vcs/vcm/layer/czml.js +141 -0
  45. package/src/vcs/vcm/layer/dataSource.js +259 -0
  46. package/src/vcs/vcm/layer/featureLayer.js +261 -0
  47. package/src/vcs/vcm/layer/featureStore.js +647 -0
  48. package/src/vcs/vcm/layer/featureStoreChanges.js +360 -0
  49. package/src/vcs/vcm/layer/featureStoreState.js +19 -0
  50. package/src/vcs/vcm/layer/featureVisibility.js +435 -0
  51. package/src/vcs/vcm/layer/geojson.js +185 -0
  52. package/src/vcs/vcm/layer/geojsonHelpers.js +450 -0
  53. package/src/vcs/vcm/layer/globalHider.js +157 -0
  54. package/src/vcs/vcm/layer/layer.js +752 -0
  55. package/src/vcs/vcm/layer/layerImplementation.js +102 -0
  56. package/src/vcs/vcm/layer/layerState.js +17 -0
  57. package/src/vcs/vcm/layer/layerSymbols.js +6 -0
  58. package/src/vcs/vcm/layer/oblique/layerOblique.js +76 -0
  59. package/src/vcs/vcm/layer/oblique/obliqueHelpers.js +175 -0
  60. package/src/vcs/vcm/layer/oblique/vectorOblique.js +469 -0
  61. package/src/vcs/vcm/layer/openStreetMap.js +194 -0
  62. package/src/vcs/vcm/layer/openlayers/layerOpenlayers.js +79 -0
  63. package/src/vcs/vcm/layer/openlayers/openStreetMapOpenlayers.js +27 -0
  64. package/src/vcs/vcm/layer/openlayers/rasterLayerOpenlayers.js +121 -0
  65. package/src/vcs/vcm/layer/openlayers/singleImageOpenlayers.js +49 -0
  66. package/src/vcs/vcm/layer/openlayers/tileDebugOpenlayers.js +39 -0
  67. package/src/vcs/vcm/layer/openlayers/tmsOpenlayers.js +62 -0
  68. package/src/vcs/vcm/layer/openlayers/vectorOpenlayers.js +118 -0
  69. package/src/vcs/vcm/layer/openlayers/vectorTileOpenlayers.js +177 -0
  70. package/src/vcs/vcm/layer/openlayers/wmsOpenlayers.js +55 -0
  71. package/src/vcs/vcm/layer/openlayers/wmtsOpenlayers.js +141 -0
  72. package/src/vcs/vcm/layer/pointCloud.js +162 -0
  73. package/src/vcs/vcm/layer/rasterLayer.js +294 -0
  74. package/src/vcs/vcm/layer/singleImage.js +119 -0
  75. package/src/vcs/vcm/layer/terrain.js +122 -0
  76. package/src/vcs/vcm/layer/terrainHelpers.js +123 -0
  77. package/src/vcs/vcm/layer/tileLoadedHelper.js +72 -0
  78. package/src/vcs/vcm/layer/tileProvider/mvtTileProvider.js +104 -0
  79. package/src/vcs/vcm/layer/tileProvider/staticGeojsonTileProvider.js +67 -0
  80. package/src/vcs/vcm/layer/tileProvider/tileProvider.js +584 -0
  81. package/src/vcs/vcm/layer/tileProvider/tileProviderFactory.js +28 -0
  82. package/src/vcs/vcm/layer/tileProvider/urlTemplateTileProvider.js +106 -0
  83. package/src/vcs/vcm/layer/tms.js +121 -0
  84. package/src/vcs/vcm/layer/vector.js +632 -0
  85. package/src/vcs/vcm/layer/vectorHelpers.js +206 -0
  86. package/src/vcs/vcm/layer/vectorProperties.js +1391 -0
  87. package/src/vcs/vcm/layer/vectorSymbols.js +40 -0
  88. package/src/vcs/vcm/layer/vectorTile.js +480 -0
  89. package/src/vcs/vcm/layer/wfs.js +165 -0
  90. package/src/vcs/vcm/layer/wms.js +270 -0
  91. package/src/vcs/vcm/layer/wmsHelpers.js +65 -0
  92. package/src/vcs/vcm/layer/wmts.js +235 -0
  93. package/src/vcs/vcm/maps/baseOLMap.js +257 -0
  94. package/src/vcs/vcm/maps/cameraLimiter.js +219 -0
  95. package/src/vcs/vcm/maps/cesium.js +1192 -0
  96. package/src/vcs/vcm/maps/map.js +511 -0
  97. package/src/vcs/vcm/maps/mapState.js +17 -0
  98. package/src/vcs/vcm/maps/oblique.js +536 -0
  99. package/src/vcs/vcm/maps/openlayers.js +205 -0
  100. package/src/vcs/vcm/object.js +92 -0
  101. package/src/vcs/vcm/oblique/ObliqueCollection.js +572 -0
  102. package/src/vcs/vcm/oblique/ObliqueDataSet.js +357 -0
  103. package/src/vcs/vcm/oblique/ObliqueImage.js +247 -0
  104. package/src/vcs/vcm/oblique/ObliqueImageMeta.js +126 -0
  105. package/src/vcs/vcm/oblique/ObliqueProvider.js +433 -0
  106. package/src/vcs/vcm/oblique/ObliqueView.js +130 -0
  107. package/src/vcs/vcm/oblique/ObliqueViewDirection.js +40 -0
  108. package/src/vcs/vcm/oblique/helpers.js +483 -0
  109. package/src/vcs/vcm/oblique/parseImageJson.js +248 -0
  110. package/src/vcs/vcm/util/clipping/clippingObject.js +386 -0
  111. package/src/vcs/vcm/util/clipping/clippingObjectManager.js +312 -0
  112. package/src/vcs/vcm/util/clipping/clippingPlaneHelper.js +413 -0
  113. package/src/vcs/vcm/util/collection.js +193 -0
  114. package/src/vcs/vcm/util/dateTime.js +60 -0
  115. package/src/vcs/vcm/util/exclusiveManager.js +135 -0
  116. package/src/vcs/vcm/util/extent.js +124 -0
  117. package/src/vcs/vcm/util/featureProvider/abstractFeatureProvider.js +196 -0
  118. package/src/vcs/vcm/util/featureProvider/featureProviderHelpers.js +51 -0
  119. package/src/vcs/vcm/util/featureProvider/featureProviderSymbols.js +11 -0
  120. package/src/vcs/vcm/util/featureProvider/tileProviderFeatureProvider.js +62 -0
  121. package/src/vcs/vcm/util/featureProvider/wmsFeatureProvider.js +280 -0
  122. package/src/vcs/vcm/util/featureconverter/circleToCesium.js +215 -0
  123. package/src/vcs/vcm/util/featureconverter/convert.js +83 -0
  124. package/src/vcs/vcm/util/featureconverter/extent3d.js +154 -0
  125. package/src/vcs/vcm/util/featureconverter/featureconverterHelper.js +591 -0
  126. package/src/vcs/vcm/util/featureconverter/lineStringToCesium.js +171 -0
  127. package/src/vcs/vcm/util/featureconverter/pointToCesium.js +359 -0
  128. package/src/vcs/vcm/util/featureconverter/polygonToCesium.js +229 -0
  129. package/src/vcs/vcm/util/geometryHelpers.js +172 -0
  130. package/src/vcs/vcm/util/indexedCollection.js +158 -0
  131. package/src/vcs/vcm/util/isMobile.js +12 -0
  132. package/src/vcs/vcm/util/layerCollection.js +216 -0
  133. package/src/vcs/vcm/util/locale.js +53 -0
  134. package/src/vcs/vcm/util/mapCollection.js +363 -0
  135. package/src/vcs/vcm/util/math.js +71 -0
  136. package/src/vcs/vcm/util/projection.js +348 -0
  137. package/src/vcs/vcm/util/splitScreen.js +233 -0
  138. package/src/vcs/vcm/util/style/declarativeStyleItem.js +631 -0
  139. package/src/vcs/vcm/util/style/shapesCategory.js +67 -0
  140. package/src/vcs/vcm/util/style/styleFactory.js +48 -0
  141. package/src/vcs/vcm/util/style/styleHelpers.js +555 -0
  142. package/src/vcs/vcm/util/style/styleItem.js +226 -0
  143. package/src/vcs/vcm/util/style/vectorStyleItem.js +927 -0
  144. package/src/vcs/vcm/util/style/writeStyle.js +48 -0
  145. package/src/vcs/vcm/util/urlHelpers.js +16 -0
  146. 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;