bruce-cesium 5.9.6 → 5.9.8

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 { BruceEvent, Cartes, Entity as Entity$1, ProjectViewTile, Carto, Geometry, MathUtils, LRUCache, Api, Calculator, ClientFile, EntityTag, EntityType, ObjectUtils, Style, DelayQueue, EntityLod, Bounds, ZoomControl, EntityRelationType, ENVIRONMENT, EntityHistoricData, Tileset, EntityCoords, DataLab, EntitySource, MenuItem, EntityRelation, ProgramKey, ProjectView, ProjectViewBookmark, Camera, ProjectViewLegacyTile, EntityAttachment, EntityAttachmentType, EntityAttribute, AbstractApi, Session } from 'bruce-models';
1
+ import { BruceEvent, Cartes, Entity as Entity$1, ProjectViewTile, Carto, Geometry, MathUtils, LRUCache, Api, Calculator, ClientFile, EntityTag, EntityType, ObjectUtils, Style, DelayQueue, EntityLod, Bounds, ZoomControl, EntityRelationType, ENVIRONMENT, EntityHistoricData, Tileset, EntityCoords, DataLab, EntitySource, MenuItem, EntityRelation, ProgramKey, ProjectView, ProjectViewBookmark, ProjectViewLegacyTile, Camera, Session, EntityAttachment, EntityAttachmentType, EntityAttribute, AbstractApi } from 'bruce-models';
2
2
  import * as Cesium from 'cesium';
3
- import { Cartographic, Cartesian2, Math as Math$1, Cartesian3, CallbackProperty, Color, HeightReference, Rectangle, JulianDate, Entity, DistanceDisplayCondition, HorizontalOrigin, VerticalOrigin, ConstantProperty, ClassificationType, ConstantPositionProperty, ArcType, CornerType, ShadowMode, PolygonHierarchy, PolylineGraphics, ColorMaterialProperty, ColorBlendMode, HeadingPitchRoll, Transforms, Model, SceneMode, Primitive, Cesium3DTileFeature, GeoJsonDataSource, Cesium3DTileStyle, Cesium3DTileColorBlendMode, HeadingPitchRange, Ion, KmlDataSource, Quaternion, Matrix3, Matrix4, SceneTransforms, OrthographicFrustum, EasingFunction, NearFarScalar, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, IonResource, CesiumInspector, defined, ClockRange, EllipsoidGeodesic, sampleTerrainMostDetailed, Cesium3DTileset, PolygonPipeline, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, BoundingSphere, GeometryInstance, ScreenSpaceEventHandler, ScreenSpaceEventType, CzmlDataSource, Intersect, Fullscreen } from 'cesium';
3
+ import { Cartographic, Cartesian2, Math as Math$1, Cartesian3, CallbackProperty, Color, HeightReference, Rectangle, Entity, DistanceDisplayCondition, ClassificationType, ArcType, CornerType, ShadowMode, ConstantProperty, ConstantPositionProperty, JulianDate, HorizontalOrigin, VerticalOrigin, PolygonHierarchy, PolylineGraphics, ColorMaterialProperty, ColorBlendMode, HeadingPitchRoll, Transforms, Model, Primitive, Cesium3DTileFeature, SceneMode, GeoJsonDataSource, HeadingPitchRange, Ion, Cesium3DTileStyle, Cesium3DTileColorBlendMode, KmlDataSource, Quaternion, Matrix3, Matrix4, SceneTransforms, EllipsoidTerrainProvider, CesiumInspector, OrthographicFrustum, defined, ClockRange, EllipsoidGeodesic, sampleTerrainMostDetailed, Cesium3DTileset, PolygonPipeline, IonResource, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, EasingFunction, NearFarScalar, ScreenSpaceEventHandler, ScreenSpaceEventType, BoundingSphere, GeometryInstance, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, CzmlDataSource, Intersect, Fullscreen } from 'cesium';
4
4
 
5
5
  const TIME_LAG = 300;
6
6
  const POSITION_CHECK_TIMER = 950;
@@ -1144,19 +1144,18 @@ var CesiumAnimatedProperty;
1144
1144
  */
