bruce-cesium 3.4.7 → 3.4.9

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.
@@ -1,6 +1,6 @@
1
- import { Cartes, Carto, Entity as Entity$1, Geometry, Tileset, MathUtils, LRUCache, ProjectViewTile, DelayQueue, ZoomControl, Style, EntityTag, Calculator, EntityLod, EntityType, ClientFile, ObjectUtils, Bounds, Api, EntityRelationType, ENVIRONMENT, BruceEvent, EntityCoords, EntitySource, MenuItem, EntityRelation, ProgramKey, AbstractApi, ProjectViewBookmark, EntityAttachment, EntityAttachmentType, EntityAttribute, ProjectView, ProjectViewLegacyTile, Camera } from 'bruce-models';
1
+ import { BruceEvent, Cartes, Carto, Entity as Entity$1, Geometry, Tileset, MathUtils, LRUCache, ProjectViewTile, DelayQueue, ZoomControl, Style, EntityTag, Calculator, EntityLod, EntityType, ClientFile, ObjectUtils, Bounds, Api, EntityRelationType, ENVIRONMENT, EntityCoords, EntitySource, MenuItem, EntityRelation, ProgramKey, AbstractApi, ProjectViewBookmark, EntityAttachment, EntityAttachmentType, EntityAttribute, ProjectView, ProjectViewLegacyTile, Camera } from 'bruce-models';
2
2
  import * as Cesium from 'cesium';
3
- import { Cartographic, Cartesian2, Math as Math$1, Cartesian3, CallbackProperty, Color, HeightReference, Rectangle, JulianDate, DistanceDisplayCondition, NearFarScalar, Model, Entity, HorizontalOrigin, VerticalOrigin, ClassificationType, ArcType, CornerType, ShadowMode, PolygonHierarchy, PolylineGraphics, HeadingPitchRoll, Transforms, ColorBlendMode, Primitive, Cesium3DTileFeature, SceneMode, Cesium3DTileColorBlendMode, HeadingPitchRange, GeoJsonDataSource, ColorMaterialProperty, Cesium3DTileStyle, Ion, KmlDataSource, SceneTransforms, OrthographicFrustum, EasingFunction, EllipsoidTerrainProvider, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, UrlTemplateImageryProvider, TileMapServiceImageryProvider, IonImageryProvider, CesiumTerrainProvider, CesiumInspector, defined, Cesium3DTileset, Matrix4, Matrix3, IonResource, EllipsoidGeodesic, sampleTerrainMostDetailed, BoundingSphere, GeometryInstance, PolygonPipeline, ScreenSpaceEventHandler, ScreenSpaceEventType, Intersect, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics } from 'cesium';
3
+ import { Cartographic, Cartesian2, Math as Math$1, Cartesian3, CallbackProperty, Color, HeightReference, Rectangle, JulianDate, DistanceDisplayCondition, NearFarScalar, Model, Entity, HorizontalOrigin, VerticalOrigin, ClassificationType, ArcType, CornerType, ShadowMode, PolygonHierarchy, PolylineGraphics, HeadingPitchRoll, Transforms, ColorBlendMode, Primitive, Cesium3DTileFeature, SceneMode, GeoJsonDataSource, ColorMaterialProperty, Cesium3DTileColorBlendMode, HeadingPitchRange, Ion, Cesium3DTileStyle, KmlDataSource, SceneTransforms, EllipsoidTerrainProvider, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, UrlTemplateImageryProvider, TileMapServiceImageryProvider, IonImageryProvider, CesiumTerrainProvider, OrthographicFrustum, EasingFunction, Cesium3DTileset, Matrix4, Matrix3, IonResource, CesiumInspector, defined, PolygonPipeline, ScreenSpaceEventHandler, ScreenSpaceEventType, BoundingSphere, GeometryInstance, EllipsoidGeodesic, sampleTerrainMostDetailed, Intersect, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics } from 'cesium';
4
4
 
5
5
  /*! *****************************************************************************
6
6
  Copyright (c) Microsoft Corporation. All rights reserved.
@@ -79,460 +79,876 @@ function __generator(thisArg, body) {
79
79
  }
80
80
  }
81
81
 
82
+ var TIME_LAG = 300;
83
+ var POSITION_CHECK_TIMER = 950;
84
+ var DEFAULT_GROUNDED_HEIGHT = 300;
85
+ var MINIMUM_VIEW_AREA_SIZE_DEGREES = 0.01;
86
+ var NET_STEP_PERCENT = 5;
87
+ var BORDER_STEPS = 3;
88
+ var ESearchStatus;
89
+ (function (ESearchStatus) {
90
+ ESearchStatus[ESearchStatus["LocationFound"] = 1] = "LocationFound";
91
+ ESearchStatus[ESearchStatus["LocationChanged"] = 2] = "LocationChanged";
92
+ ESearchStatus[ESearchStatus["LocationMissing"] = 3] = "LocationMissing";
93
+ })(ESearchStatus || (ESearchStatus = {}));
82
94
  /**
83
- * Ensures a number is returned from a given value.
84
- * If given value cannot be parsed it will return defaultNum.
85
- * @param value
86
- * @param defaultNum default is 0.
95
+ * @param viewer
96
+ * @param center the previously calculated center of the view area. This is in degrees.
87
97
  * @returns
88
98
  */
89
- function EnsureNumber(value, defaultNum) {
90
- if (!defaultNum) {
91
- defaultNum = 0;
92
- }
93
- value = Number(value);
94
- if (isNaN(value)) {
95
- return defaultNum;
96
- }
97
- return value;
98
- }
99
-
100
- var MeasureUtils;
101
- (function (MeasureUtils) {
102
- /**
103
- * Returns the total distance in meters between an array of points.
104
- * This distance is NOT following the terrain.
105
- * @param posses
106
- * @returns
107
- */
108
- function MeasurePolyline(params) {
109
- var posses = params.posses;
110
- if (posses.length < 2) {
111
- return {
112
- totalLength: 0
113
- };
99
+ function netScanViewForBoundaries(viewer, center) {
100
+ var maxLong = -2 * Math.PI;
101
+ var minLong = 2 * Math.PI;
102
+ var maxLat = -2 * Math.PI;
103
+ var minLat = 2 * Math.PI;
104
+ var found = 0;
105
+ var updateMinMax = function (lon, lat) {
106
+ // Check to see if given lon/lat (in radians) are within valid range.
107
+ if (lon < -Math.PI || lon > Math.PI || lat < -Math.PI / 2 || lat > Math.PI / 2) {
108
+ return;
114
109
  }
115
- var totalLength = 0;
116
- var pos1 = null;
117
- var pos2 = null;
118
- for (var i = 0; i < posses.length; i++) {
119
- if (pos1 == null) {
120
- pos1 = posses[i];
121
- }
122
- else if (pos2 == null) {
123
- pos2 = posses[i];
124
- totalLength += Cartesian3.distance(pos1, pos2);
125
- pos1 = pos2;
126
- pos2 = null;
110
+ maxLong = Math.max(maxLong, lon);
111
+ maxLat = Math.max(maxLat, lat);
112
+ minLong = Math.min(minLong, lon);
113
+ minLat = Math.min(minLat, lat);
114
+ };
115
+ var updateMinMaxForPoint = function (stepX, stepY) {
116
+ var x = Math.round(0 + (viewer.container.clientWidth / 100) * (stepX * NET_STEP_PERCENT));
117
+ var y = Math.round(0 + (viewer.container.clientHeight / 100) * (stepY * NET_STEP_PERCENT));
118
+ var winPos = new Cartesian2(x, y);
119
+ try {
120
+ var intersection = getAdjustedGroundIntersectionOfCameraRay(viewer, winPos);
121
+ if (intersection) {
122
+ var point = Cartographic.fromCartesian(intersection, viewer.scene.globe.ellipsoid);
123
+ updateMinMax(point.longitude, point.latitude);
124
+ found++;
127
125
  }
128
126
  }
129
- return {
130
- totalLength: totalLength
131
- };
132
- }
133
- MeasureUtils.MeasurePolyline = MeasurePolyline;
134
- function MeasurePolygon(params) {
135
- var posses = params.posses;
136
- posses = [].concat(posses);
137
- if (!Cartes.IsRing3Closed(posses)) {
138
- posses.push(posses[0].clone());
127
+ catch (e) {
128
+ console.error(e);
139
129
  }
140
- if (posses.length < 3) {
141
- return {
142
- area: 0,
143
- perimeter: 0
144
- };
130
+ };
131
+ // Outer circle.
132
+ updateMinMaxForPoint(BORDER_STEPS, BORDER_STEPS);
133
+ updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS, BORDER_STEPS);
134
+ updateMinMaxForPoint(BORDER_STEPS, (100 / NET_STEP_PERCENT) - BORDER_STEPS);
135
+ updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS, (100 / NET_STEP_PERCENT) - BORDER_STEPS);
136
+ // Inner circle.
137
+ updateMinMaxForPoint(BORDER_STEPS * 2, BORDER_STEPS * 2);
138
+ updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS * 2, BORDER_STEPS * 2);
139
+ updateMinMaxForPoint(BORDER_STEPS * 2, (100 / NET_STEP_PERCENT) - BORDER_STEPS * 2);
140
+ updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS * 2, (100 / NET_STEP_PERCENT) - BORDER_STEPS * 2);
141
+ // If we failed to find intersections and a center-point was provided, then we can use that to make some guesses.
142
+ // This happens if terrain is hidden, and there's nothing to intersect with.
143
+ if (center && found <= 0) {
144
+ updateMinMax(Math$1.toRadians(center.longitude), Math$1.toRadians(center.latitude));
145
+ found += 1;
146
+ // We'll use the camera height as an indicator on size of the rect.
147
+ var size = viewer.camera.positionCartographic.height;
148
+ var pitch = viewer.camera.pitch;
149
+ var distance = size / Math.tan(pitch);
150
+ var p1 = _offsetPoint({
151
+ altitude: center.altitude,
152
+ latitude: center.latitude,
153
+ longitude: center.longitude
154
+ }, distance, 45);
155
+ var p2 = _offsetPoint({
156
+ altitude: center.altitude,
157
+ latitude: center.latitude,
158
+ longitude: center.longitude
159
+ }, -distance, 45);
160
+ if (p1 === null || p1 === void 0 ? void 0 : p1.latitude) {
161
+ updateMinMax(Math$1.toRadians(p1.longitude), Math$1.toRadians(p1.latitude));
145
162
  }
146
- var area = 0;
147
- var indices = PolygonPipeline.triangulate(posses, []);
148
- for (var i = 0; i < indices.length; i += 3) {
149
- var vector1 = posses[indices[i]];
150
- var vector2 = posses[indices[i + 1]];
151
- var vector3 = posses[indices[i + 2]];
152
- var vectorC = Cartesian3.subtract(vector2, vector1, new Cartesian3());
153
- var vectorD = Cartesian3.subtract(vector3, vector1, new Cartesian3());
154
- var areaVector = Cartesian3.cross(vectorC, vectorD, new Cartesian3());
155
- area += Cartesian3.magnitude(areaVector) / 2.0;
163
+ if (p2 === null || p2 === void 0 ? void 0 : p2.latitude) {
164
+ updateMinMax(Math$1.toRadians(p2.longitude), Math$1.toRadians(p2.latitude));
156
165
  }
157
- var perimeter = MeasurePolyline({
158
- posses: posses
159
- }).totalLength;
160
- return {
161
- area: area,
162
- perimeter: perimeter
166
+ }
167
+ if (found > 0) {
168
+ var viewRect = {
169
+ east: maxLong,
170
+ west: minLong,
171
+ north: maxLat,
172
+ south: minLat
163
173
  };
174
+ return viewRect;
164
175
  }
165
- MeasureUtils.MeasurePolygon = MeasurePolygon;
166
- })(MeasureUtils || (MeasureUtils = {}));
167
-
168
- var C3 = [Cartesian3][0];
169
- function getT(t, alpha, p0, p1) {
170
- var d = C3.subtract(p1, p0, new C3);
171
- var a = C3.dot(d, d);
172
- var b = Math.pow(a, alpha * 0.5);
173
- return b + t;
176
+ return null;
174
177
  }
175
- function catmullRom(p0, p1, p2, p3, t) {
176
- var t0 = 0;
177
- var t1 = getT(t0, 0.5, p0, p1);
178
- var t2 = getT(t1, 0.5, p1, p2);
179
- var t3 = getT(t2, 0.5, p2, p3);
180
- t = Math$1.lerp(t1, t2, t);
181
- var _a = [function (l, r) { return C3.add(l, r, new C3); }, function (l, r) { return C3.multiplyByScalar(l, r, new C3); }], add = _a[0], mul = _a[1];
182
- var A1 = add(mul(p0, (t1 - t) / (t1 - t0)), mul(p1, (t - t0) / (t1 - t0)));
183
- var A2 = add(mul(p1, (t2 - t) / (t2 - t1)), mul(p2, (t - t1) / (t2 - t1)));
184
- var A3 = add(mul(p2, (t3 - t) / (t3 - t2)), mul(p3, (t - t2) / (t3 - t2)));
185
- var B1 = add(mul(A1, (t2 - t) / (t2 - t0)), mul(A2, (t - t0) / (t2 - t0)));
186
- var B2 = add(mul(A2, (t3 - t) / (t3 - t1)), mul(A3, (t - t1) / (t3 - t1)));
187
- var C = add(mul(B1, (t2 - t) / (t2 - t1)), mul(B2, (t - t1) / (t2 - t1)));
188
- return C;
178
+ /**
179
+ * Moves a given point by a given distance towards a heading.
180
+ * @param point in degrees.
181
+ * @param distance in meters.
182
+ * @param heading in degrees.
183
+ * @returns
184
+ */
185
+ function _offsetPoint(point, distance, heading) {
186
+ // Radius of earth.
187
+ var radius = 6371e3;
188
+ var δ = distance / radius;
189
+ var θ = Math$1.toRadians(heading);
190
+ var φ1 = Math$1.toRadians(point.latitude);
191
+ var λ1 = Math$1.toRadians(point.longitude);
192
+ var sinφ2 = Math.sin(φ1) * Math.cos(δ) + Math.cos(φ1) * Math.sin(δ) * Math.cos(θ);
193
+ var φ2 = Math.asin(sinφ2);
194
+ var y = Math.sin(θ) * Math.sin(δ) * Math.cos(φ1);
195
+ var x = Math.cos(δ) - Math.sin(φ1) * sinφ2;
196
+ var λ2 = λ1 + Math.atan2(y, x);
197
+ return {
198
+ altitude: point.altitude,
199
+ latitude: Math$1.toDegrees(φ2),
200
+ longitude: Math$1.toDegrees(λ2)
201
+ };
189
202
  }
190
- var DrawingUtils;
191
- (function (DrawingUtils) {
192
- /**
193
- * Returns the point across a polyline at a given distance.
194
- * If the distance exceeds the length of the line, the point will be placed at the end of the line.
195
- * @param viewer
196
- * @param positions
197
- * @param distance
198
- * @returns
199
- */
200
- function PointAcrossPolyline(params) {
201
- var viewer = params.viewer, positions = params.posses, distance = params.distance;
202
- if (distance <= 0 && positions.length > 0) {
203
- return {
204
- point: positions[0]
205
- };
206
- }
207
- else if (positions.length > 1) {
208
- var currentDistance = 0;
209
- var totalLength = MeasureUtils.MeasurePolyline({
210
- posses: positions,
211
- }).totalLength;
212
- if (distance > totalLength) {
213
- return {
214
- point: positions[positions.length - 1]
215
- };
216
- }
217
- for (var i = 0; i < positions.length - 1; i++) {
218
- var length_1 = Cartesian3.distance(positions[i], positions[i + 1]);
219
- if (length_1 + currentDistance >= distance) {
220
- var carto1 = Cartographic.fromCartesian(positions[i]);
221
- var carto2 = Cartographic.fromCartesian(positions[i + 1]);
222
- var geodesic = new EllipsoidGeodesic(carto1, carto2, viewer.scene.globe.ellipsoid);
223
- //const position = geodesic.interpolateUsingSurfaceDistance(distance - currentDistance);
224
- var position = geodesic.interpolateUsingFraction((distance - currentDistance) / length_1);
225
- var height = (carto1.height + carto2.height) / 2;
226
- return {
227
- point: Cartesian3.fromRadians(position.longitude, position.latitude, height)
228
- };
229
- }
230
- else {
231
- currentDistance += length_1;
232
- }
233
- }
234
- }
235
- return {
236
- point: positions.length ? positions[positions.length - 1] : null
237
- };
238
- }
239
- DrawingUtils.PointAcrossPolyline = PointAcrossPolyline;
240
- /**
241
- * Returns terrain height from current viewer's provider.
242
- * On error or flat terrain, it will return 0.
243
- * If an error occurred it will be attached to the result.
244
- * @param pos3d
245
- * @param viewer
246
- * @returns
247
- */
248
- function GetTerrainHeight(params) {
249
- return __awaiter(this, void 0, void 0, function () {
250
- var pos3d, viewer, sample, height, e_1;
251
- return __generator(this, function (_a) {
252
- switch (_a.label) {
253
- case 0:
254
- pos3d = params.pos3d, viewer = params.viewer;
255
- _a.label = 1;
256
- case 1:
257
- _a.trys.push([1, 3, , 4]);
258
- // If the terrain provider is not ready let's not ping it.
259
- if (!viewer.terrainProvider || viewer.terrainProvider["ready"] == false) {
260
- return [2 /*return*/, {
261
- height: 0,
262
- error: "Terrain provider not ready."
263
- }];
264
- }
265
- if (viewer.scene.terrainProvider instanceof EllipsoidTerrainProvider) {
266
- return [2 /*return*/, {
267
- height: 0
268
- }];
269
- }
270
- return [4 /*yield*/, sampleTerrainMostDetailed(viewer.scene.terrainProvider, [Cartographic.fromCartesian(pos3d)])];
271
- case 2:
272
- sample = _a.sent();
273
- height = (sample === null || sample === void 0 ? void 0 : sample.length) ? sample[0].height : null;
274
- if (isNaN(height)) {
275
- return [2 /*return*/, {
276
- height: 0,
277
- error: "NaN"
278
- }];
279
- }
280
- return [2 /*return*/, {
281
- height: height
282
- }];
283
- case 3:
284
- e_1 = _a.sent();
285
- return [2 /*return*/, {
286
- height: 0,
287
- error: e_1
288
- }];
289
- case 4: return [2 /*return*/];
290
- }
291
- });
292
- });
203
+ /**
204
+ * @param pos3d
205
+ * @param distance in meters
206
+ * @param heading in degrees
207
+ * @returns
208
+ */
209
+ function _offsetPos3d(pos3d, distance, heading) {
210
+ var carto = Cartographic.fromCartesian(pos3d);
211
+ var newCarto = _offsetPoint({
212
+ altitude: carto.height,
213
+ latitude: Math$1.toDegrees(carto.latitude),
214
+ longitude: Math$1.toDegrees(carto.longitude)
215
+ }, distance, heading);
216
+ return Cartesian3.fromDegrees(newCarto.longitude, newCarto.latitude, newCarto.altitude);
217
+ }
218
+ /**
219
+ * Returns the intersection of the camera ray with the ground.
220
+ * @param viewer
221
+ * @param screenPos
222
+ * @returns
223
+ */
224
+ function getAdjustedGroundIntersectionOfCameraRay(viewer, screenPos) {
225
+ var ray = viewer.camera.getPickRay(screenPos);
226
+ var intersection = ray ? viewer.scene.globe.pick(ray, viewer.scene) : null;
227
+ if (intersection) {
228
+ return intersection;
293
229
  }
294
- DrawingUtils.GetTerrainHeight = GetTerrainHeight;
295
- function EnsurePosHeight(params) {
296
- var pos3d = params.pos3d, viewer = params.viewer, desiredHeightRef = params.desiredHeightRef, heightRef = params.heightRef;
297
- var carto = Cartes.ValidateCartes3(pos3d) ? Cartographic.fromCartesian(pos3d) : null;
298
- if (!(carto === null || carto === void 0 ? void 0 : carto.latitude)) {
299
- return pos3d;
300
- }
301
- if (heightRef == null) {
302
- heightRef = HeightReference.CLAMP_TO_GROUND;
303
- }
304
- if (desiredHeightRef == null) {
305
- desiredHeightRef = HeightReference.CLAMP_TO_GROUND;
306
- }
307
- if (heightRef == desiredHeightRef) {
308
- return pos3d;
309
- }
310
- if (heightRef == HeightReference.NONE) {
311
- // Turn absolute into clamped.
312
- if (desiredHeightRef == HeightReference.CLAMP_TO_GROUND) {
313
- return Cartesian3.fromRadians(carto.longitude, carto.latitude, 0);
314
- }
315
- // Turn absolute into relative (remove terrain height).
316
- else if (desiredHeightRef == HeightReference.RELATIVE_TO_GROUND) {
317
- var terrainHeight = EnsureNumber(viewer.scene.globe.getHeight(carto), 0);
318
- return Cartesian3.fromRadians(carto.longitude, carto.latitude, carto.height - terrainHeight);
319
- }
320
- }
321
- else if (heightRef == HeightReference.CLAMP_TO_GROUND) {
322
- var terrainHeight = EnsureNumber(viewer.scene.globe.getHeight(carto), 0);
323
- return Cartesian3.fromRadians(carto.longitude, carto.latitude, terrainHeight);
324
- }
325
- else if (heightRef == HeightReference.RELATIVE_TO_GROUND) {
326
- // Turn relative into absolute (add terrain height).
327
- if (desiredHeightRef == HeightReference.NONE) {
328
- var terrainHeight = EnsureNumber(viewer.scene.globe.getHeight(carto), 0);
329
- return Cartesian3.fromRadians(carto.longitude, carto.latitude, carto.height + terrainHeight);
330
- }
331
- // Turn relative into clamped.
332
- else if (desiredHeightRef == HeightReference.CLAMP_TO_GROUND) {
333
- return Cartesian3.fromRadians(carto.longitude, carto.latitude, 0);
334
- }
335
- }
336
- return pos3d;
230
+ return null;
231
+ }
232
+ /**
233
+ * Returns the intersection of the camera ray with the ground.
234
+ * If no intersection is found, then a "guess" is made based on the camera angle and height.
235
+ * The guess is made at the center of the view! It ignores the screenPos.
236
+ * @param viewer
237
+ * @param screenPos
238
+ * @returns
239
+ */
240
+ function getGroundCenterOfCameraRay(viewer, screenPos) {
241
+ var _a, _b;
242
+ var ray = viewer.camera.getPickRay(screenPos);
243
+ var intersection = ray ? viewer.scene.globe.pick(ray, viewer.scene) : null;
244
+ if (intersection) {
245
+ return intersection;
337
246
  }
338
- DrawingUtils.EnsurePosHeight = EnsurePosHeight;
247
+ // The fallback will be to "guess" where the intersection might be.
248
+ // This happens if terrain is hidden, and there's nothing to intersect with.
249
+ // We will use the camera angle + camera height.
250
+ // Eg: if camera is looking straight down and is 100 meters above the ground, then the intersection will be 100 meters below the camera.
251
+ var cameraHeight = viewer.camera.positionCartographic.height;
252
+ if (!isNaN(cameraHeight) && cameraHeight != null && ((_b = (_a = viewer.camera) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.clone)) {
253
+ var cameraPos3d = viewer.camera.position.clone();
254
+ var pitch = viewer.camera.pitch;
255
+ var distance = cameraHeight / Math.tan(pitch);
256
+ return _offsetPos3d(cameraPos3d, -distance, Math$1.toDegrees(viewer.camera.heading));
257
+ }
258
+ return null;
259
+ }
260
+ function areBoundsEqual(a, b) {
261
+ return a.north == b.north && a.south == b.south && a.east == b.east && a.west == b.west;
262
+ }
263
+ function arePosEqual(a, b) {
264
+ return a.latitude == b.latitude && a.longitude == b.longitude;
265
+ }
266
+ var CesiumViewMonitor;
267
+ (function (CesiumViewMonitor$$1) {
339
268
  /**
340
- * Returns an accurate 3d position from a given screen position.
341
- * @param viewer
342
- * @param cursor
343
- * @returns
269
+ * Monitors and emits events when the Cesium view changes.
344
270
  */
345
- DrawingUtils.GetAccuratePosition = (function () {
346
- var cachedPick = null;
347
- var cacheTimestamp = null;
348
- var cachedCameraState = null;
349
- return function (viewer, cursor, pickOnly) {
350
- if (pickOnly === void 0) { pickOnly = false; }
351
- var scene = viewer.scene;
352
- var camera = scene.camera;
353
- // Check if we can use cached position.
354
- if (cachedPick && cacheTimestamp) {
355
- var timeElapsed = Date.now() - cacheTimestamp;
356
- var isWithinCacheDuration = timeElapsed < 3000; // 3 seconds
357
- var isNearPreviousPick = Cartesian2.distanceSquared(cursor, cachedPick.cursor) < 9; // 3 pixels
358
- var directionDot = Cartesian3.dot(camera.directionWC, cachedCameraState.direction);
359
- var directionLengths = Cartesian3.magnitude(camera.directionWC) * Cartesian3.magnitude(cachedCameraState.direction);
360
- var angle = Math.acos(directionDot / directionLengths);
361
- var hasCameraMoved = Math.abs(camera.positionWC.x - cachedCameraState.position.x) > 2 || // 2 meters
362
- Math.abs(camera.positionWC.y - cachedCameraState.position.y) > 2 ||
363
- angle > Math$1.toRadians(5); // 5 degrees
364
- if (isWithinCacheDuration && isNearPreviousPick && !hasCameraMoved) {
365
- return cachedPick.position;
271
+ var Monitor = /** @class */ (function () {
272
+ function Monitor(viewer) {
273
+ var _this = this;
274
+ this.target = null;
275
+ this.bounds = null;
276
+ this.disposed = false;
277
+ this.updatedEvent = null;
278
+ this.entity = null;
279
+ this.updating = false;
280
+ this.viewer = viewer;
281
+ this.tryEmitUpdate();
282
+ this.checkInterval = setInterval(function () {
283
+ _this.updateQueue();
284
+ }, POSITION_CHECK_TIMER);
285
+ }
286
+ Object.defineProperty(Monitor.prototype, "Disposed", {
287
+ get: function () {
288
+ return this.disposed;
289
+ },
290
+ enumerable: false,
291
+ configurable: true
292
+ });
293
+ Monitor.prototype.createEntity = function () {
294
+ var _this = this;
295
+ if (this.entity) {
296
+ return;
297
+ }
298
+ this.entity = this.viewer.entities.add({
299
+ position: new CallbackProperty(function () {
300
+ return _this.target ? Cartesian3.fromDegrees(_this.target.longitude, _this.target.latitude) : null;
301
+ }, false),
302
+ point: {
303
+ pixelSize: 8,
304
+ color: Color.ORANGE,
305
+ heightReference: HeightReference.NONE
306
+ },
307
+ rectangle: {
308
+ coordinates: new CallbackProperty(function () {
309
+ return _this.bounds ? Rectangle.fromDegrees(_this.bounds.west, _this.bounds.south, _this.bounds.east, _this.bounds.north) : null;
310
+ }, false),
311
+ material: Color.fromCssColorString('#ff0000').withAlpha(0.4),
312
+ zIndex: 1,
313
+ heightReference: HeightReference.NONE
366
314
  }
315
+ });
316
+ };
317
+ Monitor.prototype.destroyEntity = function () {
318
+ if (this.entity && this.viewer.entities.contains(this.entity)) {
319
+ this.viewer.entities.remove(this.entity);
367
320
  }
368
- // Actual picking logic
369
- // https://community.cesium.com/t/scene-pick-returning-point-inside-the-globe/18940/9
370
- var pos3d = null;
371
- // Means we can accurately pick right now.
372
- if (!pickOnly && scene.globe.depthTestAgainstTerrain) {
373
- pos3d = scene.pickPosition(cursor);
321
+ this.entity = null;
322
+ };
323
+ Monitor.prototype.Updated = function () {
324
+ if (!this.updatedEvent) {
325
+ this.updatedEvent = new BruceEvent();
374
326
  }
375
- // Means we cannot guarantee an accurate pick.
376
- // We want to prioritize pick-position when we can, so we'll try use it and if the result is sus then we'll use some fallbacks.
377
- else {
378
- if (!pickOnly) {
379
- pos3d = scene.pickPosition(cursor);
380
- }
381
- if (defined(pos3d)) {
382
- var carto = Cartographic.fromCartesian(pos3d);
383
- if (!defined(carto) || carto.height < 0) {
384
- pos3d = null;
385
- }
386
- }
387
- if (!defined(pos3d)) {
388
- pos3d = null;
389
- var ray = scene.camera.getPickRay(cursor);
390
- if (scene.pickPositionSupported) {
391
- var pickedObject = scene.pick(cursor, 1, 1);
392
- if (defined(pickedObject) &&
393
- (pickedObject instanceof Cesium3DTileFeature ||
394
- pickedObject.primitive instanceof Cesium3DTileset ||
395
- pickedObject.primitive instanceof Model)) {
396
- pos3d = scene.pickPosition(cursor);
397
- }
327
+ return this.updatedEvent;
328
+ };
329
+ Monitor.prototype.GetBounds = function () {
330
+ return this.bounds;
331
+ };
332
+ Monitor.prototype.GetTarget = function () {
333
+ return this.target;
334
+ };
335
+ Monitor.prototype.DoUpdate = function () {
336
+ this.tryEmitUpdate();
337
+ };
338
+ Monitor.prototype.Dispose = function () {
339
+ if (this.disposed) {
340
+ return;
341
+ }
342
+ this.disposed = true;
343
+ clearInterval(this.checkInterval);
344
+ this.destroyEntity();
345
+ };
346
+ Monitor.prototype.tryDoUpdate = function () {
347
+ var _a;
348
+ return __awaiter(this, void 0, void 0, function () {
349
+ var viewRect, center, camera, terrData, cameraPosition, terrHeight, viewRectRad, windowPosition, intersection, point, viewRectRad, centerLong, centerLat;
350
+ return __generator(this, function (_b) {
351
+ switch (_b.label) {
352
+ case 0:
353
+ if (!this.viewer || this.viewer.isDestroyed()) {
354
+ this.Dispose();
355
+ return [2 /*return*/, ESearchStatus.LocationMissing];
356
+ }
357
+ viewRect = null;
358
+ center = null;
359
+ camera = this.viewer.camera;
360
+ return [4 /*yield*/, DrawingUtils.GetTerrainHeight({
361
+ pos3d: camera.position,
362
+ viewer: this.viewer
363
+ })];
364
+ case 1:
365
+ terrData = _b.sent();
366
+ cameraPosition = this.viewer.camera.positionCartographic;
367
+ terrHeight = terrData.error ? cameraPosition.height + DEFAULT_GROUNDED_HEIGHT : terrData.height;
368
+ // We are almost at the ground, screw horizon, just load around.
369
+ if (terrHeight && ((cameraPosition.height - terrHeight) < DEFAULT_GROUNDED_HEIGHT)) {
370
+ // View area calculation.
371
+ viewRect = {};
372
+ viewRectRad = netScanViewForBoundaries(this.viewer);
373
+ if (viewRectRad &&
374
+ viewRectRad.east &&
375
+ viewRectRad.west &&
376
+ viewRectRad.north &&
377
+ viewRectRad.south) {
378
+ viewRect.east = Math$1.toDegrees(Math.max(viewRectRad.east, cameraPosition.longitude));
379
+ viewRect.west = Math$1.toDegrees(Math.min(viewRectRad.west, cameraPosition.longitude));
380
+ viewRect.south = Math$1.toDegrees(Math.min(viewRectRad.south, cameraPosition.latitude));
381
+ viewRect.north = Math$1.toDegrees(Math.max(viewRectRad.north, cameraPosition.latitude));
382
+ }
383
+ else {
384
+ viewRect.east = cameraPosition.longitude;
385
+ viewRect.west = cameraPosition.longitude;
386
+ viewRect.south = cameraPosition.latitude;
387
+ viewRect.north = cameraPosition.latitude;
388
+ }
389
+ center = {};
390
+ center.latitude = Math$1.toDegrees(camera.positionCartographic.latitude);
391
+ center.longitude = Math$1.toDegrees(camera.positionCartographic.longitude);
392
+ }
393
+ else {
394
+ windowPosition = new Cartesian2(this.viewer.container.clientWidth / 2, this.viewer.container.clientHeight / 2);
395
+ intersection = getGroundCenterOfCameraRay(this.viewer, windowPosition);
396
+ point = null;
397
+ if (intersection) {
398
+ point = Cartographic.fromCartesian(intersection, this.viewer.scene.globe.ellipsoid);
399
+ }
400
+ if (point) {
401
+ center = {};
402
+ center.latitude = Math$1.toDegrees(point.latitude);
403
+ center.longitude = Math$1.toDegrees(point.longitude);
404
+ viewRectRad = netScanViewForBoundaries(this.viewer, center);
405
+ if (viewRectRad) {
406
+ viewRect = {};
407
+ viewRect.east = Math$1.toDegrees(viewRectRad.east);
408
+ viewRect.west = Math$1.toDegrees(viewRectRad.west);
409
+ viewRect.south = Math$1.toDegrees(viewRectRad.south);
410
+ viewRect.north = Math$1.toDegrees(viewRectRad.north);
411
+ }
412
+ }
413
+ }
414
+ // Minimal field of view.
415
+ if (viewRect) {
416
+ centerLong = (viewRect.east + viewRect.west) / 2;
417
+ centerLat = (viewRect.north + viewRect.south) / 2;
418
+ viewRect.east = Math.max(viewRect.east, centerLong + (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
419
+ viewRect.west = Math.min(viewRect.west, centerLong - (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
420
+ viewRect.south = Math.min(viewRect.south, centerLat - (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
421
+ viewRect.north = Math.max(viewRect.north, centerLat + (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
422
+ viewRect.alt = (_a = this.viewer.scene.camera.positionCartographic) === null || _a === void 0 ? void 0 : _a.height;
423
+ }
424
+ if (center && viewRect) {
425
+ if ((!this.target || (this.target && !arePosEqual(this.target, center))) ||
426
+ (!this.bounds || (this.bounds && !areBoundsEqual(this.bounds, viewRect)))) {
427
+ this.target = center;
428
+ this.bounds = viewRect;
429
+ return [2 /*return*/, ESearchStatus.LocationChanged];
430
+ }
431
+ return [2 /*return*/, ESearchStatus.LocationFound];
432
+ }
433
+ return [2 /*return*/, ESearchStatus.LocationMissing];
398
434
  }
399
- if (!pickOnly && !defined(pos3d)) {
400
- pos3d = scene.globe.pick(ray, scene);
435
+ });
436
+ });
437
+ };
438
+ Monitor.prototype.tryEmitUpdate = function () {
439
+ var _a;
440
+ return __awaiter(this, void 0, void 0, function () {
441
+ var searchResult, interest, e_1;
442
+ return __generator(this, function (_b) {
443
+ switch (_b.label) {
444
+ case 0:
445
+ if (this.updating) {
446
+ return [2 /*return*/];
447
+ }
448
+ this.updating = true;
449
+ _b.label = 1;
450
+ case 1:
451
+ _b.trys.push([1, 3, , 4]);
452
+ return [4 /*yield*/, this.tryDoUpdate()];
453
+ case 2:
454
+ searchResult = _b.sent();
455
+ if (searchResult == ESearchStatus.LocationChanged) {
456
+ interest = {
457
+ bounds: this.bounds,
458
+ target: this.target
459
+ };
460
+ // this.createEntity();
461
+ (_a = this.updatedEvent) === null || _a === void 0 ? void 0 : _a.Trigger(interest);
462
+ }
463
+ else if (searchResult == ESearchStatus.LocationMissing) {
464
+ this.updateQueue();
465
+ }
466
+ return [3 /*break*/, 4];
467
+ case 3:
468
+ e_1 = _b.sent();
469
+ console.error(e_1);
470
+ this.updateQueue();
471
+ return [3 /*break*/, 4];
472
+ case 4:
473
+ this.updating = false;
474
+ return [2 /*return*/];
401
475
  }
402
- }
476
+ });
477
+ });
478
+ };
479
+ Monitor.prototype.queuePosition = function (lag) {
480
+ var _this = this;
481
+ if (this.pendingTimeout) {
482
+ clearTimeout(this.pendingTimeout);
403
483
  }
404
- // Update cache.
405
- cachedPick = {
406
- position: pos3d,
407
- cursor: cursor.clone()
408
- };
409
- cacheTimestamp = Date.now();
410
- cachedCameraState = {
411
- position: camera.positionWC.clone(),
412
- direction: camera.directionWC.clone()
413
- };
414
- return pos3d;
484
+ this.pendingTimeout = setTimeout(function () {
485
+ if (!_this.disposed) {
486
+ _this.tryEmitUpdate();
487
+ }
488
+ }, lag);
415
489
  };
416
- })();
490
+ Monitor.prototype.updateQueue = function () {
491
+ this.queuePosition(TIME_LAG);
492
+ };
493
+ return Monitor;
494
+ }());
495
+ CesiumViewMonitor$$1.Monitor = Monitor;
496
+ })(CesiumViewMonitor || (CesiumViewMonitor = {}));
497
+
498
+ /**
499
+ * Ensures a number is returned from a given value.
500
+ * If given value cannot be parsed it will return defaultNum.
501
+ * @param value
502
+ * @param defaultNum default is 0.
503
+ * @returns
504
+ */
505
+ function EnsureNumber(value, defaultNum) {
506
+ if (!defaultNum) {
507
+ defaultNum = 0;
508
+ }
509
+ value = Number(value);
510
+ if (isNaN(value)) {
511
+ return defaultNum;
512
+ }
513
+ return value;
514
+ }
515
+
516
+ var MeasureUtils;
517
+ (function (MeasureUtils) {
417
518
  /**
418
- * Smooths a given set of points.
419
- * @param points
420
- * @param multiplier
421
- * @param closed: true if this is a closed shape. Eg: polygon.
519
+ * Returns the total distance in meters between an array of points.
520
+ * This distance is NOT following the terrain.
521
+ * @param posses
422
522
  * @returns
423
523
  */
424
- function SmoothPoints(points, multiplier, closed) {
425
- if (points.length < 4 || multiplier < 2) {
426
- return points;
427
- }
428
- if (!closed) {
429
- points.unshift(C3.subtract(points[0], points[1], new C3));
430
- points.push(C3.subtract(points[points.length - 1], points[points.length - 2], new C3));
431
- }
432
- else {
433
- points.unshift(points[points.length - 1]);
434
- points.unshift(points[points.length - 2]);
435
- points.push(points[2]);
524
+ function MeasurePolyline(params) {
525
+ var posses = params.posses;
526
+ if (posses.length < 2) {
527
+ return {
528
+ totalLength: 0
529
+ };
436
530
  }
437
- var splinePoints = [];
438
- var _loop_1 = function (i) {
439
- var _a = [0, 1, 2, 3].map(function (n) { return points[i + n]; }), P0 = _a[0], P1 = _a[1], P2 = _a[2], P3 = _a[3];
440
- for (var j = 0; j <= multiplier; j++) {
441
- splinePoints.push(catmullRom(P0, P1, P2, P3, j / multiplier));
531
+ var totalLength = 0;
532
+ var pos1 = null;
533
+ var pos2 = null;
534
+ for (var i = 0; i < posses.length; i++) {
535
+ if (pos1 == null) {
536
+ pos1 = posses[i];
537
+ }
538
+ else if (pos2 == null) {
539
+ pos2 = posses[i];
540
+ totalLength += Cartesian3.distance(pos1, pos2);
541
+ pos1 = pos2;
542
+ pos2 = null;
442
543
  }
443
- };
444
- for (var i = 0; i < points.length - 3; i++) {
445
- _loop_1(i);
446
544
  }
447
- return splinePoints;
545
+ return {
546
+ totalLength: totalLength
547
+ };
448
548
  }
449
- DrawingUtils.SmoothPoints = SmoothPoints;
549
+ MeasureUtils.MeasurePolyline = MeasurePolyline;
550
+ function MeasurePolygon(params) {
551
+ var posses = params.posses;
552
+ posses = [].concat(posses);
553
+ if (!Cartes.IsRing3Closed(posses)) {
554
+ posses.push(posses[0].clone());
555
+ }
556
+ if (posses.length < 3) {
557
+ return {
558
+ area: 0,
559
+ perimeter: 0
560
+ };
561
+ }
562
+ var area = 0;
563
+ var indices = PolygonPipeline.triangulate(posses, []);
564
+ for (var i = 0; i < indices.length; i += 3) {
565
+ var vector1 = posses[indices[i]];
566
+ var vector2 = posses[indices[i + 1]];
567
+ var vector3 = posses[indices[i + 2]];
568
+ var vectorC = Cartesian3.subtract(vector2, vector1, new Cartesian3());
569
+ var vectorD = Cartesian3.subtract(vector3, vector1, new Cartesian3());
570
+ var areaVector = Cartesian3.cross(vectorC, vectorD, new Cartesian3());
571
+ area += Cartesian3.magnitude(areaVector) / 2.0;
572
+ }
573
+ var perimeter = MeasurePolyline({
574
+ posses: posses
575
+ }).totalLength;
576
+ return {
577
+ area: area,
578
+ perimeter: perimeter
579
+ };
580
+ }
581
+ MeasureUtils.MeasurePolygon = MeasurePolygon;
582
+ })(MeasureUtils || (MeasureUtils = {}));
583
+
584
+ var C3 = [Cartesian3][0];
585
+ function getT(t, alpha, p0, p1) {
586
+ var d = C3.subtract(p1, p0, new C3);
587
+ var a = C3.dot(d, d);
588
+ var b = Math.pow(a, alpha * 0.5);
589
+ return b + t;
590
+ }
591
+ function catmullRom(p0, p1, p2, p3, t) {
592
+ var t0 = 0;
593
+ var t1 = getT(t0, 0.5, p0, p1);
594
+ var t2 = getT(t1, 0.5, p1, p2);
595
+ var t3 = getT(t2, 0.5, p2, p3);
596
+ t = Math$1.lerp(t1, t2, t);
597
+ var _a = [function (l, r) { return C3.add(l, r, new C3); }, function (l, r) { return C3.multiplyByScalar(l, r, new C3); }], add = _a[0], mul = _a[1];
598
+ var A1 = add(mul(p0, (t1 - t) / (t1 - t0)), mul(p1, (t - t0) / (t1 - t0)));
599
+ var A2 = add(mul(p1, (t2 - t) / (t2 - t1)), mul(p2, (t - t1) / (t2 - t1)));
600
+ var A3 = add(mul(p2, (t3 - t) / (t3 - t2)), mul(p3, (t - t2) / (t3 - t2)));
601
+ var B1 = add(mul(A1, (t2 - t) / (t2 - t0)), mul(A2, (t - t0) / (t2 - t0)));
602
+ var B2 = add(mul(A2, (t3 - t) / (t3 - t1)), mul(A3, (t - t1) / (t3 - t1)));
603
+ var C = add(mul(B1, (t2 - t) / (t2 - t1)), mul(B2, (t - t1) / (t2 - t1)));
604
+ return C;
605
+ }
606
+ var DrawingUtils;
607
+ (function (DrawingUtils) {
450
608
  /**
609
+ * Returns the point across a polyline at a given distance.
610
+ * If the distance exceeds the length of the line, the point will be placed at the end of the line.
611
+ * @param viewer
612
+ * @param positions
613
+ * @param distance
614
+ * @returns
615
+ */
616
+ function PointAcrossPolyline(params) {
617
+ var viewer = params.viewer, positions = params.posses, distance = params.distance;
618
+ if (distance <= 0 && positions.length > 0) {
619
+ return {
620
+ point: positions[0]
621
+ };
622
+ }
623
+ else if (positions.length > 1) {
624
+ var currentDistance = 0;
625
+ var totalLength = MeasureUtils.MeasurePolyline({
626
+ posses: positions,
627
+ }).totalLength;
628
+ if (distance > totalLength) {
629
+ return {
630
+ point: positions[positions.length - 1]
631
+ };
632
+ }
633
+ for (var i = 0; i < positions.length - 1; i++) {
634
+ var length_1 = Cartesian3.distance(positions[i], positions[i + 1]);
635
+ if (length_1 + currentDistance >= distance) {
636
+ var carto1 = Cartographic.fromCartesian(positions[i]);
637
+ var carto2 = Cartographic.fromCartesian(positions[i + 1]);
638
+ var geodesic = new EllipsoidGeodesic(carto1, carto2, viewer.scene.globe.ellipsoid);
639
+ //const position = geodesic.interpolateUsingSurfaceDistance(distance - currentDistance);
640
+ var position = geodesic.interpolateUsingFraction((distance - currentDistance) / length_1);
641
+ var height = (carto1.height + carto2.height) / 2;
642
+ return {
643
+ point: Cartesian3.fromRadians(position.longitude, position.latitude, height)
644
+ };
645
+ }
646
+ else {
647
+ currentDistance += length_1;
648
+ }
649
+ }
650
+ }
651
+ return {
652
+ point: positions.length ? positions[positions.length - 1] : null
653
+ };
654
+ }
655
+ DrawingUtils.PointAcrossPolyline = PointAcrossPolyline;
656
+ /**
657
+ * Returns terrain height from current viewer's provider.
658
+ * On error or flat terrain, it will return 0.
659
+ * If an error occurred it will be attached to the result.
451
660
  * @param pos3d
452
- * @param minimumHeight height relative to ground
661
+ * @param viewer
662
+ * @returns
453
663
  */
454
- function RaisePos3d(viewer, pos3d, minimumHeight) {
455
- if (minimumHeight === void 0) { minimumHeight = 0; }
664
+ function GetTerrainHeight(params) {
456
665
  return __awaiter(this, void 0, void 0, function () {
457
- var carto, terrainCarto, sample, terrainHeight;
666
+ var pos3d, viewer, sample, height, e_1;
458
667
  return __generator(this, function (_a) {
459
668
  switch (_a.label) {
460
669
  case 0:
670
+ pos3d = params.pos3d, viewer = params.viewer;
671
+ _a.label = 1;
672
+ case 1:
673
+ _a.trys.push([1, 3, , 4]);
461
674
  // If the terrain provider is not ready let's not ping it.
462
675
  if (!viewer.terrainProvider || viewer.terrainProvider["ready"] == false) {
463
- return [2 /*return*/, pos3d];
676
+ return [2 /*return*/, {
677
+ height: 0,
678
+ error: "Terrain provider not ready."
679
+ }];
464
680
  }
465
- carto = Cartographic.fromCartesian(pos3d);
466
- terrainCarto = carto.clone();
467
- terrainCarto.height = 0;
468
- if (!(viewer.scene.terrainProvider instanceof EllipsoidTerrainProvider)) return [3 /*break*/, 1];
469
- carto.height = Math.max(carto.height, minimumHeight);
470
- return [3 /*break*/, 3];
471
- case 1: return [4 /*yield*/, sampleTerrainMostDetailed(viewer.scene.terrainProvider, [terrainCarto])];
681
+ if (viewer.scene.terrainProvider instanceof EllipsoidTerrainProvider) {
682
+ return [2 /*return*/, {
683
+ height: 0
684
+ }];
685
+ }
686
+ return [4 /*yield*/, sampleTerrainMostDetailed(viewer.scene.terrainProvider, [Cartographic.fromCartesian(pos3d)])];
472
687
  case 2:
473
688
  sample = _a.sent();
474
- terrainHeight = (sample === null || sample === void 0 ? void 0 : sample.length) ? sample[0].height : null;
475
- if (terrainHeight != null) {
476
- carto.height = Math.max(carto.height, terrainHeight + minimumHeight);
689
+ height = (sample === null || sample === void 0 ? void 0 : sample.length) ? sample[0].height : null;
690
+ if (isNaN(height)) {
691
+ return [2 /*return*/, {
692
+ height: 0,
693
+ error: "NaN"
694
+ }];
477
695
  }
478
- _a.label = 3;
479
- case 3: return [2 /*return*/, Cartesian3.fromRadians(carto.longitude, carto.latitude, carto.height)];
696
+ return [2 /*return*/, {
697
+ height: height
698
+ }];
699
+ case 3:
700
+ e_1 = _a.sent();
701
+ return [2 /*return*/, {
702
+ height: 0,
703
+ error: e_1
704
+ }];
705
+ case 4: return [2 /*return*/];
480
706
  }
481
707
  });
482
708
  });
483
709
  }
484
- DrawingUtils.RaisePos3d = RaisePos3d;
485
- })(DrawingUtils || (DrawingUtils = {}));
486
-
487
- /**
488
- * Returns if a given visual can be styled by this utility.
489
- * @param viewer
490
- * @param visual
491
- * @returns
492
- */
493
- function isAlive(viewer, visual) {
494
- if (!(viewer === null || viewer === void 0 ? void 0 : viewer.scene) || viewer.isDestroyed()) {
495
- return false;
496
- }
497
- if (visual instanceof Entity) {
498
- return true;
499
- }
500
- else if (visual instanceof Primitive) {
501
- return true;
502
- }
503
- else if (visual instanceof Cesium3DTileFeature) {
504
- var cTileset = visual === null || visual === void 0 ? void 0 : visual.tileset;
505
- if (!cTileset) {
506
- return false;
710
+ DrawingUtils.GetTerrainHeight = GetTerrainHeight;
711
+ function EnsurePosHeight(params) {
712
+ var pos3d = params.pos3d, viewer = params.viewer, desiredHeightRef = params.desiredHeightRef, heightRef = params.heightRef;
713
+ var carto = Cartes.ValidateCartes3(pos3d) ? Cartographic.fromCartesian(pos3d) : null;
714
+ if (!(carto === null || carto === void 0 ? void 0 : carto.latitude)) {
715
+ return pos3d;
507
716
  }
508
- if (cTileset.isDestroyed() || !viewer.scene.primitives.contains(cTileset)) {
509
- return false;
717
+ if (heightRef == null) {
718
+ heightRef = HeightReference.CLAMP_TO_GROUND;
510
719
  }
511
- return true;
720
+ if (desiredHeightRef == null) {
721
+ desiredHeightRef = HeightReference.CLAMP_TO_GROUND;
722
+ }
723
+ if (heightRef == desiredHeightRef) {
724
+ return pos3d;
725
+ }
726
+ if (heightRef == HeightReference.NONE) {
727
+ // Turn absolute into clamped.
728
+ if (desiredHeightRef == HeightReference.CLAMP_TO_GROUND) {
729
+ return Cartesian3.fromRadians(carto.longitude, carto.latitude, 0);
730
+ }
731
+ // Turn absolute into relative (remove terrain height).
732
+ else if (desiredHeightRef == HeightReference.RELATIVE_TO_GROUND) {
733
+ var terrainHeight = EnsureNumber(viewer.scene.globe.getHeight(carto), 0);
734
+ return Cartesian3.fromRadians(carto.longitude, carto.latitude, carto.height - terrainHeight);
735
+ }
736
+ }
737
+ else if (heightRef == HeightReference.CLAMP_TO_GROUND) {
738
+ var terrainHeight = EnsureNumber(viewer.scene.globe.getHeight(carto), 0);
739
+ return Cartesian3.fromRadians(carto.longitude, carto.latitude, terrainHeight);
740
+ }
741
+ else if (heightRef == HeightReference.RELATIVE_TO_GROUND) {
742
+ // Turn relative into absolute (add terrain height).
743
+ if (desiredHeightRef == HeightReference.NONE) {
744
+ var terrainHeight = EnsureNumber(viewer.scene.globe.getHeight(carto), 0);
745
+ return Cartesian3.fromRadians(carto.longitude, carto.latitude, carto.height + terrainHeight);
746
+ }
747
+ // Turn relative into clamped.
748
+ else if (desiredHeightRef == HeightReference.CLAMP_TO_GROUND) {
749
+ return Cartesian3.fromRadians(carto.longitude, carto.latitude, 0);
750
+ }
751
+ }
752
+ return pos3d;
512
753
  }
513
- return false;
514
- }
515
- var _selectColor = Color.fromAlpha(Color.YELLOW, 0.5);
516
- var _highlightColor = Color.fromCssColorString("#33b1ff").withAlpha(0.5);
517
- var STORE_COLOR_PREFIX = "_storeColor_";
518
- function getStoreKey(key) {
519
- return STORE_COLOR_PREFIX + key;
520
- }
521
- var STORE_KEY_STATE_PREFIX = "_storeKeyState_";
522
- function getStoreStateKey(key) {
523
- return STORE_KEY_STATE_PREFIX + key;
524
- }
525
- var LAST_APPLIED_OPACITY_KEY = "_lastAppliedOpacityKey";
526
- /**
527
- * Returns a color property from a graphic.
528
- * This will turn materials properties into colors before returning them.
529
- * @param viewer
530
- * @param prop
531
- * @returns
532
- */
533
- function getCesiumColorValue(viewer, prop) {
534
- if (!prop) {
535
- return Color.WHITE;
754
+ DrawingUtils.EnsurePosHeight = EnsurePosHeight;
755
+ /**
756
+ * Returns an accurate 3d position from a given screen position.
757
+ * @param viewer
758
+ * @param cursor
759
+ * @returns
760
+ */
761
+ DrawingUtils.GetAccuratePosition = (function () {
762
+ var cachedPick = null;
763
+ var cacheTimestamp = null;
764
+ var cachedCameraState = null;
765
+ return function (viewer, cursor, pickOnly) {
766
+ if (pickOnly === void 0) { pickOnly = false; }
767
+ var scene = viewer.scene;
768
+ var camera = scene.camera;
769
+ // Check if we can use cached position.
770
+ if (cachedPick && cacheTimestamp) {
771
+ var timeElapsed = Date.now() - cacheTimestamp;
772
+ var isWithinCacheDuration = timeElapsed < 3000; // 3 seconds
773
+ var isNearPreviousPick = Cartesian2.distanceSquared(cursor, cachedPick.cursor) < 9; // 3 pixels
774
+ var directionDot = Cartesian3.dot(camera.directionWC, cachedCameraState.direction);
775
+ var directionLengths = Cartesian3.magnitude(camera.directionWC) * Cartesian3.magnitude(cachedCameraState.direction);
776
+ var angle = Math.acos(directionDot / directionLengths);
777
+ var hasCameraMoved = Math.abs(camera.positionWC.x - cachedCameraState.position.x) > 2 || // 2 meters
778
+ Math.abs(camera.positionWC.y - cachedCameraState.position.y) > 2 ||
779
+ angle > Math$1.toRadians(5); // 5 degrees
780
+ if (isWithinCacheDuration && isNearPreviousPick && !hasCameraMoved) {
781
+ return cachedPick.position;
782
+ }
783
+ }
784
+ // Actual picking logic
785
+ // https://community.cesium.com/t/scene-pick-returning-point-inside-the-globe/18940/9
786
+ var pos3d = null;
787
+ // Means we can accurately pick right now.
788
+ if (!pickOnly && scene.globe.depthTestAgainstTerrain) {
789
+ pos3d = scene.pickPosition(cursor);
790
+ }
791
+ // Means we cannot guarantee an accurate pick.
792
+ // We want to prioritize pick-position when we can, so we'll try use it and if the result is sus then we'll use some fallbacks.
793
+ else {
794
+ if (!pickOnly) {
795
+ pos3d = scene.pickPosition(cursor);
796
+ }
797
+ if (defined(pos3d)) {
798
+ var carto = Cartographic.fromCartesian(pos3d);
799
+ if (!defined(carto) || carto.height < 0) {
800
+ pos3d = null;
801
+ }
802
+ }
803
+ if (!defined(pos3d)) {
804
+ pos3d = null;
805
+ var ray = scene.camera.getPickRay(cursor);
806
+ if (scene.pickPositionSupported) {
807
+ var pickedObject = scene.pick(cursor, 1, 1);
808
+ if (defined(pickedObject) &&
809
+ (pickedObject instanceof Cesium3DTileFeature ||
810
+ pickedObject.primitive instanceof Cesium3DTileset ||
811
+ pickedObject.primitive instanceof Model)) {
812
+ pos3d = scene.pickPosition(cursor);
813
+ }
814
+ }
815
+ if (!pickOnly && !defined(pos3d)) {
816
+ pos3d = scene.globe.pick(ray, scene);
817
+ }
818
+ }
819
+ }
820
+ // Update cache.
821
+ cachedPick = {
822
+ position: pos3d,
823
+ cursor: cursor.clone()
824
+ };
825
+ cacheTimestamp = Date.now();
826
+ cachedCameraState = {
827
+ position: camera.positionWC.clone(),
828
+ direction: camera.directionWC.clone()
829
+ };
830
+ return pos3d;
831
+ };
832
+ })();
833
+ /**
834
+ * Smooths a given set of points.
835
+ * @param points
836
+ * @param multiplier
837
+ * @param closed: true if this is a closed shape. Eg: polygon.
838
+ * @returns
839
+ */
840
+ function SmoothPoints(points, multiplier, closed) {
841
+ if (points.length < 4 || multiplier < 2) {
842
+ return points;
843
+ }
844
+ if (!closed) {
845
+ points.unshift(C3.subtract(points[0], points[1], new C3));
846
+ points.push(C3.subtract(points[points.length - 1], points[points.length - 2], new C3));
847
+ }
848
+ else {
849
+ points.unshift(points[points.length - 1]);
850
+ points.unshift(points[points.length - 2]);
851
+ points.push(points[2]);
852
+ }
853
+ var splinePoints = [];
854
+ var _loop_1 = function (i) {
855
+ var _a = [0, 1, 2, 3].map(function (n) { return points[i + n]; }), P0 = _a[0], P1 = _a[1], P2 = _a[2], P3 = _a[3];
856
+ for (var j = 0; j <= multiplier; j++) {
857
+ splinePoints.push(catmullRom(P0, P1, P2, P3, j / multiplier));
858
+ }
859
+ };
860
+ for (var i = 0; i < points.length - 3; i++) {
861
+ _loop_1(i);
862
+ }
863
+ return splinePoints;
864
+ }
865
+ DrawingUtils.SmoothPoints = SmoothPoints;
866
+ /**
867
+ * @param pos3d
868
+ * @param minimumHeight height relative to ground
869
+ */
870
+ function RaisePos3d(viewer, pos3d, minimumHeight) {
871
+ if (minimumHeight === void 0) { minimumHeight = 0; }
872
+ return __awaiter(this, void 0, void 0, function () {
873
+ var carto, terrainCarto, sample, terrainHeight;
874
+ return __generator(this, function (_a) {
875
+ switch (_a.label) {
876
+ case 0:
877
+ // If the terrain provider is not ready let's not ping it.
878
+ if (!viewer.terrainProvider || viewer.terrainProvider["ready"] == false) {
879
+ return [2 /*return*/, pos3d];
880
+ }
881
+ carto = Cartographic.fromCartesian(pos3d);
882
+ terrainCarto = carto.clone();
883
+ terrainCarto.height = 0;
884
+ if (!(viewer.scene.terrainProvider instanceof EllipsoidTerrainProvider)) return [3 /*break*/, 1];
885
+ carto.height = Math.max(carto.height, minimumHeight);
886
+ return [3 /*break*/, 3];
887
+ case 1: return [4 /*yield*/, sampleTerrainMostDetailed(viewer.scene.terrainProvider, [terrainCarto])];
888
+ case 2:
889
+ sample = _a.sent();
890
+ terrainHeight = (sample === null || sample === void 0 ? void 0 : sample.length) ? sample[0].height : null;
891
+ if (terrainHeight != null) {
892
+ carto.height = Math.max(carto.height, terrainHeight + minimumHeight);
893
+ }
894
+ _a.label = 3;
895
+ case 3: return [2 /*return*/, Cartesian3.fromRadians(carto.longitude, carto.latitude, carto.height)];
896
+ }
897
+ });
898
+ });
899
+ }
900
+ DrawingUtils.RaisePos3d = RaisePos3d;
901
+ })(DrawingUtils || (DrawingUtils = {}));
902
+
903
+ /**
904
+ * Returns if a given visual can be styled by this utility.
905
+ * @param viewer
906
+ * @param visual
907
+ * @returns
908
+ */
909
+ function isAlive(viewer, visual) {
910
+ if (!(viewer === null || viewer === void 0 ? void 0 : viewer.scene) || viewer.isDestroyed()) {
911
+ return false;
912
+ }
913
+ if (visual instanceof Entity) {
914
+ return true;
915
+ }
916
+ else if (visual instanceof Primitive) {
917
+ return true;
918
+ }
919
+ else if (visual instanceof Cesium3DTileFeature) {
920
+ var cTileset = visual === null || visual === void 0 ? void 0 : visual.tileset;
921
+ if (!cTileset) {
922
+ return false;
923
+ }
924
+ if (cTileset.isDestroyed() || !viewer.scene.primitives.contains(cTileset)) {
925
+ return false;
926
+ }
927
+ return true;
928
+ }
929
+ return false;
930
+ }
931
+ var _selectColor = Color.fromAlpha(Color.YELLOW, 0.5);
932
+ var _highlightColor = Color.fromCssColorString("#33b1ff").withAlpha(0.5);
933
+ var STORE_COLOR_PREFIX = "_storeColor_";
934
+ function getStoreKey(key) {
935
+ return STORE_COLOR_PREFIX + key;
936
+ }
937
+ var STORE_KEY_STATE_PREFIX = "_storeKeyState_";
938
+ function getStoreStateKey(key) {
939
+ return STORE_KEY_STATE_PREFIX + key;
940
+ }
941
+ var LAST_APPLIED_OPACITY_KEY = "_lastAppliedOpacityKey";
942
+ /**
943
+ * Returns a color property from a graphic.
944
+ * This will turn materials properties into colors before returning them.
945
+ * @param viewer
946
+ * @param prop
947
+ * @returns
948
+ */
949
+ function getCesiumColorValue(viewer, prop) {
950
+ if (!prop) {
951
+ return Color.WHITE;
536
952
  }
537
953
  if (prop.getValue) {
538
954
  prop = prop.getValue(viewer.scene.lastRenderTime);
@@ -3789,14 +4205,14 @@ var createImageBillboard = function (url) {
3789
4205
  };
3790
4206
  res(data);
3791
4207
  };
3792
- image_1.onerror = function () {
3793
- rej(null);
4208
+ image_1.onerror = function (e) {
4209
+ rej(e);
3794
4210
  };
3795
4211
  image_1.src = URL.createObjectURL(blob);
3796
4212
  return [3 /*break*/, 4];
3797
4213
  case 3:
3798
4214
  e_4 = _a.sent();
3799
- rej(null);
4215
+ rej(e_4);
3800
4216
  return [3 /*break*/, 4];
3801
4217
  case 4: return [2 /*return*/];
3802
4218
  }
@@ -6450,7 +6866,7 @@ function updateCEntityShow(viewer, visual, rego, show, ignoreParent, depth) {
6450
6866
  }
6451
6867
  // A sub-object can be culled while the siblings are not.
6452
6868
  // We only cull things that give us some benefit. For example clamped to ground graphics are expensive to keep rendered.
6453
- show = show ? !VisualRegisterCuller.IsCulled(viewer, rego, visual) : true;
6869
+ show = show ? !VisualRegisterCuller.IsCulled(viewer, rego, visual) : false;
6454
6870
  if (visual._parentEntity && !ignoreParent) {
6455
6871
  updateCEntityShow(viewer, visual._parentEntity, rego, show, false, depth + 1);
6456
6872
  }
@@ -8006,7 +8422,7 @@ var PointClustering = /** @class */ (function () {
8006
8422
  entityId: id,
8007
8423
  menuItemId: this.menuItemId
8008
8424
  });
8009
- if (rego && rego.overrideShow) {
8425
+ if (rego && rego.overrideShow != null) {
8010
8426
  rego.overrideShow = null;
8011
8427
  entitiesToUpdate.push(id);
8012
8428
  }
@@ -8085,8 +8501,8 @@ var PointClustering = /** @class */ (function () {
8085
8501
  entityId: entityId,
8086
8502
  menuItemId: this_1.menuItemId
8087
8503
  });
8088
- if (rego && !rego.overrideShow) {
8089
- rego.overrideShow = true;
8504
+ if (rego && rego.overrideShow != false) {
8505
+ rego.overrideShow = false;
8090
8506
  entitiesToUpdate.push(entityId);
8091
8507
  }
8092
8508
  }
@@ -9061,7 +9477,7 @@ var EntitiesRenderManager;
9061
9477
  entityTypeId: entity.Bruce["EntityType.ID"],
9062
9478
  accountId: this.apiGetter.accountId,
9063
9479
  tagIds: tagIds ? [].concat(tagIds) : [],
9064
- overrideShow: wasClustered ? true : null,
9480
+ overrideShow: wasClustered ? false : null,
9065
9481
  name: cEntity.name,
9066
9482
  cdn: this.item.cdnEnabled
9067
9483
  };
@@ -10474,7 +10890,7 @@ var EntitiesIdsRenderManager;
10474
10890
  priority: 0,
10475
10891
  entityTypeId: entity.Bruce["EntityType.ID"],
10476
10892
  accountId: this.apiGetter.accountId,
10477
- overrideShow: clustered ? true : null,
10893
+ overrideShow: clustered ? false : null,
10478
10894
  name: cEntity.name
10479
10895
  },
10480
10896
  requestRender: false
@@ -13433,7 +13849,7 @@ var DataSourceStaticKmlManager;
13433
13849
  configurable: true
13434
13850
  });
13435
13851
  Manager.prototype.Init = function () {
13436
- var _a;
13852
+ var _this = this;
13437
13853
  var files = this.item.KML;
13438
13854
  if (!files) {
13439
13855
  return;
@@ -13441,31 +13857,47 @@ var DataSourceStaticKmlManager;
13441
13857
  if (!Array.isArray(files)) {
13442
13858
  files = [files];
13443
13859
  }
13444
- for (var i = 0; i < files.length; i++) {
13445
- var file = files[i];
13446
- var fileId = (_a = file === null || file === void 0 ? void 0 : file.ClientFile) === null || _a === void 0 ? void 0 : _a.ID;
13447
- var externalURL = file === null || file === void 0 ? void 0 : file.fileUrl;
13448
- if (!fileId && !externalURL) {
13449
- continue;
13450
- }
13451
- var api = this.apiGetter.getApi();
13452
- var fileUrl = void 0;
13453
- if (fileId) {
13454
- fileUrl = ClientFile.GetUrl({
13455
- api: api,
13456
- fileId: fileId,
13457
- viaCdn: true
13458
- });
13459
- }
13460
- else if (externalURL) {
13461
- fileUrl = externalURL;
13462
- }
13463
- var source = new KmlDataSource();
13464
- source.load(fileUrl);
13465
- this.viewer.dataSources.add(source);
13466
- this.dataSources.push(source);
13467
- this.viewer.scene.requestRender();
13468
- }
13860
+ (function () { return __awaiter(_this, void 0, void 0, function () {
13861
+ var api, i, file, fileId, externalURL, fileUrl, source;
13862
+ var _a;
13863
+ return __generator(this, function (_b) {
13864
+ switch (_b.label) {
13865
+ case 0:
13866
+ api = this.apiGetter.getApi();
13867
+ return [4 /*yield*/, api.Loading];
13868
+ case 1:
13869
+ _b.sent();
13870
+ if (this.disposed) {
13871
+ return [2 /*return*/];
13872
+ }
13873
+ for (i = 0; i < files.length; i++) {
13874
+ file = files[i];
13875
+ fileId = (_a = file === null || file === void 0 ? void 0 : file.ClientFile) === null || _a === void 0 ? void 0 : _a.ID;
13876
+ externalURL = file === null || file === void 0 ? void 0 : file.fileUrl;
13877
+ if (!fileId && !externalURL) {
13878
+ continue;
13879
+ }
13880
+ fileUrl = void 0;
13881
+ if (fileId) {
13882
+ fileUrl = ClientFile.GetUrl({
13883
+ api: api,
13884
+ fileId: fileId,
13885
+ viaCdn: true
13886
+ });
13887
+ }
13888
+ else if (externalURL) {
13889
+ fileUrl = externalURL;
13890
+ }
13891
+ source = new KmlDataSource();
13892
+ source.load(fileUrl);
13893
+ this.viewer.dataSources.add(source);
13894
+ this.dataSources.push(source);
13895
+ this.viewer.scene.requestRender();
13896
+ }
13897
+ return [2 /*return*/];
13898
+ }
13899
+ });
13900
+ }); })();
13469
13901
  };
13470
13902
  Manager.prototype.Dispose = function () {
13471
13903
  var _a;
@@ -20975,633 +21407,217 @@ function renderNavigator(iteration, params, bookmark, view, getters) {
20975
21407
  for (i = 0; i < imagery.length; i++) {
20976
21408
  layer = imagery[i];
20977
21409
  if (layer.tilesetId == ProjectViewTile.EDefaultImagery.BingMapsAerial) {
20978
- layer.tilesetId = ProjectViewTile.EDefaultImagery.MapboxSatellite;
20979
- console.warn("Cesium Ion token not set, using mapbox satellite instead of bing maps aerial.");
20980
- }
20981
- else if (layer.tilesetId == ProjectViewTile.EDefaultImagery.BingMapsAerialWithLabels) {
20982
- layer.tilesetId = ProjectViewTile.EDefaultImagery.MapboxSatellite;
20983
- console.warn("Cesium Ion token not set, using mapbox satellite instead of bing maps aerial with labels.");
20984
- }
20985
- else if (layer.tilesetId == ProjectViewTile.EDefaultImagery.BingMapsRoads) {
20986
- layer.tilesetId = ProjectViewTile.EDefaultImagery.MapBoxStreets;
20987
- console.warn("Cesium Ion token not set, using mapbox streets instead of bing maps roads.");
20988
- }
20989
- }
20990
- }
20991
- }
20992
- // We don't wait for imageries to load, this does not affect rendering other things.
20993
- TileRenderEngine.Map.Navigator.Render({
20994
- apiGetter: params.apiGetter,
20995
- tiles: imagery,
20996
- viewer: params.manager.Viewer,
20997
- });
20998
- legacyRelationIds = bSettings === null || bSettings === void 0 ? void 0 : bSettings.renderedEntityRelations;
20999
- if (!legacyRelationIds) {
21000
- legacyRelationIds = [];
21001
- }
21002
- relations = bSettings === null || bSettings === void 0 ? void 0 : bSettings.renderedRelations;
21003
- if (!relations) {
21004
- relations = [];
21005
- }
21006
- viewer.scene.requestRender();
21007
- curEnabled = params.manager.GetEnabledItemIds();
21008
- newItemIds = (_5 = bSettings === null || bSettings === void 0 ? void 0 : bSettings.menuItemIds) !== null && _5 !== void 0 ? _5 : [];
21009
- for (_i = 0, curEnabled_1 = curEnabled; _i < curEnabled_1.length; _i++) {
21010
- id = curEnabled_1[_i];
21011
- shouldRemove = void 0;
21012
- if (id == RELATION_MENU_ITEM_ID) {
21013
- rendered = params.manager.GetEnabledItem(id);
21014
- shouldRemove = false;
21015
- if (!legacyRelationIds.length && !relations.length) {
21016
- shouldRemove = true;
21017
- }
21018
- // If we're about to render legacy relationships but a non-legacy item is currently enabled then we remove it.
21019
- else if (legacyRelationIds.length && (rendered === null || rendered === void 0 ? void 0 : rendered.type) != MenuItem.EType.Relations) {
21020
- shouldRemove = true;
21021
- }
21022
- // If we're about to render non-legacy relationships but a legacy item is currently enabled then we remove it.
21023
- else if (relations.length && (rendered === null || rendered === void 0 ? void 0 : rendered.type) != MenuItem.EType.Relationships) {
21024
- shouldRemove = true;
21025
- }
21026
- }
21027
- else {
21028
- shouldRemove = newItemIds.indexOf(id) === -1;
21029
- }
21030
- if (shouldRemove) {
21031
- params.manager.RemoveItemById({
21032
- menuItemId: id
21033
- });
21034
- }
21035
- }
21036
- if (!bookmark) return [3 /*break*/, 15];
21037
- return [4 /*yield*/, MenuItemCreator.RenderBookmarkItems({
21038
- getters: params.getters,
21039
- manager: params.manager,
21040
- view: view,
21041
- bookmark: bookmark
21042
- })];
21043
- case 14:
21044
- _8.sent();
21045
- if (!assertIteration$1(params.viewer, iteration)) {
21046
- return [2 /*return*/];
21047
- }
21048
- _8.label = 15;
21049
- case 15:
21050
- if (legacyRelationIds.length || relations.length) {
21051
- if (relations.length) {
21052
- menuItem = {
21053
- id: RELATION_MENU_ITEM_ID,
21054
- Caption: "Entity relations",
21055
- relations: relations,
21056
- Type: MenuItem.EType.Relationships
21057
- };
21058
- params.manager.RenderItem({
21059
- getters: params.getters,
21060
- item: menuItem
21061
- });
21062
- }
21063
- else if (legacyRelationIds.length) {
21064
- menuItem = {
21065
- id: RELATION_MENU_ITEM_ID,
21066
- Caption: "Entity relations",
21067
- BruceEntity: {
21068
- EntityIds: legacyRelationIds
21069
- },
21070
- Type: MenuItem.EType.Relations
21071
- };
21072
- params.manager.RenderItem({
21073
- getters: params.getters,
21074
- item: menuItem
21075
- });
21076
- }
21077
- if (!assertIteration$1(params.viewer, iteration)) {
21078
- return [2 /*return*/];
21079
- }
21080
- }
21081
- gOcclusion = bSettings === null || bSettings === void 0 ? void 0 : bSettings.groundOcclusion;
21082
- if (gOcclusion == null) {
21083
- gOcclusion = (_6 = defaults === null || defaults === void 0 ? void 0 : defaults.settings) === null || _6 === void 0 ? void 0 : _6.groundOcclusion;
21084
- }
21085
- if (gOcclusion == null) {
21086
- // TODO: Need global default.
21087
- gOcclusion = true;
21088
- }
21089
- scene.globe.depthTestAgainstTerrain = Boolean(gOcclusion);
21090
- return [2 /*return*/];
21091
- }
21092
- });
21093
- });
21094
- }
21095
- var ViewRenderEngine;
21096
- (function (ViewRenderEngine) {
21097
- function Render(params) {
21098
- var _a;
21099
- return __awaiter(this, void 0, void 0, function () {
21100
- var iteration, api, view, _b, bookmark, bookmarkId, _c, version, bWidget;
21101
- return __generator(this, function (_d) {
21102
- switch (_d.label) {
21103
- case 0:
21104
- if (!params.manager && params.viewer) {
21105
- params.manager = ViewerUtils.GetManager({
21106
- viewer: params.viewer,
21107
- createIfMissing: true
21108
- });
21109
- }
21110
- else if (!params.viewer && params.manager) {
21111
- params.viewer = params.manager.Viewer;
21112
- }
21113
- iteration = newIteration$1(params.viewer);
21114
- if (!params.getters) {
21115
- params.getters = ENVIRONMENT.Api();
21116
- }
21117
- if (params.apiGetter && !params.getters) {
21118
- console.warn("ViewRenderEngine.Render(): Please pass getters instead of apiGetter. This is now deprecated due to needing access to other kinds of apis.");
21119
- }
21120
- else if (!params.apiGetter) {
21121
- params.apiGetter = params.getters.GetBruceGetter();
21122
- }
21123
- api = params.getters.GetBruceApi();
21124
- if (!params.view) return [3 /*break*/, 1];
21125
- _b = params.view;
21126
- return [3 /*break*/, 3];
21127
- case 1: return [4 /*yield*/, ProjectView.Get({
21128
- api: api,
21129
- viewId: params.viewId
21130
- })];
21131
- case 2:
21132
- _b = (_d.sent()).view;
21133
- _d.label = 3;
21134
- case 3:
21135
- view = _b;
21136
- bookmark = params.bookmark;
21137
- if (!!bookmark) return [3 /*break*/, 7];
21138
- bookmarkId = params.bookmarkId;
21139
- if (!bookmarkId) {
21140
- bookmarkId = view.DefaultUISlideID;
21141
- }
21142
- if (!bookmarkId) return [3 /*break*/, 5];
21143
- return [4 /*yield*/, ProjectViewBookmark.Get({
21144
- api: api,
21145
- viewId: params.viewId,
21146
- bookmarkId: bookmarkId
21147
- })];
21148
- case 4:
21149
- _c = (_d.sent()).bookmark;
21150
- return [3 /*break*/, 6];
21151
- case 5:
21152
- _c = null;
21153
- _d.label = 6;
21154
- case 6:
21155
- bookmark = _c;
21156
- _d.label = 7;
21157
- case 7:
21158
- if (!assertIteration$1(params.viewer, iteration)) {
21159
- return [2 /*return*/];
21160
- }
21161
- version = view.DataVersion;
21162
- if (!(version == 1)) return [3 /*break*/, 9];
21163
- return [4 /*yield*/, renderLegacyNavigator(iteration, params, bookmark, view)];
21164
- case 8:
21165
- _d.sent();
21166
- return [3 /*break*/, 11];
21167
- case 9: return [4 /*yield*/, renderNavigator(iteration, params, bookmark, view, params.getters)];
21168
- case 10:
21169
- _d.sent();
21170
- _d.label = 11;
21171
- case 11:
21172
- if (!assertIteration$1(params.viewer, iteration)) {
21173
- return [2 /*return*/];
21174
- }
21175
- bWidget = (_a = params.viewer) === null || _a === void 0 ? void 0 : _a[VIEWER_BOOKMARKS_WIDGET_KEY];
21176
- if (bWidget) {
21177
- bWidget.ViewId = params.viewId ? params.viewId : view === null || view === void 0 ? void 0 : view.ID;
21178
- bWidget.LastEnabledBookmarkId = params.bookmarkId ? params.bookmarkId : bookmark === null || bookmark === void 0 ? void 0 : bookmark.ID;
21179
- }
21180
- return [2 /*return*/];
21181
- }
21182
- });
21183
- });
21184
- }
21185
- ViewRenderEngine.Render = Render;
21186
- })(ViewRenderEngine || (ViewRenderEngine = {}));
21187
-
21188
- var TIME_LAG = 300;
21189
- var POSITION_CHECK_TIMER = 950;
21190
- var DEFAULT_GROUNDED_HEIGHT = 300;
21191
- var MINIMUM_VIEW_AREA_SIZE_DEGREES = 0.01;
21192
- var NET_STEP_PERCENT = 5;
21193
- var BORDER_STEPS = 3;
21194
- var ESearchStatus;
21195
- (function (ESearchStatus) {
21196
- ESearchStatus[ESearchStatus["LocationFound"] = 1] = "LocationFound";
21197
- ESearchStatus[ESearchStatus["LocationChanged"] = 2] = "LocationChanged";
21198
- ESearchStatus[ESearchStatus["LocationMissing"] = 3] = "LocationMissing";
21199
- })(ESearchStatus || (ESearchStatus = {}));
21200
- /**
21201
- * @param viewer
21202
- * @param center the previously calculated center of the view area. This is in degrees.
21203
- * @returns
21204
- */
21205
- function netScanViewForBoundaries(viewer, center) {
21206
- var maxLong = -2 * Math.PI;
21207
- var minLong = 2 * Math.PI;
21208
- var maxLat = -2 * Math.PI;
21209
- var minLat = 2 * Math.PI;
21210
- var found = 0;
21211
- var updateMinMax = function (lon, lat) {
21212
- // Check to see if given lon/lat (in radians) are within valid range.
21213
- if (lon < -Math.PI || lon > Math.PI || lat < -Math.PI / 2 || lat > Math.PI / 2) {
21214
- return;
21215
- }
21216
- maxLong = Math.max(maxLong, lon);
21217
- maxLat = Math.max(maxLat, lat);
21218
- minLong = Math.min(minLong, lon);
21219
- minLat = Math.min(minLat, lat);
21220
- };
21221
- var updateMinMaxForPoint = function (stepX, stepY) {
21222
- var x = Math.round(0 + (viewer.container.clientWidth / 100) * (stepX * NET_STEP_PERCENT));
21223
- var y = Math.round(0 + (viewer.container.clientHeight / 100) * (stepY * NET_STEP_PERCENT));
21224
- var winPos = new Cartesian2(x, y);
21225
- try {
21226
- var intersection = getAdjustedGroundIntersectionOfCameraRay(viewer, winPos);
21227
- if (intersection) {
21228
- var point = Cartographic.fromCartesian(intersection, viewer.scene.globe.ellipsoid);
21229
- updateMinMax(point.longitude, point.latitude);
21230
- found++;
21231
- }
21232
- }
21233
- catch (e) {
21234
- console.error(e);
21235
- }
21236
- };
21237
- // Outer circle.
21238
- updateMinMaxForPoint(BORDER_STEPS, BORDER_STEPS);
21239
- updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS, BORDER_STEPS);
21240
- updateMinMaxForPoint(BORDER_STEPS, (100 / NET_STEP_PERCENT) - BORDER_STEPS);
21241
- updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS, (100 / NET_STEP_PERCENT) - BORDER_STEPS);
21242
- // Inner circle.
21243
- updateMinMaxForPoint(BORDER_STEPS * 2, BORDER_STEPS * 2);
21244
- updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS * 2, BORDER_STEPS * 2);
21245
- updateMinMaxForPoint(BORDER_STEPS * 2, (100 / NET_STEP_PERCENT) - BORDER_STEPS * 2);
21246
- updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS * 2, (100 / NET_STEP_PERCENT) - BORDER_STEPS * 2);
21247
- // If we failed to find intersections and a center-point was provided, then we can use that to make some guesses.
21248
- // This happens if terrain is hidden, and there's nothing to intersect with.
21249
- if (center && found <= 0) {
21250
- updateMinMax(Math$1.toRadians(center.longitude), Math$1.toRadians(center.latitude));
21251
- found += 1;
21252
- // We'll use the camera height as an indicator on size of the rect.
21253
- var size = viewer.camera.positionCartographic.height;
21254
- var pitch = viewer.camera.pitch;
21255
- var distance = size / Math.tan(pitch);
21256
- var p1 = _offsetPoint({
21257
- altitude: center.altitude,
21258
- latitude: center.latitude,
21259
- longitude: center.longitude
21260
- }, distance, 45);
21261
- var p2 = _offsetPoint({
21262
- altitude: center.altitude,
21263
- latitude: center.latitude,
21264
- longitude: center.longitude
21265
- }, -distance, 45);
21266
- if (p1 === null || p1 === void 0 ? void 0 : p1.latitude) {
21267
- updateMinMax(Math$1.toRadians(p1.longitude), Math$1.toRadians(p1.latitude));
21268
- }
21269
- if (p2 === null || p2 === void 0 ? void 0 : p2.latitude) {
21270
- updateMinMax(Math$1.toRadians(p2.longitude), Math$1.toRadians(p2.latitude));
21271
- }
21272
- }
21273
- if (found > 0) {
21274
- var viewRect = {
21275
- east: maxLong,
21276
- west: minLong,
21277
- north: maxLat,
21278
- south: minLat
21279
- };
21280
- return viewRect;
21281
- }
21282
- return null;
21283
- }
21284
- /**
21285
- * Moves a given point by a given distance towards a heading.
21286
- * @param point in degrees.
21287
- * @param distance in meters.
21288
- * @param heading in degrees.
21289
- * @returns
21290
- */
21291
- function _offsetPoint(point, distance, heading) {
21292
- // Radius of earth.
21293
- var radius = 6371e3;
21294
- var δ = distance / radius;
21295
- var θ = Math$1.toRadians(heading);
21296
- var φ1 = Math$1.toRadians(point.latitude);
21297
- var λ1 = Math$1.toRadians(point.longitude);
21298
- var sinφ2 = Math.sin(φ1) * Math.cos(δ) + Math.cos(φ1) * Math.sin(δ) * Math.cos(θ);
21299
- var φ2 = Math.asin(sinφ2);
21300
- var y = Math.sin(θ) * Math.sin(δ) * Math.cos(φ1);
21301
- var x = Math.cos(δ) - Math.sin(φ1) * sinφ2;
21302
- var λ2 = λ1 + Math.atan2(y, x);
21303
- return {
21304
- altitude: point.altitude,
21305
- latitude: Math$1.toDegrees(φ2),
21306
- longitude: Math$1.toDegrees(λ2)
21307
- };
21308
- }
21309
- /**
21310
- * @param pos3d
21311
- * @param distance in meters
21312
- * @param heading in degrees
21313
- * @returns
21314
- */
21315
- function _offsetPos3d(pos3d, distance, heading) {
21316
- var carto = Cartographic.fromCartesian(pos3d);
21317
- var newCarto = _offsetPoint({
21318
- altitude: carto.height,
21319
- latitude: Math$1.toDegrees(carto.latitude),
21320
- longitude: Math$1.toDegrees(carto.longitude)
21321
- }, distance, heading);
21322
- return Cartesian3.fromDegrees(newCarto.longitude, newCarto.latitude, newCarto.altitude);
21323
- }
21324
- /**
21325
- * Returns the intersection of the camera ray with the ground.
21326
- * @param viewer
21327
- * @param screenPos
21328
- * @returns
21329
- */
21330
- function getAdjustedGroundIntersectionOfCameraRay(viewer, screenPos) {
21331
- var ray = viewer.camera.getPickRay(screenPos);
21332
- var intersection = ray ? viewer.scene.globe.pick(ray, viewer.scene) : null;
21333
- if (intersection) {
21334
- return intersection;
21335
- }
21336
- return null;
21337
- }
21338
- /**
21339
- * Returns the intersection of the camera ray with the ground.
21340
- * If no intersection is found, then a "guess" is made based on the camera angle and height.
21341
- * The guess is made at the center of the view! It ignores the screenPos.
21342
- * @param viewer
21343
- * @param screenPos
21344
- * @returns
21345
- */
21346
- function getGroundCenterOfCameraRay(viewer, screenPos) {
21347
- var _a, _b;
21348
- var ray = viewer.camera.getPickRay(screenPos);
21349
- var intersection = ray ? viewer.scene.globe.pick(ray, viewer.scene) : null;
21350
- if (intersection) {
21351
- return intersection;
21352
- }
21353
- // The fallback will be to "guess" where the intersection might be.
21354
- // This happens if terrain is hidden, and there's nothing to intersect with.
21355
- // We will use the camera angle + camera height.
21356
- // Eg: if camera is looking straight down and is 100 meters above the ground, then the intersection will be 100 meters below the camera.
21357
- var cameraHeight = viewer.camera.positionCartographic.height;
21358
- if (!isNaN(cameraHeight) && cameraHeight != null && ((_b = (_a = viewer.camera) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.clone)) {
21359
- var cameraPos3d = viewer.camera.position.clone();
21360
- var pitch = viewer.camera.pitch;
21361
- var distance = cameraHeight / Math.tan(pitch);
21362
- return _offsetPos3d(cameraPos3d, -distance, Math$1.toDegrees(viewer.camera.heading));
21363
- }
21364
- return null;
21365
- }
21366
- function areBoundsEqual(a, b) {
21367
- return a.north == b.north && a.south == b.south && a.east == b.east && a.west == b.west;
21368
- }
21369
- function arePosEqual(a, b) {
21370
- return a.latitude == b.latitude && a.longitude == b.longitude;
21371
- }
21372
- var CesiumViewMonitor;
21373
- (function (CesiumViewMonitor$$1) {
21374
- /**
21375
- * Monitors and emits events when the Cesium view changes.
21376
- */
21377
- var Monitor = /** @class */ (function () {
21378
- function Monitor(viewer) {
21379
- var _this = this;
21380
- this.target = null;
21381
- this.bounds = null;
21382
- this.disposed = false;
21383
- this.updatedEvent = null;
21384
- this.entity = null;
21385
- this.updating = false;
21386
- this.viewer = viewer;
21387
- this.tryEmitUpdate();
21388
- this.checkInterval = setInterval(function () {
21389
- _this.updateQueue();
21390
- }, POSITION_CHECK_TIMER);
21391
- }
21392
- Object.defineProperty(Monitor.prototype, "Disposed", {
21393
- get: function () {
21394
- return this.disposed;
21395
- },
21396
- enumerable: false,
21397
- configurable: true
21398
- });
21399
- Monitor.prototype.createEntity = function () {
21400
- var _this = this;
21401
- if (this.entity) {
21402
- return;
21403
- }
21404
- this.entity = this.viewer.entities.add({
21405
- position: new CallbackProperty(function () {
21406
- return _this.target ? Cartesian3.fromDegrees(_this.target.longitude, _this.target.latitude) : null;
21407
- }, false),
21408
- point: {
21409
- pixelSize: 8,
21410
- color: Color.ORANGE,
21411
- heightReference: HeightReference.NONE
21412
- },
21413
- rectangle: {
21414
- coordinates: new CallbackProperty(function () {
21415
- return _this.bounds ? Rectangle.fromDegrees(_this.bounds.west, _this.bounds.south, _this.bounds.east, _this.bounds.north) : null;
21416
- }, false),
21417
- material: Color.fromCssColorString('#ff0000').withAlpha(0.4),
21418
- zIndex: 1,
21419
- heightReference: HeightReference.NONE
21420
- }
21421
- });
21422
- };
21423
- Monitor.prototype.destroyEntity = function () {
21424
- if (this.entity && this.viewer.entities.contains(this.entity)) {
21425
- this.viewer.entities.remove(this.entity);
21426
- }
21427
- this.entity = null;
21428
- };
21429
- Monitor.prototype.Updated = function () {
21430
- if (!this.updatedEvent) {
21431
- this.updatedEvent = new BruceEvent();
21432
- }
21433
- return this.updatedEvent;
21434
- };
21435
- Monitor.prototype.GetBounds = function () {
21436
- return this.bounds;
21437
- };
21438
- Monitor.prototype.GetTarget = function () {
21439
- return this.target;
21440
- };
21441
- Monitor.prototype.DoUpdate = function () {
21442
- this.tryEmitUpdate();
21443
- };
21444
- Monitor.prototype.Dispose = function () {
21445
- if (this.disposed) {
21446
- return;
21447
- }
21448
- this.disposed = true;
21449
- clearInterval(this.checkInterval);
21450
- this.destroyEntity();
21451
- };
21452
- Monitor.prototype.tryDoUpdate = function () {
21453
- var _a;
21454
- return __awaiter(this, void 0, void 0, function () {
21455
- var viewRect, center, camera, terrData, cameraPosition, terrHeight, viewRectRad, windowPosition, intersection, point, viewRectRad, centerLong, centerLat;
21456
- return __generator(this, function (_b) {
21457
- switch (_b.label) {
21458
- case 0:
21459
- if (!this.viewer || this.viewer.isDestroyed()) {
21460
- this.Dispose();
21461
- return [2 /*return*/, ESearchStatus.LocationMissing];
21462
- }
21463
- viewRect = null;
21464
- center = null;
21465
- camera = this.viewer.camera;
21466
- return [4 /*yield*/, DrawingUtils.GetTerrainHeight({
21467
- pos3d: camera.position,
21468
- viewer: this.viewer
21469
- })];
21470
- case 1:
21471
- terrData = _b.sent();
21472
- cameraPosition = this.viewer.camera.positionCartographic;
21473
- terrHeight = terrData.error ? cameraPosition.height + DEFAULT_GROUNDED_HEIGHT : terrData.height;
21474
- // We are almost at the ground, screw horizon, just load around.
21475
- if (terrHeight && ((cameraPosition.height - terrHeight) < DEFAULT_GROUNDED_HEIGHT)) {
21476
- // View area calculation.
21477
- viewRect = {};
21478
- viewRectRad = netScanViewForBoundaries(this.viewer);
21479
- if (viewRectRad &&
21480
- viewRectRad.east &&
21481
- viewRectRad.west &&
21482
- viewRectRad.north &&
21483
- viewRectRad.south) {
21484
- viewRect.east = Math$1.toDegrees(Math.max(viewRectRad.east, cameraPosition.longitude));
21485
- viewRect.west = Math$1.toDegrees(Math.min(viewRectRad.west, cameraPosition.longitude));
21486
- viewRect.south = Math$1.toDegrees(Math.min(viewRectRad.south, cameraPosition.latitude));
21487
- viewRect.north = Math$1.toDegrees(Math.max(viewRectRad.north, cameraPosition.latitude));
21488
- }
21489
- else {
21490
- viewRect.east = cameraPosition.longitude;
21491
- viewRect.west = cameraPosition.longitude;
21492
- viewRect.south = cameraPosition.latitude;
21493
- viewRect.north = cameraPosition.latitude;
21494
- }
21495
- center = {};
21496
- center.latitude = Math$1.toDegrees(camera.positionCartographic.latitude);
21497
- center.longitude = Math$1.toDegrees(camera.positionCartographic.longitude);
21498
- }
21499
- else {
21500
- windowPosition = new Cartesian2(this.viewer.container.clientWidth / 2, this.viewer.container.clientHeight / 2);
21501
- intersection = getGroundCenterOfCameraRay(this.viewer, windowPosition);
21502
- point = null;
21503
- if (intersection) {
21504
- point = Cartographic.fromCartesian(intersection, this.viewer.scene.globe.ellipsoid);
21505
- }
21506
- if (point) {
21507
- center = {};
21508
- center.latitude = Math$1.toDegrees(point.latitude);
21509
- center.longitude = Math$1.toDegrees(point.longitude);
21510
- viewRectRad = netScanViewForBoundaries(this.viewer, center);
21511
- if (viewRectRad) {
21512
- viewRect = {};
21513
- viewRect.east = Math$1.toDegrees(viewRectRad.east);
21514
- viewRect.west = Math$1.toDegrees(viewRectRad.west);
21515
- viewRect.south = Math$1.toDegrees(viewRectRad.south);
21516
- viewRect.north = Math$1.toDegrees(viewRectRad.north);
21517
- }
21518
- }
21519
- }
21520
- // Minimal field of view.
21521
- if (viewRect) {
21522
- centerLong = (viewRect.east + viewRect.west) / 2;
21523
- centerLat = (viewRect.north + viewRect.south) / 2;
21524
- viewRect.east = Math.max(viewRect.east, centerLong + (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
21525
- viewRect.west = Math.min(viewRect.west, centerLong - (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
21526
- viewRect.south = Math.min(viewRect.south, centerLat - (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
21527
- viewRect.north = Math.max(viewRect.north, centerLat + (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
21528
- viewRect.alt = (_a = this.viewer.scene.camera.positionCartographic) === null || _a === void 0 ? void 0 : _a.height;
21529
- }
21530
- if (center && viewRect) {
21531
- if ((!this.target || (this.target && !arePosEqual(this.target, center))) ||
21532
- (!this.bounds || (this.bounds && !areBoundsEqual(this.bounds, viewRect)))) {
21533
- this.target = center;
21534
- this.bounds = viewRect;
21535
- return [2 /*return*/, ESearchStatus.LocationChanged];
21410
+ layer.tilesetId = ProjectViewTile.EDefaultImagery.MapboxSatellite;
21411
+ console.warn("Cesium Ion token not set, using mapbox satellite instead of bing maps aerial.");
21412
+ }
21413
+ else if (layer.tilesetId == ProjectViewTile.EDefaultImagery.BingMapsAerialWithLabels) {
21414
+ layer.tilesetId = ProjectViewTile.EDefaultImagery.MapboxSatellite;
21415
+ console.warn("Cesium Ion token not set, using mapbox satellite instead of bing maps aerial with labels.");
21416
+ }
21417
+ else if (layer.tilesetId == ProjectViewTile.EDefaultImagery.BingMapsRoads) {
21418
+ layer.tilesetId = ProjectViewTile.EDefaultImagery.MapBoxStreets;
21419
+ console.warn("Cesium Ion token not set, using mapbox streets instead of bing maps roads.");
21536
21420
  }
21537
- return [2 /*return*/, ESearchStatus.LocationFound];
21538
21421
  }
21539
- return [2 /*return*/, ESearchStatus.LocationMissing];
21422
+ }
21540
21423
  }
21541
- });
21542
- });
21543
- };
21544
- Monitor.prototype.tryEmitUpdate = function () {
21545
- var _a;
21546
- return __awaiter(this, void 0, void 0, function () {
21547
- var searchResult, interest, e_1;
21548
- return __generator(this, function (_b) {
21549
- switch (_b.label) {
21550
- case 0:
21551
- if (this.updating) {
21552
- return [2 /*return*/];
21424
+ // We don't wait for imageries to load, this does not affect rendering other things.
21425
+ TileRenderEngine.Map.Navigator.Render({
21426
+ apiGetter: params.apiGetter,
21427
+ tiles: imagery,
21428
+ viewer: params.manager.Viewer,
21429
+ });
21430
+ legacyRelationIds = bSettings === null || bSettings === void 0 ? void 0 : bSettings.renderedEntityRelations;
21431
+ if (!legacyRelationIds) {
21432
+ legacyRelationIds = [];
21433
+ }
21434
+ relations = bSettings === null || bSettings === void 0 ? void 0 : bSettings.renderedRelations;
21435
+ if (!relations) {
21436
+ relations = [];
21437
+ }
21438
+ viewer.scene.requestRender();
21439
+ curEnabled = params.manager.GetEnabledItemIds();
21440
+ newItemIds = (_5 = bSettings === null || bSettings === void 0 ? void 0 : bSettings.menuItemIds) !== null && _5 !== void 0 ? _5 : [];
21441
+ for (_i = 0, curEnabled_1 = curEnabled; _i < curEnabled_1.length; _i++) {
21442
+ id = curEnabled_1[_i];
21443
+ shouldRemove = void 0;
21444
+ if (id == RELATION_MENU_ITEM_ID) {
21445
+ rendered = params.manager.GetEnabledItem(id);
21446
+ shouldRemove = false;
21447
+ if (!legacyRelationIds.length && !relations.length) {
21448
+ shouldRemove = true;
21553
21449
  }
21554
- this.updating = true;
21555
- _b.label = 1;
21556
- case 1:
21557
- _b.trys.push([1, 3, , 4]);
21558
- return [4 /*yield*/, this.tryDoUpdate()];
21559
- case 2:
21560
- searchResult = _b.sent();
21561
- if (searchResult == ESearchStatus.LocationChanged) {
21562
- interest = {
21563
- bounds: this.bounds,
21564
- target: this.target
21565
- };
21566
- // this.createEntity();
21567
- (_a = this.updatedEvent) === null || _a === void 0 ? void 0 : _a.Trigger(interest);
21450
+ // If we're about to render legacy relationships but a non-legacy item is currently enabled then we remove it.
21451
+ else if (legacyRelationIds.length && (rendered === null || rendered === void 0 ? void 0 : rendered.type) != MenuItem.EType.Relations) {
21452
+ shouldRemove = true;
21568
21453
  }
21569
- else if (searchResult == ESearchStatus.LocationMissing) {
21570
- this.updateQueue();
21454
+ // If we're about to render non-legacy relationships but a legacy item is currently enabled then we remove it.
21455
+ else if (relations.length && (rendered === null || rendered === void 0 ? void 0 : rendered.type) != MenuItem.EType.Relationships) {
21456
+ shouldRemove = true;
21571
21457
  }
21572
- return [3 /*break*/, 4];
21573
- case 3:
21574
- e_1 = _b.sent();
21575
- console.error(e_1);
21576
- this.updateQueue();
21577
- return [3 /*break*/, 4];
21578
- case 4:
21579
- this.updating = false;
21458
+ }
21459
+ else {
21460
+ shouldRemove = newItemIds.indexOf(id) === -1;
21461
+ }
21462
+ if (shouldRemove) {
21463
+ params.manager.RemoveItemById({
21464
+ menuItemId: id
21465
+ });
21466
+ }
21467
+ }
21468
+ if (!bookmark) return [3 /*break*/, 15];
21469
+ return [4 /*yield*/, MenuItemCreator.RenderBookmarkItems({
21470
+ getters: params.getters,
21471
+ manager: params.manager,
21472
+ view: view,
21473
+ bookmark: bookmark
21474
+ })];
21475
+ case 14:
21476
+ _8.sent();
21477
+ if (!assertIteration$1(params.viewer, iteration)) {
21478
+ return [2 /*return*/];
21479
+ }
21480
+ _8.label = 15;
21481
+ case 15:
21482
+ if (legacyRelationIds.length || relations.length) {
21483
+ if (relations.length) {
21484
+ menuItem = {
21485
+ id: RELATION_MENU_ITEM_ID,
21486
+ Caption: "Entity relations",
21487
+ relations: relations,
21488
+ Type: MenuItem.EType.Relationships
21489
+ };
21490
+ params.manager.RenderItem({
21491
+ getters: params.getters,
21492
+ item: menuItem
21493
+ });
21494
+ }
21495
+ else if (legacyRelationIds.length) {
21496
+ menuItem = {
21497
+ id: RELATION_MENU_ITEM_ID,
21498
+ Caption: "Entity relations",
21499
+ BruceEntity: {
21500
+ EntityIds: legacyRelationIds
21501
+ },
21502
+ Type: MenuItem.EType.Relations
21503
+ };
21504
+ params.manager.RenderItem({
21505
+ getters: params.getters,
21506
+ item: menuItem
21507
+ });
21508
+ }
21509
+ if (!assertIteration$1(params.viewer, iteration)) {
21580
21510
  return [2 /*return*/];
21511
+ }
21581
21512
  }
21582
- });
21583
- });
21584
- };
21585
- Monitor.prototype.queuePosition = function (lag) {
21586
- var _this = this;
21587
- if (this.pendingTimeout) {
21588
- clearTimeout(this.pendingTimeout);
21513
+ gOcclusion = bSettings === null || bSettings === void 0 ? void 0 : bSettings.groundOcclusion;
21514
+ if (gOcclusion == null) {
21515
+ gOcclusion = (_6 = defaults === null || defaults === void 0 ? void 0 : defaults.settings) === null || _6 === void 0 ? void 0 : _6.groundOcclusion;
21516
+ }
21517
+ if (gOcclusion == null) {
21518
+ // TODO: Need global default.
21519
+ gOcclusion = true;
21520
+ }
21521
+ scene.globe.depthTestAgainstTerrain = Boolean(gOcclusion);
21522
+ return [2 /*return*/];
21589
21523
  }
21590
- this.pendingTimeout = setTimeout(function () {
21591
- if (!_this.disposed) {
21592
- _this.tryEmitUpdate();
21524
+ });
21525
+ });
21526
+ }
21527
+ var ViewRenderEngine;
21528
+ (function (ViewRenderEngine) {
21529
+ function Render(params) {
21530
+ var _a;
21531
+ return __awaiter(this, void 0, void 0, function () {
21532
+ var iteration, api, view, _b, bookmark, bookmarkId, _c, version, bWidget;
21533
+ return __generator(this, function (_d) {
21534
+ switch (_d.label) {
21535
+ case 0:
21536
+ if (!params.manager && params.viewer) {
21537
+ params.manager = ViewerUtils.GetManager({
21538
+ viewer: params.viewer,
21539
+ createIfMissing: true
21540
+ });
21541
+ }
21542
+ else if (!params.viewer && params.manager) {
21543
+ params.viewer = params.manager.Viewer;
21544
+ }
21545
+ iteration = newIteration$1(params.viewer);
21546
+ if (!params.getters) {
21547
+ params.getters = ENVIRONMENT.Api();
21548
+ }
21549
+ if (params.apiGetter && !params.getters) {
21550
+ console.warn("ViewRenderEngine.Render(): Please pass getters instead of apiGetter. This is now deprecated due to needing access to other kinds of apis.");
21551
+ }
21552
+ else if (!params.apiGetter) {
21553
+ params.apiGetter = params.getters.GetBruceGetter();
21554
+ }
21555
+ api = params.getters.GetBruceApi();
21556
+ if (!params.view) return [3 /*break*/, 1];
21557
+ _b = params.view;
21558
+ return [3 /*break*/, 3];
21559
+ case 1: return [4 /*yield*/, ProjectView.Get({
21560
+ api: api,
21561
+ viewId: params.viewId
21562
+ })];
21563
+ case 2:
21564
+ _b = (_d.sent()).view;
21565
+ _d.label = 3;
21566
+ case 3:
21567
+ view = _b;
21568
+ bookmark = params.bookmark;
21569
+ if (!!bookmark) return [3 /*break*/, 7];
21570
+ bookmarkId = params.bookmarkId;
21571
+ if (!bookmarkId) {
21572
+ bookmarkId = view.DefaultUISlideID;
21573
+ }
21574
+ if (!bookmarkId) return [3 /*break*/, 5];
21575
+ return [4 /*yield*/, ProjectViewBookmark.Get({
21576
+ api: api,
21577
+ viewId: params.viewId,
21578
+ bookmarkId: bookmarkId
21579
+ })];
21580
+ case 4:
21581
+ _c = (_d.sent()).bookmark;
21582
+ return [3 /*break*/, 6];
21583
+ case 5:
21584
+ _c = null;
21585
+ _d.label = 6;
21586
+ case 6:
21587
+ bookmark = _c;
21588
+ _d.label = 7;
21589
+ case 7:
21590
+ if (!assertIteration$1(params.viewer, iteration)) {
21591
+ return [2 /*return*/];
21592
+ }
21593
+ version = view.DataVersion;
21594
+ if (!(version == 1)) return [3 /*break*/, 9];
21595
+ return [4 /*yield*/, renderLegacyNavigator(iteration, params, bookmark, view)];
21596
+ case 8:
21597
+ _d.sent();
21598
+ return [3 /*break*/, 11];
21599
+ case 9: return [4 /*yield*/, renderNavigator(iteration, params, bookmark, view, params.getters)];
21600
+ case 10:
21601
+ _d.sent();
21602
+ _d.label = 11;
21603
+ case 11:
21604
+ if (!assertIteration$1(params.viewer, iteration)) {
21605
+ return [2 /*return*/];
21606
+ }
21607
+ bWidget = (_a = params.viewer) === null || _a === void 0 ? void 0 : _a[VIEWER_BOOKMARKS_WIDGET_KEY];
21608
+ if (bWidget) {
21609
+ bWidget.ViewId = params.viewId ? params.viewId : view === null || view === void 0 ? void 0 : view.ID;
21610
+ bWidget.LastEnabledBookmarkId = params.bookmarkId ? params.bookmarkId : bookmark === null || bookmark === void 0 ? void 0 : bookmark.ID;
21611
+ }
21612
+ return [2 /*return*/];
21593
21613
  }
21594
- }, lag);
21595
- };
21596
- Monitor.prototype.updateQueue = function () {
21597
- this.queuePosition(TIME_LAG);
21598
- };
21599
- return Monitor;
21600
- }());
21601
- CesiumViewMonitor$$1.Monitor = Monitor;
21602
- })(CesiumViewMonitor || (CesiumViewMonitor = {}));
21614
+ });
21615
+ });
21616
+ }
21617
+ ViewRenderEngine.Render = Render;
21618
+ })(ViewRenderEngine || (ViewRenderEngine = {}));
21603
21619
 
21604
- var VERSION$1 = "3.4.7";
21620
+ var VERSION = "3.4.9";
21605
21621
 
21606
- export { VERSION$1 as VERSION, CesiumViewMonitor, ViewerUtils, MenuItemManager, EntityRenderEngine, MenuItemCreator, VisualsRegister, RenderManager, EntitiesIdsRenderManager, EntitiesLoadedRenderManager, EntitiesRenderManager, EntityRenderManager, TilesetCadRenderManager, TilesetArbRenderManager, TilesetEntitiesRenderManager, TilesetOsmRenderManager, TilesetPointcloudRenderManager, TilesetGooglePhotosRenderManager, DataSourceStaticKmlManager, RelationsRenderManager, SharedGetters, CesiumParabola, EntityLabel, ViewRenderEngine, TileRenderEngine, TilesetRenderEngine, CESIUM_INSPECTOR_KEY, ViewUtils, DrawingUtils, MeasureUtils, EntityUtils, Draw3dPolygon, Draw3dPolyline };
21622
+ export { VERSION, CesiumViewMonitor, ViewerUtils, MenuItemManager, EntityRenderEngine, MenuItemCreator, VisualsRegister, RenderManager, EntitiesIdsRenderManager, EntitiesLoadedRenderManager, EntitiesRenderManager, EntityRenderManager, TilesetCadRenderManager, TilesetArbRenderManager, TilesetEntitiesRenderManager, TilesetOsmRenderManager, TilesetPointcloudRenderManager, TilesetGooglePhotosRenderManager, DataSourceStaticKmlManager, RelationsRenderManager, SharedGetters, CesiumParabola, EntityLabel, ViewRenderEngine, TileRenderEngine, TilesetRenderEngine, CESIUM_INSPECTOR_KEY, ViewUtils, DrawingUtils, MeasureUtils, EntityUtils, Draw3dPolygon, Draw3dPolyline };
21607
21623
  //# sourceMappingURL=bruce-cesium.es5.js.map