1145
1145
  class AnimatePositionSeries {
1146
1146
  constructor(params) {
1147
- // Animation state.
1148
- this.currentAnimatedPos = null;
1149
- this.currentTargetPos = null;
1150
- this.animationStartPos = null;
1151
- this.animationStartTime = null;
1152
- this.animationDuration = 200;
1153
- // Cached data for performance.
1147
+ this.currentPos = null;
1148
+ this.currentVelocity = new Cartesian3(0, 0, 0);
1149
+ this.smoothingFactor = 0.5;
1150
+ this.positionHistory = [];
1151
+ this.maxHistorySize = 10;
1152
+ this.averageSpeed = 0;
1153
+ this.averageTimeInterval = 0;
1154
+ this.lastUpdateTime = null;
1154
1155
  this.lastDesiredPosIndex = -1;
1155
1156
  this.lastDesiredNextIndex = -1;
1156
- // Series data for rendering path
1157
1157
  this.lastCalcSeriesPos3d = [];
1158
1158
  this.lastCalcSeriesTime = null;
1159
- // Orientation cache.
1160
1159
  this.lastCalcOrient = null;
1161
1160
  this.lastCalcOrientTime = null;
1162
1161
  this.viewer = params.viewer;
@@ -1165,25 +1164,23 @@ var CesiumAnimatedProperty;
1165
1164
  this.roll = params.roll || 0;
1166
1165
  this.processHeadings();
1167
1166
  this.sortPositions();
1168
- // Initialize animation from starting position if provided.
1169
- if (params.animateFromPos3d) {
1170
- this.animationStartPos = params.animateFromPos3d;
1171
- const currentTime = Date.now();
1172
- const providedTime = params.animateFromPos3dTimeStart || 0;
1173
- // Check if the provided timestamp is stale.
1174
- if (!providedTime || (currentTime - providedTime) >= this.animationDuration) {
1175
- this.animationStartTime = currentTime;
1176
- }
1177
- else {
1178
- this.animationStartTime = providedTime;
1179
- }
1180
- }
1181
1167
  }
1182
1168
  AddPosition(pos) {
1183
1169
  if (!pos || !pos.pos3d || !pos.dateTime) {
1184
1170
  console.warn("Invalid position provided to AnimatePositionSeries.");
1185
1171
  return;
1186
1172
  }
1173
+ const now = Date.now();
1174
+ const posTime = pos.dateTime.getTime();
1175
+ this.positionHistory.push({
1176
+ pos: pos.pos3d.clone(),
1177
+ time: posTime,
1178
+ realTime: now
1179
+ });
1180
+ if (this.positionHistory.length > this.maxHistorySize) {
1181
+ this.positionHistory.shift();
1182
+ }
1183
+ this.analyzeMovementPatterns();
1187
1184
  this.positions.push(pos);
1188
1185
  this.processHeadings();
1189
1186
  this.sortPositions();
@@ -1194,12 +1191,70 @@ var CesiumAnimatedProperty;
1194
1191
  this.roll = roll;
1195
1192
  this.invalidateCache();
1196
1193
  }
1197
- GetAnimateFromDateTime() {
1198
- return this.animationStartTime;
1199
- }
1200
1194
  GetPositions() {
1201
1195
  return this.positions;
1202
1196
  }
1197
+ analyzeMovementPatterns() {
1198
+ if (this.positionHistory.length < 2) {
1199
+ return;
1200
+ }
1201
+ let totalDistance = 0;
1202
+ let totalTimeSpan = 0;
1203
+ let totalRealTimeSpan = 0;
1204
+ let validSegments = 0;
1205
+ for (let i = 1; i < this.positionHistory.length; i++) {
1206
+ const prev = this.positionHistory[i - 1];
1207
+ const curr = this.positionHistory[i];
1208
+ const distance = Cartesian3.distance(prev.pos, curr.pos);
1209
+ const timeSpan = Math.abs(curr.time - prev.time) / 1000.0;
1210
+ const realTimeSpan = Math.abs(curr.realTime - prev.realTime) / 1000.0;
1211
+ if (distance > 0.1 && timeSpan > 0.01) {
1212
+ totalDistance += distance;
1213
+ totalTimeSpan += timeSpan;
1214
+ totalRealTimeSpan += realTimeSpan;
1215
+ validSegments++;
1216
+ }
1217
+ }
1218
+ if (validSegments > 0) {
1219
+ this.averageSpeed = totalDistance / totalTimeSpan;
1220
+ this.averageTimeInterval = totalRealTimeSpan / validSegments;
1221
+ this.averageSpeed = Math.max(0.1, Math.min(this.averageSpeed, 1000));
1222
+ this.averageTimeInterval = Math.max(0.01, Math.min(this.averageTimeInterval, 10));
1223
+ }
1224
+ }
1225
+ calculateExpectedPosition(viewerTimeMs) {
1226
+ const desired = this.calculateDesiredPosition(viewerTimeMs);
1227
+ if (!desired.position) {
1228
+ return { position: null, timeDelta: 0 };
1229
+ }
1230
+ let timeDelta = 0;
1231
+ if (this.positionHistory.length >= 2) {
1232
+ // Calculate how far behind we are based on viewer time vs real time.
1233
+ const now = Date.now();
1234
+ const timeDiffFromNow = (viewerTimeMs - now) / 1000.0;
1235
+ // Negative means we're behind, positive means ahead.
1236
+ timeDelta = timeDiffFromNow;
1237
+ }
1238
+ return { position: desired.position, timeDelta };
1239
+ }
1240
+ calculateAutonomousSpeed(distanceToTarget, timeDelta) {
1241
+ let baseSpeed = this.averageSpeed || 50;
1242
+ let speedMultiplier = 1.0;
1243
+ // Calculate speed multiplier based on distance and time lag.
1244
+ if (distanceToTarget > 50) {
1245
+ speedMultiplier *= Math.min(100.0, distanceToTarget / 10.0);
1246
+ }
1247
+ else if (distanceToTarget > 10) {
1248
+ const distanceMultiplier = Math.min(20.0, 1.0 + (distanceToTarget / 5.0));
1249
+ speedMultiplier *= distanceMultiplier;
1250
+ }
1251
+ else if (Math.abs(timeDelta) > 0.1) {
1252
+ const timeLagMultiplier = Math.max(0.1, 1.0 - (timeDelta * 5.0));
1253
+ speedMultiplier *= Math.min(50.0, timeLagMultiplier);
1254
+ }
1255
+ // Minimum 10% speed.
1256
+ return Math.max(baseSpeed * 0.1, baseSpeed * speedMultiplier);
1257
+ }
1203
1258
  sortPositions() {
1204
1259
  if (this.positions.length > 0) {
1205
1260
  this.positions.sort((a, b) => a.dateTime.getTime() - b.dateTime.getTime());
@@ -1209,10 +1264,6 @@ var CesiumAnimatedProperty;
1209
1264
  this.lastCalcSeriesTime = null;
1210
1265
  this.lastCalcOrientTime = null;
1211
1266
  }
1212
- /**
1213
- * Pre-process headings in the series.
1214
- * If all are null or 0, then we assume all are null.
1215
- */
1216
1267
  processHeadings() {
1217
1268
  if (!this.positions || this.positions.length === 0) {
1218
1269
  return;
@@ -1234,15 +1285,10 @@ var CesiumAnimatedProperty;
1234
1285
  easeInOutQuad(t) {
1235
1286
  return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
1236
1287
  }
1237
- /**
1238
- * Calculate the desired position based on current time without any animation smoothing.
1239
- */
1240
1288
  calculateDesiredPosition(timeMs) {
1241
- // No positions available
1242
1289
  if (!this.positions || this.positions.length === 0) {
1243
1290
  return { position: null, lastIndex: -1, nextIndex: -1 };
1244
1291
  }
1245
- // Only one position.
1246
1292
  if (this.positions.length === 1) {
1247
1293
  return {
1248
1294
  position: this.positions[0].pos3d || null,
@@ -1250,7 +1296,6 @@ var CesiumAnimatedProperty;
1250
1296
  nextIndex: 0
1251
1297
  };
1252
1298
  }
1253
- // Before first position - use first two positions for orientation.
1254
1299
  if (timeMs <= this.positions[0].dateTime.getTime()) {
1255
1300
  return {
1256
1301
  position: this.positions[0].pos3d || null,
@@ -1258,7 +1303,6 @@ var CesiumAnimatedProperty;
1258
1303
  nextIndex: Math.min(1, this.positions.length - 1)
1259
1304
  };
1260
1305
  }
1261
- // After last position - use last two positions for orientation.
1262
1306
  const lastIdx = this.positions.length - 1;
1263
1307
  if (timeMs >= this.positions[lastIdx].dateTime.getTime()) {
1264
1308
  return {
@@ -1267,12 +1311,10 @@ var CesiumAnimatedProperty;
1267
1311
  nextIndex: lastIdx
1268
1312
  };
1269
1313
  }
1270
- // Find positions to interpolate between.
1271
1314
  for (let i = 0; i < this.positions.length - 1; i++) {
1272
1315
  const current = this.positions[i];
1273
1316
  const next = this.positions[i + 1];
1274
1317
  if (timeMs >= current.dateTime.getTime() && timeMs < next.dateTime.getTime()) {
1275
- // Exact match on current position - still use current and next for orientation.
1276
1318
  if (timeMs === current.dateTime.getTime()) {
1277
1319
  return {
1278
1320
  position: current.pos3d || null,
@@ -1280,7 +1322,6 @@ var CesiumAnimatedProperty;
1280
1322
  nextIndex: i + 1
1281
1323
  };
1282
1324
  }
1283
- // Interpolate between current and next.
1284
1325
  if (!current.pos3d || !next.pos3d) {
1285
1326
  return {
1286
1327
  position: current.pos3d || next.pos3d || null,
@@ -1307,99 +1348,59 @@ var CesiumAnimatedProperty;
1307
1348
  }
1308
1349
  }
1309
1350
  }
1310
- // Fallback to last position with previous position for orientation.
1311
1351
  return {
1312
1352
  position: this.positions[lastIdx].pos3d || null,
1313
1353
  lastIndex: Math.max(0, lastIdx - 1),
1314
1354
  nextIndex: lastIdx
1315
1355
  };
1316
1356
  }
1317
- /**
1318
- * Main method to get the current position based on time.
1319
- */
1320
1357
  GetValue() {
1321
- let now = this.viewer.scene.lastRenderTime;
1322
- if (!now) {
1323
- now = this.viewer.clock.currentTime;
1358
+ let viewerTime = this.viewer.scene.lastRenderTime;
1359
+ if (!viewerTime) {
1360
+ viewerTime = this.viewer.clock.currentTime;
1324
1361
  }
1325
- const nowTimeMs = JulianDate.toDate(now).getTime();
1362
+ const viewerTimeMs = JulianDate.toDate(viewerTime).getTime();
1326
1363
  const currentRealTimeMs = Date.now();
1327
- // Calculate the desired position based on time.
1328
- const desired = this.calculateDesiredPosition(nowTimeMs);
1329
- // If no desired position, return empty position.
1330
- if (!desired.position) {
1331
- this.currentAnimatedPos = null;
1332
- this.currentTargetPos = null;
1364
+ const expected = this.calculateExpectedPosition(viewerTimeMs);
1365
+ if (!expected.position) {
1366
+ this.currentPos = null;
1367
+ this.currentVelocity = new Cartesian3(0, 0, 0);
1333
1368
  return new Cartesian3();
1334
1369
  }
1335
- // Cache the desired position info for orientation calculations.
1370
+ const desired = this.calculateDesiredPosition(viewerTimeMs);
1336
1371
  this.lastDesiredPosIndex = desired.lastIndex;
1337
1372
  this.lastDesiredNextIndex = desired.nextIndex;
1338
- // First time or no previous position - start here.
1339
- if (!this.currentAnimatedPos) {
1340
- // If we have a starting animation position, animate from it.
1341
- if (this.animationStartPos) {
1342
- this.currentTargetPos = desired.position;
1343
- const progress = this.getAnimationProgress(currentRealTimeMs, this.animationStartTime);
1344
- if (progress >= 1.0) {
1345
- // Animation complete.
1346
- this.currentAnimatedPos = desired.position;
1347
- this.animationStartPos = null;
1348
- this.animationStartTime = null;
1349
- return desired.position;
1350
- }
1351
- else {
1352
- // Continue animation.
1353
- const easedProgress = this.easeInOutQuad(progress);
1354
- this.currentAnimatedPos = Cartesian3.lerp(this.animationStartPos, desired.position, easedProgress, new Cartesian3());
1355
- return this.currentAnimatedPos;
1356
- }
1357
- }
1358
- else {
1359
- // No animation, start at desired position.
1360
- this.currentAnimatedPos = desired.position;
1361
- this.currentTargetPos = desired.position;
1362
- return desired.position;
1363
- }
1364
- }
1365
- // Check if target has changed.
1366
- const targetChanged = !this.currentTargetPos || !Cartesian3.equals(this.currentTargetPos, desired.position);
1367
- if (targetChanged) {
1368
- // Target changed mid-animation - start new animation from current position.
1369
- this.animationStartPos = this.currentAnimatedPos;
1370
- this.animationStartTime = currentRealTimeMs;
1371
- this.currentTargetPos = desired.position;
1372
- }
1373
- // Continue or start animation to target.
1374
- if (this.animationStartPos && this.animationStartTime) {
1375
- const progress = this.getAnimationProgress(currentRealTimeMs, this.animationStartTime);
1376
- // Animation complete.
1377
- if (progress >= 1.0) {
1378
- this.currentAnimatedPos = desired.position;
1379
- this.animationStartPos = null;
1380
- this.animationStartTime = null;
1381
- return desired.position;
1382
- }
1383
- // Continue animation.
1384
- else {
1385
- const easedProgress = this.easeInOutQuad(progress);
1386
- this.currentAnimatedPos = Cartesian3.lerp(this.animationStartPos, desired.position, easedProgress, new Cartesian3());
1387
- return this.currentAnimatedPos;
1388
- }
1389
- }
1390
- // No animation needed - already at target.
1391
- this.currentAnimatedPos = desired.position;
1392
- return desired.position;
1393
- }
1394
- getAnimationProgress(currentTime, startTime) {
1395
- const elapsed = currentTime - startTime;
1396
- return Math.min(elapsed / this.animationDuration, 1.0);
1373
+ if (!this.currentPos) {
1374
+ this.currentPos = expected.position.clone();
1375
+ this.currentVelocity = new Cartesian3(0, 0, 0);
1376
+ this.lastUpdateTime = currentRealTimeMs;
1377
+ return this.currentPos;
1378
+ }
1379
+ const deltaTime = this.lastUpdateTime ? (currentRealTimeMs - this.lastUpdateTime) / 1000.0 : 0.016;
1380
+ this.lastUpdateTime = currentRealTimeMs;
1381
+ const clampedDeltaTime = Math.min(deltaTime, 0.1);
1382
+ const targetDistance = Cartesian3.distance(this.currentPos, expected.position);
1383
+ if (targetDistance < 0.5) {
1384
+ this.currentPos = expected.position.clone();
1385
+ this.currentVelocity = new Cartesian3(0, 0, 0);
1386
+ return this.currentPos;
1387
+ }
1388
+ // Check if we're really far behind and need to teleport.
1389
+ if (targetDistance > 500) {
1390
+ this.currentPos = expected.position.clone();
1391
+ this.currentVelocity = new Cartesian3(0, 0, 0);
1392
+ return this.currentPos;
1393
+ }
1394
+ const direction = Cartesian3.subtract(expected.position, this.currentPos, new Cartesian3());
1395
+ Cartesian3.normalize(direction, direction);
1396
+ const targetSpeed = this.calculateAutonomousSpeed(targetDistance, expected.timeDelta);
1397
+ const targetVelocity = Cartesian3.multiplyByScalar(direction, targetSpeed, new Cartesian3());
1398
+ this.currentVelocity = Cartesian3.lerp(this.currentVelocity, targetVelocity, this.smoothingFactor, new Cartesian3());
1399
+ const velocityDelta = Cartesian3.multiplyByScalar(this.currentVelocity, clampedDeltaTime, new Cartesian3());
1400
+ this.currentPos = Cartesian3.add(this.currentPos, velocityDelta, new Cartesian3());
1401
+ return this.currentPos;
1397
1402
  }
1398
- /**
1399
- * Returns a series of positions to use for rendering the path.
1400
- */
1401
1403
  GetSeries() {
1402
- // Update at 30 fps.
1403
1404
  let doUpdate = this.lastCalcSeriesTime == null;
1404
1405
  if (!doUpdate && this.lastCalcSeriesTime && (new Date().getTime() - this.lastCalcSeriesTime) > 1000 / 30) {
1405
1406
  doUpdate = true;
@@ -1407,33 +1408,27 @@ var CesiumAnimatedProperty;
1407
1408
  if (!doUpdate) {
1408
1409
  return this.lastCalcSeriesPos3d;
1409
1410
  }
1410
- // Ensure position indices are up-to-date.
1411
1411
  this.GetValue();
1412
1412
  let now = this.viewer.scene.lastRenderTime;
1413
1413
  if (!now) {
1414
1414
  now = this.viewer.clock.currentTime;
1415
1415
  }
1416
1416
  const nowDate = JulianDate.toDate(now);
1417
- // Get total duration.
1418
1417
  if (!this.positions || this.positions.length < 2) {
1419
1418
  this.lastCalcSeriesTime = nowDate.getTime();
1420
1419
  this.lastCalcSeriesPos3d = [];
1421
1420
  return [];
1422
1421
  }
1423
- const totalDuration = this.positions[this.positions.length - 1].dateTime.getTime() -
1424
- this.positions[0].dateTime.getTime();
1425
- // Percentage of the polyline to be visible before and after each point.
1426
- const visibilityPercentage = 0.05; // 5%
1422
+ const totalDuration = this.positions[this.positions.length - 1].dateTime.getTime() - this.positions[0].dateTime.getTime();
1423
+ const visibilityPercentage = 0.05;
1427
1424
  const visibilityDuration = totalDuration * visibilityPercentage;
1428
- // Gather positions that fall within the visibility duration.
1429
1425
  const newPosses = [];
1430
1426
  for (let i = 0; i < this.positions.length; i++) {
1431
1427
  const pos = this.positions[i];
1432
- if (!pos.pos3d)
1428
+ if (!pos.pos3d) {
1433
1429
  continue;
1434
- let add = nowDate >= new Date(pos.dateTime.getTime() - visibilityDuration / 2) &&
1435
- nowDate <= new Date(pos.dateTime.getTime() + visibilityDuration / 2);
1436
- // Also include the segment we're currently traversing.
1430
+ }
1431
+ let add = nowDate >= new Date(pos.dateTime.getTime() - visibilityDuration / 2) && nowDate <= new Date(pos.dateTime.getTime() + visibilityDuration / 2);
1437
1432
  if (!add && this.lastDesiredPosIndex > -1 && this.lastDesiredNextIndex > -1) {
1438
1433
  add = i >= this.lastDesiredPosIndex && i <= this.lastDesiredNextIndex;
1439
1434
  }
@@ -1445,11 +1440,7 @@ var CesiumAnimatedProperty;
1445
1440
  this.lastCalcSeriesPos3d = newPosses;
1446
1441
  return newPosses;
1447
1442
  }
1448
- /**
1449
- * Returns the orientation based on current position and heading.
1450
- */
1451
1443
  GetOrient() {
1452
- // Update at 30 fps.
1453
1444
  let doUpdate = this.lastCalcOrientTime == null;
1454
1445
  if (!doUpdate && this.lastCalcOrientTime && (new Date().getTime() - this.lastCalcOrientTime) > 1000 / 30) {
1455
1446
  doUpdate = true;
@@ -1457,26 +1448,34 @@ var CesiumAnimatedProperty;
1457
1448
  if (!doUpdate && this.lastCalcOrient) {
1458
1449
  return this.lastCalcOrient;
1459
1450
  }
1460
- // Default quaternion to return if we can't calculate.
1461
1451
  const defaultQuaternion = new Quaternion();
1462
1452
  if (!this.positions || this.positions.length === 0) {
1463
1453
  return defaultQuaternion;
1464
1454
  }
1465
- // Ensure position is up-to-date.
1466
1455
  const currentPosition = this.GetValue();
1467
1456
  if (!currentPosition) {
1468
1457
  return defaultQuaternion;
1469
1458
  }
1470
- let now = this.viewer.scene.lastRenderTime;
1471
- if (!now) {
1472
- now = this.viewer.clock.currentTime;
1473
- }
1474
- const nowTime = JulianDate.toDate(now).getTime();
1475
1459
  try {
1476
- // Get current position indices.
1460
+ const velocityMagnitude = Cartesian3.magnitude(this.currentVelocity);
1461
+ const minimumSpeedForVelocityOrientation = Math.max(1.0, this.averageSpeed * 0.1);
1462
+ if (velocityMagnitude > minimumSpeedForVelocityOrientation) {
1463
+ const normalizedVelocity = Cartesian3.normalize(this.currentVelocity, new Cartesian3());
1464
+ const rotationMatrix = Transforms.rotationMatrixFromPositionVelocity(currentPosition, normalizedVelocity);
1465
+ const quaternion = Quaternion.fromRotationMatrix(rotationMatrix);
1466
+ const hpr = new HeadingPitchRoll(0, Math$1.toRadians(this.pitch), Math$1.toRadians(this.roll));
1467
+ const pitchRollQuaternion = Quaternion.fromHeadingPitchRoll(hpr);
1468
+ this.lastCalcOrient = Quaternion.multiply(quaternion, pitchRollQuaternion, new Quaternion());
1469
+ this.lastCalcOrientTime = Date.now();
1470
+ return this.lastCalcOrient;
1471
+ }
1472
+ let now = this.viewer.scene.lastRenderTime;
1473
+ if (!now) {
1474
+ now = this.viewer.clock.currentTime;
1475
+ }
1476
+ const nowTime = JulianDate.toDate(now).getTime();
1477
1477
  const lastIndex = this.lastDesiredPosIndex;
1478
1478
  const nextIndex = this.lastDesiredNextIndex;
1479
- // Invalid indices.
1480
1479
  if (lastIndex < 0 || nextIndex < 0 ||
1481
1480
  lastIndex >= this.positions.length || nextIndex >= this.positions.length) {
1482
1481
  return this.lastCalcOrient || defaultQuaternion;
@@ -1486,74 +1485,53 @@ var CesiumAnimatedProperty;
1486
1485
  if (!lastPos || !nextPos) {
1487
1486
  return this.lastCalcOrient || defaultQuaternion;
1488
1487
  }
1489
- // Single position case - use its heading if available.
1490
1488
  if (lastIndex === nextIndex) {
1491
1489
  if (lastPos.heading !== null) {
1492
1490
  this.lastCalcOrient = Transforms.headingPitchRollQuaternion(currentPosition, new HeadingPitchRoll(Math$1.toRadians(lastPos.heading), Math$1.toRadians(this.pitch), Math$1.toRadians(this.roll)));
1493
1491
  this.lastCalcOrientTime = Date.now();
1494
1492
  return this.lastCalcOrient;
1495
1493
  }
1496
- // No heading data and single position, return previous or default.
1497
1494
  return this.lastCalcOrient || defaultQuaternion;
1498
1495
  }
1499
- // Two different positions - we can calculate orientation.
1500
- // Use explicit heading values if available.
1501
1496
  if (lastPos.heading !== null && nextPos.heading !== null) {
1502
- // Calculate interpolated heading.
1503
1497
  let deltaHeading = nextPos.heading - lastPos.heading;
1504
- // Handle wrap-around between 359° and 0°.
1505
1498
  if (deltaHeading > 180) {
1506
1499
  deltaHeading -= 360;
1507
1500
  }
1508
1501
  else if (deltaHeading < -180) {
1509
1502
  deltaHeading += 360;
1510
1503
  }
1511
- // Calculate interpolation factor.
1512
1504
  let factor = 0;
1513
1505
  if (lastPos.dateTime.getTime() !== nextPos.dateTime.getTime()) {
1514
- factor = (nowTime - lastPos.dateTime.getTime()) /
1515
- (nextPos.dateTime.getTime() - lastPos.dateTime.getTime());
1506
+ factor = (nowTime - lastPos.dateTime.getTime()) / (nextPos.dateTime.getTime() - lastPos.dateTime.getTime());
1516
1507
  factor = Math.max(0, Math.min(1, factor));
1517
1508
  }
1518
- // Apply easing for smoother rotation.
1519
1509
  factor = this.easeInOutQuad(factor);
1520
- // Calculate final heading.
1521
1510
  let interpolatedHeading = lastPos.heading + factor * deltaHeading;
1522
1511
  interpolatedHeading = (interpolatedHeading + 360) % 360;
1523
- // Create quaternion from heading, pitch, roll.
1524
1512
  this.lastCalcOrient = Transforms.headingPitchRollQuaternion(currentPosition, new HeadingPitchRoll(Math$1.toRadians(interpolatedHeading), Math$1.toRadians(this.pitch), Math$1.toRadians(this.roll)));
1525
1513
  }
1526
- // Calculate heading from position changes if heading data not available.
1527
1514
  else {
1528
1515
  if (!lastPos.pos3d || !nextPos.pos3d) {
1529
1516
  return this.lastCalcOrient || defaultQuaternion;
1530
1517
  }
1531
- // Flatten positions to avoid altitude-related heading changes.
1532
1518
  const adjustedPointPrev = Cartographic.fromCartesian(lastPos.pos3d);
1533
1519
  const adjustedPos3dPrev = Cartesian3.fromRadians(adjustedPointPrev.longitude, adjustedPointPrev.latitude, 0);
1534
1520
  const adjustedPointNext = Cartographic.fromCartesian(nextPos.pos3d);
1535
1521
  const adjustedPos3dNext = Cartesian3.fromRadians(adjustedPointNext.longitude, adjustedPointNext.latitude, 0);
1536
- // Skip if positions are too close (less than 5cm).
1537
1522
  const distance = Cartesian3.distance(adjustedPos3dPrev, adjustedPos3dNext);
1538
1523
  if (distance < 0.05) {
1539
1524
  return this.lastCalcOrient || defaultQuaternion;
1540
1525
  }
1541
- // Calculate direction vector.
1542
1526
  const direction = Cartesian3.subtract(adjustedPos3dNext, adjustedPos3dPrev, new Cartesian3());
1543
- // Skip if no movement.
1544
1527
  if (direction.x === 0 && direction.y === 0 && direction.z === 0) {
1545
1528
  return this.lastCalcOrient || defaultQuaternion;
1546
1529
  }
1547
- // Normalize the direction vector.
1548
1530
  Cartesian3.normalize(direction, direction);
1549
- // Calculate rotation based on movement direction.
1550
1531
  const rotationMatrix = Transforms.rotationMatrixFromPositionVelocity(currentPosition, direction);
1551
- // Convert to quaternion.
1552
1532
  const quaternion = Quaternion.fromRotationMatrix(rotationMatrix);
1553
- // Add pitch and roll adjustments.
1554
1533
  const hpr = new HeadingPitchRoll(0, Math$1.toRadians(this.pitch), Math$1.toRadians(this.roll));
1555
1534
  const pitchRollQuaternion = Quaternion.fromHeadingPitchRoll(hpr);
1556
- // Combine quaternions.
1557
1535
  this.lastCalcOrient = Quaternion.multiply(quaternion, pitchRollQuaternion, new Quaternion());
1558
1536
  }
1559
1537
  }
@@ -1564,6 +1542,52 @@ var CesiumAnimatedProperty;
1564
1542
  this.lastCalcOrientTime = Date.now();
1565
1543
  return this.lastCalcOrient;
1566
1544
  }
1545
+ GetCurrentVelocity() {
1546
+ return this.currentVelocity ? this.currentVelocity.clone() : new Cartesian3(0, 0, 0);
1547
+ }
1548
+ SupplementSeries(newSeries) {
1549
+ if (!newSeries || newSeries.length === 0) {
1550
+ return;
1551
+ }
1552
+ for (const pos of newSeries) {
1553
+ if (!pos || !pos.pos3d || !pos.dateTime) {
1554
+ continue;
1555
+ }
1556
+ const existingIndex = this.positions.findIndex(p => p.dateTime.getTime() === pos.dateTime.getTime());
1557
+ if (existingIndex >= 0) {
1558
+ this.positions[existingIndex] = pos;
1559
+ }
1560
+ else {
1561
+ this.AddPosition(pos);
1562
+ }
1563
+ }
1564
+ }
1565
+ UpdatePositionForDateTime(pos3d, dateTime, heading) {
1566
+ if (!pos3d || !dateTime) {
1567
+ return;
1568
+ }
1569
+ const existingIndex = this.positions.findIndex(p => p.dateTime.getTime() === dateTime.getTime());
1570
+ const newPos = {
1571
+ pos3d: pos3d,
1572
+ dateTime: dateTime,
1573
+ heading: heading !== undefined ? heading : null
1574
+ };
1575
+ if (existingIndex >= 0) {
1576
+ this.positions[existingIndex] = newPos;
1577
+ this.processHeadings();
1578
+ this.sortPositions();
1579
+ this.invalidateCache();
1580
+ }
1581
+ else {
1582
+ this.AddPosition(newPos);
1583
+ }
1584
+ }
1585
+ HasPositionForDateTime(dateTime) {
1586
+ return this.positions.some(p => p.dateTime.getTime() === dateTime.getTime());
1587
+ }
1588
+ GetPositionCount() {
1589
+ return this.positions.length;
1590
+ }
1567
1591
  }
1568
1592
  CesiumAnimatedProperty.AnimatePositionSeries = AnimatePositionSeries;
1569
1593
  function GetSeriesPossesForHistoricEntity(viewer, dataHeightRef, heightRef, historic) {
@@ -5446,7 +5470,7 @@ var EntityRenderEnginePoint;
5446
5470
  * @returns
5447
5471
  */
5448
5472
  async function Render(params) {
5449
- var _a, _b, _c, _d;
5473
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
5450
5474
  const entity = params.entity;
5451
5475
  if (!params.entityHistoric) {
5452
5476
  params.entityHistoric = [];
@@ -5647,39 +5671,69 @@ var EntityRenderEnginePoint;
5647
5671
  // Unset width/height.
5648
5672
  cEntity.billboard.width = undefined;
5649
5673
  cEntity.billboard.height = undefined;
5674
+ const pos3d = EntityUtils.GetPos({
5675
+ viewer: params.viewer,
5676
+ entity,
5677
+ recordHeightRef: heightRef,
5678
+ returnHeightRef: heightRef,
5679
+ allowRendered: false
5680
+ });
5650
5681
  const prevPos3d = GetCValue(params.viewer, cEntity.position);
5651
- let prevStartTime = null;
5652
5682
  if (cEntity.position && cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"]) {
5653
- prevStartTime = cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"].GetAnimateFromDateTime();
5654
- }
5655
- // If we have a series of time-based positions then we'll animate as time changes.
5656
- const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
5657
- if (series.length > 1) {
5658
- animatePosition = new CesiumAnimatedProperty.AnimatePositionSeries({
5659
- posses: series,
5660
- viewer: params.viewer,
5661
- animateFromPos3d: prevPos3d,
5662
- animateFromPos3dTimeStart: prevStartTime
5663
- });
5664
- cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
5665
- cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"] = animatePosition;
5683
+ animatePosition = cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"];
5684
+ const animateSeries = animatePosition;
5685
+ const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
5686
+ if (series.length) {
5687
+ animateSeries.SupplementSeries(series);
5688
+ }
5689
+ const dateTimeStr = (_d = (_c = entity.Bruce.Outline) === null || _c === void 0 ? void 0 : _c.find(x => !!x.DateTime)) === null || _d === void 0 ? void 0 : _d.DateTime;
5690
+ const dateTime = dateTimeStr ? new Date(dateTimeStr) : null;
5691
+ if (dateTime) {
5692
+ animateSeries.UpdatePositionForDateTime(pos3d, dateTime);
5693
+ }
5694
+ // We don't have a date-stamped incoming position.
5695
+ if (!dateTime && !series.length) {
5696
+ animatePosition = null;
5697
+ }
5666
5698
  }
5667
- else {
5668
- const pos3d = EntityUtils.GetPos({
5669
- viewer: params.viewer,
5670
- entity,
5671
- recordHeightRef: heightRef,
5672
- returnHeightRef: heightRef,
5673
- allowRendered: false
5674
- });
5675
- if (!prevPos3d || !Cartesian3.equals(prevPos3d, pos3d)) {
5676
- animatePosition = new CesiumAnimatedProperty.AnimatePosition({
5677
- durationMs: 200,
5678
- targetPos3d: pos3d,
5679
- viewer: params.viewer,
5680
- startPos3d: prevPos3d
5699
+ if (!animatePosition) {
5700
+ // If we've loaded a set of series positions then we'll animate through them.
5701
+ const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
5702
+ if (series.length > 1) {
5703
+ animatePosition = new CesiumAnimatedProperty.AnimatePositionSeries({
5704
+ posses: series,
5705
+ viewer: params.viewer
5681
5706
  });
5682
5707
  cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
5708
+ cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"] = animatePosition;
5709
+ }
5710
+ else {
5711
+ const dateTimeStr = (_f = (_e = entity.Bruce.Outline) === null || _e === void 0 ? void 0 : _e.find(x => !!x.DateTime)) === null || _f === void 0 ? void 0 : _f.DateTime;
5712
+ const dateTime = dateTimeStr ? new Date(dateTimeStr) : null;
5713
+ const posChanged = !prevPos3d || !Cartesian3.equals(prevPos3d, pos3d);
5714
+ if (posChanged) {
5715
+ let posses = [];
5716
+ const isLive = ViewUtils.GetTimeDetails({ viewer: params.viewer }).isLive;
5717
+ if (prevPos3d && isLive) {
5718
+ posses.push({
5719
+ pos3d: prevPos3d,
5720
+ // Guess so that we can determine a direction of movement right away :)
5721
+ dateTime: new Date(dateTime.getTime() - 1000),
5722
+ heading: null
5723
+ });
5724
+ }
5725
+ posses.push({
5726
+ pos3d: pos3d,
5727
+ dateTime: dateTime,
5728
+ heading: null
5729
+ });
5730
+ animatePosition = new CesiumAnimatedProperty.AnimatePositionSeries({
5731
+ posses: posses,
5732
+ viewer: params.viewer
5733
+ });
5734
+ cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
5735
+ cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"] = animatePosition;
5736
+ }
5683
5737
  }
5684
5738
  }
5685
5739
  // We'll use "SetDefaultColor" to updating the internal reference and to allow for an animation.
@@ -5978,39 +6032,52 @@ var EntityRenderEnginePoint;
5978
6032
  cEntity.billboard.heightReference = new ConstantProperty(heightRef);
5979
6033
  cEntity.billboard.distanceDisplayCondition = new ConstantProperty(EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance));
5980
6034
  cEntity.billboard.disableDepthTestDistance = new ConstantProperty(disableDepthTest ? Number.POSITIVE_INFINITY : undefined);
6035
+ const pos3d = EntityUtils.GetPos({
6036
+ viewer: params.viewer,
6037
+ entity,
6038
+ recordHeightRef: heightRef,
6039
+ returnHeightRef: heightRef,
6040
+ allowRendered: false
6041
+ });
5981
6042
  const prevPos3d = GetCValue(params.viewer, cEntity.position);
5982
- let prevStartTime = null;
5983
6043
  if (cEntity.position && cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"]) {
5984
- prevStartTime = cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"].GetAnimateFromDateTime();
5985
- }
5986
- // If we have a series of time-based positions then we'll animate as time changes.
5987
- const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
5988
- if (series.length > 1) {
5989
- animatePosition = new CesiumAnimatedProperty.AnimatePositionSeries({
5990
- posses: series,
5991
- viewer: params.viewer,
5992
- animateFromPos3d: prevPos3d,
5993
- animateFromPos3dTimeStart: prevStartTime
5994
- });
5995
- cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
5996
- cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"] = animatePosition;
5997
- }
5998
- else {
5999
- const pos3d = EntityUtils.GetPos({
6000
- viewer: params.viewer,
6001
- entity,
6002
- recordHeightRef: heightRef,
6003
- returnHeightRef: heightRef,
6004
- allowRendered: false
6005
- });
6006
- if (!prevPos3d || !Cartesian3.equals(prevPos3d, pos3d)) {
6007
- animatePosition = new CesiumAnimatedProperty.AnimatePosition({
6008
- durationMs: 200,
6009
- targetPos3d: pos3d,
6010
- viewer: params.viewer,
6011
- startPos3d: prevPos3d
6044
+ animatePosition = cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"];
6045
+ const animateSeries = animatePosition;
6046
+ const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
6047
+ if (series.length) {
6048
+ animateSeries.SupplementSeries(series);
6049
+ }
6050
+ const dateTimeStr = (_h = (_g = entity.Bruce.Outline) === null || _g === void 0 ? void 0 : _g.find(x => !!x.DateTime)) === null || _h === void 0 ? void 0 : _h.DateTime;
6051
+ const dateTime = dateTimeStr ? new Date(dateTimeStr) : null;
6052
+ if (dateTime) {
6053
+ animateSeries.UpdatePositionForDateTime(pos3d, dateTime);
6054
+ }
6055
+ // We don't have a date-stamped incoming position.
6056
+ if (!dateTime && !series.length) {
6057
+ animatePosition = null;
6058
+ }
6059
+ }
6060
+ if (!animatePosition) {
6061
+ // If we have a series of time-based positions then we'll animate as time changes.
6062
+ const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
6063
+ if (series.length > 1) {
6064
+ animatePosition = new CesiumAnimatedProperty.AnimatePositionSeries({
6065
+ posses: series,
6066
+ viewer: params.viewer
6012
6067
  });
6013
6068
  cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
6069
+ cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"] = animatePosition;
6070
+ }
6071
+ else {
6072
+ if (!prevPos3d || !Cartesian3.equals(prevPos3d, pos3d)) {
6073
+ animatePosition = new CesiumAnimatedProperty.AnimatePosition({
6074
+ durationMs: 200,
6075
+ targetPos3d: pos3d,
6076
+ viewer: params.viewer,
6077
+ startPos3d: prevPos3d
6078
+ });
6079
+ cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
6080
+ }
6014
6081
  }
6015
6082
  }
6016
6083
  // We'll use "SetDefaultColor" to updating the internal reference and to allow for an animation.
@@ -6029,7 +6096,7 @@ var EntityRenderEnginePoint;
6029
6096
  // Generate a polyline 'track' for the historic data.
6030
6097
  // We do this for historic data that exists and is moving.
6031
6098
  if (shouldShowTrack && animatePosition && animatePosition instanceof CesiumAnimatedProperty.AnimatePositionSeries && animatePosition.GetSeries) {
6032
- const lStyle = (_d = (_c = params.fullStyle) === null || _c === void 0 ? void 0 : _c.polylineStyle) !== null && _d !== void 0 ? _d : {};
6099
+ const lStyle = (_k = (_j = params.fullStyle) === null || _j === void 0 ? void 0 : _j.polylineStyle) !== null && _k !== void 0 ? _k : {};
6033
6100
  const bColor = lStyle.lineColor ? Calculator.GetColor(lStyle.lineColor, entity, params.tags) : null;
6034
6101
  const cColor = bColor ? ColorToCColor(bColor) : Color.fromCssColorString("rgba(255, 193, 7, 0.8)");
6035
6102
  let width = lStyle.lineWidth ? EnsureNumber(Calculator.GetNumber(lStyle.lineWidth, entity, params.tags)) : 2;
@@ -7049,7 +7116,7 @@ var EntityRenderEngineModel3d;
7049
7116
  * @returns
7050
7117
  */
7051
7118
  function Render(params) {
7052
- var _a, _b, _c, _d;
7119
+ var _a, _b, _c, _d, _e, _f;
7053
7120
  const entity = params.entity;
7054
7121
  if (!params.entityHistoric) {
7055
7122
  params.entityHistoric = [];
@@ -7241,40 +7308,41 @@ var EntityRenderEngineModel3d;
7241
7308
  cEntity.model.colorBlendAmount = new ConstantProperty(blendAmount);
7242
7309
  cEntity.model.colorBlendMode = new ConstantProperty(blendMode);
7243
7310
  cEntity.model.distanceDisplayCondition = new ConstantProperty(EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance));
7244
- let prevStartTime = null;
7245
7311
  if (cEntity.position && cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"]) {
7246
- prevStartTime = cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"].GetAnimateFromDateTime();
7247
- }
7248
- // If we've loaded a set of series positions then we'll animate through them.
7249
- const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
7250
- if (series.length > 1) {
7251
- animatePosition = new CesiumAnimatedProperty.AnimatePositionSeries({
7252
- posses: series,
7253
- viewer: params.viewer,
7254
- pitch: pitch,
7255
- roll: roll,
7256
- animateFromPos3d: prevPos3d,
7257
- animateFromPos3dTimeStart: prevStartTime
7258
- });
7259
- cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
7260
- cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"] = animatePosition;
7261
- }
7262
- else {
7312
+ animatePosition = cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"];
7313
+ const animateSeries = animatePosition;
7314
+ const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
7315
+ if (series.length) {
7316
+ animateSeries.SupplementSeries(series);
7317
+ }
7263
7318
  const dateTimeStr = (_b = (_a = entity.Bruce.Outline) === null || _a === void 0 ? void 0 : _a.find(x => !!x.DateTime)) === null || _b === void 0 ? void 0 : _b.DateTime;
7264
7319
  const dateTime = dateTimeStr ? new Date(dateTimeStr) : null;
7265
- const posChanged = !prevPos3d || !Cartesian3.equals(prevPos3d, pos3d);
7266
- if (posChanged) {
7267
- if (cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"]) {
7268
- const prevAnimatePosition = cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"];
7269
- animatePosition = prevAnimatePosition;
7270
- animatePosition.AddPosition({
7271
- pos3d: pos3d,
7272
- dateTime: dateTime,
7273
- heading: !EnsureNumber(transform === null || transform === void 0 ? void 0 : transform.heading) ? null : heading
7274
- });
7275
- animatePosition.UpdatePitchRoll(pitch, roll);
7276
- }
7277
- else {
7320
+ if (dateTime) {
7321
+ animateSeries.UpdatePositionForDateTime(pos3d, dateTime, !EnsureNumber(transform === null || transform === void 0 ? void 0 : transform.heading) ? null : heading);
7322
+ }
7323
+ // We don't have a date-stamped incoming position.
7324
+ if (!dateTime && !series.length) {
7325
+ animatePosition = null;
7326
+ }
7327
+ }
7328
+ if (!animatePosition) {
7329
+ // If we've loaded a set of series positions then we'll animate through them.
7330
+ const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
7331
+ if (series.length > 1) {
7332
+ animatePosition = new CesiumAnimatedProperty.AnimatePositionSeries({
7333
+ posses: series,
7334
+ viewer: params.viewer,
7335
+ pitch: pitch,
7336
+ roll: roll
7337
+ });
7338
+ cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
7339
+ cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"] = animatePosition;
7340
+ }
7341
+ else {
7342
+ const dateTimeStr = (_d = (_c = entity.Bruce.Outline) === null || _c === void 0 ? void 0 : _c.find(x => !!x.DateTime)) === null || _d === void 0 ? void 0 : _d.DateTime;
7343
+ const dateTime = dateTimeStr ? new Date(dateTimeStr) : null;
7344
+ const posChanged = !prevPos3d || !Cartesian3.equals(prevPos3d, pos3d);
7345
+ if (posChanged) {
7278
7346
  let posses = [];
7279
7347
  const isLive = ViewUtils.GetTimeDetails({ viewer: params.viewer }).isLive;
7280
7348
  if (prevPos3d && isLive) {
@@ -7294,9 +7362,7 @@ var EntityRenderEngineModel3d;
7294
7362
  posses: posses,
7295
7363
  viewer: params.viewer,
7296
7364
  pitch: pitch,
7297
- roll: roll,
7298
- animateFromPos3d: prevPos3d && !isLive ? prevPos3d : null,
7299
- animateFromPos3dTimeStart: null
7365
+ roll: roll
7300
7366
  });
7301
7367
  cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
7302
7368
  cEntity.position["CesiumAnimatedProperty.AnimatePositionSeries"] = animatePosition;
@@ -7449,7 +7515,7 @@ var EntityRenderEngineModel3d;
7449
7515
  // Generate a polyline 'track' for the historic data.
7450
7516
  // We do this for historic data that exists and is moving.
7451
7517
  if (shouldShowTrack && animatePosition && animatePosition instanceof CesiumAnimatedProperty.AnimatePositionSeries && animatePosition.GetSeries) {
7452
- const lStyle = (_d = (_c = params.fullStyle) === null || _c === void 0 ? void 0 : _c.polylineStyle) !== null && _d !== void 0 ? _d : {};
7518
+ const lStyle = (_f = (_e = params.fullStyle) === null || _e === void 0 ? void 0 : _e.polylineStyle) !== null && _f !== void 0 ? _f : {};
7453
7519
  const bColor = lStyle.lineColor ? Calculator.GetColor(lStyle.lineColor, entity, params.tags) : null;
7454
7520
  const cColor = bColor ? ColorToCColor(bColor) : Color.fromCssColorString("rgba(255, 193, 7, 0.8)");
7455
7521
  let width = lStyle.lineWidth ? EnsureNumber(Calculator.GetNumber(lStyle.lineWidth, entity, params.tags)) : 2;
@@ -33243,7 +33309,7 @@ class WidgetViewBar extends Widget.AWidget {
33243
33309
  }
33244
33310
  }
33245
33311
 
33246
- const VERSION = "5.9.6";
33312
+ const VERSION = "5.9.8";
33247
33313
 
33248
33314
  export { VERSION, CesiumViewMonitor, ViewerUtils, ViewerEventTracker, MenuItemManager, isOutlineChanged, EntityRenderEngine, EntityRenderEnginePoint, EntityRenderEnginePolyline, EntityRenderEnginePolygon, EntityRenderEngineModel3d, MenuItemCreator, VisualsRegister, RenderManager, EntitiesIdsRenderManager, DataLabRenderManager, EntitiesLoadedRenderManager, EntitiesRenderManager, EntityRenderManager, TilesetCadRenderManager, TilesetArbRenderManager, TilesetEntitiesRenderManager, TilesetOsmRenderManager, TilesetPointcloudRenderManager, TilesetGooglePhotosRenderManager, DataSourceStaticKmlManager, GoogleSearchRenderManager, AssemblyRenderManager, RelationsRenderManager, SharedGetters, CesiumParabola, EntityLabel, ViewRenderEngine, TileRenderEngine, TilesetRenderEngine, CESIUM_INSPECTOR_KEY, CESIUM_TIMELINE_KEY, CESIUM_TIMELINE_LIVE_KEY, CESIUM_TIMELINE_LIVE_PADDING_KEY, CESIUM_TIMELINE_INTERVAL_KEY, DEFAULT_LIVE_PADDING_SECONDS, ViewUtils, DrawingUtils, MeasureUtils, EntityUtils, CesiumEntityStyler, CesiumAnimatedProperty, CesiumAnimatedInOut, Draw3dPolygon, Draw3dPolyline, MeasureCreator, Walkthrough, Widget, VIEWER_BOOKMARKS_WIDGET_KEY, WidgetBookmarks, WidgetBranding, WidgetCursorBar, WidgetEmbeddedInfoView, WidgetInfoView, WidgetNavCompass$$1 as WidgetNavCompass, VIEWER_VIEW_BAR_WIDGET_KEY, WidgetViewBar, WidgetControlViewBar, WidgetControlViewBarSearch, VIEWER_LEFT_PANEL_WIDGET_KEY, VIEWER_LEFT_PANEL_CSS_VAR_LEFT, WidgetLeftPanel, WidgetLeftPanelTab, WidgetLeftPanelTabBookmarks };
33249
33315
  //# sourceMappingURL=bruce-cesium.es5.js.map