bruce-cesium 5.4.5 → 5.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bruce-cesium.es5.js +2053 -1939
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +2052 -1938
- package/dist/bruce-cesium.umd.js.map +1 -1
- package/dist/lib/bruce-cesium.js +1 -1
- package/dist/lib/rendering/cesium-animated-property.js +152 -39
- package/dist/lib/rendering/cesium-animated-property.js.map +1 -1
- package/dist/lib/rendering/entity-gatherer.js +327 -0
- package/dist/lib/rendering/entity-gatherer.js.map +1 -0
- package/dist/lib/rendering/entity-render-engine-model3d.js +3 -2
- package/dist/lib/rendering/entity-render-engine-model3d.js.map +1 -1
- package/dist/lib/rendering/entity-render-engine-point.js +6 -4
- package/dist/lib/rendering/entity-render-engine-point.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entities-ids-render-manager.js +38 -28
- package/dist/lib/rendering/render-managers/entities/entities-ids-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-arb-render-manager.js +6 -2
- package/dist/lib/rendering/render-managers/tilesets/tileset-arb-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-cad-render-manager.js +37 -34
- package/dist/lib/rendering/render-managers/tilesets/tileset-cad-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js +6 -2
- package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js.map +1 -1
- package/dist/lib/rendering/tileset-render-engine.js +5 -899
- package/dist/lib/rendering/tileset-render-engine.js.map +1 -1
- package/dist/lib/rendering/tileset-styler.js +555 -0
- package/dist/lib/rendering/tileset-styler.js.map +1 -0
- package/dist/types/bruce-cesium.d.ts +1 -1
- package/dist/types/rendering/cesium-animated-property.d.ts +18 -0
- package/dist/types/rendering/entity-gatherer.d.ts +36 -0
- package/dist/types/rendering/render-managers/entities/entities-ids-render-manager.d.ts +0 -2
- package/dist/types/rendering/render-managers/tilesets/tileset-cad-render-manager.d.ts +0 -2
- package/dist/types/rendering/tileset-render-engine.d.ts +3 -99
- package/dist/types/rendering/tileset-styler.d.ts +80 -0
- package/package.json +1 -1
package/dist/bruce-cesium.es5.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BruceEvent, Cartes, Entity as Entity$1, Carto, Geometry, MathUtils, LRUCache, Api, Calculator, ClientFile, EntityTag, EntityType, ObjectUtils, Style, ProjectViewTile, 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';
|
|
2
2
|
import * as Cesium from 'cesium';
|
|
3
|
-
import { Cartographic, Cartesian2, Math as Math$1, Cartesian3, CallbackProperty, Color, HeightReference, Rectangle, JulianDate, Entity, DistanceDisplayCondition,
|
|
3
|
+
import { Cartographic, Cartesian2, Math as Math$1, Cartesian3, CallbackProperty, Color, HeightReference, Rectangle, JulianDate, Entity, DistanceDisplayCondition, ClassificationType, ArcType, CornerType, ShadowMode, ConstantProperty, ConstantPositionProperty, PolygonHierarchy, PolylineGraphics, ColorMaterialProperty, HorizontalOrigin, VerticalOrigin, ColorBlendMode, HeadingPitchRoll, Transforms, Model, Primitive, Cesium3DTileFeature, SceneMode, GeoJsonDataSource, Cesium3DTileStyle, HeadingPitchRange, Ion, Cesium3DTileColorBlendMode, KmlDataSource, OrthographicFrustum, EasingFunction, NearFarScalar, SceneTransforms, Cesium3DTileset, Matrix4, Matrix3, IonResource, EllipsoidTerrainProvider, CesiumInspector, defined, ClockRange, EllipsoidGeodesic, sampleTerrainMostDetailed, PolygonPipeline, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, BoundingSphere, GeometryInstance, Quaternion, ScreenSpaceEventHandler, ScreenSpaceEventType, CzmlDataSource, Intersect, Fullscreen } from 'cesium';
|
|
4
4
|
|
|
5
5
|
const TIME_LAG = 300;
|
|
6
6
|
const POSITION_CHECK_TIMER = 950;
|
|
@@ -1152,10 +1152,15 @@ var CesiumAnimatedProperty;
|
|
|
1152
1152
|
this.lastCalcSeriesTime = null;
|
|
1153
1153
|
this.lastCalcOrient = null;
|
|
1154
1154
|
this.lastCalcOrientTime = null;
|
|
1155
|
+
// Indicates that the first time we get a GetValue position, we need to animate into it.
|
|
1156
|
+
this.animateFromPos3d = null;
|
|
1157
|
+
this.animateFromPos3dTimeStart = null;
|
|
1155
1158
|
this.viewer = params.viewer;
|
|
1156
1159
|
this.positions = params.posses;
|
|
1157
1160
|
this.pitch = params.pitch;
|
|
1158
1161
|
this.roll = params.roll;
|
|
1162
|
+
this.animateFromPos3d = params.animateFromPos3d;
|
|
1163
|
+
this.animateFromPos3dTimeStart = Date.now();
|
|
1159
1164
|
this.processHeadings();
|
|
1160
1165
|
// Order positions by date.
|
|
1161
1166
|
this.positions.sort((a, b) => {
|
|
@@ -1189,19 +1194,28 @@ var CesiumAnimatedProperty;
|
|
|
1189
1194
|
if (!now) {
|
|
1190
1195
|
now = this.viewer.clock.currentTime;
|
|
1191
1196
|
}
|
|
1192
|
-
const
|
|
1193
|
-
if
|
|
1197
|
+
const nowTimeMs = JulianDate.toDate(now).getTime();
|
|
1198
|
+
// Skip calculation if time hasn't changed.
|
|
1199
|
+
if (this.lastCalcTime === nowTimeMs) {
|
|
1200
|
+
if (this.animateFromPos3d) {
|
|
1201
|
+
// We emit an interpolated position if we're animating from the start position.
|
|
1202
|
+
const interpolatedPos = this.interpolateToStartPos3d(this.animateFromPos3dTimeStart, Date.now());
|
|
1203
|
+
if (Cartesian3.equals(interpolatedPos, this.animateFromPos3d)) {
|
|
1204
|
+
this.animateFromPos3d = null;
|
|
1205
|
+
}
|
|
1206
|
+
return interpolatedPos;
|
|
1207
|
+
}
|
|
1194
1208
|
return this.lastCalcPos3d;
|
|
1195
1209
|
}
|
|
1196
1210
|
const calculate = () => {
|
|
1197
1211
|
// See if we're before the first position.
|
|
1198
|
-
if (
|
|
1212
|
+
if (nowTimeMs <= this.positions[0].dateTime.getTime()) {
|
|
1199
1213
|
this.lastCalcPosIndexLast = 0;
|
|
1200
1214
|
this.lastCalcPosIndexNext = 0;
|
|
1201
1215
|
return this.positions[0].pos3d;
|
|
1202
1216
|
}
|
|
1203
1217
|
// See if we're after the last position.
|
|
1204
|
-
if (
|
|
1218
|
+
if (nowTimeMs >= this.positions[this.positions.length - 1].dateTime.getTime()) {
|
|
1205
1219
|
this.lastCalcPosIndexLast = this.positions.length - 1;
|
|
1206
1220
|
this.lastCalcPosIndexNext = this.positions.length - 1;
|
|
1207
1221
|
return this.positions[this.positions.length - 1].pos3d;
|
|
@@ -1210,7 +1224,7 @@ var CesiumAnimatedProperty;
|
|
|
1210
1224
|
let lastIndex = 0;
|
|
1211
1225
|
for (let i = 1; i < this.positions.length; i++) {
|
|
1212
1226
|
let pos = this.positions[i];
|
|
1213
|
-
if (
|
|
1227
|
+
if (nowTimeMs >= pos.dateTime.getTime()) {
|
|
1214
1228
|
lastIndex = i;
|
|
1215
1229
|
}
|
|
1216
1230
|
else {
|
|
@@ -1226,12 +1240,43 @@ var CesiumAnimatedProperty;
|
|
|
1226
1240
|
return last.pos3d;
|
|
1227
1241
|
}
|
|
1228
1242
|
this.lastCalcPosIndexNext = lastIndex + 1;
|
|
1229
|
-
let progress = (
|
|
1243
|
+
let progress = (nowTimeMs - last.dateTime.getTime()) / (next.dateTime.getTime() - last.dateTime.getTime());
|
|
1230
1244
|
return Cartesian3.lerp(last.pos3d, next.pos3d, progress, new Cartesian3());
|
|
1231
1245
|
};
|
|
1232
|
-
this.lastCalcTime =
|
|
1246
|
+
this.lastCalcTime = nowTimeMs;
|
|
1233
1247
|
this.lastCalcPos3d = calculate();
|
|
1234
|
-
|
|
1248
|
+
let pos3d = this.lastCalcPos3d;
|
|
1249
|
+
// We emit an interpolated position if we're animating from the start position.
|
|
1250
|
+
if (this.animateFromPos3d && Cartes.ValidateCartes3(this.lastCalcPos3d)) {
|
|
1251
|
+
if (Cartesian3.equals(this.animateFromPos3d, this.lastCalcPos3d)) {
|
|
1252
|
+
this.animateFromPos3d = null;
|
|
1253
|
+
}
|
|
1254
|
+
else if (this.animateFromPos3d) {
|
|
1255
|
+
pos3d = this.interpolateToStartPos3d(this.animateFromPos3dTimeStart, Date.now());
|
|
1256
|
+
if (Cartesian3.equals(pos3d, this.animateFromPos3d)) {
|
|
1257
|
+
this.animateFromPos3d = null;
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
return pos3d;
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Interpolates between the start position and the last calculated position.
|
|
1265
|
+
* This lets us animate in the series positions.
|
|
1266
|
+
* @param nowMs
|
|
1267
|
+
*/
|
|
1268
|
+
interpolateToStartPos3d(startMs, nowMs) {
|
|
1269
|
+
const startPos = this.animateFromPos3d;
|
|
1270
|
+
const targetPos = this.lastCalcPos3d;
|
|
1271
|
+
if (!startPos || !targetPos) {
|
|
1272
|
+
return startPos ? startPos : targetPos;
|
|
1273
|
+
}
|
|
1274
|
+
const duration = nowMs - startMs;
|
|
1275
|
+
let progress = duration / 300; // 300ms duration.
|
|
1276
|
+
if (progress > 1) {
|
|
1277
|
+
progress = 1;
|
|
1278
|
+
}
|
|
1279
|
+
return Cartesian3.lerp(startPos, targetPos, progress, new Cartesian3());
|
|
1235
1280
|
}
|
|
1236
1281
|
/**
|
|
1237
1282
|
* Returns a series of positions to use for rendering the path.
|
|
@@ -1414,6 +1459,9 @@ var CesiumAnimatedProperty;
|
|
|
1414
1459
|
// Cache for calculated values.
|
|
1415
1460
|
this.lastCalcTime = null;
|
|
1416
1461
|
this.lastCalcPos3d = null;
|
|
1462
|
+
this.lastCalcPosApplyOverTime = false;
|
|
1463
|
+
this.lastCalcPos3dApplyOverTimeTarget = null;
|
|
1464
|
+
this.lastCalcPos3dApplyOverTimeTimeStart = null;
|
|
1417
1465
|
this.lastCalcHeading = null;
|
|
1418
1466
|
this.removal = null;
|
|
1419
1467
|
// Track the timeline range for which we have data.
|
|
@@ -1511,17 +1559,75 @@ var CesiumAnimatedProperty;
|
|
|
1511
1559
|
const nowTimeMs = nowTime.getTime();
|
|
1512
1560
|
// Skip calculation if time hasn't changed.
|
|
1513
1561
|
if (this.lastCalcTime === nowTimeMs) {
|
|
1562
|
+
// If we're currently mid-animation, we need to update the position over time.
|
|
1563
|
+
if (this.lastCalcPosApplyOverTime) {
|
|
1564
|
+
const interpolatedPos = this.interpolatePos3dOverTime(this.lastCalcPos3dApplyOverTimeTimeStart, Date.now());
|
|
1565
|
+
if (Cartesian3.equals(interpolatedPos, this.lastCalcPos3dApplyOverTimeTarget)) {
|
|
1566
|
+
this.lastCalcPosApplyOverTime = false;
|
|
1567
|
+
this.lastCalcPos3d = interpolatedPos;
|
|
1568
|
+
}
|
|
1569
|
+
this.onUpdate(interpolatedPos, this.lastCalcHeading);
|
|
1570
|
+
}
|
|
1514
1571
|
return;
|
|
1515
1572
|
}
|
|
1516
1573
|
// Calculate position.
|
|
1517
1574
|
const position = this.calculatePosition(nowTimeMs);
|
|
1575
|
+
// Calculate what position to emit.
|
|
1576
|
+
let pos3d = null;
|
|
1518
1577
|
// Update cache values.
|
|
1519
1578
|
this.lastCalcTime = nowTimeMs;
|
|
1520
|
-
this.lastCalcPos3d
|
|
1579
|
+
if (position.applyOverTime && Cartes.ValidateCartes3(this.lastCalcPos3d)) {
|
|
1580
|
+
if (Cartesian3.equals(this.lastCalcPos3d, position.pos3d)) {
|
|
1581
|
+
pos3d = position.pos3d;
|
|
1582
|
+
this.lastCalcPosApplyOverTime = false;
|
|
1583
|
+
}
|
|
1584
|
+
else if (Cartesian3.equals(this.lastCalcPos3dApplyOverTimeTarget, position.pos3d)) {
|
|
1585
|
+
pos3d = this.interpolatePos3dOverTime(this.lastCalcPos3dApplyOverTimeTimeStart, Date.now());
|
|
1586
|
+
if (Cartesian3.equals(pos3d, this.lastCalcPos3dApplyOverTimeTarget)) {
|
|
1587
|
+
this.lastCalcPos3d = pos3d;
|
|
1588
|
+
this.lastCalcPosApplyOverTime = false;
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
else {
|
|
1592
|
+
if (!this.lastCalcPosApplyOverTime) {
|
|
1593
|
+
this.lastCalcPos3dApplyOverTimeTimeStart = Date.now();
|
|
1594
|
+
}
|
|
1595
|
+
this.lastCalcPosApplyOverTime = true;
|
|
1596
|
+
this.lastCalcPos3dApplyOverTimeTarget = position.pos3d;
|
|
1597
|
+
pos3d = this.interpolatePos3dOverTime(this.lastCalcPos3dApplyOverTimeTimeStart, Date.now());
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
else {
|
|
1601
|
+
this.lastCalcPos3d = position.pos3d;
|
|
1602
|
+
pos3d = position.pos3d;
|
|
1603
|
+
}
|
|
1521
1604
|
// Calculate heading.
|
|
1522
|
-
|
|
1605
|
+
const posses = this.positions;
|
|
1606
|
+
const lastPos = posses[position.indexLast];
|
|
1607
|
+
const nextPos = posses[position.indexNext];
|
|
1608
|
+
if (lastPos && nextPos) {
|
|
1609
|
+
this.lastCalcHeading = this.calculateHeading(nowTimeMs, lastPos, nextPos);
|
|
1610
|
+
}
|
|
1523
1611
|
// Provide the calculated values to the caller.
|
|
1524
|
-
this.onUpdate(
|
|
1612
|
+
this.onUpdate(pos3d, this.lastCalcHeading);
|
|
1613
|
+
}
|
|
1614
|
+
/**
|
|
1615
|
+
* Interpolates the position over time between the last and target positions.
|
|
1616
|
+
* This is used when we reach a boundary position so to smoothly animate to it, we move from the current position to it.
|
|
1617
|
+
* @param nowMs
|
|
1618
|
+
*/
|
|
1619
|
+
interpolatePos3dOverTime(prevMs, nowMs) {
|
|
1620
|
+
const lastPos = this.lastCalcPos3d;
|
|
1621
|
+
const targetPos = this.lastCalcPos3dApplyOverTimeTarget;
|
|
1622
|
+
if (!lastPos || !targetPos) {
|
|
1623
|
+
return lastPos ? lastPos : targetPos;
|
|
1624
|
+
}
|
|
1625
|
+
const duration = nowMs - prevMs;
|
|
1626
|
+
let progress = duration / 300; // 300ms duration.
|
|
1627
|
+
if (progress > 1) {
|
|
1628
|
+
progress = 1;
|
|
1629
|
+
}
|
|
1630
|
+
return Cartesian3.lerp(lastPos, targetPos, progress, new Cartesian3());
|
|
1525
1631
|
}
|
|
1526
1632
|
/**
|
|
1527
1633
|
* Pre-process headings in the series.
|
|
@@ -1553,7 +1659,8 @@ var CesiumAnimatedProperty;
|
|
|
1553
1659
|
return {
|
|
1554
1660
|
pos3d: new Cartesian3(),
|
|
1555
1661
|
indexLast: -1,
|
|
1556
|
-
indexNext: -1
|
|
1662
|
+
indexNext: -1,
|
|
1663
|
+
applyOverTime: false
|
|
1557
1664
|
};
|
|
1558
1665
|
}
|
|
1559
1666
|
// See if we're before the first position.
|
|
@@ -1561,7 +1668,8 @@ var CesiumAnimatedProperty;
|
|
|
1561
1668
|
return {
|
|
1562
1669
|
pos3d: posses[0].pos3d,
|
|
1563
1670
|
indexLast: 0,
|
|
1564
|
-
indexNext: 0
|
|
1671
|
+
indexNext: 0,
|
|
1672
|
+
applyOverTime: true
|
|
1565
1673
|
};
|
|
1566
1674
|
}
|
|
1567
1675
|
// See if we're after the last position.
|
|
@@ -1570,7 +1678,8 @@ var CesiumAnimatedProperty;
|
|
|
1570
1678
|
return {
|
|
1571
1679
|
pos3d: posses[lastIndex].pos3d,
|
|
1572
1680
|
indexLast: lastIndex,
|
|
1573
|
-
indexNext: lastIndex
|
|
1681
|
+
indexNext: lastIndex,
|
|
1682
|
+
applyOverTime: true
|
|
1574
1683
|
};
|
|
1575
1684
|
}
|
|
1576
1685
|
// Binary search to find the closest position.
|
|
@@ -1596,7 +1705,8 @@ var CesiumAnimatedProperty;
|
|
|
1596
1705
|
return {
|
|
1597
1706
|
pos3d: last.pos3d,
|
|
1598
1707
|
indexLast: lastIndex,
|
|
1599
|
-
indexNext: lastIndex
|
|
1708
|
+
indexNext: lastIndex,
|
|
1709
|
+
applyOverTime: true
|
|
1600
1710
|
};
|
|
1601
1711
|
}
|
|
1602
1712
|
// Interpolate between the two closest positions.
|
|
@@ -1607,25 +1717,18 @@ var CesiumAnimatedProperty;
|
|
|
1607
1717
|
return {
|
|
1608
1718
|
pos3d: interpolatedPos,
|
|
1609
1719
|
indexLast: lastIndex,
|
|
1610
|
-
indexNext: nextIndex
|
|
1720
|
+
indexNext: nextIndex,
|
|
1721
|
+
applyOverTime: false
|
|
1611
1722
|
};
|
|
1612
1723
|
}
|
|
1613
1724
|
/**
|
|
1614
1725
|
* Calculate the heading at the given time.
|
|
1615
1726
|
*/
|
|
1616
|
-
calculateHeading(currentTimeMs,
|
|
1617
|
-
const posses = this.positions;
|
|
1618
|
-
// Ensure valid indices.
|
|
1619
|
-
if (lastIndex < 0 || nextIndex < 0 ||
|
|
1620
|
-
lastIndex >= posses.length || nextIndex >= posses.length) {
|
|
1621
|
-
return null;
|
|
1622
|
-
}
|
|
1623
|
-
const lastPos = posses[lastIndex];
|
|
1624
|
-
const nextPos = posses[nextIndex];
|
|
1727
|
+
calculateHeading(currentTimeMs, lastPos, nextPos) {
|
|
1625
1728
|
// If the heading is present and not null, interpolate or use it directly.
|
|
1626
1729
|
if (lastPos.heading !== null && nextPos.heading !== null) {
|
|
1627
1730
|
// If they're the same position or same time, just return the heading.
|
|
1628
|
-
if (
|
|
1731
|
+
if (lastPos === nextPos ||
|
|
1629
1732
|
lastPos.dateTime.getTime() === nextPos.dateTime.getTime()) {
|
|
1630
1733
|
return lastPos.heading;
|
|
1631
1734
|
}
|
|
@@ -1645,16 +1748,16 @@ var CesiumAnimatedProperty;
|
|
|
1645
1748
|
}
|
|
1646
1749
|
// If no valid heading is available, calculate based on movement direction.
|
|
1647
1750
|
else {
|
|
1648
|
-
const
|
|
1649
|
-
const
|
|
1650
|
-
if (!
|
|
1651
|
-
!
|
|
1751
|
+
const prevPos3d = lastPos.pos3d;
|
|
1752
|
+
const nextPos3d = nextPos.pos3d;
|
|
1753
|
+
if (!prevPos3d || isNaN(prevPos3d.x) ||
|
|
1754
|
+
!nextPos3d || isNaN(nextPos3d.x)) {
|
|
1652
1755
|
return null;
|
|
1653
1756
|
}
|
|
1654
1757
|
// Flatten to avoid orientation changes due to height differences.
|
|
1655
|
-
const adjustedPointPrev = Cartographic.fromCartesian(
|
|
1758
|
+
const adjustedPointPrev = Cartographic.fromCartesian(prevPos3d);
|
|
1656
1759
|
const adjustedPos3dPrev = Cartesian3.fromRadians(adjustedPointPrev.longitude, adjustedPointPrev.latitude, 0);
|
|
1657
|
-
const adjustedPointNext = Cartographic.fromCartesian(
|
|
1760
|
+
const adjustedPointNext = Cartographic.fromCartesian(nextPos3d);
|
|
1658
1761
|
const adjustedPos3dNext = Cartesian3.fromRadians(adjustedPointNext.longitude, adjustedPointNext.latitude, 0);
|
|
1659
1762
|
// Check if the positions are too close.
|
|
1660
1763
|
if (Cartesian3.distance(adjustedPos3dPrev, adjustedPos3dNext) < 0.05) {
|
|
@@ -1665,14 +1768,24 @@ var CesiumAnimatedProperty;
|
|
|
1665
1768
|
if (direction.x === 0 && direction.y === 0 && direction.z === 0) {
|
|
1666
1769
|
return null;
|
|
1667
1770
|
}
|
|
1668
|
-
//
|
|
1771
|
+
// Normalize the direction vector.
|
|
1669
1772
|
Cartesian3.normalize(direction, direction);
|
|
1670
|
-
//
|
|
1671
|
-
|
|
1672
|
-
const
|
|
1673
|
-
|
|
1674
|
-
//
|
|
1675
|
-
|
|
1773
|
+
// Calculate heading in the ENU (East-North-Up).
|
|
1774
|
+
// First, get the local ENU frame at the midpoint.
|
|
1775
|
+
const midPoint = Cartesian3.midpoint(adjustedPos3dPrev, adjustedPos3dNext, new Cartesian3());
|
|
1776
|
+
// Convert direction from ECEF to ENU.
|
|
1777
|
+
// We need to create a transform from ECEF to ENU at our position.
|
|
1778
|
+
const transform = Transforms.eastNorthUpToFixedFrame(midPoint);
|
|
1779
|
+
const inverseTransform = Matrix4.inverseTransformation(transform, new Matrix4());
|
|
1780
|
+
// Transform our direction vector to local ENU.
|
|
1781
|
+
const localDirection = Matrix4.multiplyByPointAsVector(inverseTransform, direction, new Cartesian3());
|
|
1782
|
+
Cartesian3.normalize(localDirection, localDirection);
|
|
1783
|
+
// Now calculate the heading in the ENU frame (clockwise from north).
|
|
1784
|
+
// atan2(east, north) gives us the angle in the east-north plane measured clockwise from north.
|
|
1785
|
+
const heading = Math.atan2(localDirection.x, localDirection.y);
|
|
1786
|
+
// Convert to degrees and ensure it's in the range [0, 360].
|
|
1787
|
+
const headingDegrees = (Math$1.toDegrees(heading) + 360) % 360;
|
|
1788
|
+
return headingDegrees;
|
|
1676
1789
|
}
|
|
1677
1790
|
}
|
|
1678
1791
|
}
|
|
@@ -4554,12 +4667,14 @@ var EntityRenderEnginePoint;
|
|
|
4554
4667
|
// Unset width/height.
|
|
4555
4668
|
cEntity.billboard.width = undefined;
|
|
4556
4669
|
cEntity.billboard.height = undefined;
|
|
4670
|
+
const prevPos3d = GetCValue(params.viewer, cEntity.position);
|
|
4557
4671
|
// If we have a series of time-based positions then we'll animate as time changes.
|
|
4558
4672
|
const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
|
|
4559
4673
|
if (series.length > 1) {
|
|
4560
4674
|
animatePosition = new CesiumAnimatedProperty.AnimatePositionSeries({
|
|
4561
4675
|
posses: series,
|
|
4562
|
-
viewer: params.viewer
|
|
4676
|
+
viewer: params.viewer,
|
|
4677
|
+
animateFromPos3d: prevPos3d
|
|
4563
4678
|
});
|
|
4564
4679
|
cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
|
|
4565
4680
|
}
|
|
@@ -4571,7 +4686,6 @@ var EntityRenderEnginePoint;
|
|
|
4571
4686
|
returnHeightRef: heightRef,
|
|
4572
4687
|
allowRendered: false
|
|
4573
4688
|
});
|
|
4574
|
-
const prevPos3d = GetCValue(params.viewer, cEntity.position);
|
|
4575
4689
|
if (!prevPos3d || !Cartesian3.equals(prevPos3d, pos3d)) {
|
|
4576
4690
|
animatePosition = new CesiumAnimatedProperty.AnimatePosition({
|
|
4577
4691
|
durationMs: 200,
|
|
@@ -4877,12 +4991,14 @@ var EntityRenderEnginePoint;
|
|
|
4877
4991
|
cEntity.billboard.heightReference = new ConstantProperty(heightRef);
|
|
4878
4992
|
cEntity.billboard.distanceDisplayCondition = new ConstantProperty(EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance));
|
|
4879
4993
|
cEntity.billboard.disableDepthTestDistance = new ConstantProperty(disableDepthTest ? Number.POSITIVE_INFINITY : undefined);
|
|
4994
|
+
const prevPos3d = GetCValue(params.viewer, cEntity.position);
|
|
4880
4995
|
// If we have a series of time-based positions then we'll animate as time changes.
|
|
4881
4996
|
const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
|
|
4882
4997
|
if (series.length > 1) {
|
|
4883
4998
|
animatePosition = new CesiumAnimatedProperty.AnimatePositionSeries({
|
|
4884
4999
|
posses: series,
|
|
4885
|
-
viewer: params.viewer
|
|
5000
|
+
viewer: params.viewer,
|
|
5001
|
+
animateFromPos3d: prevPos3d
|
|
4886
5002
|
});
|
|
4887
5003
|
cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
|
|
4888
5004
|
}
|
|
@@ -4894,7 +5010,6 @@ var EntityRenderEnginePoint;
|
|
|
4894
5010
|
returnHeightRef: heightRef,
|
|
4895
5011
|
allowRendered: false
|
|
4896
5012
|
});
|
|
4897
|
-
const prevPos3d = GetCValue(params.viewer, cEntity.position);
|
|
4898
5013
|
if (!prevPos3d || !Cartesian3.equals(prevPos3d, pos3d)) {
|
|
4899
5014
|
animatePosition = new CesiumAnimatedProperty.AnimatePosition({
|
|
4900
5015
|
durationMs: 200,
|
|
@@ -6474,6 +6589,7 @@ var EntityRenderEngineModel3d;
|
|
|
6474
6589
|
cEntity.model.colorBlendAmount = new ConstantProperty(blendAmount);
|
|
6475
6590
|
cEntity.model.colorBlendMode = new ConstantProperty(blendMode);
|
|
6476
6591
|
cEntity.model.distanceDisplayCondition = new ConstantProperty(EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance));
|
|
6592
|
+
const prevPos3d = GetCValue(params.viewer, cEntity.position);
|
|
6477
6593
|
// If we have a series of time-based positions then we'll animate as time changes.
|
|
6478
6594
|
const series = CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(params.viewer, heightRef, heightRef, params.entityHistoric);
|
|
6479
6595
|
if (series.length > 1) {
|
|
@@ -6481,12 +6597,12 @@ var EntityRenderEngineModel3d;
|
|
|
6481
6597
|
posses: series,
|
|
6482
6598
|
viewer: params.viewer,
|
|
6483
6599
|
pitch: pitch,
|
|
6484
|
-
roll: roll
|
|
6600
|
+
roll: roll,
|
|
6601
|
+
animateFromPos3d: prevPos3d
|
|
6485
6602
|
});
|
|
6486
6603
|
cEntity.position = new CallbackProperty(() => animatePosition.GetValue(), false);
|
|
6487
6604
|
}
|
|
6488
6605
|
else {
|
|
6489
|
-
const prevPos3d = GetCValue(params.viewer, cEntity.position);
|
|
6490
6606
|
const posChanged = !prevPos3d || !Cartesian3.equals(prevPos3d, pos3d);
|
|
6491
6607
|
if (posChanged) {
|
|
6492
6608
|
animatePosition = new CesiumAnimatedProperty.AnimatePosition({
|
|
@@ -14395,36 +14511,54 @@ var EntitiesIdsRenderManager;
|
|
|
14395
14511
|
* @param entities
|
|
14396
14512
|
*/
|
|
14397
14513
|
async getHistoricInfo(entities) {
|
|
14398
|
-
|
|
14399
|
-
|
|
14514
|
+
// Time padding in milliseconds (15 seconds).
|
|
14515
|
+
// Helps account for desync between client and server.
|
|
14516
|
+
const TIME_PADDING_MS = 15000;
|
|
14517
|
+
const minDateTimeStr = this.viewer.clock.startTime.toString();
|
|
14518
|
+
const maxDateTimeStr = this.viewer.clock.stopTime.toString();
|
|
14519
|
+
const minDateTime = new Date(minDateTimeStr).getTime();
|
|
14520
|
+
const maxDateTime = new Date(maxDateTimeStr).getTime();
|
|
14400
14521
|
let rangesToRequest = [{
|
|
14401
|
-
start:
|
|
14402
|
-
stop:
|
|
14522
|
+
start: minDateTime,
|
|
14523
|
+
stop: maxDateTime
|
|
14403
14524
|
}];
|
|
14404
14525
|
// If we already have cached data, determine what ranges we're missing.
|
|
14405
|
-
if (
|
|
14406
|
-
|
|
14407
|
-
|
|
14408
|
-
|
|
14409
|
-
|
|
14526
|
+
if (Object.keys(this.entitiesHistoric).length >= entities.length) {
|
|
14527
|
+
let foundMinDateTime = null;
|
|
14528
|
+
let foundMaxDateTime = null;
|
|
14529
|
+
// Find the min/max based on cached data.
|
|
14530
|
+
// Since we set the values sorted, we only have to check the first and last records for each entity.
|
|
14531
|
+
for (const entityId of Object.keys(this.entitiesHistoric)) {
|
|
14532
|
+
const records = this.entitiesHistoric[entityId] || [];
|
|
14533
|
+
if (records.length) {
|
|
14534
|
+
const dateTime = new Date(records[0].dateTime).getTime();
|
|
14535
|
+
if (foundMinDateTime == null || dateTime < foundMinDateTime) {
|
|
14536
|
+
foundMinDateTime = dateTime;
|
|
14537
|
+
}
|
|
14538
|
+
const dateTime2 = new Date(records[records.length - 1].dateTime).getTime();
|
|
14539
|
+
if (foundMaxDateTime == null || dateTime2 > foundMaxDateTime) {
|
|
14540
|
+
foundMaxDateTime = dateTime2;
|
|
14541
|
+
}
|
|
14542
|
+
}
|
|
14543
|
+
}
|
|
14410
14544
|
// Complete overlap - we already have all the data.
|
|
14411
|
-
if (
|
|
14545
|
+
if (foundMinDateTime != null && foundMaxDateTime != null && foundMinDateTime <= minDateTime && foundMaxDateTime >= maxDateTime) {
|
|
14412
14546
|
return [false, this.entitiesHistoric];
|
|
14413
14547
|
}
|
|
14414
14548
|
// Calculate missing ranges.
|
|
14415
14549
|
rangesToRequest = [];
|
|
14416
14550
|
// Check if we need data before our cached range.
|
|
14417
|
-
if (
|
|
14551
|
+
if (foundMinDateTime != null && foundMinDateTime > minDateTime) {
|
|
14418
14552
|
rangesToRequest.push({
|
|
14419
|
-
start:
|
|
14420
|
-
stop: new Date(
|
|
14553
|
+
start: minDateTime,
|
|
14554
|
+
stop: new Date(foundMinDateTime).getTime()
|
|
14421
14555
|
});
|
|
14422
14556
|
}
|
|
14423
14557
|
// Check if we need data after our cached range.
|
|
14424
|
-
if (
|
|
14558
|
+
if (foundMaxDateTime != null && foundMaxDateTime < maxDateTime) {
|
|
14425
14559
|
rangesToRequest.push({
|
|
14426
|
-
start: new Date(
|
|
14427
|
-
stop:
|
|
14560
|
+
start: new Date(foundMaxDateTime).getTime(),
|
|
14561
|
+
stop: maxDateTime
|
|
14428
14562
|
});
|
|
14429
14563
|
}
|
|
14430
14564
|
}
|
|
@@ -14435,17 +14569,12 @@ var EntitiesIdsRenderManager;
|
|
|
14435
14569
|
if (this.disposed) {
|
|
14436
14570
|
break;
|
|
14437
14571
|
}
|
|
14438
|
-
|
|
14439
|
-
const
|
|
14440
|
-
const stop = new Date(range.stop);
|
|
14441
|
-
start.setSeconds(start.getSeconds() - 1);
|
|
14442
|
-
stop.setSeconds(stop.getSeconds() + 1);
|
|
14443
|
-
const paddedStartStr = start.toISOString();
|
|
14444
|
-
const paddedStopStr = stop.toISOString();
|
|
14572
|
+
const start = new Date(range.start - TIME_PADDING_MS);
|
|
14573
|
+
const stop = new Date(range.stop + TIME_PADDING_MS);
|
|
14445
14574
|
const historicData = await EntityHistoricData.GetList({
|
|
14446
14575
|
attrKey: this.item.BruceEntity.historicAttrKey,
|
|
14447
|
-
dateTimeFrom:
|
|
14448
|
-
dateTimeTo:
|
|
14576
|
+
dateTimeFrom: start.toISOString(),
|
|
14577
|
+
dateTimeTo: stop.toISOString(),
|
|
14449
14578
|
entityIds: entityIds,
|
|
14450
14579
|
api: this.apiGetter.getApi()
|
|
14451
14580
|
});
|
|
@@ -14479,9 +14608,6 @@ var EntitiesIdsRenderManager;
|
|
|
14479
14608
|
}
|
|
14480
14609
|
}
|
|
14481
14610
|
if (!this.disposed) {
|
|
14482
|
-
// Update our cache boundaries.
|
|
14483
|
-
this.lastHistoricMin = startTmp.toISOString();
|
|
14484
|
-
this.lastHistoricMax = stopTmp.toISOString();
|
|
14485
14611
|
this.entitiesHistoric = combined;
|
|
14486
14612
|
}
|
|
14487
14613
|
return [rangesToRequest.length > 0, combined];
|
|
@@ -14703,969 +14829,873 @@ var EntityRenderManager;
|
|
|
14703
14829
|
EntityRenderManager.Manager = Manager;
|
|
14704
14830
|
})(EntityRenderManager || (EntityRenderManager = {}));
|
|
14705
14831
|
|
|
14706
|
-
|
|
14707
|
-
|
|
14708
|
-
|
|
14709
|
-
|
|
14710
|
-
*/
|
|
14711
|
-
var EntityGlobe;
|
|
14712
|
-
(function (EntityGlobe) {
|
|
14713
|
-
class Cell {
|
|
14714
|
-
constructor() {
|
|
14715
|
-
this.Fetched = false;
|
|
14716
|
-
this.IsFetched = null;
|
|
14717
|
-
this.FetchPageIndex = 0;
|
|
14718
|
-
// Optional URL to use instead of default URL generation.
|
|
14719
|
-
// This is typically a response from the API to use this specific URL for the next page.
|
|
14720
|
-
this.FetchURL = null;
|
|
14721
|
-
this.Boundaries = null;
|
|
14722
|
-
this.Fetching = false;
|
|
14832
|
+
class EntityGatherer {
|
|
14833
|
+
get OnQueueProgress() {
|
|
14834
|
+
if (!this._onQueueProgress) {
|
|
14835
|
+
this._onQueueProgress = new BruceEvent();
|
|
14723
14836
|
}
|
|
14724
|
-
|
|
14725
|
-
|
|
14726
|
-
|
|
14727
|
-
|
|
14728
|
-
|
|
14729
|
-
|
|
14730
|
-
|
|
14731
|
-
|
|
14732
|
-
|
|
14733
|
-
|
|
14734
|
-
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
|
|
14739
|
-
|
|
14740
|
-
|
|
14741
|
-
|
|
14742
|
-
|
|
14837
|
+
return this._onQueueProgress;
|
|
14838
|
+
}
|
|
14839
|
+
constructor(api, viewer, emitEntities) {
|
|
14840
|
+
this.disposed = false;
|
|
14841
|
+
this.expandSources = false;
|
|
14842
|
+
this.historic = null;
|
|
14843
|
+
this.hDisposals = [];
|
|
14844
|
+
// Last date-time taken from the clock.
|
|
14845
|
+
this.lastDateTime = null;
|
|
14846
|
+
// Last date-time range taken from the clock.
|
|
14847
|
+
this.lastDateTimeMin = null;
|
|
14848
|
+
this.lastDateTimeMax = null;
|
|
14849
|
+
// Entity ID -> last resolved date time.
|
|
14850
|
+
// Helps determine if a slow resolved request can still be applied while we wait for the next one.
|
|
14851
|
+
this.lastFoundDateTimes = new Map();
|
|
14852
|
+
// ID of Entity IDs that need to be requested.
|
|
14853
|
+
this.eIdQueue = [];
|
|
14854
|
+
// All IDs that have ever been queued.
|
|
14855
|
+
// When nothing is in queue, we'll re-request the existing IDs based on timeline changes.
|
|
14856
|
+
this.allEIds = new Set();
|
|
14857
|
+
// Indicates a tick is active.
|
|
14858
|
+
// When true, we won't bother calling onTick again.
|
|
14859
|
+
this.runningTick = false;
|
|
14860
|
+
// Entity ID -> Entity blob.
|
|
14861
|
+
// This is a tool that lets developers set their own JSON blobs instead of requesting data from API.
|
|
14862
|
+
this.entityDataOverrides = new Map();
|
|
14863
|
+
// 0 - 100 % progress callback for the queue.
|
|
14864
|
+
// Only called if at least 1 Entity is in the queue at start of the tick.
|
|
14865
|
+
this._onQueueProgress = null;
|
|
14866
|
+
this.api = api;
|
|
14867
|
+
this.viewer = viewer;
|
|
14868
|
+
this.emitEntities = emitEntities;
|
|
14869
|
+
}
|
|
14870
|
+
SetEntityDataOverride(eId, entity) {
|
|
14871
|
+
if (this.disposed) {
|
|
14872
|
+
return;
|
|
14873
|
+
}
|
|
14874
|
+
if (entity) {
|
|
14875
|
+
this.entityDataOverrides.set(eId, entity);
|
|
14876
|
+
}
|
|
14877
|
+
else {
|
|
14878
|
+
this.entityDataOverrides.delete(eId);
|
|
14743
14879
|
}
|
|
14744
14880
|
}
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14881
|
+
/**
|
|
14882
|
+
* Initializes or updates the manager with given new state settings.
|
|
14883
|
+
* @param historic
|
|
14884
|
+
* @param expandSources
|
|
14885
|
+
* @returns
|
|
14886
|
+
*/
|
|
14887
|
+
Init(historic, expandSources) {
|
|
14888
|
+
if (historic == null || historic == undefined) {
|
|
14889
|
+
historic = this.historic;
|
|
14749
14890
|
}
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
|
|
14753
|
-
|
|
14754
|
-
|
|
14755
|
-
|
|
14756
|
-
|
|
14757
|
-
|
|
14758
|
-
|
|
14759
|
-
|
|
14760
|
-
|
|
14761
|
-
|
|
14762
|
-
|
|
14763
|
-
|
|
14764
|
-
|
|
14765
|
-
|
|
14766
|
-
|
|
14767
|
-
|
|
14768
|
-
|
|
14769
|
-
|
|
14770
|
-
|
|
14771
|
-
|
|
14772
|
-
|
|
14773
|
-
|
|
14774
|
-
// For larger views we add additional padding because our view-area culling is too strong.
|
|
14775
|
-
if (cellDegreeSize >= 2) {
|
|
14776
|
-
width += 1;
|
|
14777
|
-
height += 1;
|
|
14778
|
-
}
|
|
14779
|
-
const cellDistances = [];
|
|
14780
|
-
for (let x = 0; x < width; x++) {
|
|
14781
|
-
for (let y = 0; y < height; y++) {
|
|
14782
|
-
const lon = x * cellDegreeSize + curMinLon;
|
|
14783
|
-
const lat = y * cellDegreeSize + curMinLat;
|
|
14784
|
-
const cellCenterX = lon + cellDegreeSize / 2;
|
|
14785
|
-
const cellCenterY = lat + cellDegreeSize / 2;
|
|
14786
|
-
const dist = Math.sqrt(Math.pow(cellCenterX - centerX, 2) + Math.pow(cellCenterY - centerY, 2));
|
|
14787
|
-
cellDistances.push({ x, y, dist });
|
|
14788
|
-
}
|
|
14789
|
-
}
|
|
14790
|
-
cellDistances.sort((a, b) => a.dist - b.dist);
|
|
14791
|
-
for (const { x, y } of cellDistances) {
|
|
14792
|
-
const lon = x * cellDegreeSize + curMinLon;
|
|
14793
|
-
const lat = y * cellDegreeSize + curMinLat;
|
|
14794
|
-
const [id, cell] = getOrCreateCell(this.cells, cellDegreeSize, lon, lon + cellDegreeSize, lat, lat + cellDegreeSize);
|
|
14795
|
-
cells.push(cell);
|
|
14796
|
-
if (cells.length >= MAX_CELLS) {
|
|
14797
|
-
break;
|
|
14891
|
+
if (expandSources == null || expandSources == undefined) {
|
|
14892
|
+
expandSources = this.expandSources;
|
|
14893
|
+
}
|
|
14894
|
+
if (historic === this.historic && expandSources === this.expandSources) {
|
|
14895
|
+
return;
|
|
14896
|
+
}
|
|
14897
|
+
this.historic = historic;
|
|
14898
|
+
this.expandSources = expandSources;
|
|
14899
|
+
if (this.historic) {
|
|
14900
|
+
// 4 ticks per second.
|
|
14901
|
+
// The fastest data we are working with is 5 times per second.
|
|
14902
|
+
let tickDelay = new DelayQueue(() => {
|
|
14903
|
+
this.onTick(false);
|
|
14904
|
+
}, 250, true);
|
|
14905
|
+
this.hDisposals.push(() => {
|
|
14906
|
+
if (tickDelay) {
|
|
14907
|
+
tickDelay.Dispose();
|
|
14908
|
+
}
|
|
14909
|
+
tickDelay = null;
|
|
14910
|
+
});
|
|
14911
|
+
// React to clock changes and request new Entities.
|
|
14912
|
+
this.hDisposals.push(this.viewer.clock.onTick.addEventListener(() => {
|
|
14913
|
+
if (tickDelay) {
|
|
14914
|
+
tickDelay.Call();
|
|
14798
14915
|
}
|
|
14799
|
-
}
|
|
14800
|
-
|
|
14916
|
+
}));
|
|
14917
|
+
// Since the timeline range can change even without it ticking we have to check it occasionally.
|
|
14918
|
+
let rangeCheckInterval = setInterval(() => {
|
|
14919
|
+
this.checkRange(false);
|
|
14920
|
+
}, 800);
|
|
14921
|
+
this.hDisposals.push(() => {
|
|
14922
|
+
if (rangeCheckInterval) {
|
|
14923
|
+
clearInterval(rangeCheckInterval);
|
|
14924
|
+
}
|
|
14925
|
+
rangeCheckInterval = null;
|
|
14926
|
+
});
|
|
14801
14927
|
}
|
|
14928
|
+
else {
|
|
14929
|
+
this.hDisposals.forEach((d) => d());
|
|
14930
|
+
this.hDisposals = [];
|
|
14931
|
+
}
|
|
14932
|
+
this.checkRange(true);
|
|
14802
14933
|
}
|
|
14803
|
-
|
|
14804
|
-
|
|
14805
|
-
|
|
14806
|
-
|
|
14807
|
-
|
|
14808
|
-
|
|
14809
|
-
|
|
14810
|
-
|
|
14811
|
-
}
|
|
14812
|
-
if (height < 5000) {
|
|
14813
|
-
return 0.04;
|
|
14934
|
+
Empty() {
|
|
14935
|
+
if (this.disposed) {
|
|
14936
|
+
return;
|
|
14937
|
+
}
|
|
14938
|
+
this.eIdQueue = [];
|
|
14939
|
+
this.allEIds.clear();
|
|
14940
|
+
this.lastFoundDateTimes.clear();
|
|
14941
|
+
this.lastDateTime = null;
|
|
14814
14942
|
}
|
|
14815
|
-
|
|
14816
|
-
|
|
14943
|
+
ReQueueAll() {
|
|
14944
|
+
if (this.disposed) {
|
|
14945
|
+
return;
|
|
14946
|
+
}
|
|
14947
|
+
this.eIdQueue = Array.from(this.allEIds);
|
|
14817
14948
|
}
|
|
14818
|
-
|
|
14819
|
-
|
|
14949
|
+
Queue(entityIds, topOfQueue = false) {
|
|
14950
|
+
if (this.disposed || !(entityIds === null || entityIds === void 0 ? void 0 : entityIds.length)) {
|
|
14951
|
+
return;
|
|
14952
|
+
}
|
|
14953
|
+
let changes = 0;
|
|
14954
|
+
for (let i = 0; i < entityIds.length; i++) {
|
|
14955
|
+
const eId = entityIds[i];
|
|
14956
|
+
const index = this.eIdQueue.indexOf(eId);
|
|
14957
|
+
if (topOfQueue) {
|
|
14958
|
+
// If we want it to be at the top of the queue, remove it from the queue first.
|
|
14959
|
+
if (index !== -1) {
|
|
14960
|
+
this.eIdQueue.splice(index, 1);
|
|
14961
|
+
}
|
|
14962
|
+
this.eIdQueue.unshift(eId);
|
|
14963
|
+
changes += 1;
|
|
14964
|
+
}
|
|
14965
|
+
else if (index === -1) {
|
|
14966
|
+
this.eIdQueue.push(eId);
|
|
14967
|
+
changes += 1;
|
|
14968
|
+
}
|
|
14969
|
+
// Flag that we've seen this ID.
|
|
14970
|
+
this.allEIds.add(entityIds[i]);
|
|
14971
|
+
}
|
|
14972
|
+
if (!changes) {
|
|
14973
|
+
return;
|
|
14974
|
+
}
|
|
14975
|
+
this.onTick(false);
|
|
14820
14976
|
}
|
|
14821
|
-
|
|
14822
|
-
|
|
14977
|
+
Dispose() {
|
|
14978
|
+
if (this.disposed) {
|
|
14979
|
+
return;
|
|
14980
|
+
}
|
|
14981
|
+
this.disposed = true;
|
|
14982
|
+
this.hDisposals.forEach((d) => d());
|
|
14983
|
+
this.hDisposals = [];
|
|
14823
14984
|
}
|
|
14824
|
-
|
|
14825
|
-
|
|
14985
|
+
checkRange(force) {
|
|
14986
|
+
const min = this.viewer.clock.startTime.toString();
|
|
14987
|
+
const max = this.viewer.clock.stopTime.toString();
|
|
14988
|
+
if (force || this.lastDateTimeMin !== min || this.lastDateTimeMax !== max) {
|
|
14989
|
+
this.lastDateTimeMin = min;
|
|
14990
|
+
this.lastDateTimeMax = max;
|
|
14991
|
+
// Changed, so we can pretend it's a clock tick and request new Entities.
|
|
14992
|
+
this.onTick(true);
|
|
14993
|
+
}
|
|
14826
14994
|
}
|
|
14827
|
-
|
|
14828
|
-
|
|
14995
|
+
onTick(force) {
|
|
14996
|
+
if (this.runningTick) {
|
|
14997
|
+
return;
|
|
14998
|
+
}
|
|
14999
|
+
const rTime = this.viewer.clock.currentTime.toString();
|
|
15000
|
+
if (!force && !this.eIdQueue.length && this.historic && this.lastDateTime === rTime) {
|
|
15001
|
+
return;
|
|
15002
|
+
}
|
|
15003
|
+
this.lastDateTime = rTime;
|
|
15004
|
+
(async () => {
|
|
15005
|
+
this.runningTick = true;
|
|
15006
|
+
let rerun = false;
|
|
15007
|
+
try {
|
|
15008
|
+
const handleResponse = async (entities) => {
|
|
15009
|
+
var _a, _b;
|
|
15010
|
+
if (!(entities === null || entities === void 0 ? void 0 : entities.length)) {
|
|
15011
|
+
return;
|
|
15012
|
+
}
|
|
15013
|
+
// Lazy substitution of the entity data overrides.
|
|
15014
|
+
if (this.entityDataOverrides.size) {
|
|
15015
|
+
for (let i = 0; i < entities.length; i++) {
|
|
15016
|
+
const entity = entities[i];
|
|
15017
|
+
const eId = entity.Bruce.ID;
|
|
15018
|
+
if (this.entityDataOverrides.has(eId)) {
|
|
15019
|
+
entities[i] = this.entityDataOverrides.get(eId);
|
|
15020
|
+
}
|
|
15021
|
+
}
|
|
15022
|
+
}
|
|
15023
|
+
// Gather all Tag IDs from found Entities.
|
|
15024
|
+
let tagIds = new Set();
|
|
15025
|
+
for (let i = 0; i < entities.length; i++) {
|
|
15026
|
+
const entity = entities[i];
|
|
15027
|
+
if ((_b = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a["Layer.ID"]) === null || _b === void 0 ? void 0 : _b.length) {
|
|
15028
|
+
const eTagIds = entity.Bruce["Layer.ID"];
|
|
15029
|
+
for (let j = 0; j < eTagIds.length; j++) {
|
|
15030
|
+
const tagId = eTagIds[j];
|
|
15031
|
+
if (tagId) {
|
|
15032
|
+
tagIds.add(tagId);
|
|
15033
|
+
}
|
|
15034
|
+
}
|
|
15035
|
+
}
|
|
15036
|
+
}
|
|
15037
|
+
// Gather records.
|
|
15038
|
+
let tags = [];
|
|
15039
|
+
if (tagIds.size) {
|
|
15040
|
+
tags = (await EntityTag.GetListByIds({
|
|
15041
|
+
tagIds: Array.from(tagIds),
|
|
15042
|
+
api: this.api
|
|
15043
|
+
})).tags;
|
|
15044
|
+
}
|
|
15045
|
+
// 0 = rTime is still the current time.
|
|
15046
|
+
// 1 = rTime is in the future.
|
|
15047
|
+
// -1 = rTime is in the past.
|
|
15048
|
+
let changeDir = 0;
|
|
15049
|
+
if (this.lastDateTime !== this.viewer.clock.currentTime.toString()) {
|
|
15050
|
+
changeDir = this.lastDateTime < this.viewer.clock.currentTime.toString() ? 1 : -1;
|
|
15051
|
+
}
|
|
15052
|
+
let toEmit;
|
|
15053
|
+
if (this.historic) {
|
|
15054
|
+
// We can emit Entities if the last resolved time (per Entity) isn't newer than rTime.
|
|
15055
|
+
// We compare using the changeDir to determine if we should emit or not.
|
|
15056
|
+
toEmit = entities.filter((e) => {
|
|
15057
|
+
const lastFoundDateTime = this.lastFoundDateTimes.get(e.id);
|
|
15058
|
+
if (lastFoundDateTime) {
|
|
15059
|
+
if (changeDir === 1) {
|
|
15060
|
+
return lastFoundDateTime <= rTime;
|
|
15061
|
+
}
|
|
15062
|
+
else if (changeDir === -1) {
|
|
15063
|
+
return lastFoundDateTime >= rTime;
|
|
15064
|
+
}
|
|
15065
|
+
}
|
|
15066
|
+
return true;
|
|
15067
|
+
});
|
|
15068
|
+
// Update the last found date times for the filtered Entities.
|
|
15069
|
+
toEmit.forEach((e) => {
|
|
15070
|
+
this.lastFoundDateTimes.set(e.id, rTime);
|
|
15071
|
+
});
|
|
15072
|
+
}
|
|
15073
|
+
else {
|
|
15074
|
+
// If we're not historic, we can just emit everything.
|
|
15075
|
+
toEmit = entities;
|
|
15076
|
+
}
|
|
15077
|
+
this.emitEntities(toEmit, tags);
|
|
15078
|
+
};
|
|
15079
|
+
const QUEUE_BATCH_SIZE = 500;
|
|
15080
|
+
const requestedIds = [];
|
|
15081
|
+
// If we have a queue, we need to request those first.
|
|
15082
|
+
if (this.eIdQueue.length) {
|
|
15083
|
+
const total = this.eIdQueue.length;
|
|
15084
|
+
let done = 0;
|
|
15085
|
+
while (this.eIdQueue.length && !this.disposed) {
|
|
15086
|
+
if (this.historic && this.lastDateTime !== rTime) {
|
|
15087
|
+
break;
|
|
15088
|
+
}
|
|
15089
|
+
const batch = this.eIdQueue.splice(0, QUEUE_BATCH_SIZE);
|
|
15090
|
+
const { entities } = await Entity$1.GetListByIds({
|
|
15091
|
+
entityIds: batch,
|
|
15092
|
+
historicPoint: this.historic ? rTime : null,
|
|
15093
|
+
expandSources: this.expandSources,
|
|
15094
|
+
api: this.api
|
|
15095
|
+
});
|
|
15096
|
+
handleResponse(entities);
|
|
15097
|
+
requestedIds.push(...batch);
|
|
15098
|
+
done += batch.length;
|
|
15099
|
+
if (this._onQueueProgress) {
|
|
15100
|
+
let progress = (done / total) * 100;
|
|
15101
|
+
if (progress > 100) {
|
|
15102
|
+
progress = 100;
|
|
15103
|
+
}
|
|
15104
|
+
if (progress < 0) {
|
|
15105
|
+
progress = 0;
|
|
15106
|
+
}
|
|
15107
|
+
this._onQueueProgress.Trigger(progress);
|
|
15108
|
+
}
|
|
15109
|
+
}
|
|
15110
|
+
if (this._onQueueProgress) {
|
|
15111
|
+
this._onQueueProgress.Trigger(100);
|
|
15112
|
+
}
|
|
15113
|
+
}
|
|
15114
|
+
// Now run through all IDs that we've seen and request them.
|
|
15115
|
+
// We'll skip those that we just requested.
|
|
15116
|
+
let allEIds = Array.from(this.allEIds);
|
|
15117
|
+
if (requestedIds.length) {
|
|
15118
|
+
allEIds = allEIds.filter((eId) => requestedIds.indexOf(eId) === -1);
|
|
15119
|
+
}
|
|
15120
|
+
if (allEIds.length) {
|
|
15121
|
+
while (allEIds.length && !this.disposed && !this.eIdQueue.length) {
|
|
15122
|
+
if (this.historic && this.lastDateTime !== rTime) {
|
|
15123
|
+
break;
|
|
15124
|
+
}
|
|
15125
|
+
const batch = allEIds.splice(0, QUEUE_BATCH_SIZE);
|
|
15126
|
+
const { entities } = await Entity$1.GetListByIds({
|
|
15127
|
+
entityIds: batch,
|
|
15128
|
+
historicPoint: this.historic ? rTime : null,
|
|
15129
|
+
expandSources: this.expandSources,
|
|
15130
|
+
api: this.api
|
|
15131
|
+
});
|
|
15132
|
+
handleResponse(entities);
|
|
15133
|
+
requestedIds.push(...batch);
|
|
15134
|
+
}
|
|
15135
|
+
}
|
|
15136
|
+
// If we had leftovers because we stopped early, we need to re-run the tick.
|
|
15137
|
+
if (this.eIdQueue.length || allEIds.length) {
|
|
15138
|
+
rerun = true;
|
|
15139
|
+
}
|
|
15140
|
+
}
|
|
15141
|
+
catch (e) {
|
|
15142
|
+
console.error(e);
|
|
15143
|
+
}
|
|
15144
|
+
finally {
|
|
15145
|
+
this.runningTick = false;
|
|
15146
|
+
}
|
|
15147
|
+
if (rerun) {
|
|
15148
|
+
this.onTick(true);
|
|
15149
|
+
}
|
|
15150
|
+
})();
|
|
14829
15151
|
}
|
|
14830
|
-
else if (height < 200000) {
|
|
14831
|
-
return 1.5;
|
|
14832
|
-
}
|
|
14833
|
-
else if (height < 300000) {
|
|
14834
|
-
return 1.5;
|
|
14835
|
-
}
|
|
14836
|
-
else if (height < 500000) {
|
|
14837
|
-
return 3;
|
|
14838
|
-
}
|
|
14839
|
-
else if (height < 1000000) {
|
|
14840
|
-
return 3;
|
|
14841
|
-
}
|
|
14842
|
-
else if (height < 1200000) {
|
|
14843
|
-
return 4;
|
|
14844
|
-
}
|
|
14845
|
-
else if (height < 2000000) {
|
|
14846
|
-
return 6;
|
|
14847
|
-
}
|
|
14848
|
-
else if (height < 3000000) {
|
|
14849
|
-
return 20;
|
|
14850
|
-
}
|
|
14851
|
-
return 35;
|
|
14852
|
-
}
|
|
14853
|
-
function isCellFetched(cell) {
|
|
14854
|
-
if (cell.Fetched) {
|
|
14855
|
-
return true;
|
|
14856
|
-
}
|
|
14857
|
-
return false;
|
|
14858
|
-
}
|
|
14859
|
-
function getOrCreateCell(cells, cellSize, lon, maxLon, lat, maxLat) {
|
|
14860
|
-
const id = cellSize + "_" + lon + "_" + maxLon + "_" + lat + "_" + maxLat;
|
|
14861
|
-
let cell = cells[id];
|
|
14862
|
-
if (!cell) {
|
|
14863
|
-
cell = cells[id] = new EntityGlobe.Cell();
|
|
14864
|
-
cell.Boundaries = {
|
|
14865
|
-
minLatitude: lat,
|
|
14866
|
-
maxLatitude: maxLat,
|
|
14867
|
-
minLongitude: lon,
|
|
14868
|
-
maxLongitude: maxLon
|
|
14869
|
-
};
|
|
14870
|
-
cell.IsFetched = () => isCellFetched(cell);
|
|
14871
|
-
}
|
|
14872
|
-
return [id, cell];
|
|
14873
15152
|
}
|
|
14874
15153
|
|
|
14875
|
-
|
|
14876
|
-
|
|
14877
|
-
|
|
14878
|
-
|
|
14879
|
-
|
|
14880
|
-
|
|
14881
|
-
|
|
14882
|
-
|
|
14883
|
-
|
|
14884
|
-
|
|
15154
|
+
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
15155
|
+
// We have some evil hard-coded style mappings that need to be fixed.
|
|
15156
|
+
// These exist within legacy project views.
|
|
15157
|
+
function correctStyle(style) {
|
|
15158
|
+
if (style && !style.Settings && !style.ID) {
|
|
15159
|
+
return {
|
|
15160
|
+
ID: -1,
|
|
15161
|
+
Name: "Unknown",
|
|
15162
|
+
Settings: {
|
|
15163
|
+
...style
|
|
15164
|
+
},
|
|
15165
|
+
Type: Style.EType.Entity
|
|
15166
|
+
};
|
|
14885
15167
|
}
|
|
15168
|
+
return style;
|
|
14886
15169
|
}
|
|
14887
|
-
|
|
14888
|
-
return new
|
|
14889
|
-
setTimeout(() => {
|
|
14890
|
-
res();
|
|
14891
|
-
}, milliseconds);
|
|
14892
|
-
});
|
|
15170
|
+
function colorToCColor$3(color) {
|
|
15171
|
+
return new Color(color.red ? color.red / 255 : 0, color.green ? color.green / 255 : 0, color.blue ? color.blue / 255 : 0, color.alpha);
|
|
14893
15172
|
}
|
|
14894
|
-
|
|
14895
|
-
|
|
14896
|
-
|
|
14897
|
-
|
|
14898
|
-
|
|
14899
|
-
|
|
14900
|
-
|
|
14901
|
-
|
|
14902
|
-
|
|
14903
|
-
|
|
14904
|
-
|
|
14905
|
-
|
|
14906
|
-
|
|
14907
|
-
|
|
14908
|
-
|
|
14909
|
-
|
|
14910
|
-
|
|
14911
|
-
|
|
15173
|
+
class TilesetStyler {
|
|
15174
|
+
constructor() {
|
|
15175
|
+
this.disposed = false;
|
|
15176
|
+
// Indicates if the styler has been loaded/initialized and is ready to style.
|
|
15177
|
+
this.loaded = false;
|
|
15178
|
+
// Indicates that all mappings have been loaded.
|
|
15179
|
+
this.styleMappingLoaded = false;
|
|
15180
|
+
// Map of Entity Type ID -> boolean to indicate if the style mapping has been loaded.
|
|
15181
|
+
this.styleMappingsLoaded = new Map();
|
|
15182
|
+
// Dictionary of Entity Type ID -> Set of Entity IDs that are pending styling.
|
|
15183
|
+
// Once the style is loaded, we can queue the set for styling.
|
|
15184
|
+
this.stylePendingEntityIds = new Map();
|
|
15185
|
+
this.fallbackStyle = null;
|
|
15186
|
+
this.loadingCounter = 0;
|
|
15187
|
+
// Entity IDs -> boolean to indicate if we should override the feature colour.
|
|
15188
|
+
this.overrideFeatureColor = new Map();
|
|
15189
|
+
this.scenario = 0;
|
|
15190
|
+
// Indicates that we should expand the sources of the Entity.
|
|
15191
|
+
this.expandSources = false;
|
|
15192
|
+
// Indicates that we are retrieving historic records.
|
|
15193
|
+
// This means that the current scene's time is included in the request.
|
|
15194
|
+
this.historic = false;
|
|
15195
|
+
// More expensive process.
|
|
15196
|
+
// When an Entity is styled, the rego is reviewed and updated if needed.
|
|
15197
|
+
// This is currently used for scenarios, and off by default to keep other processes faster.
|
|
15198
|
+
this.shouldUpdateRegoStates = false;
|
|
15199
|
+
// Entity ID -> styled status.
|
|
15200
|
+
// Helps us emit progress events.
|
|
15201
|
+
this.styledEntityIds = new Map();
|
|
15202
|
+
// % progress for how many Entities have been styled so far.
|
|
15203
|
+
// This can change as Tiles load in and more queue.
|
|
15204
|
+
this._styleProgress = 0;
|
|
15205
|
+
this._styleProgressQueue = new DelayQueue(() => {
|
|
15206
|
+
this.updateStyleProgress();
|
|
15207
|
+
}, 250);
|
|
15208
|
+
// Event for when the style progress changes.
|
|
15209
|
+
this.OnStyleProgress = new BruceEvent();
|
|
15210
|
+
}
|
|
15211
|
+
get Disposed() {
|
|
15212
|
+
return this.disposed;
|
|
15213
|
+
}
|
|
15214
|
+
get Loaded() {
|
|
15215
|
+
return this.loaded;
|
|
15216
|
+
}
|
|
15217
|
+
get StyleProgress() {
|
|
15218
|
+
return this._styleProgress;
|
|
15219
|
+
}
|
|
15220
|
+
Init(params) {
|
|
15221
|
+
var _a;
|
|
15222
|
+
let { viewer, api, cTileset, fallbackStyleId, styleMapping, expandSources, menuItemId, register, scenario, historic } = params;
|
|
15223
|
+
this.viewer = viewer;
|
|
15224
|
+
this.api = api;
|
|
15225
|
+
this.cTileset = cTileset;
|
|
15226
|
+
this.register = register;
|
|
15227
|
+
this.menuItemId = menuItemId;
|
|
15228
|
+
this.historic = Boolean(historic);
|
|
15229
|
+
if (expandSources != null) {
|
|
15230
|
+
this.expandSources = expandSources;
|
|
14912
15231
|
}
|
|
14913
|
-
|
|
14914
|
-
|
|
14915
|
-
this.onStateUpdate = new BruceEvent();
|
|
14916
|
-
}
|
|
14917
|
-
return this.onStateUpdate;
|
|
15232
|
+
if (fallbackStyleId != null) {
|
|
15233
|
+
this.fallbackStyleId = fallbackStyleId;
|
|
14918
15234
|
}
|
|
14919
|
-
|
|
14920
|
-
|
|
14921
|
-
|
|
15235
|
+
if (styleMapping) {
|
|
15236
|
+
this.styleMapping = styleMapping;
|
|
15237
|
+
if (this.styleMapping) {
|
|
15238
|
+
// Dereference.
|
|
15239
|
+
this.styleMapping = JSON.parse(JSON.stringify(this.styleMapping));
|
|
15240
|
+
}
|
|
15241
|
+
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
15242
|
+
// We have some evil hard-coded style mappings that need to be fixed.
|
|
15243
|
+
// These exist within legacy project views.
|
|
15244
|
+
// Update: This now also lets people have a style mapping without a real style record.
|
|
15245
|
+
if ((_a = this.styleMapping) === null || _a === void 0 ? void 0 : _a.length) {
|
|
15246
|
+
for (let i = 0; i < this.styleMapping.length; i++) {
|
|
15247
|
+
const mapItem = this.styleMapping[i];
|
|
15248
|
+
const mapStyle = mapItem.style ? mapItem.style : mapItem.Style;
|
|
15249
|
+
this.styleMapping[i].style = correctStyle(mapStyle);
|
|
15250
|
+
}
|
|
14922
15251
|
}
|
|
14923
|
-
return this.onScanUpdate;
|
|
14924
15252
|
}
|
|
14925
|
-
|
|
14926
|
-
|
|
15253
|
+
if (scenario != null) {
|
|
15254
|
+
this.scenario = scenario;
|
|
14927
15255
|
}
|
|
14928
|
-
|
|
14929
|
-
this.
|
|
14930
|
-
this.LastStateUpdates = {};
|
|
14931
|
-
this.onStateUpdate = null;
|
|
14932
|
-
this.onScanUpdate = null;
|
|
14933
|
-
this.viewPortChangeRemoval = null;
|
|
14934
|
-
this.viewPortDelayQueue = null;
|
|
14935
|
-
this.viewerDateTimeChangeRemoval = null;
|
|
14936
|
-
this.cells = null;
|
|
14937
|
-
this.registeredItems = {};
|
|
14938
|
-
this.getterLoopId = 0;
|
|
14939
|
-
this.getterLoopAbortControllers = {};
|
|
14940
|
-
this.looping = 0;
|
|
14941
|
-
this.tagIds = null;
|
|
14942
|
-
this.minHeight = 0;
|
|
14943
|
-
this.maxHeight = 100000;
|
|
14944
|
-
this.viewRect = null;
|
|
14945
|
-
this.viewCenter = null;
|
|
14946
|
-
this.scenario = 0;
|
|
14947
|
-
this.historicRefreshAbortController = null;
|
|
14948
|
-
// Entity IDs found for the latest integrity.
|
|
14949
|
-
// We use this for refreshing historic data without having to repeat geographic queries.
|
|
14950
|
-
this.gatheredIntegrity = null;
|
|
14951
|
-
this.gatheredEntityIds = [];
|
|
14952
|
-
const { api, viewer, viewPort, typeIds, schemaId, batchSize, attrFilter, historicAttrKey, historicInterpolation, historic, viaCdn, scenario } = params;
|
|
14953
|
-
this.api = api;
|
|
14954
|
-
this.typeIds = typeIds;
|
|
14955
|
-
this.schemaId = schemaId;
|
|
14956
|
-
this.historic = Boolean(historic);
|
|
14957
|
-
this.historicAttrKey = historicAttrKey;
|
|
14958
|
-
this.historicInterpolation = Boolean(historicInterpolation);
|
|
14959
|
-
this.viaCdn = Boolean(viaCdn);
|
|
14960
|
-
this.batchSize = isNaN(batchSize) ? 300 : batchSize;
|
|
14961
|
-
this.viewPort = viewPort;
|
|
14962
|
-
this.attrFilter = attrFilter;
|
|
14963
|
-
this.viewer = viewer;
|
|
14964
|
-
this.scenario = scenario ? scenario : 0;
|
|
14965
|
-
this.updateBounds();
|
|
15256
|
+
if (!!scenario) {
|
|
15257
|
+
this.shouldUpdateRegoStates = true;
|
|
14966
15258
|
}
|
|
14967
|
-
|
|
14968
|
-
|
|
14969
|
-
|
|
14970
|
-
|
|
14971
|
-
|
|
14972
|
-
|
|
14973
|
-
let integrity = this.tagIds == null ? "" : this.tagIds.join();
|
|
14974
|
-
if (this.historicAttrKey) {
|
|
14975
|
-
integrity += "isHistoric";
|
|
14976
|
-
integrity += this.historicAttrKey;
|
|
15259
|
+
else if (this.historic) {
|
|
15260
|
+
this.shouldUpdateRegoStates = true;
|
|
15261
|
+
}
|
|
15262
|
+
this.entityGatherer = new EntityGatherer(this.api, this.viewer, (entities, tags) => {
|
|
15263
|
+
if (!(entities === null || entities === void 0 ? void 0 : entities.length)) {
|
|
15264
|
+
return;
|
|
14977
15265
|
}
|
|
14978
|
-
|
|
14979
|
-
|
|
15266
|
+
for (let i = 0; i < entities.length; i++) {
|
|
15267
|
+
const entity = entities[i];
|
|
15268
|
+
const feature = this.getEntityRego(entity.Bruce.ID);
|
|
15269
|
+
if (feature) {
|
|
15270
|
+
const eTags = tags.filter(t => { var _a, _b, _c, _d; return ((_b = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a["Layer.ID"]) === null || _b === void 0 ? void 0 : _b.length) && ((_d = (_c = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _c === void 0 ? void 0 : _c["Layer.ID"]) === null || _d === void 0 ? void 0 : _d.includes(t.ID)); });
|
|
15271
|
+
this.styleTilesetFeatureFullData(feature, entity, eTags);
|
|
15272
|
+
}
|
|
14980
15273
|
}
|
|
14981
|
-
|
|
14982
|
-
|
|
15274
|
+
});
|
|
15275
|
+
this.loaded = true;
|
|
15276
|
+
this.loadStyles();
|
|
15277
|
+
}
|
|
15278
|
+
/**
|
|
15279
|
+
* Updates style mapping and fallback style.
|
|
15280
|
+
* This will trigger a re-style of all entities, and will stop existing style loads.
|
|
15281
|
+
* @param params
|
|
15282
|
+
*/
|
|
15283
|
+
UpdateStyleMapping(params) {
|
|
15284
|
+
var _a;
|
|
15285
|
+
if (params.styleMapping) {
|
|
15286
|
+
// Dereference.
|
|
15287
|
+
params.styleMapping = JSON.parse(JSON.stringify(params.styleMapping));
|
|
15288
|
+
this.styleMapping = params.styleMapping;
|
|
15289
|
+
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
15290
|
+
// We have some evil hard-coded style mappings that need to be fixed.
|
|
15291
|
+
// These exist within legacy project views.
|
|
15292
|
+
// Update: This now also lets people have a style mapping without a real style record.
|
|
15293
|
+
if ((_a = this.styleMapping) === null || _a === void 0 ? void 0 : _a.length) {
|
|
15294
|
+
for (let i = 0; i < this.styleMapping.length; i++) {
|
|
15295
|
+
const mapItem = this.styleMapping[i];
|
|
15296
|
+
const mapStyle = mapItem.style ? mapItem.style : mapItem.Style;
|
|
15297
|
+
this.styleMapping[i].style = correctStyle(mapStyle);
|
|
15298
|
+
}
|
|
14983
15299
|
}
|
|
14984
|
-
|
|
14985
|
-
|
|
15300
|
+
}
|
|
15301
|
+
if (!isNaN(params.fallbackStyleId) && params.fallbackStyleId != null) {
|
|
15302
|
+
this.fallbackStyleId = params.fallbackStyleId;
|
|
15303
|
+
}
|
|
15304
|
+
if (params.fallbackStyle) {
|
|
15305
|
+
this.fallbackStyle = params.fallbackStyle;
|
|
15306
|
+
}
|
|
15307
|
+
else {
|
|
15308
|
+
this.fallbackStyle = null;
|
|
15309
|
+
}
|
|
15310
|
+
if (params.scenario != null) {
|
|
15311
|
+
this.scenario = params.scenario;
|
|
15312
|
+
if (!this.shouldUpdateRegoStates && !!this.scenario) {
|
|
15313
|
+
this.shouldUpdateRegoStates = true;
|
|
14986
15314
|
}
|
|
14987
|
-
return integrity;
|
|
14988
15315
|
}
|
|
14989
|
-
|
|
14990
|
-
this.
|
|
14991
|
-
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
|
|
14995
|
-
|
|
14996
|
-
|
|
14997
|
-
|
|
14998
|
-
|
|
15316
|
+
if (params.historic != null) {
|
|
15317
|
+
this.historic = params.historic;
|
|
15318
|
+
if (params.historic || this.historic != params.historic) {
|
|
15319
|
+
this.shouldUpdateRegoStates = true;
|
|
15320
|
+
}
|
|
15321
|
+
}
|
|
15322
|
+
// Reload styles.
|
|
15323
|
+
if (this.loaded) {
|
|
15324
|
+
this.styledEntityIds.clear();
|
|
15325
|
+
this.styleMappingsLoaded.clear();
|
|
15326
|
+
this.loadStyles();
|
|
15327
|
+
this._styleProgressQueue.Call(true);
|
|
15328
|
+
// Putting all rendered things back into the queue.
|
|
15329
|
+
const regos = this.register.GetRegos({
|
|
15330
|
+
menuItemId: this.menuItemId
|
|
14999
15331
|
});
|
|
15332
|
+
this.QueueEntities(regos);
|
|
15000
15333
|
}
|
|
15001
|
-
|
|
15002
|
-
|
|
15003
|
-
|
|
15004
|
-
|
|
15005
|
-
|
|
15006
|
-
|
|
15334
|
+
}
|
|
15335
|
+
/**
|
|
15336
|
+
* Updates a cache of Entity objects to use when styling.
|
|
15337
|
+
* When a cache is available, a request won't be performed to get that Entity's data.
|
|
15338
|
+
* @param entityIds
|
|
15339
|
+
* @param entities If an object is not available for a supplied Entity ID, then the cache for it is removed.
|
|
15340
|
+
*/
|
|
15341
|
+
SetEntityCache(entityIds, entities) {
|
|
15342
|
+
// Turn the Entities array into an accessible dictionary.
|
|
15343
|
+
const newDataMap = new Map();
|
|
15344
|
+
if (entities) {
|
|
15345
|
+
for (let i = 0; i < entities.length; i++) {
|
|
15346
|
+
const entity = entities[i];
|
|
15347
|
+
if (entity.Bruce) {
|
|
15348
|
+
newDataMap.set(entity.Bruce.ID, entity);
|
|
15349
|
+
}
|
|
15350
|
+
}
|
|
15007
15351
|
}
|
|
15008
|
-
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
|
|
15012
|
-
|
|
15013
|
-
|
|
15014
|
-
|
|
15352
|
+
// Update the cache for each supplied Entity ID.
|
|
15353
|
+
for (let i = 0; i < entityIds.length; i++) {
|
|
15354
|
+
const entityId = entityIds[i];
|
|
15355
|
+
this.entityGatherer.SetEntityDataOverride(entityId, newDataMap.get(entityId));
|
|
15356
|
+
}
|
|
15357
|
+
}
|
|
15358
|
+
QueueEntities(regos, highPriority = false) {
|
|
15359
|
+
if (!this.loaded) {
|
|
15360
|
+
// Mark as pending?
|
|
15361
|
+
return;
|
|
15362
|
+
}
|
|
15363
|
+
for (let i = 0; i < regos.length; i++) {
|
|
15364
|
+
const rego = regos[i];
|
|
15365
|
+
this.overrideFeatureColor.set(rego.entityId, true);
|
|
15366
|
+
// We set a default colour right away to avoid race conditions at later times.
|
|
15367
|
+
CesiumEntityStyler.BakeDefaultColor({
|
|
15368
|
+
entity: rego.visual,
|
|
15369
|
+
viewer: this.viewer,
|
|
15370
|
+
override: false
|
|
15371
|
+
});
|
|
15372
|
+
}
|
|
15373
|
+
this.queueTilesetFeatureStyle(regos, highPriority);
|
|
15374
|
+
}
|
|
15375
|
+
/**
|
|
15376
|
+
* Calculates the current progress % and updates the progress if there is a change.
|
|
15377
|
+
*/
|
|
15378
|
+
updateStyleProgress() {
|
|
15379
|
+
if (this.disposed) {
|
|
15380
|
+
return;
|
|
15381
|
+
}
|
|
15382
|
+
const total = this.overrideFeatureColor.size;
|
|
15383
|
+
const styled = this.styledEntityIds.size;
|
|
15384
|
+
let progress = 100;
|
|
15385
|
+
if (styled < total) {
|
|
15386
|
+
progress = Math.round((styled / total) * 100);
|
|
15387
|
+
if (progress < 0) {
|
|
15388
|
+
progress = 0;
|
|
15015
15389
|
}
|
|
15016
|
-
|
|
15017
|
-
|
|
15018
|
-
let INTERVAL_WHILE_ANIMATING = 2.5 * 1000;
|
|
15019
|
-
let INTERVAL_WHILE_NOT_ANIMATING = 1000;
|
|
15020
|
-
if (this.historicInterpolation) {
|
|
15021
|
-
INTERVAL_WHILE_ANIMATING = 6 * 1000;
|
|
15022
|
-
INTERVAL_WHILE_NOT_ANIMATING = 3.5 * 1000;
|
|
15390
|
+
else if (progress > 100) {
|
|
15391
|
+
progress = 100;
|
|
15023
15392
|
}
|
|
15024
|
-
let lastUpdateTime = null;
|
|
15025
|
-
let delayQueue = new DelayQueue(() => {
|
|
15026
|
-
try {
|
|
15027
|
-
// If the timeline is animating then we'll wait longer to update.
|
|
15028
|
-
if (this.viewer.clock.shouldAnimate && lastUpdateTime) {
|
|
15029
|
-
if (Math.abs(new Date().getTime() - lastUpdateTime) < INTERVAL_WHILE_ANIMATING) {
|
|
15030
|
-
return;
|
|
15031
|
-
}
|
|
15032
|
-
}
|
|
15033
|
-
const current = this.historicAttrDateTime;
|
|
15034
|
-
this.updateHistoricDateTime();
|
|
15035
|
-
if (current != this.historicAttrDateTime) {
|
|
15036
|
-
this.emitHistoricData();
|
|
15037
|
-
}
|
|
15038
|
-
}
|
|
15039
|
-
catch (e) {
|
|
15040
|
-
console.error(e);
|
|
15041
|
-
}
|
|
15042
|
-
}, INTERVAL_WHILE_NOT_ANIMATING);
|
|
15043
|
-
let postUpdateRemoval = this.viewer.scene.postUpdate.addEventListener(() => {
|
|
15044
|
-
if (delayQueue) {
|
|
15045
|
-
delayQueue.Call();
|
|
15046
|
-
}
|
|
15047
|
-
});
|
|
15048
|
-
this.viewerDateTimeChangeRemoval = () => {
|
|
15049
|
-
delayQueue === null || delayQueue === void 0 ? void 0 : delayQueue.Dispose();
|
|
15050
|
-
postUpdateRemoval === null || postUpdateRemoval === void 0 ? void 0 : postUpdateRemoval();
|
|
15051
|
-
delayQueue = null;
|
|
15052
|
-
postUpdateRemoval = null;
|
|
15053
|
-
};
|
|
15054
15393
|
}
|
|
15055
|
-
|
|
15056
|
-
|
|
15057
|
-
|
|
15058
|
-
|
|
15394
|
+
if (this._styleProgress != progress) {
|
|
15395
|
+
this._styleProgress = progress;
|
|
15396
|
+
this.OnStyleProgress.Trigger(progress);
|
|
15397
|
+
}
|
|
15398
|
+
}
|
|
15399
|
+
getEntityRego(entityId) {
|
|
15400
|
+
return this.register.GetRego({
|
|
15401
|
+
entityId,
|
|
15402
|
+
menuItemId: this.menuItemId
|
|
15403
|
+
});
|
|
15404
|
+
}
|
|
15405
|
+
Dispose() {
|
|
15406
|
+
if (this.disposed) {
|
|
15407
|
+
return;
|
|
15408
|
+
}
|
|
15409
|
+
this.disposed = true;
|
|
15410
|
+
this._styleProgressQueue.Dispose();
|
|
15411
|
+
this.disposeGatherer();
|
|
15412
|
+
}
|
|
15413
|
+
async loadStyles() {
|
|
15414
|
+
var _a, _b;
|
|
15415
|
+
const counter = ++this.loadingCounter;
|
|
15416
|
+
this.styleMappingLoaded = false;
|
|
15417
|
+
this.styleMappingsLoaded.clear();
|
|
15418
|
+
// Apply state changes.
|
|
15419
|
+
this.entityGatherer.Empty();
|
|
15420
|
+
this.entityGatherer.Init(this.historic, this.expandSources);
|
|
15421
|
+
let fallbackStyleId = this.fallbackStyleId;
|
|
15422
|
+
if (fallbackStyleId && fallbackStyleId > 0) {
|
|
15423
|
+
try {
|
|
15424
|
+
let { style: data } = await Style.Get({
|
|
15425
|
+
api: this.api,
|
|
15426
|
+
styleId: fallbackStyleId
|
|
15427
|
+
});
|
|
15428
|
+
this.fallbackStyle = data;
|
|
15059
15429
|
}
|
|
15060
|
-
|
|
15061
|
-
|
|
15062
|
-
return true;
|
|
15063
|
-
}
|
|
15064
|
-
if (!before && after) {
|
|
15065
|
-
return true;
|
|
15066
|
-
}
|
|
15067
|
-
// Change must be at least 0.1 seconds.
|
|
15068
|
-
return Math.abs(before.getTime() - after.getTime()) > 100;
|
|
15069
|
-
};
|
|
15070
|
-
const oldDateTime = this.historicAttrDateTime ? new Date(this.historicAttrDateTime) : null;
|
|
15071
|
-
const newDateTime = JulianDate.toDate(this.viewer.clock.currentTime);
|
|
15072
|
-
if (isChanged(oldDateTime, newDateTime)) {
|
|
15073
|
-
this.historicAttrDateTime = newDateTime.toISOString();
|
|
15430
|
+
catch (e) {
|
|
15431
|
+
console.error(e);
|
|
15074
15432
|
}
|
|
15075
15433
|
}
|
|
15076
|
-
|
|
15077
|
-
|
|
15078
|
-
(_a = this.viewerDateTimeChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
15079
|
-
this.viewerDateTimeChangeRemoval = null;
|
|
15434
|
+
if (this.loadingCounter != counter) {
|
|
15435
|
+
return;
|
|
15080
15436
|
}
|
|
15081
|
-
|
|
15082
|
-
|
|
15437
|
+
// Load styles in the style mapping
|
|
15438
|
+
let styleMapping = this.styleMapping;
|
|
15439
|
+
if (!styleMapping) {
|
|
15440
|
+
styleMapping = [];
|
|
15083
15441
|
}
|
|
15084
|
-
|
|
15085
|
-
|
|
15086
|
-
|
|
15442
|
+
this.styleMapping = styleMapping;
|
|
15443
|
+
// Append all found entity-types.
|
|
15444
|
+
// That way we can mark them as loaded instead of just the ones in the style mapping.
|
|
15445
|
+
try {
|
|
15446
|
+
const modelTree = (_b = (_a = this.cTileset) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.modelTree;
|
|
15447
|
+
if (modelTree) {
|
|
15448
|
+
const entityTypeIds = this.getEntityTypeIdsFromModelTree(modelTree);
|
|
15449
|
+
for (let i = 0; i < entityTypeIds.length; i++) {
|
|
15450
|
+
const entityTypeId = entityTypeIds[i];
|
|
15451
|
+
if (styleMapping.findIndex(x => x.EntityTypeID == entityTypeId) <= -1) {
|
|
15452
|
+
styleMapping.push({
|
|
15453
|
+
EntityTypeID: entityTypeId,
|
|
15454
|
+
StyleID: this.fallbackStyle ? fallbackStyleId : 0,
|
|
15455
|
+
style: this.fallbackStyle
|
|
15456
|
+
});
|
|
15457
|
+
}
|
|
15458
|
+
}
|
|
15459
|
+
}
|
|
15087
15460
|
}
|
|
15088
|
-
|
|
15089
|
-
|
|
15090
|
-
delete this.registeredItems[menuItemId];
|
|
15091
|
-
this.updateState(true);
|
|
15461
|
+
catch (e) {
|
|
15462
|
+
console.error(e);
|
|
15092
15463
|
}
|
|
15093
|
-
|
|
15094
|
-
|
|
15095
|
-
|
|
15096
|
-
|
|
15097
|
-
|
|
15098
|
-
|
|
15099
|
-
|
|
15100
|
-
|
|
15101
|
-
|
|
15464
|
+
// Before we start the loop we'll do a single request for the needed Entity Types.
|
|
15465
|
+
// This will be aimed at rows that don't specify a Style and if the default fallback-
|
|
15466
|
+
//is set to 0 (using the default of the Entity Type).
|
|
15467
|
+
const typeMap = new Map();
|
|
15468
|
+
const typeIds = styleMapping.map(x => x.StyleID == -1 || Boolean(x.style) ? null : x.EntityTypeID).filter(x => !!x);
|
|
15469
|
+
if (typeIds.length) {
|
|
15470
|
+
// We'll split up into batches of 50.
|
|
15471
|
+
// Since we add the type IDs as query params I am paranoid of hitting the limit.
|
|
15472
|
+
const splits = Math.ceil(typeIds.length / 50);
|
|
15473
|
+
const batchSize = 50;
|
|
15474
|
+
for (let i = 0; i < splits; i++) {
|
|
15475
|
+
const batch = typeIds.slice(i * batchSize, (i + 1) * batchSize);
|
|
15476
|
+
const { entityTypes } = await EntityType.GetList({
|
|
15477
|
+
api: this.api,
|
|
15478
|
+
entityTypeIds: batch
|
|
15479
|
+
});
|
|
15480
|
+
for (let i = 0; i < entityTypes.length; i++) {
|
|
15481
|
+
const entityType = entityTypes[i];
|
|
15482
|
+
typeMap.set(entityType.ID, entityType);
|
|
15102
15483
|
}
|
|
15103
|
-
this.viewRect = viewRect;
|
|
15104
|
-
this.viewCenter = poi;
|
|
15105
15484
|
}
|
|
15106
15485
|
}
|
|
15107
|
-
|
|
15108
|
-
|
|
15109
|
-
|
|
15110
|
-
|
|
15111
|
-
let
|
|
15112
|
-
|
|
15113
|
-
|
|
15114
|
-
|
|
15115
|
-
|
|
15116
|
-
|
|
15117
|
-
|
|
15486
|
+
for (let i = 0; i < styleMapping.length; i++) {
|
|
15487
|
+
if (this.disposed) {
|
|
15488
|
+
break;
|
|
15489
|
+
}
|
|
15490
|
+
let styleMap = styleMapping[i];
|
|
15491
|
+
if (!styleMap.style && styleMap.StyleID != -1) {
|
|
15492
|
+
let styleId = styleMap.StyleID;
|
|
15493
|
+
// Get default style of the entity type, if
|
|
15494
|
+
//no default is already specified.
|
|
15495
|
+
if (!styleId && !this.fallbackStyle) {
|
|
15496
|
+
try {
|
|
15497
|
+
let entityType = typeMap.get(styleMap.EntityTypeID);
|
|
15498
|
+
// If the map excluded the type for whatever reason we'll load it now.
|
|
15499
|
+
if (!entityType) {
|
|
15500
|
+
entityType = (await EntityType.Get({
|
|
15501
|
+
api: this.api,
|
|
15502
|
+
entityTypeId: styleMap.EntityTypeID
|
|
15503
|
+
})).entityType;
|
|
15504
|
+
}
|
|
15505
|
+
styleId = entityType === null || entityType === void 0 ? void 0 : entityType["DisplaySetting.ID"];
|
|
15118
15506
|
}
|
|
15119
|
-
|
|
15120
|
-
|
|
15507
|
+
catch (e) {
|
|
15508
|
+
console.error(e);
|
|
15121
15509
|
}
|
|
15122
|
-
|
|
15123
|
-
|
|
15124
|
-
|
|
15125
|
-
|
|
15126
|
-
|
|
15127
|
-
|
|
15128
|
-
|
|
15510
|
+
}
|
|
15511
|
+
if (styleId) {
|
|
15512
|
+
try {
|
|
15513
|
+
let { style: data } = await Style.Get({
|
|
15514
|
+
api: this.api,
|
|
15515
|
+
styleId
|
|
15516
|
+
});
|
|
15517
|
+
if (data) {
|
|
15518
|
+
styleMap.style = data;
|
|
15519
|
+
styleMap.StyleID = styleId;
|
|
15129
15520
|
}
|
|
15130
15521
|
}
|
|
15131
|
-
|
|
15132
|
-
|
|
15133
|
-
if (!typeIds.includes(itemTypeId)) {
|
|
15134
|
-
typeIds.push(itemTypeId);
|
|
15135
|
-
}
|
|
15522
|
+
catch (e) {
|
|
15523
|
+
console.error(e);
|
|
15136
15524
|
}
|
|
15137
15525
|
}
|
|
15526
|
+
if (this.loadingCounter != counter) {
|
|
15527
|
+
return;
|
|
15528
|
+
}
|
|
15138
15529
|
}
|
|
15139
|
-
|
|
15140
|
-
|
|
15141
|
-
|
|
15142
|
-
|
|
15143
|
-
|
|
15144
|
-
|
|
15145
|
-
|
|
15146
|
-
|
|
15147
|
-
|
|
15148
|
-
this.startGetterLoop();
|
|
15149
|
-
this.viewAreaSub();
|
|
15150
|
-
this.viewerDateTimeSub();
|
|
15530
|
+
this.styleMappingsLoaded.set(styleMap.EntityTypeID, true);
|
|
15531
|
+
if (this.loaded) {
|
|
15532
|
+
// If we have a bunch of Entities that were waiting for the style to load,
|
|
15533
|
+
// then we can pass them to the gatherer now.
|
|
15534
|
+
const relatedIds = this.stylePendingEntityIds.get(styleMap.EntityTypeID);
|
|
15535
|
+
if (relatedIds) {
|
|
15536
|
+
this.entityGatherer.Queue(Array.from(relatedIds));
|
|
15537
|
+
this.stylePendingEntityIds.delete(styleMap.EntityTypeID);
|
|
15538
|
+
}
|
|
15151
15539
|
}
|
|
15152
|
-
|
|
15153
|
-
|
|
15154
|
-
|
|
15155
|
-
|
|
15540
|
+
}
|
|
15541
|
+
if (this.loadingCounter != counter) {
|
|
15542
|
+
return;
|
|
15543
|
+
}
|
|
15544
|
+
this.styleMappingLoaded = true;
|
|
15545
|
+
if (!this.disposed && this.loaded) {
|
|
15546
|
+
if (this.loadingCounter != counter) {
|
|
15547
|
+
return;
|
|
15548
|
+
}
|
|
15549
|
+
// Queue all Entities that are pending styling.
|
|
15550
|
+
const pendingKeys = this.stylePendingEntityIds.keys();
|
|
15551
|
+
for (const key of pendingKeys) {
|
|
15552
|
+
const relatedIds = this.stylePendingEntityIds[key];
|
|
15553
|
+
if (relatedIds) {
|
|
15554
|
+
this.entityGatherer.Queue(Array.from(relatedIds));
|
|
15555
|
+
}
|
|
15156
15556
|
}
|
|
15557
|
+
this.stylePendingEntityIds.clear();
|
|
15157
15558
|
}
|
|
15158
|
-
|
|
15159
|
-
|
|
15160
|
-
|
|
15161
|
-
|
|
15559
|
+
}
|
|
15560
|
+
disposeGatherer() {
|
|
15561
|
+
if (this.entityGatherer) {
|
|
15562
|
+
this.entityGatherer.Dispose();
|
|
15563
|
+
this.entityGatherer = null;
|
|
15162
15564
|
}
|
|
15163
|
-
|
|
15164
|
-
|
|
15165
|
-
|
|
15166
|
-
|
|
15167
|
-
|
|
15168
|
-
|
|
15169
|
-
|
|
15170
|
-
|
|
15171
|
-
|
|
15172
|
-
{
|
|
15173
|
-
|
|
15174
|
-
|
|
15175
|
-
|
|
15565
|
+
}
|
|
15566
|
+
getEntityTypeIdsFromModelTree(modelTree) {
|
|
15567
|
+
const entityTypeIds = [];
|
|
15568
|
+
this.digEntityTypeIdsFromModelTreeBranch(modelTree, entityTypeIds);
|
|
15569
|
+
return entityTypeIds;
|
|
15570
|
+
}
|
|
15571
|
+
digEntityTypeIdsFromModelTreeBranch(branch, arr) {
|
|
15572
|
+
if (branch) {
|
|
15573
|
+
// Does not yet include this entity type id.
|
|
15574
|
+
if (branch.typeId && !arr.includes(branch.typeId)) {
|
|
15575
|
+
arr.push(branch.typeId);
|
|
15576
|
+
}
|
|
15577
|
+
if (branch.children) {
|
|
15578
|
+
for (let i = 0; i < branch.children.length; i++) {
|
|
15579
|
+
let child = branch.children[i];
|
|
15580
|
+
this.digEntityTypeIdsFromModelTreeBranch(child, arr);
|
|
15176
15581
|
}
|
|
15177
|
-
this.getterLoopAbortControllers = newAbortControllers;
|
|
15178
15582
|
}
|
|
15179
|
-
|
|
15180
|
-
|
|
15181
|
-
|
|
15182
|
-
|
|
15183
|
-
|
|
15184
|
-
|
|
15185
|
-
|
|
15186
|
-
|
|
15187
|
-
|
|
15188
|
-
|
|
15189
|
-
|
|
15190
|
-
|
|
15191
|
-
let retryDelay = 0;
|
|
15192
|
-
let prevFirstId = "";
|
|
15193
|
-
let prevLastId = "";
|
|
15194
|
-
let prevTicks = 0;
|
|
15195
|
-
while ((!this.viewCenter || !this.viewRect) && this.getterLoopId == loopId) {
|
|
15196
|
-
await delay(RETRY_DELAY_INCREMENT);
|
|
15583
|
+
}
|
|
15584
|
+
}
|
|
15585
|
+
queueTilesetFeatureStyle(entities, highPriority) {
|
|
15586
|
+
const needsDataIds = [];
|
|
15587
|
+
for (const rego of entities) {
|
|
15588
|
+
if (!this.overrideFeatureColor.has(rego.entityId)) {
|
|
15589
|
+
this.overrideFeatureColor.set(rego.entityId, false);
|
|
15590
|
+
}
|
|
15591
|
+
const typeId = rego.entityTypeId || "";
|
|
15592
|
+
if (this.styleMappingLoaded || this.styleMappingsLoaded.get(typeId)) {
|
|
15593
|
+
if (this.getTilesetFeatureNeedsFullData(typeId)) {
|
|
15594
|
+
needsDataIds.push(rego.entityId);
|
|
15197
15595
|
}
|
|
15198
|
-
|
|
15199
|
-
|
|
15596
|
+
else {
|
|
15597
|
+
this.styleTilesetFeature(rego);
|
|
15200
15598
|
}
|
|
15201
|
-
|
|
15202
|
-
|
|
15203
|
-
|
|
15599
|
+
}
|
|
15600
|
+
else {
|
|
15601
|
+
if (!this.stylePendingEntityIds.has(typeId)) {
|
|
15602
|
+
this.stylePendingEntityIds.set(typeId, new Set());
|
|
15204
15603
|
}
|
|
15205
|
-
|
|
15206
|
-
(_a = this.onScanUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(cells);
|
|
15207
|
-
let curCellIndex = cells.length > 0 ? 0 : null;
|
|
15208
|
-
let postedScanning = false;
|
|
15209
|
-
let postedLoading = false;
|
|
15210
|
-
let total = 0;
|
|
15211
|
-
while (retryAttempts > 0 && curCellIndex != null) {
|
|
15212
|
-
if (retryDelay > 0) {
|
|
15213
|
-
await delay(retryDelay);
|
|
15214
|
-
}
|
|
15215
|
-
if (this.getterLoopId != loopId) {
|
|
15216
|
-
break;
|
|
15217
|
-
}
|
|
15218
|
-
if (!postedScanning) {
|
|
15219
|
-
this.postStatus({ msg: EStatus.Scanning, revoking: false });
|
|
15220
|
-
postedScanning = true;
|
|
15221
|
-
}
|
|
15222
|
-
const curCell = cells[curCellIndex];
|
|
15223
|
-
if (curCell.IsFetched()) {
|
|
15224
|
-
curCell.Fetching = false;
|
|
15225
|
-
curCellIndex += 1;
|
|
15226
|
-
if (cells[curCellIndex]) {
|
|
15227
|
-
cells[curCellIndex].Fetching = true;
|
|
15228
|
-
}
|
|
15229
|
-
else {
|
|
15230
|
-
curCellIndex = null;
|
|
15231
|
-
}
|
|
15232
|
-
(_b = this.onScanUpdate) === null || _b === void 0 ? void 0 : _b.Trigger(cells);
|
|
15233
|
-
continue;
|
|
15234
|
-
}
|
|
15235
|
-
try {
|
|
15236
|
-
let response = {
|
|
15237
|
-
entities: [],
|
|
15238
|
-
nextPage: false,
|
|
15239
|
-
nextPageUrl: null
|
|
15240
|
-
};
|
|
15241
|
-
await SharedGetters.Queue.Run("Loading Entities from Menu Item that loads Entity Type: " + this.typeIds, async () => {
|
|
15242
|
-
var _a;
|
|
15243
|
-
if (abortController.signal.aborted || !((_a = this.GetMenuItems()) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
15244
|
-
return;
|
|
15245
|
-
}
|
|
15246
|
-
// API gave us a URL to use.
|
|
15247
|
-
if (curCell.FetchURL) {
|
|
15248
|
-
const tmpResponse = await this.api.get(curCell.FetchURL, {
|
|
15249
|
-
abortSignal: abortController.signal,
|
|
15250
|
-
noCache: true
|
|
15251
|
-
});
|
|
15252
|
-
// Same mapping as bruce-models doing Entity.GetList.
|
|
15253
|
-
response = {
|
|
15254
|
-
entities: tmpResponse.Items ? tmpResponse.Items : [],
|
|
15255
|
-
nextPage: tmpResponse.NextPage,
|
|
15256
|
-
nextPageUrl: tmpResponse.NextPageURL
|
|
15257
|
-
};
|
|
15258
|
-
}
|
|
15259
|
-
else {
|
|
15260
|
-
response = await Entity$1.GetList({
|
|
15261
|
-
api: this.api,
|
|
15262
|
-
scenario: this.scenario,
|
|
15263
|
-
historicKey: this.historicAttrKey,
|
|
15264
|
-
historicPoint: (this.historicAttrKey || this.historic) ? this.historicAttrDateTime : null,
|
|
15265
|
-
schemaId: this.schemaId,
|
|
15266
|
-
filter: {
|
|
15267
|
-
pageSize: PAGE_SIZE,
|
|
15268
|
-
pageIndex: curCell.FetchPageIndex,
|
|
15269
|
-
entityTypeId: this.typeIds,
|
|
15270
|
-
layerIds: this.tagIds,
|
|
15271
|
-
// Any tag specified will be allowed.
|
|
15272
|
-
layerIdsOperator: "in",
|
|
15273
|
-
bounds: curCell.GetBounds(),
|
|
15274
|
-
sortOrder: Api.ESortOrder.Asc,
|
|
15275
|
-
entityTypeConditions: this.attrFilter
|
|
15276
|
-
},
|
|
15277
|
-
viaCdn: this.viaCdn,
|
|
15278
|
-
migrated: true,
|
|
15279
|
-
// If we're taking 2+ minutes to make a query, it's a dud.
|
|
15280
|
-
// This is a timeout imposed on our DB and not external sources.
|
|
15281
|
-
// Honestly could lower down to 30 seconds, but we'll keep it high for now.
|
|
15282
|
-
maxSearchTimeSec: 60 * 2,
|
|
15283
|
-
req: {
|
|
15284
|
-
// If we are passing in an abort, we MUST pass in noCache.
|
|
15285
|
-
// Otherwise we will cache an aborted request.
|
|
15286
|
-
noCache: true,
|
|
15287
|
-
abortSignal: abortController.signal
|
|
15288
|
-
}
|
|
15289
|
-
});
|
|
15290
|
-
}
|
|
15291
|
-
});
|
|
15292
|
-
const entities = response.entities;
|
|
15293
|
-
const integrity = this.getIntegrityId();
|
|
15294
|
-
if (loopIntegrity == integrity && entities) {
|
|
15295
|
-
(_c = this.onUpdate) === null || _c === void 0 ? void 0 : _c.Trigger(entities);
|
|
15296
|
-
}
|
|
15297
|
-
if (this.gatheredIntegrity != integrity) {
|
|
15298
|
-
this.gatheredIntegrity = integrity;
|
|
15299
|
-
this.gatheredEntityIds = [];
|
|
15300
|
-
}
|
|
15301
|
-
// Add to the integrity list for any new IDs found.
|
|
15302
|
-
// This lets us keep track of all IDs we've found within the same integrity for historic data.
|
|
15303
|
-
if (this.historicAttrKey || this.historic) {
|
|
15304
|
-
for (let i = 0; i < entities.length; i++) {
|
|
15305
|
-
const entity = entities[i];
|
|
15306
|
-
if (!this.gatheredEntityIds.includes(entity.Bruce.ID)) {
|
|
15307
|
-
this.gatheredEntityIds.push(entity.Bruce.ID);
|
|
15308
|
-
}
|
|
15309
|
-
}
|
|
15310
|
-
}
|
|
15311
|
-
if (this.getterLoopId != loopId) {
|
|
15312
|
-
break;
|
|
15313
|
-
}
|
|
15314
|
-
if (entities.length) {
|
|
15315
|
-
total += entities.length;
|
|
15316
|
-
}
|
|
15317
|
-
if (!postedLoading) {
|
|
15318
|
-
this.postStatus({ msg: EStatus.Loading, revoking: false });
|
|
15319
|
-
postedLoading = true;
|
|
15320
|
-
}
|
|
15321
|
-
// Only mark as fetched when ALL pages are done.
|
|
15322
|
-
// Known issue where external sources may return less than page size.
|
|
15323
|
-
// Right now we're making it as fetched as we're siding with the majority use-case.
|
|
15324
|
-
if (
|
|
15325
|
-
// API explicity says no more pages.
|
|
15326
|
-
response.nextPage === false ||
|
|
15327
|
-
// API didn't explicity say anything so we guess based on size of response.
|
|
15328
|
-
(response.nextPage == null &&
|
|
15329
|
-
(entities.length <= 0 || entities.length < PAGE_SIZE))) {
|
|
15330
|
-
curCell.Fetched = true;
|
|
15331
|
-
curCell.Fetching = false;
|
|
15332
|
-
(_d = this.onScanUpdate) === null || _d === void 0 ? void 0 : _d.Trigger(cells);
|
|
15333
|
-
continue;
|
|
15334
|
-
}
|
|
15335
|
-
// Checking to make sure it's not just the same batch over and over again.
|
|
15336
|
-
if (entities.length > 0) {
|
|
15337
|
-
const first = (_f = (_e = entities[0]) === null || _e === void 0 ? void 0 : _e.Bruce) === null || _f === void 0 ? void 0 : _f.ID;
|
|
15338
|
-
const last = (_h = (_g = entities[entities.length - 1]) === null || _g === void 0 ? void 0 : _g.Bruce) === null || _h === void 0 ? void 0 : _h.ID;
|
|
15339
|
-
if (prevFirstId == first && prevLastId == last) {
|
|
15340
|
-
prevTicks += 1;
|
|
15341
|
-
if (prevTicks > 3) {
|
|
15342
|
-
break;
|
|
15343
|
-
}
|
|
15344
|
-
}
|
|
15345
|
-
else {
|
|
15346
|
-
prevFirstId = first;
|
|
15347
|
-
prevLastId = last;
|
|
15348
|
-
prevTicks = 0;
|
|
15349
|
-
}
|
|
15350
|
-
}
|
|
15351
|
-
// Using URL if specified.
|
|
15352
|
-
// If not then we'll just manually paginate.
|
|
15353
|
-
curCell.FetchURL = response.nextPageUrl;
|
|
15354
|
-
curCell.FetchPageIndex++;
|
|
15355
|
-
// Request passed so let's assume it was server hiccup and refresh counts.
|
|
15356
|
-
retryAttempts = MAX_RETRY_ATTEMPTS;
|
|
15357
|
-
retryDelay = 0;
|
|
15358
|
-
}
|
|
15359
|
-
catch (e) {
|
|
15360
|
-
// Ignore abort errors.
|
|
15361
|
-
if (e && typeof e === "object" && e.name == "AbortError") {
|
|
15362
|
-
// console.debug("Aborted entity-filter-getter request.");
|
|
15363
|
-
break;
|
|
15364
|
-
}
|
|
15365
|
-
console.error(e);
|
|
15366
|
-
if (this.getterLoopId != loopId) {
|
|
15367
|
-
break;
|
|
15368
|
-
}
|
|
15369
|
-
// Request failed so let's add a delay and try again soon.
|
|
15370
|
-
retryDelay += RETRY_DELAY_INCREMENT;
|
|
15371
|
-
retryAttempts -= 1;
|
|
15372
|
-
}
|
|
15373
|
-
await delay(REQUEST_PAGE_DELAY);
|
|
15374
|
-
}
|
|
15375
|
-
if (postedLoading) {
|
|
15376
|
-
this.postStatus({ msg: EStatus.Loading, revoking: true });
|
|
15377
|
-
}
|
|
15378
|
-
if (postedScanning) {
|
|
15379
|
-
this.postStatus({ msg: EStatus.Scanning, revoking: true });
|
|
15380
|
-
}
|
|
15381
|
-
})().then(() => {
|
|
15382
|
-
this.looping -= 1;
|
|
15383
|
-
}).catch(() => {
|
|
15384
|
-
this.looping -= 1;
|
|
15385
|
-
});
|
|
15386
|
-
}
|
|
15387
|
-
/**
|
|
15388
|
-
* Gets the historic state of found Entities for the current date times and emits them.
|
|
15389
|
-
* Since geometry searches are tied to the base Entity, we don't have to re-scan the viewport.
|
|
15390
|
-
*/
|
|
15391
|
-
emitHistoricData() {
|
|
15392
|
-
if (!this.GetMenuItems().length) {
|
|
15393
|
-
return;
|
|
15394
|
-
}
|
|
15395
|
-
let integrity = this.getIntegrityId();
|
|
15396
|
-
// Gathered ID does't match current one.
|
|
15397
|
-
if (this.gatheredIntegrity != integrity) {
|
|
15398
|
-
return;
|
|
15604
|
+
this.stylePendingEntityIds.get(typeId).add(rego.entityId);
|
|
15399
15605
|
}
|
|
15400
|
-
|
|
15401
|
-
|
|
15402
|
-
|
|
15403
|
-
this.historicRefreshAbortController.abort();
|
|
15404
|
-
this.historicRefreshAbortController = null;
|
|
15405
|
-
}
|
|
15406
|
-
(async () => {
|
|
15407
|
-
var _a;
|
|
15408
|
-
try {
|
|
15409
|
-
// Loop through all IDs we've found and get their historic records.
|
|
15410
|
-
for (let i = 0; i < this.gatheredEntityIds.length; i += SCAN_BATCH_SIZE) {
|
|
15411
|
-
let batch = this.gatheredEntityIds.slice(i, i + SCAN_BATCH_SIZE);
|
|
15412
|
-
if (!batch.length) {
|
|
15413
|
-
break;
|
|
15414
|
-
}
|
|
15415
|
-
// Controller we can use to abort the request when a new loop starts.
|
|
15416
|
-
const controller = this.historicRefreshAbortController = new AbortController();
|
|
15417
|
-
let entities = [];
|
|
15418
|
-
await SharedGetters.Queue.Run("Refreshing historic data in Menu Item that loads Entity Type: " + this.typeIds, async () => {
|
|
15419
|
-
var _a;
|
|
15420
|
-
if (controller.signal.aborted || !((_a = this.GetMenuItems()) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
15421
|
-
return;
|
|
15422
|
-
}
|
|
15423
|
-
entities = (await Entity$1.GetList({
|
|
15424
|
-
api: this.api,
|
|
15425
|
-
scenario: this.scenario,
|
|
15426
|
-
historicKey: this.historicAttrKey,
|
|
15427
|
-
historicPoint: historicAttrDateTime,
|
|
15428
|
-
schemaId: this.schemaId,
|
|
15429
|
-
filter: {
|
|
15430
|
-
pageSize: batch.length,
|
|
15431
|
-
pageIndex: 0,
|
|
15432
|
-
entityTypeId: this.typeIds,
|
|
15433
|
-
layerIds: this.tagIds,
|
|
15434
|
-
layerIdsOperator: "in",
|
|
15435
|
-
sortOrder: Api.ESortOrder.Asc,
|
|
15436
|
-
entityTypeConditions: {
|
|
15437
|
-
"ID": {
|
|
15438
|
-
"in": batch
|
|
15439
|
-
}
|
|
15440
|
-
},
|
|
15441
|
-
},
|
|
15442
|
-
viaCdn: this.viaCdn,
|
|
15443
|
-
migrated: true,
|
|
15444
|
-
// If we're taking 5+ minutes to make a query, it's a dud.
|
|
15445
|
-
// This is a timeout imposed on our DB and not external sources.
|
|
15446
|
-
// Honestly could lower down to 30 seconds, but we'll keep it high for now.
|
|
15447
|
-
maxSearchTimeSec: 60 * 5,
|
|
15448
|
-
req: {
|
|
15449
|
-
// If we are passing in an abort, we MUST pass in noCache.
|
|
15450
|
-
// Otherwise we will cache an aborted request.
|
|
15451
|
-
noCache: true,
|
|
15452
|
-
abortSignal: controller.signal
|
|
15453
|
-
}
|
|
15454
|
-
})).entities;
|
|
15455
|
-
});
|
|
15456
|
-
// Date changed.
|
|
15457
|
-
if (this.historicAttrDateTime != historicAttrDateTime) {
|
|
15458
|
-
break;
|
|
15459
|
-
}
|
|
15460
|
-
// Integrity changed.
|
|
15461
|
-
if (this.gatheredIntegrity != integrity) {
|
|
15462
|
-
break;
|
|
15463
|
-
}
|
|
15464
|
-
// No Menu Items.
|
|
15465
|
-
if (!this.GetMenuItems().length) {
|
|
15466
|
-
break;
|
|
15467
|
-
}
|
|
15468
|
-
(_a = this.onUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(entities);
|
|
15469
|
-
}
|
|
15470
|
-
}
|
|
15471
|
-
catch (e) {
|
|
15472
|
-
// Ignore abort errors.
|
|
15473
|
-
if (e && typeof e === "object" && e.name == "AbortError") {
|
|
15474
|
-
// console.debug("Aborted entity-filter-getter historic refresh request.");
|
|
15475
|
-
return;
|
|
15476
|
-
}
|
|
15477
|
-
console.error(e);
|
|
15478
|
-
}
|
|
15479
|
-
})();
|
|
15606
|
+
}
|
|
15607
|
+
if (needsDataIds.length) {
|
|
15608
|
+
this.entityGatherer.Queue(needsDataIds, highPriority);
|
|
15480
15609
|
}
|
|
15481
15610
|
}
|
|
15482
|
-
|
|
15483
|
-
|
|
15484
|
-
|
|
15485
|
-
function createFilterGetterCacheKey(params) {
|
|
15486
|
-
let cacheKey = "";
|
|
15487
|
-
cacheKey += params.api.GetBaseUrl();
|
|
15488
|
-
// Not including Type ID in the cache key now.
|
|
15489
|
-
// This allows us to re-use the same getter between Entity Types.
|
|
15490
|
-
// cacheKey += params.typeId;
|
|
15491
|
-
cacheKey += params.batchSize;
|
|
15492
|
-
cacheKey += String(params.cdn);
|
|
15493
|
-
cacheKey += params.schemaId ? params.schemaId : "";
|
|
15494
|
-
cacheKey += JSON.stringify(params.tagIds ? params.tagIds : []);
|
|
15495
|
-
cacheKey += params.historicAttrKey ? params.historicAttrKey : "";
|
|
15496
|
-
cacheKey += params.historic ? "true" : "false";
|
|
15497
|
-
cacheKey += params.scenario ? params.scenario : 0;
|
|
15498
|
-
if (params.historicAttrKey) {
|
|
15499
|
-
cacheKey += params.historicInterpolation ? "true" : "false";
|
|
15611
|
+
styleTilesetFeature(entity) {
|
|
15612
|
+
this.styleTilesetFeatureFullData(entity, null, []);
|
|
15500
15613
|
}
|
|
15501
|
-
|
|
15502
|
-
|
|
15503
|
-
|
|
15504
|
-
|
|
15505
|
-
|
|
15506
|
-
(function (SharedGetters) {
|
|
15507
|
-
class Cache {
|
|
15508
|
-
constructor() {
|
|
15509
|
-
this.data = {};
|
|
15614
|
+
styleTilesetFeatureFullData(entity, data, tags) {
|
|
15615
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
15616
|
+
const visual = entity.visual;
|
|
15617
|
+
if (!visual || !(visual instanceof Cesium3DTileFeature)) {
|
|
15618
|
+
return;
|
|
15510
15619
|
}
|
|
15511
|
-
|
|
15512
|
-
|
|
15513
|
-
|
|
15514
|
-
|
|
15515
|
-
|
|
15516
|
-
|
|
15517
|
-
|
|
15518
|
-
|
|
15519
|
-
|
|
15520
|
-
|
|
15521
|
-
|
|
15522
|
-
|
|
15523
|
-
|
|
15524
|
-
|
|
15525
|
-
|
|
15526
|
-
|
|
15527
|
-
|
|
15528
|
-
|
|
15620
|
+
const style = this.getTilesetFeatureStyle(entity.entityTypeId);
|
|
15621
|
+
const bColor = style && ((_a = style.modelStyle) === null || _a === void 0 ? void 0 : _a.fillColor) ? Calculator.GetColor(style.modelStyle.fillColor, data, tags) : null;
|
|
15622
|
+
let cColor = null;
|
|
15623
|
+
if (bColor == null) {
|
|
15624
|
+
cColor = Color.WHITE;
|
|
15625
|
+
}
|
|
15626
|
+
else {
|
|
15627
|
+
cColor = colorToCColor$3(bColor);
|
|
15628
|
+
}
|
|
15629
|
+
const override = this.overrideFeatureColor.get(entity.entityId) == true;
|
|
15630
|
+
CesiumEntityStyler.SetDefaultColor({
|
|
15631
|
+
color: cColor,
|
|
15632
|
+
entity: visual,
|
|
15633
|
+
viewer: this.viewer,
|
|
15634
|
+
override: override
|
|
15635
|
+
});
|
|
15636
|
+
this.overrideFeatureColor.set(entity.entityId, true);
|
|
15637
|
+
this.styledEntityIds.set(entity.entityId, true);
|
|
15638
|
+
this._styleProgressQueue.Call();
|
|
15639
|
+
// Since we only need to update it for scenarios right now.
|
|
15640
|
+
// We'll avoid doing it if not needed, eg: first render and no scenario (same state as default).
|
|
15641
|
+
if (this.shouldUpdateRegoStates && (override || ((_b = data === null || data === void 0 ? void 0 : data.Bruce) === null || _b === void 0 ? void 0 : _b.Scenario) || this.historic)) {
|
|
15642
|
+
// Update the Entity's rego state.
|
|
15643
|
+
let changed = false;
|
|
15644
|
+
// Changed scenario.
|
|
15645
|
+
if (entity.scenario != ((_c = data === null || data === void 0 ? void 0 : data.Bruce) === null || _c === void 0 ? void 0 : _c.Scenario)) {
|
|
15646
|
+
entity.scenario = (_d = data === null || data === void 0 ? void 0 : data.Bruce) === null || _d === void 0 ? void 0 : _d.Scenario;
|
|
15647
|
+
changed = true;
|
|
15648
|
+
}
|
|
15649
|
+
// Changed historic.
|
|
15650
|
+
if ((data && isHistoricMetadataChanged(entity, data)) || (!data && ((_e = entity.historicLayers) === null || _e === void 0 ? void 0 : _e.length) && !((_g = (_f = data.Bruce) === null || _f === void 0 ? void 0 : _f.HistoricLayers) === null || _g === void 0 ? void 0 : _g.length))) {
|
|
15651
|
+
entity.historicLayers = (_h = data === null || data === void 0 ? void 0 : data.Bruce) === null || _h === void 0 ? void 0 : _h.HistoricLayers;
|
|
15652
|
+
changed = true;
|
|
15653
|
+
}
|
|
15654
|
+
// Something changed, trigger a rego update.
|
|
15655
|
+
// This lets UI know when the rego has changed.
|
|
15656
|
+
if (changed) {
|
|
15657
|
+
this.register.OnUpdate.Trigger({
|
|
15658
|
+
type: VisualsRegister.EVisualUpdateType.Update,
|
|
15659
|
+
entityId: entity.entityId,
|
|
15660
|
+
rego: entity
|
|
15529
15661
|
});
|
|
15530
|
-
this.data[cacheKey] = getter;
|
|
15531
|
-
/**
|
|
15532
|
-
* Debug option.
|
|
15533
|
-
* This will display the bounds of the cells that are being fetched.
|
|
15534
|
-
*/
|
|
15535
|
-
if (params.viewer && params.debugShowBounds) {
|
|
15536
|
-
// Cell id -> entity.
|
|
15537
|
-
const cellCache = {};
|
|
15538
|
-
const cellPrefix = ObjectUtils.UId(10) + "_";
|
|
15539
|
-
getter.OnScanUpdate.Subscribe((cells) => {
|
|
15540
|
-
if (window.ON_SCAN_UPDATE_PAUSED == true) {
|
|
15541
|
-
return;
|
|
15542
|
-
}
|
|
15543
|
-
const curCellIds = [];
|
|
15544
|
-
let fetchingCellId = null;
|
|
15545
|
-
const fetchedCells = {};
|
|
15546
|
-
cells.forEach((cell) => {
|
|
15547
|
-
var _a;
|
|
15548
|
-
const bounds = cell.GetBounds();
|
|
15549
|
-
const id = cellPrefix + bounds.east + "_" + bounds.north + "_" + bounds.south + "_" + bounds.west;
|
|
15550
|
-
curCellIds.push(id);
|
|
15551
|
-
fetchedCells[id] = cell.IsFetched();
|
|
15552
|
-
fetchingCellId = cell.Fetching ? id : fetchingCellId;
|
|
15553
|
-
let material = null;
|
|
15554
|
-
if (fetchedCells[id]) {
|
|
15555
|
-
material = Color.LIGHTGREEN.clone().withAlpha(0.3);
|
|
15556
|
-
}
|
|
15557
|
-
else if (fetchingCellId == id) {
|
|
15558
|
-
material = Color.LIGHTBLUE.clone().withAlpha(0.3);
|
|
15559
|
-
}
|
|
15560
|
-
else {
|
|
15561
|
-
material = Color.GOLD.clone().withAlpha(0.3);
|
|
15562
|
-
}
|
|
15563
|
-
if (cellCache[id]) {
|
|
15564
|
-
const rect = (_a = cellCache[id]) === null || _a === void 0 ? void 0 : _a.rectangle;
|
|
15565
|
-
if (rect) {
|
|
15566
|
-
rect.material = material;
|
|
15567
|
-
}
|
|
15568
|
-
return;
|
|
15569
|
-
}
|
|
15570
|
-
const rect = new Rectangle(Math$1.toRadians(bounds.west), Math$1.toRadians(bounds.south), Math$1.toRadians(bounds.east), Math$1.toRadians(bounds.north));
|
|
15571
|
-
const entity = params.viewer.entities.add(new Entity({
|
|
15572
|
-
id: id,
|
|
15573
|
-
rectangle: {
|
|
15574
|
-
coordinates: rect,
|
|
15575
|
-
fill: true,
|
|
15576
|
-
//material: Cesium.Color.fromRandom().withAlpha(0.3),
|
|
15577
|
-
material: material,
|
|
15578
|
-
zIndex: 0
|
|
15579
|
-
},
|
|
15580
|
-
// point: {
|
|
15581
|
-
// pixelSize: 15,
|
|
15582
|
-
// outlineColor: Cesium.Color.WHITE,
|
|
15583
|
-
// outlineWidth: 2,
|
|
15584
|
-
// color: Cesium.Color.fromRandom().withAlpha(0.5),
|
|
15585
|
-
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
|
15586
|
-
// },
|
|
15587
|
-
position: Cartesian3.fromRadians((rect.east + rect.west) / 2, (rect.north + rect.south) / 2)
|
|
15588
|
-
}));
|
|
15589
|
-
cellCache[id] = entity;
|
|
15590
|
-
});
|
|
15591
|
-
Object.keys(cellCache).forEach((id) => {
|
|
15592
|
-
if (curCellIds.indexOf(id) == -1) {
|
|
15593
|
-
const entity = cellCache[id];
|
|
15594
|
-
if (entity && params.viewer.entities.contains(entity)) {
|
|
15595
|
-
params.viewer.entities.remove(entity);
|
|
15596
|
-
}
|
|
15597
|
-
delete cellCache[id];
|
|
15598
|
-
}
|
|
15599
|
-
});
|
|
15600
|
-
});
|
|
15601
|
-
}
|
|
15602
15662
|
}
|
|
15603
|
-
return getter;
|
|
15604
15663
|
}
|
|
15605
15664
|
}
|
|
15606
|
-
|
|
15607
|
-
|
|
15608
|
-
|
|
15609
|
-
|
|
15610
|
-
|
|
15611
|
-
|
|
15612
|
-
(function (Queue) {
|
|
15613
|
-
const queue = [];
|
|
15614
|
-
let isProcessing = false;
|
|
15615
|
-
/**
|
|
15616
|
-
* Called to run a provided function.
|
|
15617
|
-
* When the function is complete, the next function in the queue will be called.
|
|
15618
|
-
* This function will resolve when the provided function is complete.
|
|
15619
|
-
* If the provided function crashes, the error bubbles up to the caller.
|
|
15620
|
-
* @param name
|
|
15621
|
-
* @param call
|
|
15622
|
-
*/
|
|
15623
|
-
function Run(name, call) {
|
|
15624
|
-
// console.debug(`Queueing: ${name}`);
|
|
15625
|
-
return new Promise((resolve, reject) => {
|
|
15626
|
-
queue.push(async () => {
|
|
15627
|
-
try {
|
|
15628
|
-
// console.debug(`Running: ${name}`);
|
|
15629
|
-
const result = await call();
|
|
15630
|
-
resolve(result);
|
|
15631
|
-
}
|
|
15632
|
-
catch (error) {
|
|
15633
|
-
reject(error);
|
|
15634
|
-
}
|
|
15635
|
-
finally {
|
|
15636
|
-
// Process the next function in the queue.
|
|
15637
|
-
queue.shift();
|
|
15638
|
-
// If there are more functions in the queue, process the next one.
|
|
15639
|
-
if (queue.length > 0) {
|
|
15640
|
-
processNext();
|
|
15641
|
-
}
|
|
15642
|
-
// No more items to process.
|
|
15643
|
-
else {
|
|
15644
|
-
isProcessing = false;
|
|
15645
|
-
}
|
|
15646
|
-
}
|
|
15647
|
-
});
|
|
15648
|
-
if (!isProcessing) {
|
|
15649
|
-
// If not currently processing, start processing the queue.
|
|
15650
|
-
isProcessing = true;
|
|
15651
|
-
processNext();
|
|
15652
|
-
}
|
|
15653
|
-
});
|
|
15665
|
+
getTilesetFeatureStyle(entityTypeId) {
|
|
15666
|
+
var _a, _b, _c, _d;
|
|
15667
|
+
// Locate what style is applicable to the feature.
|
|
15668
|
+
let style = null;
|
|
15669
|
+
if (entityTypeId) {
|
|
15670
|
+
style = ((_b = (_a = this.styleMapping.find(x => x.EntityTypeID == entityTypeId)) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.Settings);
|
|
15654
15671
|
}
|
|
15655
|
-
|
|
15656
|
-
|
|
15657
|
-
|
|
15658
|
-
|
|
15659
|
-
|
|
15660
|
-
|
|
15661
|
-
|
|
15672
|
+
if (!style) {
|
|
15673
|
+
style = ((_c = this.fallbackStyle) === null || _c === void 0 ? void 0 : _c.Settings);
|
|
15674
|
+
}
|
|
15675
|
+
if (!style || !((_d = style === null || style === void 0 ? void 0 : style.modelStyle) === null || _d === void 0 ? void 0 : _d.customize)) {
|
|
15676
|
+
return null;
|
|
15677
|
+
}
|
|
15678
|
+
return style;
|
|
15679
|
+
}
|
|
15680
|
+
getTilesetFeatureNeedsFullData(entityTypeId) {
|
|
15681
|
+
var _a;
|
|
15682
|
+
if (this.historic) {
|
|
15683
|
+
// Unfortunately when we are working with historic we have to request the entity.
|
|
15684
|
+
// This is because we need to know if a record exists at the point in time.
|
|
15685
|
+
return true;
|
|
15686
|
+
}
|
|
15687
|
+
const style = this.getTilesetFeatureStyle(entityTypeId);
|
|
15688
|
+
if (!style) {
|
|
15689
|
+
return false;
|
|
15662
15690
|
}
|
|
15663
|
-
|
|
15664
|
-
|
|
15665
|
-
|
|
15666
|
-
|
|
15667
|
-
|
|
15691
|
+
const fill = (_a = style === null || style === void 0 ? void 0 : style.modelStyle) === null || _a === void 0 ? void 0 : _a.fillColor;
|
|
15692
|
+
if (!fill || fill.length <= 0) {
|
|
15693
|
+
return false;
|
|
15694
|
+
}
|
|
15695
|
+
return fill[0].type != 0;
|
|
15696
|
+
}
|
|
15668
15697
|
}
|
|
15698
|
+
|
|
15669
15699
|
/**
|
|
15670
15700
|
* Returns if a given tileset is alive and in the scene.
|
|
15671
15701
|
* @param viewer
|
|
@@ -15684,22 +15714,6 @@ function isAlive$2(viewer, cTileset) {
|
|
|
15684
15714
|
}
|
|
15685
15715
|
return viewer.scene.primitives.contains(cTileset);
|
|
15686
15716
|
}
|
|
15687
|
-
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
15688
|
-
// We have some evil hard-coded style mappings that need to be fixed.
|
|
15689
|
-
// These exist within legacy project views.
|
|
15690
|
-
function correctStyle(style) {
|
|
15691
|
-
if (style && !style.Settings && !style.ID) {
|
|
15692
|
-
return {
|
|
15693
|
-
ID: -1,
|
|
15694
|
-
Name: "Unknown",
|
|
15695
|
-
Settings: {
|
|
15696
|
-
...style
|
|
15697
|
-
},
|
|
15698
|
-
Type: Style.EType.Entity
|
|
15699
|
-
};
|
|
15700
|
-
}
|
|
15701
|
-
return style;
|
|
15702
|
-
}
|
|
15703
15717
|
const VIEWER_WATCH_KEY = "bruce-viewer-watch";
|
|
15704
15718
|
const WATCH_KEY = "bruce-tileset-watch";
|
|
15705
15719
|
/**
|
|
@@ -16060,693 +16074,896 @@ var TilesetRenderEngine;
|
|
|
16060
16074
|
else if (etc === null || etc === void 0 ? void 0 : etc.ExternalTilesetURL) {
|
|
16061
16075
|
loadUrl = etc.ExternalTilesetURL;
|
|
16062
16076
|
}
|
|
16063
|
-
if (!loadUrl && tileset) {
|
|
16064
|
-
const api = apiGetter.getApi(accountId);
|
|
16065
|
-
await api.Loading;
|
|
16066
|
-
loadUrl = Tileset.GetFileUrl({
|
|
16067
|
-
file: "tileset.json",
|
|
16068
|
-
tilesetId: (tileset === null || tileset === void 0 ? void 0 : tileset.ID) ? tileset.ID : params.tileset.id,
|
|
16069
|
-
viaCdn: false,
|
|
16070
|
-
legacy: true,
|
|
16071
|
-
cacheToken: tileset.GenerateVersion,
|
|
16072
|
-
api: api
|
|
16073
|
-
});
|
|
16077
|
+
if (!loadUrl && tileset) {
|
|
16078
|
+
const api = apiGetter.getApi(accountId);
|
|
16079
|
+
await api.Loading;
|
|
16080
|
+
loadUrl = Tileset.GetFileUrl({
|
|
16081
|
+
file: "tileset.json",
|
|
16082
|
+
tilesetId: (tileset === null || tileset === void 0 ? void 0 : tileset.ID) ? tileset.ID : params.tileset.id,
|
|
16083
|
+
viaCdn: false,
|
|
16084
|
+
legacy: true,
|
|
16085
|
+
cacheToken: tileset.GenerateVersion,
|
|
16086
|
+
api: api
|
|
16087
|
+
});
|
|
16088
|
+
}
|
|
16089
|
+
if (viaCdn && (tileset === null || tileset === void 0 ? void 0 : tileset.ID) && !ionId && !(etc === null || etc === void 0 ? void 0 : etc.ExternalTilesetURL)) {
|
|
16090
|
+
const api = apiGetter.getApi(accountId);
|
|
16091
|
+
await api.Loading;
|
|
16092
|
+
if (api.GetCdnBaseUrl()) {
|
|
16093
|
+
/*
|
|
16094
|
+
const rootFile = tileset.RootFileName ? tileset.RootFileName : "tileset.json";
|
|
16095
|
+
loadUrl = api.LegacyTilesetCdnUrl
|
|
16096
|
+
.replace("<TILESETID>", tileset.ID)
|
|
16097
|
+
.replace("<FILEPATH>", rootFile)
|
|
16098
|
+
.replace("<ACCOUNT>", accountId);
|
|
16099
|
+
*/
|
|
16100
|
+
loadUrl = Tileset.GetFileUrl({
|
|
16101
|
+
file: "tileset.json",
|
|
16102
|
+
tilesetId: (tileset === null || tileset === void 0 ? void 0 : tileset.ID) ? tileset.ID : params.tileset.id,
|
|
16103
|
+
viaCdn: true,
|
|
16104
|
+
legacy: true,
|
|
16105
|
+
cacheToken: params.tileset.generateVersion,
|
|
16106
|
+
api: api
|
|
16107
|
+
});
|
|
16108
|
+
}
|
|
16109
|
+
}
|
|
16110
|
+
const cTileset = await createTileset(loadUrl, {
|
|
16111
|
+
backFaceCulling: backFaceCulling === true
|
|
16112
|
+
}, noMemoryLimit);
|
|
16113
|
+
viewer.scene.primitives.add(cTileset);
|
|
16114
|
+
OnTilesetReady(cTileset).then(() => {
|
|
16115
|
+
var _a;
|
|
16116
|
+
try {
|
|
16117
|
+
if (!isAlive$2(viewer, cTileset)) {
|
|
16118
|
+
return;
|
|
16119
|
+
}
|
|
16120
|
+
if (noMemoryLimit != true) {
|
|
16121
|
+
(_a = GetMemoryWatcher(params.viewer)) === null || _a === void 0 ? void 0 : _a.Watch(cTileset);
|
|
16122
|
+
}
|
|
16123
|
+
if (tileset) {
|
|
16124
|
+
let settings = tileset.Settings;
|
|
16125
|
+
settings = {
|
|
16126
|
+
...settings
|
|
16127
|
+
};
|
|
16128
|
+
let origin = settings.origin;
|
|
16129
|
+
origin = {
|
|
16130
|
+
...origin
|
|
16131
|
+
};
|
|
16132
|
+
let etc = settings.etc;
|
|
16133
|
+
etc = {
|
|
16134
|
+
...etc
|
|
16135
|
+
};
|
|
16136
|
+
let positionOffset = settings.positionOffset;
|
|
16137
|
+
positionOffset = {
|
|
16138
|
+
...positionOffset
|
|
16139
|
+
};
|
|
16140
|
+
const rotation = settings.rotation;
|
|
16141
|
+
ApplySettings({
|
|
16142
|
+
cTileset,
|
|
16143
|
+
settings: {
|
|
16144
|
+
attenuation: visual.attenuation != false,
|
|
16145
|
+
colorMask: visual.colorMask,
|
|
16146
|
+
maximumAttenuation: visual.attenuationMax,
|
|
16147
|
+
maxScreenSpaceError: visual.maximumScreenSpaceError
|
|
16148
|
+
}
|
|
16149
|
+
});
|
|
16150
|
+
ApplyPosition({
|
|
16151
|
+
cTileset: cTileset,
|
|
16152
|
+
position: {
|
|
16153
|
+
transform: rotation ? {
|
|
16154
|
+
heading: rotation.z,
|
|
16155
|
+
pitch: rotation.x,
|
|
16156
|
+
roll: rotation.y,
|
|
16157
|
+
scale: EnsureNumber(origin === null || origin === void 0 ? void 0 : origin.scale, 1),
|
|
16158
|
+
z: EnsureNumber(positionOffset === null || positionOffset === void 0 ? void 0 : positionOffset.altitude),
|
|
16159
|
+
x: EnsureNumber(positionOffset === null || positionOffset === void 0 ? void 0 : positionOffset.latitude),
|
|
16160
|
+
y: EnsureNumber(positionOffset === null || positionOffset === void 0 ? void 0 : positionOffset.longitude)
|
|
16161
|
+
} : null,
|
|
16162
|
+
location: (origin === null || origin === void 0 ? void 0 : origin.latitude) ? {
|
|
16163
|
+
latitude: origin.latitude,
|
|
16164
|
+
longitude: origin.longitude,
|
|
16165
|
+
altitude: origin.altitude
|
|
16166
|
+
} : null,
|
|
16167
|
+
isLegacy: true,
|
|
16168
|
+
legacyProps: {
|
|
16169
|
+
rotate: etc.dontRotate != true,
|
|
16170
|
+
transform: etc.dontTransform != true,
|
|
16171
|
+
usingBoundingBox: etc.usingBoundingBox != false
|
|
16172
|
+
}
|
|
16173
|
+
}
|
|
16174
|
+
});
|
|
16175
|
+
params.viewer.scene.requestRender();
|
|
16176
|
+
}
|
|
16177
|
+
}
|
|
16178
|
+
catch (e) {
|
|
16179
|
+
console.error(e);
|
|
16180
|
+
}
|
|
16181
|
+
});
|
|
16182
|
+
return cTileset;
|
|
16183
|
+
}
|
|
16184
|
+
TilesetRenderEngine.RenderLegacy = RenderLegacy;
|
|
16185
|
+
// Util for styling Tileset features.
|
|
16186
|
+
// Also used to flag historic metadata based on timeline changes.
|
|
16187
|
+
class Styler extends TilesetStyler {
|
|
16188
|
+
}
|
|
16189
|
+
TilesetRenderEngine.Styler = Styler;
|
|
16190
|
+
/**
|
|
16191
|
+
* The maximum memory in MB that can be used by all tilesets.
|
|
16192
|
+
* This is distributed evenly between all loaded tilesets.
|
|
16193
|
+
*/
|
|
16194
|
+
TilesetRenderEngine.MAX_TILESET_MEMORY = 1024;
|
|
16195
|
+
/**
|
|
16196
|
+
* Watches tilesets in the viewer.
|
|
16197
|
+
* This will regulate their max memory param.
|
|
16198
|
+
* As more get watched their memory will be reduced.
|
|
16199
|
+
*/
|
|
16200
|
+
class MemoryWatcher {
|
|
16201
|
+
constructor(viewer) {
|
|
16202
|
+
this.watched = [];
|
|
16203
|
+
this.viewer = viewer;
|
|
16204
|
+
}
|
|
16205
|
+
distributeMemory() {
|
|
16206
|
+
this.clean();
|
|
16207
|
+
// Total 1gb as default.
|
|
16208
|
+
// We'll need to allow user to change this somehow.
|
|
16209
|
+
const maxMemory = TilesetRenderEngine.MAX_TILESET_MEMORY;
|
|
16210
|
+
// Minimum memory in MB per tileset.
|
|
16211
|
+
const minMemory = 80;
|
|
16212
|
+
const totalPerTileset = Math.max(this.watched.length ? maxMemory / this.watched.length : maxMemory, minMemory);
|
|
16213
|
+
this.watched.forEach(x => {
|
|
16214
|
+
// Newer Cesium killed this property.
|
|
16215
|
+
// TODO: Check if it's needed then.
|
|
16216
|
+
x["maximumMemoryUsage"] = totalPerTileset;
|
|
16217
|
+
});
|
|
16218
|
+
}
|
|
16219
|
+
destroy() {
|
|
16220
|
+
this.watched = [];
|
|
16221
|
+
}
|
|
16222
|
+
/**
|
|
16223
|
+
* Remove all dead tilesets.
|
|
16224
|
+
*/
|
|
16225
|
+
clean() {
|
|
16226
|
+
// Remove all dead tilesets.
|
|
16227
|
+
this.watched = this.watched.filter(x => isAlive$2(this.viewer, x));
|
|
16228
|
+
// Check if viewer is destroyed.
|
|
16229
|
+
if (!this.viewer || this.viewer.isDestroyed()) {
|
|
16230
|
+
this.destroy();
|
|
16231
|
+
}
|
|
16232
|
+
}
|
|
16233
|
+
Watch(tileset) {
|
|
16234
|
+
if (!tileset) {
|
|
16235
|
+
return;
|
|
16236
|
+
}
|
|
16237
|
+
if (!tileset[WATCH_KEY]) {
|
|
16238
|
+
tileset[WATCH_KEY] = ObjectUtils.UId();
|
|
16239
|
+
}
|
|
16240
|
+
const index = this.watched.findIndex(x => x[WATCH_KEY] === tileset[WATCH_KEY]);
|
|
16241
|
+
if (index >= 0) {
|
|
16242
|
+
return;
|
|
16243
|
+
}
|
|
16244
|
+
this.watched.push(tileset);
|
|
16245
|
+
this.distributeMemory();
|
|
16246
|
+
}
|
|
16247
|
+
Unwatch(tileset) {
|
|
16248
|
+
if (!tileset) {
|
|
16249
|
+
return;
|
|
16250
|
+
}
|
|
16251
|
+
if (!tileset[WATCH_KEY]) {
|
|
16252
|
+
tileset[WATCH_KEY] = ObjectUtils.UId();
|
|
16253
|
+
}
|
|
16254
|
+
const index = this.watched.findIndex(x => (x === null || x === void 0 ? void 0 : x[WATCH_KEY]) === tileset[WATCH_KEY]);
|
|
16255
|
+
if (index > -1) {
|
|
16256
|
+
this.watched.splice(index, 1);
|
|
16257
|
+
}
|
|
16258
|
+
this.distributeMemory();
|
|
16259
|
+
}
|
|
16260
|
+
}
|
|
16261
|
+
TilesetRenderEngine.MemoryWatcher = MemoryWatcher;
|
|
16262
|
+
function GetMemoryWatcher(viewer) {
|
|
16263
|
+
// If viewer is dead return nothing.
|
|
16264
|
+
if (!viewer || viewer.isDestroyed()) {
|
|
16265
|
+
return null;
|
|
16266
|
+
}
|
|
16267
|
+
if (!viewer[VIEWER_WATCH_KEY]) {
|
|
16268
|
+
viewer[VIEWER_WATCH_KEY] = new MemoryWatcher(viewer);
|
|
16269
|
+
}
|
|
16270
|
+
return viewer[VIEWER_WATCH_KEY];
|
|
16271
|
+
}
|
|
16272
|
+
TilesetRenderEngine.GetMemoryWatcher = GetMemoryWatcher;
|
|
16273
|
+
})(TilesetRenderEngine || (TilesetRenderEngine = {}));
|
|
16274
|
+
|
|
16275
|
+
/**
|
|
16276
|
+
* This is a helper for making entity requests based on a grid area.
|
|
16277
|
+
* It will return grid cells based on given view-area then will remember when stuff-
|
|
16278
|
+
* was fully-fetched for those cells to avoid making duplicate requests.
|
|
16279
|
+
*/
|
|
16280
|
+
var EntityGlobe;
|
|
16281
|
+
(function (EntityGlobe) {
|
|
16282
|
+
class Cell {
|
|
16283
|
+
constructor() {
|
|
16284
|
+
this.Fetched = false;
|
|
16285
|
+
this.IsFetched = null;
|
|
16286
|
+
this.FetchPageIndex = 0;
|
|
16287
|
+
// Optional URL to use instead of default URL generation.
|
|
16288
|
+
// This is typically a response from the API to use this specific URL for the next page.
|
|
16289
|
+
this.FetchURL = null;
|
|
16290
|
+
this.Boundaries = null;
|
|
16291
|
+
this.Fetching = false;
|
|
16292
|
+
}
|
|
16293
|
+
GetBounds() {
|
|
16294
|
+
// Entity data works in -180 to 180 range.
|
|
16295
|
+
function prepareRangeForBounds(range) {
|
|
16296
|
+
if (range > 180) {
|
|
16297
|
+
return range - 360;
|
|
16298
|
+
}
|
|
16299
|
+
return range;
|
|
16300
|
+
}
|
|
16301
|
+
// Add minor decimal as API crashes when giving it whole numbers.
|
|
16302
|
+
const maxLon = prepareRangeForBounds(this.Boundaries.maxLongitude);
|
|
16303
|
+
const minLon = prepareRangeForBounds(this.Boundaries.minLongitude);
|
|
16304
|
+
const maxLat = prepareRangeForBounds(this.Boundaries.maxLatitude);
|
|
16305
|
+
const minLat = prepareRangeForBounds(this.Boundaries.minLatitude);
|
|
16306
|
+
return {
|
|
16307
|
+
east: maxLon,
|
|
16308
|
+
north: maxLat,
|
|
16309
|
+
south: minLat,
|
|
16310
|
+
west: minLon
|
|
16311
|
+
};
|
|
16312
|
+
}
|
|
16313
|
+
}
|
|
16314
|
+
EntityGlobe.Cell = Cell;
|
|
16315
|
+
class Grid {
|
|
16316
|
+
constructor() {
|
|
16317
|
+
this.cells = {};
|
|
16074
16318
|
}
|
|
16075
|
-
|
|
16076
|
-
const
|
|
16077
|
-
|
|
16078
|
-
|
|
16079
|
-
|
|
16080
|
-
|
|
16081
|
-
|
|
16082
|
-
|
|
16083
|
-
|
|
16084
|
-
|
|
16085
|
-
|
|
16086
|
-
|
|
16087
|
-
|
|
16088
|
-
|
|
16089
|
-
|
|
16090
|
-
legacy: true,
|
|
16091
|
-
cacheToken: params.tileset.generateVersion,
|
|
16092
|
-
api: api
|
|
16093
|
-
});
|
|
16319
|
+
GetCellsForView(cameraPos, viewRect) {
|
|
16320
|
+
const cells = [];
|
|
16321
|
+
const minLat = viewRect.south;
|
|
16322
|
+
const minLon = viewRect.west;
|
|
16323
|
+
const maxLat = viewRect.north;
|
|
16324
|
+
const maxLon = viewRect.east;
|
|
16325
|
+
const MAX_CELLS = 150;
|
|
16326
|
+
const cellDegreeSize = getCellSizeFromHeight(viewRect.alt);
|
|
16327
|
+
// console.log("cell size", cellDegreeSize, "height", viewRect.alt);
|
|
16328
|
+
let curMinLon = floorValueToCellSize(cellDegreeSize, minLon);
|
|
16329
|
+
let curMinLat = floorValueToCellSize(cellDegreeSize, minLat);
|
|
16330
|
+
// For larger views we add additional padding because our view-area culling is too strong.
|
|
16331
|
+
if (cellDegreeSize >= 2) {
|
|
16332
|
+
curMinLon -= cellDegreeSize;
|
|
16333
|
+
curMinLat -= cellDegreeSize;
|
|
16094
16334
|
}
|
|
16095
|
-
|
|
16096
|
-
|
|
16097
|
-
|
|
16098
|
-
|
|
16099
|
-
|
|
16100
|
-
|
|
16101
|
-
|
|
16102
|
-
|
|
16103
|
-
|
|
16104
|
-
|
|
16105
|
-
|
|
16106
|
-
|
|
16107
|
-
|
|
16335
|
+
let centerX = cameraPos === null || cameraPos === void 0 ? void 0 : cameraPos.longitude;
|
|
16336
|
+
let centerY = cameraPos === null || cameraPos === void 0 ? void 0 : cameraPos.latitude;
|
|
16337
|
+
if (isNaN(centerX) || isNaN(centerY)) {
|
|
16338
|
+
centerX = (minLon + maxLon) / 2;
|
|
16339
|
+
centerY = (minLat + maxLat) / 2;
|
|
16340
|
+
}
|
|
16341
|
+
let width = Math.ceil((maxLon - curMinLon) / cellDegreeSize);
|
|
16342
|
+
let height = Math.ceil((maxLat - curMinLat) / cellDegreeSize);
|
|
16343
|
+
// For larger views we add additional padding because our view-area culling is too strong.
|
|
16344
|
+
if (cellDegreeSize >= 2) {
|
|
16345
|
+
width += 1;
|
|
16346
|
+
height += 1;
|
|
16347
|
+
}
|
|
16348
|
+
const cellDistances = [];
|
|
16349
|
+
for (let x = 0; x < width; x++) {
|
|
16350
|
+
for (let y = 0; y < height; y++) {
|
|
16351
|
+
const lon = x * cellDegreeSize + curMinLon;
|
|
16352
|
+
const lat = y * cellDegreeSize + curMinLat;
|
|
16353
|
+
const cellCenterX = lon + cellDegreeSize / 2;
|
|
16354
|
+
const cellCenterY = lat + cellDegreeSize / 2;
|
|
16355
|
+
const dist = Math.sqrt(Math.pow(cellCenterX - centerX, 2) + Math.pow(cellCenterY - centerY, 2));
|
|
16356
|
+
cellDistances.push({ x, y, dist });
|
|
16108
16357
|
}
|
|
16109
|
-
|
|
16110
|
-
|
|
16111
|
-
|
|
16112
|
-
|
|
16113
|
-
|
|
16114
|
-
|
|
16115
|
-
|
|
16116
|
-
|
|
16117
|
-
|
|
16118
|
-
let etc = settings.etc;
|
|
16119
|
-
etc = {
|
|
16120
|
-
...etc
|
|
16121
|
-
};
|
|
16122
|
-
let positionOffset = settings.positionOffset;
|
|
16123
|
-
positionOffset = {
|
|
16124
|
-
...positionOffset
|
|
16125
|
-
};
|
|
16126
|
-
const rotation = settings.rotation;
|
|
16127
|
-
ApplySettings({
|
|
16128
|
-
cTileset,
|
|
16129
|
-
settings: {
|
|
16130
|
-
attenuation: visual.attenuation != false,
|
|
16131
|
-
colorMask: visual.colorMask,
|
|
16132
|
-
maximumAttenuation: visual.attenuationMax,
|
|
16133
|
-
maxScreenSpaceError: visual.maximumScreenSpaceError
|
|
16134
|
-
}
|
|
16135
|
-
});
|
|
16136
|
-
ApplyPosition({
|
|
16137
|
-
cTileset: cTileset,
|
|
16138
|
-
position: {
|
|
16139
|
-
transform: rotation ? {
|
|
16140
|
-
heading: rotation.z,
|
|
16141
|
-
pitch: rotation.x,
|
|
16142
|
-
roll: rotation.y,
|
|
16143
|
-
scale: EnsureNumber(origin === null || origin === void 0 ? void 0 : origin.scale, 1),
|
|
16144
|
-
z: EnsureNumber(positionOffset === null || positionOffset === void 0 ? void 0 : positionOffset.altitude),
|
|
16145
|
-
x: EnsureNumber(positionOffset === null || positionOffset === void 0 ? void 0 : positionOffset.latitude),
|
|
16146
|
-
y: EnsureNumber(positionOffset === null || positionOffset === void 0 ? void 0 : positionOffset.longitude)
|
|
16147
|
-
} : null,
|
|
16148
|
-
location: (origin === null || origin === void 0 ? void 0 : origin.latitude) ? {
|
|
16149
|
-
latitude: origin.latitude,
|
|
16150
|
-
longitude: origin.longitude,
|
|
16151
|
-
altitude: origin.altitude
|
|
16152
|
-
} : null,
|
|
16153
|
-
isLegacy: true,
|
|
16154
|
-
legacyProps: {
|
|
16155
|
-
rotate: etc.dontRotate != true,
|
|
16156
|
-
transform: etc.dontTransform != true,
|
|
16157
|
-
usingBoundingBox: etc.usingBoundingBox != false
|
|
16158
|
-
}
|
|
16159
|
-
}
|
|
16160
|
-
});
|
|
16161
|
-
params.viewer.scene.requestRender();
|
|
16358
|
+
}
|
|
16359
|
+
cellDistances.sort((a, b) => a.dist - b.dist);
|
|
16360
|
+
for (const { x, y } of cellDistances) {
|
|
16361
|
+
const lon = x * cellDegreeSize + curMinLon;
|
|
16362
|
+
const lat = y * cellDegreeSize + curMinLat;
|
|
16363
|
+
const [id, cell] = getOrCreateCell(this.cells, cellDegreeSize, lon, lon + cellDegreeSize, lat, lat + cellDegreeSize);
|
|
16364
|
+
cells.push(cell);
|
|
16365
|
+
if (cells.length >= MAX_CELLS) {
|
|
16366
|
+
break;
|
|
16162
16367
|
}
|
|
16163
16368
|
}
|
|
16164
|
-
|
|
16165
|
-
|
|
16369
|
+
return cells;
|
|
16370
|
+
}
|
|
16371
|
+
}
|
|
16372
|
+
EntityGlobe.Grid = Grid;
|
|
16373
|
+
})(EntityGlobe || (EntityGlobe = {}));
|
|
16374
|
+
function floorValueToCellSize(size, value) {
|
|
16375
|
+
return Math.floor(value / size) * size;
|
|
16376
|
+
}
|
|
16377
|
+
function getCellSizeFromHeight(height) {
|
|
16378
|
+
if (height < 1000) {
|
|
16379
|
+
return 0.01;
|
|
16380
|
+
}
|
|
16381
|
+
if (height < 5000) {
|
|
16382
|
+
return 0.04;
|
|
16383
|
+
}
|
|
16384
|
+
else if (height < 10000) {
|
|
16385
|
+
return 0.15;
|
|
16386
|
+
}
|
|
16387
|
+
else if (height < 30000) {
|
|
16388
|
+
return 0.5;
|
|
16389
|
+
}
|
|
16390
|
+
else if (height < 70000) {
|
|
16391
|
+
return 0.5;
|
|
16392
|
+
}
|
|
16393
|
+
else if (height < 100000) {
|
|
16394
|
+
return 1;
|
|
16395
|
+
}
|
|
16396
|
+
else if (height < 150000) {
|
|
16397
|
+
return 1;
|
|
16398
|
+
}
|
|
16399
|
+
else if (height < 200000) {
|
|
16400
|
+
return 1.5;
|
|
16401
|
+
}
|
|
16402
|
+
else if (height < 300000) {
|
|
16403
|
+
return 1.5;
|
|
16404
|
+
}
|
|
16405
|
+
else if (height < 500000) {
|
|
16406
|
+
return 3;
|
|
16407
|
+
}
|
|
16408
|
+
else if (height < 1000000) {
|
|
16409
|
+
return 3;
|
|
16410
|
+
}
|
|
16411
|
+
else if (height < 1200000) {
|
|
16412
|
+
return 4;
|
|
16413
|
+
}
|
|
16414
|
+
else if (height < 2000000) {
|
|
16415
|
+
return 6;
|
|
16416
|
+
}
|
|
16417
|
+
else if (height < 3000000) {
|
|
16418
|
+
return 20;
|
|
16419
|
+
}
|
|
16420
|
+
return 35;
|
|
16421
|
+
}
|
|
16422
|
+
function isCellFetched(cell) {
|
|
16423
|
+
if (cell.Fetched) {
|
|
16424
|
+
return true;
|
|
16425
|
+
}
|
|
16426
|
+
return false;
|
|
16427
|
+
}
|
|
16428
|
+
function getOrCreateCell(cells, cellSize, lon, maxLon, lat, maxLat) {
|
|
16429
|
+
const id = cellSize + "_" + lon + "_" + maxLon + "_" + lat + "_" + maxLat;
|
|
16430
|
+
let cell = cells[id];
|
|
16431
|
+
if (!cell) {
|
|
16432
|
+
cell = cells[id] = new EntityGlobe.Cell();
|
|
16433
|
+
cell.Boundaries = {
|
|
16434
|
+
minLatitude: lat,
|
|
16435
|
+
maxLatitude: maxLat,
|
|
16436
|
+
minLongitude: lon,
|
|
16437
|
+
maxLongitude: maxLon
|
|
16438
|
+
};
|
|
16439
|
+
cell.IsFetched = () => isCellFetched(cell);
|
|
16440
|
+
}
|
|
16441
|
+
return [id, cell];
|
|
16442
|
+
}
|
|
16443
|
+
|
|
16444
|
+
const MAX_AREA_IN_DEGREES$1 = 90;
|
|
16445
|
+
const MAX_RETRY_ATTEMPTS = 1;
|
|
16446
|
+
const RETRY_DELAY_INCREMENT = 500;
|
|
16447
|
+
const REQUEST_PAGE_DELAY = 50;
|
|
16448
|
+
class regMenuItemGetter {
|
|
16449
|
+
constructor(typeId, tagIds, minHeight, maxHeight) {
|
|
16450
|
+
this.TypeId = typeId;
|
|
16451
|
+
this.TagIds = tagIds;
|
|
16452
|
+
this.MinHeight = minHeight;
|
|
16453
|
+
this.MaxHeight = maxHeight;
|
|
16454
|
+
}
|
|
16455
|
+
}
|
|
16456
|
+
async function delay(milliseconds) {
|
|
16457
|
+
return new Promise((res) => {
|
|
16458
|
+
setTimeout(() => {
|
|
16459
|
+
res();
|
|
16460
|
+
}, milliseconds);
|
|
16461
|
+
});
|
|
16462
|
+
}
|
|
16463
|
+
/**
|
|
16464
|
+
* This is a batched entity getter.
|
|
16465
|
+
* It will scan for entity records in a view-area and emit them in batches.
|
|
16466
|
+
* It will restart scanning if the camera moves.
|
|
16467
|
+
*/
|
|
16468
|
+
var EntityFilterGetter;
|
|
16469
|
+
(function (EntityFilterGetter) {
|
|
16470
|
+
let EStatus;
|
|
16471
|
+
(function (EStatus) {
|
|
16472
|
+
EStatus["Scanning"] = "SCANNING";
|
|
16473
|
+
EStatus["Loading"] = "LOADING";
|
|
16474
|
+
})(EStatus = EntityFilterGetter.EStatus || (EntityFilterGetter.EStatus = {}));
|
|
16475
|
+
class Getter {
|
|
16476
|
+
get OnUpdate() {
|
|
16477
|
+
if (!this.onUpdate) {
|
|
16478
|
+
this.onUpdate = new BruceEvent();
|
|
16166
16479
|
}
|
|
16167
|
-
|
|
16168
|
-
return cTileset;
|
|
16169
|
-
}
|
|
16170
|
-
TilesetRenderEngine.RenderLegacy = RenderLegacy;
|
|
16171
|
-
class Styler {
|
|
16172
|
-
constructor() {
|
|
16173
|
-
this.disposed = false;
|
|
16174
|
-
// Indicates if the styler has been loaded/initialized and is ready to style.
|
|
16175
|
-
this.loaded = false;
|
|
16176
|
-
this.styleMappingLoaded = false;
|
|
16177
|
-
this.styleMappingsLoaded = {};
|
|
16178
|
-
this.fallbackStyle = null;
|
|
16179
|
-
this.expandSources = false;
|
|
16180
|
-
this.loadingCounter = 0;
|
|
16181
|
-
// Dictionary of Entity ID -> boolean to indicate which Entities have been styled.
|
|
16182
|
-
// This is used to determine if the Style colour needs to be overriden or not.
|
|
16183
|
-
this.styledEntityIds = {};
|
|
16184
|
-
// Dictionary of Entity ID -> boolean to indicate which Entities have had full Entity data loaded.
|
|
16185
|
-
// This is used to determine what Entities need to be re-requested when the scene time changes.
|
|
16186
|
-
this.styledWithAttrEntityIds = {};
|
|
16187
|
-
this.scenario = 0;
|
|
16188
|
-
// Indicates that we are retrieving historic records.
|
|
16189
|
-
// This means that the current scene's time is included in the request.
|
|
16190
|
-
this.historic = false;
|
|
16191
|
-
this.viewerDateTimeChangeRemoval = null;
|
|
16192
|
-
this.historicRefreshAbortController = null;
|
|
16193
|
-
// More expensive process.
|
|
16194
|
-
// When an Entity is styled, the rego is reviewed and updated if needed.
|
|
16195
|
-
// This is currently used for scenarios, and off by default to keep other processes faster.
|
|
16196
|
-
this.shouldUpdateRegoStates = false;
|
|
16197
|
-
this.runningQueues = 0;
|
|
16198
|
-
this.recordLoadQueue = [];
|
|
16199
|
-
this.recordCheckQueue = [];
|
|
16200
|
-
// % progress for how many Entities have been styled so far.
|
|
16201
|
-
// This can change as Tiles load in and more queue.
|
|
16202
|
-
this._styleProgress = 0;
|
|
16203
|
-
this._styleProgressQueue = new DelayQueue(() => {
|
|
16204
|
-
this.updateStyleProgress();
|
|
16205
|
-
}, 250);
|
|
16206
|
-
// Event for when the style progress changes.
|
|
16207
|
-
this.OnStyleProgress = new BruceEvent();
|
|
16208
|
-
// Cache of Entity objects to use when styling instead of requesting them.
|
|
16209
|
-
this.entityDataCache = {};
|
|
16480
|
+
return this.onUpdate;
|
|
16210
16481
|
}
|
|
16211
|
-
get
|
|
16212
|
-
|
|
16482
|
+
get OnStateUpdate() {
|
|
16483
|
+
if (!this.onStateUpdate) {
|
|
16484
|
+
this.onStateUpdate = new BruceEvent();
|
|
16485
|
+
}
|
|
16486
|
+
return this.onStateUpdate;
|
|
16213
16487
|
}
|
|
16214
|
-
get
|
|
16215
|
-
|
|
16488
|
+
get OnScanUpdate() {
|
|
16489
|
+
if (!this.onScanUpdate) {
|
|
16490
|
+
this.onScanUpdate = new BruceEvent();
|
|
16491
|
+
}
|
|
16492
|
+
return this.onScanUpdate;
|
|
16216
16493
|
}
|
|
16217
|
-
get
|
|
16218
|
-
return this.
|
|
16494
|
+
get isLooping() {
|
|
16495
|
+
return this.looping > 0;
|
|
16219
16496
|
}
|
|
16220
|
-
|
|
16221
|
-
|
|
16222
|
-
|
|
16223
|
-
this.
|
|
16497
|
+
constructor(params) {
|
|
16498
|
+
this.onUpdate = null;
|
|
16499
|
+
this.LastStateUpdates = {};
|
|
16500
|
+
this.onStateUpdate = null;
|
|
16501
|
+
this.onScanUpdate = null;
|
|
16502
|
+
this.viewPortChangeRemoval = null;
|
|
16503
|
+
this.viewPortDelayQueue = null;
|
|
16504
|
+
this.viewerDateTimeChangeRemoval = null;
|
|
16505
|
+
this.cells = null;
|
|
16506
|
+
this.registeredItems = {};
|
|
16507
|
+
this.getterLoopId = 0;
|
|
16508
|
+
this.getterLoopAbortControllers = {};
|
|
16509
|
+
this.looping = 0;
|
|
16510
|
+
this.tagIds = null;
|
|
16511
|
+
this.minHeight = 0;
|
|
16512
|
+
this.maxHeight = 100000;
|
|
16513
|
+
this.viewRect = null;
|
|
16514
|
+
this.viewCenter = null;
|
|
16515
|
+
this.scenario = 0;
|
|
16516
|
+
this.historicRefreshAbortController = null;
|
|
16517
|
+
// Entity IDs found for the latest integrity.
|
|
16518
|
+
// We use this for refreshing historic data without having to repeat geographic queries.
|
|
16519
|
+
this.gatheredIntegrity = null;
|
|
16520
|
+
this.gatheredEntityIds = [];
|
|
16521
|
+
const { api, viewer, viewPort, typeIds, schemaId, batchSize, attrFilter, historicAttrKey, historicInterpolation, historic, viaCdn, scenario } = params;
|
|
16224
16522
|
this.api = api;
|
|
16225
|
-
this.
|
|
16226
|
-
this.
|
|
16227
|
-
this.menuItemId = menuItemId;
|
|
16523
|
+
this.typeIds = typeIds;
|
|
16524
|
+
this.schemaId = schemaId;
|
|
16228
16525
|
this.historic = Boolean(historic);
|
|
16229
|
-
|
|
16230
|
-
|
|
16231
|
-
|
|
16232
|
-
|
|
16233
|
-
|
|
16234
|
-
|
|
16235
|
-
|
|
16236
|
-
|
|
16237
|
-
|
|
16238
|
-
// Dereference.
|
|
16239
|
-
this.styleMapping = JSON.parse(JSON.stringify(this.styleMapping));
|
|
16240
|
-
}
|
|
16241
|
-
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
16242
|
-
// We have some evil hard-coded style mappings that need to be fixed.
|
|
16243
|
-
// These exist within legacy project views.
|
|
16244
|
-
// Update: This now also lets people have a style mapping without a real style record.
|
|
16245
|
-
if ((_a = this.styleMapping) === null || _a === void 0 ? void 0 : _a.length) {
|
|
16246
|
-
for (let i = 0; i < this.styleMapping.length; i++) {
|
|
16247
|
-
const mapItem = this.styleMapping[i];
|
|
16248
|
-
const mapStyle = mapItem.style ? mapItem.style : mapItem.Style;
|
|
16249
|
-
this.styleMapping[i].style = correctStyle(mapStyle);
|
|
16250
|
-
}
|
|
16251
|
-
}
|
|
16252
|
-
}
|
|
16253
|
-
if (scenario != null) {
|
|
16254
|
-
this.scenario = scenario;
|
|
16255
|
-
}
|
|
16256
|
-
if (!!scenario) {
|
|
16257
|
-
this.shouldUpdateRegoStates = true;
|
|
16258
|
-
}
|
|
16259
|
-
else if (this.historic) {
|
|
16260
|
-
this.shouldUpdateRegoStates = true;
|
|
16261
|
-
}
|
|
16262
|
-
this.loadStyles();
|
|
16263
|
-
this.viewerDateTimeSub();
|
|
16264
|
-
this.loaded = true;
|
|
16526
|
+
this.historicAttrKey = historicAttrKey;
|
|
16527
|
+
this.historicInterpolation = Boolean(historicInterpolation);
|
|
16528
|
+
this.viaCdn = Boolean(viaCdn);
|
|
16529
|
+
this.batchSize = isNaN(batchSize) ? 300 : batchSize;
|
|
16530
|
+
this.viewPort = viewPort;
|
|
16531
|
+
this.attrFilter = attrFilter;
|
|
16532
|
+
this.viewer = viewer;
|
|
16533
|
+
this.scenario = scenario ? scenario : 0;
|
|
16534
|
+
this.updateBounds();
|
|
16265
16535
|
}
|
|
16266
16536
|
/**
|
|
16267
|
-
*
|
|
16268
|
-
*
|
|
16269
|
-
* @
|
|
16537
|
+
* Returns id that represents the combined menu item parameters.
|
|
16538
|
+
* If integrity changes while a request is running, the request will not emit a response.
|
|
16539
|
+
* @returns
|
|
16270
16540
|
*/
|
|
16271
|
-
|
|
16272
|
-
|
|
16273
|
-
if (
|
|
16274
|
-
|
|
16275
|
-
|
|
16276
|
-
this.styleMapping = params.styleMapping;
|
|
16277
|
-
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
16278
|
-
// We have some evil hard-coded style mappings that need to be fixed.
|
|
16279
|
-
// These exist within legacy project views.
|
|
16280
|
-
// Update: This now also lets people have a style mapping without a real style record.
|
|
16281
|
-
if ((_a = this.styleMapping) === null || _a === void 0 ? void 0 : _a.length) {
|
|
16282
|
-
for (let i = 0; i < this.styleMapping.length; i++) {
|
|
16283
|
-
const mapItem = this.styleMapping[i];
|
|
16284
|
-
const mapStyle = mapItem.style ? mapItem.style : mapItem.Style;
|
|
16285
|
-
this.styleMapping[i].style = correctStyle(mapStyle);
|
|
16286
|
-
}
|
|
16287
|
-
}
|
|
16288
|
-
}
|
|
16289
|
-
if (!isNaN(params.fallbackStyleId) && params.fallbackStyleId != null) {
|
|
16290
|
-
this.fallbackStyleId = params.fallbackStyleId;
|
|
16291
|
-
}
|
|
16292
|
-
if (params.fallbackStyle) {
|
|
16293
|
-
this.fallbackStyle = params.fallbackStyle;
|
|
16294
|
-
}
|
|
16295
|
-
else {
|
|
16296
|
-
this.fallbackStyle = null;
|
|
16297
|
-
}
|
|
16298
|
-
if (params.expandSources != null) {
|
|
16299
|
-
this.expandSources = params.expandSources;
|
|
16541
|
+
getIntegrityId() {
|
|
16542
|
+
let integrity = this.tagIds == null ? "" : this.tagIds.join();
|
|
16543
|
+
if (this.historicAttrKey) {
|
|
16544
|
+
integrity += "isHistoric";
|
|
16545
|
+
integrity += this.historicAttrKey;
|
|
16300
16546
|
}
|
|
16301
|
-
if (
|
|
16302
|
-
|
|
16303
|
-
if (!this.shouldUpdateRegoStates && !!this.scenario) {
|
|
16304
|
-
this.shouldUpdateRegoStates = true;
|
|
16305
|
-
}
|
|
16547
|
+
else if (this.historic) {
|
|
16548
|
+
integrity += "isHistoric";
|
|
16306
16549
|
}
|
|
16307
|
-
if (
|
|
16308
|
-
|
|
16309
|
-
if (params.historic || this.historic != params.historic) {
|
|
16310
|
-
this.shouldUpdateRegoStates = true;
|
|
16311
|
-
}
|
|
16312
|
-
if (params.historic) {
|
|
16313
|
-
this.viewerDateTimeSub();
|
|
16314
|
-
}
|
|
16315
|
-
else {
|
|
16316
|
-
this.viewerDateTimeDispose();
|
|
16317
|
-
}
|
|
16550
|
+
if (this.scenario) {
|
|
16551
|
+
integrity += this.scenario;
|
|
16318
16552
|
}
|
|
16319
|
-
if (this.
|
|
16320
|
-
|
|
16321
|
-
// Requeue all.
|
|
16322
|
-
this.recordLoadQueue = [];
|
|
16323
|
-
this.recordCheckQueue = [];
|
|
16324
|
-
const regos = this.register.GetRegos({
|
|
16325
|
-
menuItemId: this.menuItemId
|
|
16326
|
-
});
|
|
16327
|
-
// Reset progress.
|
|
16328
|
-
this._styleProgressQueue.Call(true);
|
|
16329
|
-
this.styleMappingLoaded = false;
|
|
16330
|
-
this.styleMappingsLoaded = {};
|
|
16331
|
-
this.QueueEntities(regos);
|
|
16332
|
-
this.loadStyles();
|
|
16553
|
+
if (this.typeIds) {
|
|
16554
|
+
integrity += this.typeIds.join();
|
|
16333
16555
|
}
|
|
16556
|
+
return integrity;
|
|
16557
|
+
}
|
|
16558
|
+
viewAreaSub() {
|
|
16559
|
+
this.viewAreaDispose();
|
|
16560
|
+
// We'll avoid restarting the scanner too often.
|
|
16561
|
+
this.viewPortDelayQueue = new DelayQueue(() => {
|
|
16562
|
+
this.updateBounds();
|
|
16563
|
+
this.startGetterLoop();
|
|
16564
|
+
}, 2000);
|
|
16565
|
+
this.viewPortChangeRemoval = this.viewPort.Updated().Subscribe(() => {
|
|
16566
|
+
var _a;
|
|
16567
|
+
(_a = this.viewPortDelayQueue) === null || _a === void 0 ? void 0 : _a.Call();
|
|
16568
|
+
});
|
|
16569
|
+
}
|
|
16570
|
+
viewAreaDispose() {
|
|
16571
|
+
var _a, _b;
|
|
16572
|
+
(_a = this.viewPortChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
16573
|
+
this.viewPortChangeRemoval = null;
|
|
16574
|
+
(_b = this.viewPortDelayQueue) === null || _b === void 0 ? void 0 : _b.Dispose();
|
|
16575
|
+
this.viewPortDelayQueue = null;
|
|
16334
16576
|
}
|
|
16335
16577
|
/**
|
|
16336
|
-
*
|
|
16337
|
-
*
|
|
16338
|
-
* @param entityIds
|
|
16339
|
-
* @param entities If an object is not available for a supplied Entity ID, then the cache for it is removed.
|
|
16578
|
+
* Monitors the Cesium viewer and updates the historic data filter values.
|
|
16579
|
+
* If there is no historic attr set, this will do nothing.
|
|
16340
16580
|
*/
|
|
16341
|
-
|
|
16342
|
-
|
|
16343
|
-
|
|
16344
|
-
|
|
16345
|
-
|
|
16346
|
-
|
|
16347
|
-
|
|
16348
|
-
|
|
16581
|
+
viewerDateTimeSub() {
|
|
16582
|
+
if ((!this.historicAttrKey && !this.historic) || this.viewerDateTimeChangeRemoval) {
|
|
16583
|
+
return;
|
|
16584
|
+
}
|
|
16585
|
+
// This is multiplied by the speed of animation to figure
|
|
16586
|
+
// out how many animation "ticks" before we allow an update.
|
|
16587
|
+
let INTERVAL_WHILE_ANIMATING = 2.5 * 1000;
|
|
16588
|
+
let INTERVAL_WHILE_NOT_ANIMATING = 1000;
|
|
16589
|
+
if (this.historicInterpolation) {
|
|
16590
|
+
INTERVAL_WHILE_ANIMATING = 6 * 1000;
|
|
16591
|
+
INTERVAL_WHILE_NOT_ANIMATING = 3.5 * 1000;
|
|
16592
|
+
}
|
|
16593
|
+
let lastUpdateTime = null;
|
|
16594
|
+
let delayQueue = new DelayQueue(() => {
|
|
16595
|
+
try {
|
|
16596
|
+
// If the timeline is animating then we'll wait longer to update.
|
|
16597
|
+
if (this.viewer.clock.shouldAnimate && lastUpdateTime) {
|
|
16598
|
+
if (Math.abs(new Date().getTime() - lastUpdateTime) < INTERVAL_WHILE_ANIMATING) {
|
|
16599
|
+
return;
|
|
16600
|
+
}
|
|
16601
|
+
}
|
|
16602
|
+
const current = this.historicAttrDateTime;
|
|
16603
|
+
this.updateHistoricDateTime();
|
|
16604
|
+
if (current != this.historicAttrDateTime) {
|
|
16605
|
+
this.emitHistoricData();
|
|
16349
16606
|
}
|
|
16350
16607
|
}
|
|
16351
|
-
|
|
16352
|
-
|
|
16353
|
-
for (let i = 0; i < entityIds.length; i++) {
|
|
16354
|
-
const entityId = entityIds[i];
|
|
16355
|
-
if (newDataMap[entityId]) {
|
|
16356
|
-
this.entityDataCache[entityId] = newDataMap[entityId];
|
|
16608
|
+
catch (e) {
|
|
16609
|
+
console.error(e);
|
|
16357
16610
|
}
|
|
16358
|
-
|
|
16359
|
-
|
|
16611
|
+
}, INTERVAL_WHILE_NOT_ANIMATING);
|
|
16612
|
+
let postUpdateRemoval = this.viewer.scene.postUpdate.addEventListener(() => {
|
|
16613
|
+
if (delayQueue) {
|
|
16614
|
+
delayQueue.Call();
|
|
16360
16615
|
}
|
|
16361
|
-
}
|
|
16616
|
+
});
|
|
16617
|
+
this.viewerDateTimeChangeRemoval = () => {
|
|
16618
|
+
delayQueue === null || delayQueue === void 0 ? void 0 : delayQueue.Dispose();
|
|
16619
|
+
postUpdateRemoval === null || postUpdateRemoval === void 0 ? void 0 : postUpdateRemoval();
|
|
16620
|
+
delayQueue = null;
|
|
16621
|
+
postUpdateRemoval = null;
|
|
16622
|
+
};
|
|
16362
16623
|
}
|
|
16363
|
-
|
|
16364
|
-
if (!this.
|
|
16624
|
+
updateHistoricDateTime() {
|
|
16625
|
+
if (!this.historicAttrKey && !this.historic) {
|
|
16626
|
+
this.historicAttrDateTime = null;
|
|
16365
16627
|
return;
|
|
16366
16628
|
}
|
|
16367
|
-
|
|
16368
|
-
|
|
16369
|
-
|
|
16370
|
-
|
|
16371
|
-
|
|
16372
|
-
|
|
16373
|
-
|
|
16374
|
-
|
|
16375
|
-
|
|
16376
|
-
}
|
|
16377
|
-
|
|
16378
|
-
|
|
16379
|
-
|
|
16380
|
-
|
|
16381
|
-
if (this.recordLoadQueue.length > 0) {
|
|
16382
|
-
this.processQueue();
|
|
16629
|
+
const isChanged = (before, after) => {
|
|
16630
|
+
if (before && !after) {
|
|
16631
|
+
return true;
|
|
16632
|
+
}
|
|
16633
|
+
if (!before && after) {
|
|
16634
|
+
return true;
|
|
16635
|
+
}
|
|
16636
|
+
// Change must be at least 0.1 seconds.
|
|
16637
|
+
return Math.abs(before.getTime() - after.getTime()) > 100;
|
|
16638
|
+
};
|
|
16639
|
+
const oldDateTime = this.historicAttrDateTime ? new Date(this.historicAttrDateTime) : null;
|
|
16640
|
+
const newDateTime = JulianDate.toDate(this.viewer.clock.currentTime);
|
|
16641
|
+
if (isChanged(oldDateTime, newDateTime)) {
|
|
16642
|
+
this.historicAttrDateTime = newDateTime.toISOString();
|
|
16383
16643
|
}
|
|
16384
16644
|
}
|
|
16385
|
-
|
|
16386
|
-
var _a
|
|
16387
|
-
|
|
16388
|
-
|
|
16389
|
-
|
|
16390
|
-
|
|
16391
|
-
|
|
16392
|
-
|
|
16393
|
-
|
|
16394
|
-
|
|
16395
|
-
this.
|
|
16396
|
-
|
|
16397
|
-
|
|
16398
|
-
|
|
16399
|
-
|
|
16400
|
-
|
|
16401
|
-
|
|
16402
|
-
|
|
16403
|
-
|
|
16404
|
-
|
|
16405
|
-
|
|
16406
|
-
|
|
16407
|
-
|
|
16408
|
-
|
|
16409
|
-
|
|
16410
|
-
|
|
16411
|
-
|
|
16412
|
-
|
|
16413
|
-
|
|
16414
|
-
|
|
16415
|
-
|
|
16416
|
-
|
|
16417
|
-
|
|
16418
|
-
|
|
16419
|
-
|
|
16420
|
-
|
|
16421
|
-
|
|
16422
|
-
|
|
16423
|
-
|
|
16424
|
-
|
|
16425
|
-
|
|
16426
|
-
|
|
16427
|
-
// If not, then we have to re-add the Entities to the queue and re-run.
|
|
16428
|
-
const curDateTime = this.historic ? this.historicAttrDateTime : null;
|
|
16429
|
-
if (curDateTime == dateTime) {
|
|
16430
|
-
// Add all found Entities to the list.
|
|
16431
|
-
entities.push(...response);
|
|
16432
|
-
}
|
|
16433
|
-
else {
|
|
16434
|
-
rerun = true;
|
|
16435
|
-
}
|
|
16436
|
-
}
|
|
16645
|
+
viewerDateTimeDispose() {
|
|
16646
|
+
var _a;
|
|
16647
|
+
(_a = this.viewerDateTimeChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
16648
|
+
this.viewerDateTimeChangeRemoval = null;
|
|
16649
|
+
}
|
|
16650
|
+
GetMenuItems() {
|
|
16651
|
+
return Object.keys(this.registeredItems);
|
|
16652
|
+
}
|
|
16653
|
+
IncludeMenuItem(menuItemId, typeId, layerIds, minHeight, maxHeight) {
|
|
16654
|
+
this.registeredItems[menuItemId] = new regMenuItemGetter(typeId, layerIds, minHeight, maxHeight);
|
|
16655
|
+
this.updateState();
|
|
16656
|
+
}
|
|
16657
|
+
ExcludeMenuItem(menuItemId) {
|
|
16658
|
+
this.registeredItems[menuItemId] = null;
|
|
16659
|
+
delete this.registeredItems[menuItemId];
|
|
16660
|
+
this.updateState(true);
|
|
16661
|
+
}
|
|
16662
|
+
updateBounds() {
|
|
16663
|
+
const viewRect = this.viewPort.GetBounds();
|
|
16664
|
+
const poi = this.viewPort.GetTarget();
|
|
16665
|
+
if (viewRect && poi) {
|
|
16666
|
+
if (Math.abs(viewRect.west - viewRect.east) > MAX_AREA_IN_DEGREES$1) {
|
|
16667
|
+
return;
|
|
16668
|
+
}
|
|
16669
|
+
if (Math.abs(viewRect.south - viewRect.north) > MAX_AREA_IN_DEGREES$1) {
|
|
16670
|
+
return;
|
|
16671
|
+
}
|
|
16672
|
+
this.viewRect = viewRect;
|
|
16673
|
+
this.viewCenter = poi;
|
|
16674
|
+
}
|
|
16675
|
+
}
|
|
16676
|
+
updateState(onlyIfLooping = false) {
|
|
16677
|
+
const tagIds = [];
|
|
16678
|
+
const typeIds = [];
|
|
16679
|
+
const menuItemIds = this.GetMenuItems();
|
|
16680
|
+
let minHeight = null;
|
|
16681
|
+
let maxHeight = null;
|
|
16682
|
+
for (let i = 0; i < menuItemIds.length; i++) {
|
|
16683
|
+
const menuItem = this.registeredItems[menuItemIds[i]];
|
|
16684
|
+
if (menuItem) {
|
|
16685
|
+
if (maxHeight == null || maxHeight < menuItem.MaxHeight) {
|
|
16686
|
+
maxHeight = menuItem.MaxHeight;
|
|
16437
16687
|
}
|
|
16438
|
-
if (
|
|
16439
|
-
|
|
16688
|
+
if (minHeight == null || minHeight > menuItem.MinHeight) {
|
|
16689
|
+
minHeight = menuItem.MinHeight;
|
|
16440
16690
|
}
|
|
16441
|
-
|
|
16442
|
-
|
|
16443
|
-
|
|
16444
|
-
|
|
16445
|
-
|
|
16446
|
-
|
|
16447
|
-
const entity = entities[i];
|
|
16448
|
-
entityMap[entity.Bruce.ID] = entity;
|
|
16449
|
-
if ((_b = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a["Layer.ID"]) === null || _b === void 0 ? void 0 : _b.length) {
|
|
16450
|
-
const eTagIds = entity.Bruce["Layer.ID"];
|
|
16451
|
-
for (let j = 0; j < eTagIds.length; j++) {
|
|
16452
|
-
tagIds.push(eTagIds[j]);
|
|
16453
|
-
}
|
|
16691
|
+
const itemLayerIds = menuItem.TagIds;
|
|
16692
|
+
if (itemLayerIds) {
|
|
16693
|
+
for (let j = 0; j < itemLayerIds.length; j++) {
|
|
16694
|
+
const itemLayerId = itemLayerIds[j];
|
|
16695
|
+
if (!tagIds.includes(itemLayerId)) {
|
|
16696
|
+
tagIds.push(itemLayerId);
|
|
16454
16697
|
}
|
|
16455
16698
|
}
|
|
16456
|
-
|
|
16457
|
-
|
|
16458
|
-
|
|
16459
|
-
|
|
16460
|
-
|
|
16461
|
-
let tags = [];
|
|
16462
|
-
if (tagIds.length) {
|
|
16463
|
-
tags = (await EntityTag.GetListByIds({
|
|
16464
|
-
tagIds: tagIds,
|
|
16465
|
-
api: this.api
|
|
16466
|
-
})).tags;
|
|
16467
|
-
}
|
|
16468
|
-
for (let i = 0; i < batch.length; i++) {
|
|
16469
|
-
const entityId = batch[i];
|
|
16470
|
-
const record = entityMap[entityId];
|
|
16471
|
-
const feature = this.getEntityRego(entityId);
|
|
16472
|
-
if (feature) {
|
|
16473
|
-
const eTags = tags.filter(t => { var _a, _b, _c, _d; return ((_b = (_a = record === null || record === void 0 ? void 0 : record.Bruce) === null || _a === void 0 ? void 0 : _a["Layer.ID"]) === null || _b === void 0 ? void 0 : _b.length) && ((_d = (_c = record === null || record === void 0 ? void 0 : record.Bruce) === null || _c === void 0 ? void 0 : _c["Layer.ID"]) === null || _d === void 0 ? void 0 : _d.includes(t.ID)); });
|
|
16474
|
-
this.styleTilesetFeatureFullData(feature, record, eTags);
|
|
16475
|
-
}
|
|
16699
|
+
}
|
|
16700
|
+
const itemTypeId = menuItem.TypeId;
|
|
16701
|
+
if (itemTypeId) {
|
|
16702
|
+
if (!typeIds.includes(itemTypeId)) {
|
|
16703
|
+
typeIds.push(itemTypeId);
|
|
16476
16704
|
}
|
|
16477
|
-
rerun = rerun || batch.length > 0;
|
|
16478
|
-
this.viewer.scene.requestRender();
|
|
16479
16705
|
}
|
|
16480
16706
|
}
|
|
16481
16707
|
}
|
|
16482
|
-
|
|
16483
|
-
|
|
16484
|
-
|
|
16485
|
-
|
|
16486
|
-
|
|
16487
|
-
|
|
16488
|
-
|
|
16489
|
-
|
|
16490
|
-
|
|
16491
|
-
|
|
16492
|
-
|
|
16493
|
-
|
|
16494
|
-
return this.recordLoadQueue.splice(0, BATCH_SIZE);
|
|
16495
|
-
}
|
|
16496
|
-
/**
|
|
16497
|
-
* Calculates the current progress % and updates the progress if there is a change.
|
|
16498
|
-
*/
|
|
16499
|
-
updateStyleProgress() {
|
|
16500
|
-
if (this.disposed) {
|
|
16501
|
-
return;
|
|
16502
|
-
}
|
|
16503
|
-
let progress = 100; // Done when idling.
|
|
16504
|
-
if (this.recordCheckQueue.length || this.recordLoadQueue.length) {
|
|
16505
|
-
const total = Object.keys(this.styledEntityIds).length;
|
|
16506
|
-
// Done is the total minus the amount left.
|
|
16507
|
-
// We have to ensure the same ID isn't counted within or across these arrays as well.
|
|
16508
|
-
const uniqueSet = new Set(this.recordCheckQueue.concat(this.recordLoadQueue));
|
|
16509
|
-
const done = total - uniqueSet.size;
|
|
16510
|
-
progress = done / total * 100;
|
|
16511
|
-
// Round to 2dp, 0, or 100.
|
|
16512
|
-
if (progress < 0) {
|
|
16513
|
-
progress = 0;
|
|
16514
|
-
}
|
|
16515
|
-
else if (progress < 100) {
|
|
16516
|
-
progress = Math.round(progress * 100) / 100;
|
|
16517
|
-
}
|
|
16518
|
-
else if (progress > 100) {
|
|
16519
|
-
progress = 100;
|
|
16520
|
-
}
|
|
16708
|
+
if (menuItemIds.length > 0 && (!onlyIfLooping || this.isLooping)) {
|
|
16709
|
+
// Reset cells so none are marked as fetched.
|
|
16710
|
+
this.cells = new EntityGlobe.Grid();
|
|
16711
|
+
this.tagIds = tagIds;
|
|
16712
|
+
this.typeIds = typeIds;
|
|
16713
|
+
this.minHeight = minHeight;
|
|
16714
|
+
this.maxHeight = maxHeight;
|
|
16715
|
+
this.updateBounds();
|
|
16716
|
+
this.updateHistoricDateTime();
|
|
16717
|
+
this.startGetterLoop();
|
|
16718
|
+
this.viewAreaSub();
|
|
16719
|
+
this.viewerDateTimeSub();
|
|
16521
16720
|
}
|
|
16522
|
-
|
|
16523
|
-
this.
|
|
16524
|
-
this.
|
|
16721
|
+
else {
|
|
16722
|
+
this.getterLoopId += 1;
|
|
16723
|
+
this.viewAreaDispose();
|
|
16724
|
+
this.viewerDateTimeDispose();
|
|
16525
16725
|
}
|
|
16526
16726
|
}
|
|
16527
|
-
|
|
16528
|
-
|
|
16529
|
-
|
|
16530
|
-
|
|
16531
|
-
});
|
|
16532
|
-
}
|
|
16533
|
-
Dispose() {
|
|
16534
|
-
if (this.disposed) {
|
|
16535
|
-
return;
|
|
16536
|
-
}
|
|
16537
|
-
this.disposed = true;
|
|
16538
|
-
clearInterval(this.queueLoadInterval);
|
|
16539
|
-
clearInterval(this.queueCheckInterval);
|
|
16540
|
-
this._styleProgressQueue.Dispose();
|
|
16541
|
-
this.viewerDateTimeDispose();
|
|
16727
|
+
postStatus(status) {
|
|
16728
|
+
var _a;
|
|
16729
|
+
this.LastStateUpdates[status.msg] = status;
|
|
16730
|
+
(_a = this.onStateUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(status);
|
|
16542
16731
|
}
|
|
16543
|
-
|
|
16544
|
-
|
|
16545
|
-
|
|
16546
|
-
|
|
16547
|
-
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
this.
|
|
16556
|
-
}
|
|
16557
|
-
catch (e) {
|
|
16558
|
-
console.error(e);
|
|
16732
|
+
startGetterLoop() {
|
|
16733
|
+
// Increase id so that existing loops stop.
|
|
16734
|
+
this.getterLoopId += 1;
|
|
16735
|
+
const loopId = this.getterLoopId;
|
|
16736
|
+
const loopIntegrity = this.getIntegrityId();
|
|
16737
|
+
// Abort any existing loops that don't match the current loop.
|
|
16738
|
+
// We tried using integrity, however we want to interrupt when user moves camera quickly.
|
|
16739
|
+
// So it's better to use the loop ID.
|
|
16740
|
+
const abortId = String(loopId);
|
|
16741
|
+
{
|
|
16742
|
+
const newAbortControllers = {};
|
|
16743
|
+
for (const key in this.getterLoopAbortControllers) {
|
|
16744
|
+
this.getterLoopAbortControllers[key].abort();
|
|
16559
16745
|
}
|
|
16746
|
+
this.getterLoopAbortControllers = newAbortControllers;
|
|
16560
16747
|
}
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
|
|
16565
|
-
|
|
16566
|
-
|
|
16567
|
-
|
|
16568
|
-
|
|
16569
|
-
|
|
16570
|
-
|
|
16571
|
-
|
|
16572
|
-
|
|
16573
|
-
|
|
16574
|
-
|
|
16575
|
-
|
|
16576
|
-
|
|
16577
|
-
|
|
16578
|
-
|
|
16579
|
-
styleMapping.push({
|
|
16580
|
-
EntityTypeID: entityTypeId,
|
|
16581
|
-
StyleID: this.fallbackStyle ? fallbackStyleId : 0,
|
|
16582
|
-
style: this.fallbackStyle
|
|
16583
|
-
});
|
|
16584
|
-
}
|
|
16585
|
-
}
|
|
16748
|
+
const abortController = this.getterLoopAbortControllers[abortId] = new AbortController();
|
|
16749
|
+
this.looping += 1;
|
|
16750
|
+
(async () => {
|
|
16751
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
16752
|
+
// Larger initial delay for the first loops because terrain is likely loading in.
|
|
16753
|
+
// We also delay because if we enable 50 Menu Items at the same time, common requests we be made if we wait a bit.
|
|
16754
|
+
// Eg: same entity type will be grouped into the same filter getter instance.
|
|
16755
|
+
await delay(loopId <= 3 ? 800 : 300);
|
|
16756
|
+
const MIN_HEIGHT = this.minHeight;
|
|
16757
|
+
const MAX_HEIGHT = this.maxHeight;
|
|
16758
|
+
const PAGE_SIZE = this.batchSize;
|
|
16759
|
+
let retryAttempts = MAX_RETRY_ATTEMPTS;
|
|
16760
|
+
let retryDelay = 0;
|
|
16761
|
+
let prevFirstId = "";
|
|
16762
|
+
let prevLastId = "";
|
|
16763
|
+
let prevTicks = 0;
|
|
16764
|
+
while ((!this.viewCenter || !this.viewRect) && this.getterLoopId == loopId) {
|
|
16765
|
+
await delay(RETRY_DELAY_INCREMENT);
|
|
16586
16766
|
}
|
|
16587
|
-
|
|
16588
|
-
|
|
16589
|
-
console.error(e);
|
|
16590
|
-
}
|
|
16591
|
-
// Before we start the loop we'll do a single request for the needed Entity Types.
|
|
16592
|
-
// This will be aimed at rows that don't specify a Style and if the default fallback-
|
|
16593
|
-
//is set to 0 (using the default of the Entity Type).
|
|
16594
|
-
const typeMap = new Map();
|
|
16595
|
-
const typeIds = styleMapping.map(x => x.StyleID == -1 || Boolean(x.style) ? null : x.EntityTypeID).filter(x => !!x);
|
|
16596
|
-
if (typeIds.length) {
|
|
16597
|
-
// We'll split up into batches of 50.
|
|
16598
|
-
// Since we add the type IDs as query params I am paranoid of hitting the limit.
|
|
16599
|
-
const splits = Math.ceil(typeIds.length / 50);
|
|
16600
|
-
const batchSize = 50;
|
|
16601
|
-
for (let i = 0; i < splits; i++) {
|
|
16602
|
-
const batch = typeIds.slice(i * batchSize, (i + 1) * batchSize);
|
|
16603
|
-
const { entityTypes } = await EntityType.GetList({
|
|
16604
|
-
api: this.api,
|
|
16605
|
-
entityTypeIds: batch
|
|
16606
|
-
});
|
|
16607
|
-
for (let i = 0; i < entityTypes.length; i++) {
|
|
16608
|
-
const entityType = entityTypes[i];
|
|
16609
|
-
typeMap.set(entityType.ID, entityType);
|
|
16610
|
-
}
|
|
16767
|
+
if (this.getterLoopId != loopId) {
|
|
16768
|
+
return;
|
|
16611
16769
|
}
|
|
16612
|
-
|
|
16613
|
-
|
|
16614
|
-
|
|
16615
|
-
break;
|
|
16770
|
+
const alt = this.viewRect.alt;
|
|
16771
|
+
if (alt > MAX_HEIGHT || (alt < MIN_HEIGHT && MIN_HEIGHT > 0)) {
|
|
16772
|
+
return;
|
|
16616
16773
|
}
|
|
16617
|
-
|
|
16618
|
-
|
|
16619
|
-
|
|
16620
|
-
|
|
16621
|
-
|
|
16622
|
-
|
|
16623
|
-
|
|
16624
|
-
|
|
16625
|
-
|
|
16626
|
-
|
|
16627
|
-
|
|
16774
|
+
const cells = this.cells.GetCellsForView(this.viewCenter, this.viewRect);
|
|
16775
|
+
(_a = this.onScanUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(cells);
|
|
16776
|
+
let curCellIndex = cells.length > 0 ? 0 : null;
|
|
16777
|
+
let postedScanning = false;
|
|
16778
|
+
let postedLoading = false;
|
|
16779
|
+
let total = 0;
|
|
16780
|
+
while (retryAttempts > 0 && curCellIndex != null) {
|
|
16781
|
+
if (retryDelay > 0) {
|
|
16782
|
+
await delay(retryDelay);
|
|
16783
|
+
}
|
|
16784
|
+
if (this.getterLoopId != loopId) {
|
|
16785
|
+
break;
|
|
16786
|
+
}
|
|
16787
|
+
if (!postedScanning) {
|
|
16788
|
+
this.postStatus({ msg: EStatus.Scanning, revoking: false });
|
|
16789
|
+
postedScanning = true;
|
|
16790
|
+
}
|
|
16791
|
+
const curCell = cells[curCellIndex];
|
|
16792
|
+
if (curCell.IsFetched()) {
|
|
16793
|
+
curCell.Fetching = false;
|
|
16794
|
+
curCellIndex += 1;
|
|
16795
|
+
if (cells[curCellIndex]) {
|
|
16796
|
+
cells[curCellIndex].Fetching = true;
|
|
16797
|
+
}
|
|
16798
|
+
else {
|
|
16799
|
+
curCellIndex = null;
|
|
16800
|
+
}
|
|
16801
|
+
(_b = this.onScanUpdate) === null || _b === void 0 ? void 0 : _b.Trigger(cells);
|
|
16802
|
+
continue;
|
|
16803
|
+
}
|
|
16804
|
+
try {
|
|
16805
|
+
let response = {
|
|
16806
|
+
entities: [],
|
|
16807
|
+
nextPage: false,
|
|
16808
|
+
nextPageUrl: null
|
|
16809
|
+
};
|
|
16810
|
+
await SharedGetters.Queue.Run("Loading Entities from Menu Item that loads Entity Type: " + this.typeIds, async () => {
|
|
16811
|
+
var _a;
|
|
16812
|
+
if (abortController.signal.aborted || !((_a = this.GetMenuItems()) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
16813
|
+
return;
|
|
16814
|
+
}
|
|
16815
|
+
// API gave us a URL to use.
|
|
16816
|
+
if (curCell.FetchURL) {
|
|
16817
|
+
const tmpResponse = await this.api.get(curCell.FetchURL, {
|
|
16818
|
+
abortSignal: abortController.signal,
|
|
16819
|
+
noCache: true
|
|
16820
|
+
});
|
|
16821
|
+
// Same mapping as bruce-models doing Entity.GetList.
|
|
16822
|
+
response = {
|
|
16823
|
+
entities: tmpResponse.Items ? tmpResponse.Items : [],
|
|
16824
|
+
nextPage: tmpResponse.NextPage,
|
|
16825
|
+
nextPageUrl: tmpResponse.NextPageURL
|
|
16826
|
+
};
|
|
16827
|
+
}
|
|
16828
|
+
else {
|
|
16829
|
+
response = await Entity$1.GetList({
|
|
16628
16830
|
api: this.api,
|
|
16629
|
-
|
|
16630
|
-
|
|
16831
|
+
scenario: this.scenario,
|
|
16832
|
+
historicKey: this.historicAttrKey,
|
|
16833
|
+
historicPoint: (this.historicAttrKey || this.historic) ? this.historicAttrDateTime : null,
|
|
16834
|
+
schemaId: this.schemaId,
|
|
16835
|
+
filter: {
|
|
16836
|
+
pageSize: PAGE_SIZE,
|
|
16837
|
+
pageIndex: curCell.FetchPageIndex,
|
|
16838
|
+
entityTypeId: this.typeIds,
|
|
16839
|
+
layerIds: this.tagIds,
|
|
16840
|
+
// Any tag specified will be allowed.
|
|
16841
|
+
layerIdsOperator: "in",
|
|
16842
|
+
bounds: curCell.GetBounds(),
|
|
16843
|
+
sortOrder: Api.ESortOrder.Asc,
|
|
16844
|
+
entityTypeConditions: this.attrFilter
|
|
16845
|
+
},
|
|
16846
|
+
viaCdn: this.viaCdn,
|
|
16847
|
+
migrated: true,
|
|
16848
|
+
// If we're taking 2+ minutes to make a query, it's a dud.
|
|
16849
|
+
// This is a timeout imposed on our DB and not external sources.
|
|
16850
|
+
// Honestly could lower down to 30 seconds, but we'll keep it high for now.
|
|
16851
|
+
maxSearchTimeSec: 60 * 2,
|
|
16852
|
+
req: {
|
|
16853
|
+
// If we are passing in an abort, we MUST pass in noCache.
|
|
16854
|
+
// Otherwise we will cache an aborted request.
|
|
16855
|
+
noCache: true,
|
|
16856
|
+
abortSignal: abortController.signal
|
|
16857
|
+
}
|
|
16858
|
+
});
|
|
16859
|
+
}
|
|
16860
|
+
});
|
|
16861
|
+
const entities = response.entities;
|
|
16862
|
+
const integrity = this.getIntegrityId();
|
|
16863
|
+
if (loopIntegrity == integrity && entities) {
|
|
16864
|
+
(_c = this.onUpdate) === null || _c === void 0 ? void 0 : _c.Trigger(entities);
|
|
16865
|
+
}
|
|
16866
|
+
if (this.gatheredIntegrity != integrity) {
|
|
16867
|
+
this.gatheredIntegrity = integrity;
|
|
16868
|
+
this.gatheredEntityIds = [];
|
|
16869
|
+
}
|
|
16870
|
+
// Add to the integrity list for any new IDs found.
|
|
16871
|
+
// This lets us keep track of all IDs we've found within the same integrity for historic data.
|
|
16872
|
+
if (this.historicAttrKey || this.historic) {
|
|
16873
|
+
for (let i = 0; i < entities.length; i++) {
|
|
16874
|
+
const entity = entities[i];
|
|
16875
|
+
if (!this.gatheredEntityIds.includes(entity.Bruce.ID)) {
|
|
16876
|
+
this.gatheredEntityIds.push(entity.Bruce.ID);
|
|
16877
|
+
}
|
|
16631
16878
|
}
|
|
16632
|
-
styleId = entityType === null || entityType === void 0 ? void 0 : entityType["DisplaySetting.ID"];
|
|
16633
16879
|
}
|
|
16634
|
-
|
|
16635
|
-
|
|
16880
|
+
if (this.getterLoopId != loopId) {
|
|
16881
|
+
break;
|
|
16636
16882
|
}
|
|
16637
|
-
|
|
16638
|
-
|
|
16639
|
-
try {
|
|
16640
|
-
let { style: data } = await Style.Get({
|
|
16641
|
-
api: this.api,
|
|
16642
|
-
styleId
|
|
16643
|
-
});
|
|
16644
|
-
if (data) {
|
|
16645
|
-
styleMap.style = data;
|
|
16646
|
-
styleMap.StyleID = styleId;
|
|
16647
|
-
}
|
|
16883
|
+
if (entities.length) {
|
|
16884
|
+
total += entities.length;
|
|
16648
16885
|
}
|
|
16649
|
-
|
|
16650
|
-
|
|
16886
|
+
if (!postedLoading) {
|
|
16887
|
+
this.postStatus({ msg: EStatus.Loading, revoking: false });
|
|
16888
|
+
postedLoading = true;
|
|
16651
16889
|
}
|
|
16652
|
-
|
|
16653
|
-
|
|
16654
|
-
|
|
16655
|
-
|
|
16656
|
-
|
|
16657
|
-
|
|
16658
|
-
|
|
16659
|
-
|
|
16660
|
-
|
|
16661
|
-
|
|
16662
|
-
|
|
16663
|
-
|
|
16664
|
-
|
|
16665
|
-
|
|
16666
|
-
|
|
16667
|
-
|
|
16668
|
-
|
|
16669
|
-
|
|
16670
|
-
|
|
16671
|
-
|
|
16672
|
-
|
|
16673
|
-
|
|
16674
|
-
|
|
16675
|
-
|
|
16676
|
-
|
|
16677
|
-
|
|
16678
|
-
|
|
16679
|
-
|
|
16680
|
-
|
|
16681
|
-
return;
|
|
16682
|
-
}
|
|
16683
|
-
// This is multiplied by the speed of animation to figure
|
|
16684
|
-
// out how many animation "ticks" before we allow an update.
|
|
16685
|
-
const INTERVAL_WHILE_ANIMATING = 2.5 * 1000;
|
|
16686
|
-
const INTERVAL_WHILE_NOT_ANIMATING = 1000;
|
|
16687
|
-
let lastUpdateTime = null;
|
|
16688
|
-
let delayQueue = new DelayQueue(() => {
|
|
16689
|
-
try {
|
|
16690
|
-
// If the timeline is animating then we'll wait longer to update.
|
|
16691
|
-
if (this.viewer.clock.shouldAnimate && lastUpdateTime) {
|
|
16692
|
-
if (Math.abs(new Date().getTime() - lastUpdateTime) < INTERVAL_WHILE_ANIMATING) {
|
|
16693
|
-
return;
|
|
16890
|
+
// Only mark as fetched when ALL pages are done.
|
|
16891
|
+
// Known issue where external sources may return less than page size.
|
|
16892
|
+
// Right now we're making it as fetched as we're siding with the majority use-case.
|
|
16893
|
+
if (
|
|
16894
|
+
// API explicity says no more pages.
|
|
16895
|
+
response.nextPage === false ||
|
|
16896
|
+
// API didn't explicity say anything so we guess based on size of response.
|
|
16897
|
+
(response.nextPage == null &&
|
|
16898
|
+
(entities.length <= 0 || entities.length < PAGE_SIZE))) {
|
|
16899
|
+
curCell.Fetched = true;
|
|
16900
|
+
curCell.Fetching = false;
|
|
16901
|
+
(_d = this.onScanUpdate) === null || _d === void 0 ? void 0 : _d.Trigger(cells);
|
|
16902
|
+
continue;
|
|
16903
|
+
}
|
|
16904
|
+
// Checking to make sure it's not just the same batch over and over again.
|
|
16905
|
+
if (entities.length > 0) {
|
|
16906
|
+
const first = (_f = (_e = entities[0]) === null || _e === void 0 ? void 0 : _e.Bruce) === null || _f === void 0 ? void 0 : _f.ID;
|
|
16907
|
+
const last = (_h = (_g = entities[entities.length - 1]) === null || _g === void 0 ? void 0 : _g.Bruce) === null || _h === void 0 ? void 0 : _h.ID;
|
|
16908
|
+
if (prevFirstId == first && prevLastId == last) {
|
|
16909
|
+
prevTicks += 1;
|
|
16910
|
+
if (prevTicks > 3) {
|
|
16911
|
+
break;
|
|
16912
|
+
}
|
|
16913
|
+
}
|
|
16914
|
+
else {
|
|
16915
|
+
prevFirstId = first;
|
|
16916
|
+
prevLastId = last;
|
|
16917
|
+
prevTicks = 0;
|
|
16918
|
+
}
|
|
16694
16919
|
}
|
|
16920
|
+
// Using URL if specified.
|
|
16921
|
+
// If not then we'll just manually paginate.
|
|
16922
|
+
curCell.FetchURL = response.nextPageUrl;
|
|
16923
|
+
curCell.FetchPageIndex++;
|
|
16924
|
+
// Request passed so let's assume it was server hiccup and refresh counts.
|
|
16925
|
+
retryAttempts = MAX_RETRY_ATTEMPTS;
|
|
16926
|
+
retryDelay = 0;
|
|
16695
16927
|
}
|
|
16696
|
-
|
|
16697
|
-
|
|
16698
|
-
|
|
16699
|
-
|
|
16928
|
+
catch (e) {
|
|
16929
|
+
// Ignore abort errors.
|
|
16930
|
+
if (e && typeof e === "object" && e.name == "AbortError") {
|
|
16931
|
+
// console.debug("Aborted entity-filter-getter request.");
|
|
16932
|
+
break;
|
|
16933
|
+
}
|
|
16934
|
+
console.error(e);
|
|
16935
|
+
if (this.getterLoopId != loopId) {
|
|
16936
|
+
break;
|
|
16937
|
+
}
|
|
16938
|
+
// Request failed so let's add a delay and try again soon.
|
|
16939
|
+
retryDelay += RETRY_DELAY_INCREMENT;
|
|
16940
|
+
retryAttempts -= 1;
|
|
16700
16941
|
}
|
|
16942
|
+
await delay(REQUEST_PAGE_DELAY);
|
|
16701
16943
|
}
|
|
16702
|
-
|
|
16703
|
-
|
|
16944
|
+
if (postedLoading) {
|
|
16945
|
+
this.postStatus({ msg: EStatus.Loading, revoking: true });
|
|
16704
16946
|
}
|
|
16705
|
-
|
|
16706
|
-
|
|
16707
|
-
if (delayQueue) {
|
|
16708
|
-
delayQueue.Call();
|
|
16947
|
+
if (postedScanning) {
|
|
16948
|
+
this.postStatus({ msg: EStatus.Scanning, revoking: true });
|
|
16709
16949
|
}
|
|
16950
|
+
})().then(() => {
|
|
16951
|
+
this.looping -= 1;
|
|
16952
|
+
}).catch(() => {
|
|
16953
|
+
this.looping -= 1;
|
|
16710
16954
|
});
|
|
16711
|
-
this.viewerDateTimeChangeRemoval = () => {
|
|
16712
|
-
delayQueue === null || delayQueue === void 0 ? void 0 : delayQueue.Dispose();
|
|
16713
|
-
postUpdateRemoval === null || postUpdateRemoval === void 0 ? void 0 : postUpdateRemoval();
|
|
16714
|
-
delayQueue = null;
|
|
16715
|
-
postUpdateRemoval = null;
|
|
16716
|
-
};
|
|
16717
|
-
}
|
|
16718
|
-
updateHistoricDateTime() {
|
|
16719
|
-
if (!this.historic) {
|
|
16720
|
-
this.historicAttrDateTime = null;
|
|
16721
|
-
return;
|
|
16722
|
-
}
|
|
16723
|
-
const isChanged = (before, after) => {
|
|
16724
|
-
if (before && !after) {
|
|
16725
|
-
return true;
|
|
16726
|
-
}
|
|
16727
|
-
if (!before && after) {
|
|
16728
|
-
return true;
|
|
16729
|
-
}
|
|
16730
|
-
// Change must be at least 0.1 seconds.
|
|
16731
|
-
return Math.abs(before.getTime() - after.getTime()) > 100;
|
|
16732
|
-
};
|
|
16733
|
-
const oldDateTime = this.historicAttrDateTime ? new Date(this.historicAttrDateTime) : null;
|
|
16734
|
-
const newDateTime = JulianDate.toDate(this.viewer.clock.currentTime);
|
|
16735
|
-
if (isChanged(oldDateTime, newDateTime)) {
|
|
16736
|
-
this.historicAttrDateTime = newDateTime.toISOString();
|
|
16737
|
-
}
|
|
16738
|
-
}
|
|
16739
|
-
viewerDateTimeDispose() {
|
|
16740
|
-
var _a;
|
|
16741
|
-
(_a = this.viewerDateTimeChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
16742
|
-
this.viewerDateTimeChangeRemoval = null;
|
|
16743
16955
|
}
|
|
16744
16956
|
/**
|
|
16745
16957
|
* Gets the historic state of found Entities for the current date times and emits them.
|
|
16746
16958
|
* Since geometry searches are tied to the base Entity, we don't have to re-scan the viewport.
|
|
16747
16959
|
*/
|
|
16748
16960
|
emitHistoricData() {
|
|
16749
|
-
if (this.
|
|
16961
|
+
if (!this.GetMenuItems().length) {
|
|
16962
|
+
return;
|
|
16963
|
+
}
|
|
16964
|
+
let integrity = this.getIntegrityId();
|
|
16965
|
+
// Gathered ID does't match current one.
|
|
16966
|
+
if (this.gatheredIntegrity != integrity) {
|
|
16750
16967
|
return;
|
|
16751
16968
|
}
|
|
16752
16969
|
const historicAttrDateTime = this.historicAttrDateTime;
|
|
@@ -16756,29 +16973,34 @@ var TilesetRenderEngine;
|
|
|
16756
16973
|
this.historicRefreshAbortController = null;
|
|
16757
16974
|
}
|
|
16758
16975
|
(async () => {
|
|
16759
|
-
var _a
|
|
16976
|
+
var _a;
|
|
16760
16977
|
try {
|
|
16761
|
-
const gatheredEntityIds = Object.keys(this.styledWithAttrEntityIds);
|
|
16762
16978
|
// Loop through all IDs we've found and get their historic records.
|
|
16763
|
-
for (let i = 0; i < gatheredEntityIds.length; i += SCAN_BATCH_SIZE) {
|
|
16764
|
-
let batch = gatheredEntityIds.slice(i, i + SCAN_BATCH_SIZE);
|
|
16979
|
+
for (let i = 0; i < this.gatheredEntityIds.length; i += SCAN_BATCH_SIZE) {
|
|
16980
|
+
let batch = this.gatheredEntityIds.slice(i, i + SCAN_BATCH_SIZE);
|
|
16765
16981
|
if (!batch.length) {
|
|
16766
16982
|
break;
|
|
16767
16983
|
}
|
|
16768
16984
|
// Controller we can use to abort the request when a new loop starts.
|
|
16769
16985
|
const controller = this.historicRefreshAbortController = new AbortController();
|
|
16770
16986
|
let entities = [];
|
|
16771
|
-
await SharedGetters.Queue.Run("Refreshing historic data in Menu Item that loads
|
|
16772
|
-
|
|
16987
|
+
await SharedGetters.Queue.Run("Refreshing historic data in Menu Item that loads Entity Type: " + this.typeIds, async () => {
|
|
16988
|
+
var _a;
|
|
16989
|
+
if (controller.signal.aborted || !((_a = this.GetMenuItems()) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
16773
16990
|
return;
|
|
16774
16991
|
}
|
|
16775
16992
|
entities = (await Entity$1.GetList({
|
|
16776
16993
|
api: this.api,
|
|
16777
16994
|
scenario: this.scenario,
|
|
16995
|
+
historicKey: this.historicAttrKey,
|
|
16778
16996
|
historicPoint: historicAttrDateTime,
|
|
16997
|
+
schemaId: this.schemaId,
|
|
16779
16998
|
filter: {
|
|
16780
16999
|
pageSize: batch.length,
|
|
16781
17000
|
pageIndex: 0,
|
|
17001
|
+
entityTypeId: this.typeIds,
|
|
17002
|
+
layerIds: this.tagIds,
|
|
17003
|
+
layerIdsOperator: "in",
|
|
16782
17004
|
sortOrder: Api.ESortOrder.Asc,
|
|
16783
17005
|
entityTypeConditions: {
|
|
16784
17006
|
"ID": {
|
|
@@ -16786,6 +17008,7 @@ var TilesetRenderEngine;
|
|
|
16786
17008
|
}
|
|
16787
17009
|
},
|
|
16788
17010
|
},
|
|
17011
|
+
viaCdn: this.viaCdn,
|
|
16789
17012
|
migrated: true,
|
|
16790
17013
|
// If we're taking 5+ minutes to make a query, it's a dud.
|
|
16791
17014
|
// This is a timeout imposed on our DB and not external sources.
|
|
@@ -16803,331 +17026,211 @@ var TilesetRenderEngine;
|
|
|
16803
17026
|
if (this.historicAttrDateTime != historicAttrDateTime) {
|
|
16804
17027
|
break;
|
|
16805
17028
|
}
|
|
16806
|
-
//
|
|
16807
|
-
|
|
16808
|
-
for (let i = 0; i < entities.length; i++) {
|
|
16809
|
-
const entity = entities[i];
|
|
16810
|
-
if ((_b = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a["Layer.ID"]) === null || _b === void 0 ? void 0 : _b.length) {
|
|
16811
|
-
const eTagIds = entity.Bruce["Layer.ID"];
|
|
16812
|
-
for (let j = 0; j < eTagIds.length; j++) {
|
|
16813
|
-
tagIds.push(eTagIds[j]);
|
|
16814
|
-
}
|
|
16815
|
-
}
|
|
16816
|
-
}
|
|
16817
|
-
// Turn into unique list.
|
|
16818
|
-
if (tagIds.length) {
|
|
16819
|
-
tagIds = tagIds.filter((v, i, a) => a.indexOf(v) === i);
|
|
16820
|
-
}
|
|
16821
|
-
// Gather records.
|
|
16822
|
-
let tags = [];
|
|
16823
|
-
if (tagIds.length) {
|
|
16824
|
-
tags = (await EntityTag.GetListByIds({
|
|
16825
|
-
tagIds: tagIds,
|
|
16826
|
-
api: this.api
|
|
16827
|
-
})).tags;
|
|
16828
|
-
}
|
|
16829
|
-
// Date changed.
|
|
16830
|
-
if (this.historicAttrDateTime != historicAttrDateTime) {
|
|
17029
|
+
// Integrity changed.
|
|
17030
|
+
if (this.gatheredIntegrity != integrity) {
|
|
16831
17031
|
break;
|
|
16832
17032
|
}
|
|
16833
|
-
//
|
|
16834
|
-
|
|
16835
|
-
|
|
16836
|
-
const feature = this.getEntityRego(entity.Bruce.ID);
|
|
16837
|
-
if (feature) {
|
|
16838
|
-
const eTags = tags.filter(t => { var _a, _b, _c, _d; return ((_b = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a["Layer.ID"]) === null || _b === void 0 ? void 0 : _b.length) && ((_d = (_c = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _c === void 0 ? void 0 : _c["Layer.ID"]) === null || _d === void 0 ? void 0 : _d.includes(t.ID)); });
|
|
16839
|
-
this.styleTilesetFeatureFullData(feature, entity, eTags);
|
|
16840
|
-
}
|
|
17033
|
+
// No Menu Items.
|
|
17034
|
+
if (!this.GetMenuItems().length) {
|
|
17035
|
+
break;
|
|
16841
17036
|
}
|
|
17037
|
+
(_a = this.onUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(entities);
|
|
16842
17038
|
}
|
|
16843
17039
|
}
|
|
16844
17040
|
catch (e) {
|
|
16845
17041
|
// Ignore abort errors.
|
|
16846
17042
|
if (e && typeof e === "object" && e.name == "AbortError") {
|
|
17043
|
+
// console.debug("Aborted entity-filter-getter historic refresh request.");
|
|
16847
17044
|
return;
|
|
16848
17045
|
}
|
|
16849
17046
|
console.error(e);
|
|
16850
17047
|
}
|
|
16851
17048
|
})();
|
|
16852
17049
|
}
|
|
16853
|
-
|
|
16854
|
-
|
|
16855
|
-
|
|
16856
|
-
|
|
16857
|
-
|
|
16858
|
-
|
|
16859
|
-
|
|
16860
|
-
|
|
16861
|
-
|
|
16862
|
-
|
|
16863
|
-
|
|
16864
|
-
|
|
16865
|
-
|
|
16866
|
-
|
|
16867
|
-
|
|
16868
|
-
|
|
16869
|
-
|
|
16870
|
-
|
|
17050
|
+
}
|
|
17051
|
+
EntityFilterGetter.Getter = Getter;
|
|
17052
|
+
})(EntityFilterGetter || (EntityFilterGetter = {}));
|
|
17053
|
+
|
|
17054
|
+
function createFilterGetterCacheKey(params) {
|
|
17055
|
+
let cacheKey = "";
|
|
17056
|
+
cacheKey += params.api.GetBaseUrl();
|
|
17057
|
+
// Not including Type ID in the cache key now.
|
|
17058
|
+
// This allows us to re-use the same getter between Entity Types.
|
|
17059
|
+
// cacheKey += params.typeId;
|
|
17060
|
+
cacheKey += params.batchSize;
|
|
17061
|
+
cacheKey += String(params.cdn);
|
|
17062
|
+
cacheKey += params.schemaId ? params.schemaId : "";
|
|
17063
|
+
cacheKey += JSON.stringify(params.tagIds ? params.tagIds : []);
|
|
17064
|
+
cacheKey += params.historicAttrKey ? params.historicAttrKey : "";
|
|
17065
|
+
cacheKey += params.historic ? "true" : "false";
|
|
17066
|
+
cacheKey += params.scenario ? params.scenario : 0;
|
|
17067
|
+
if (params.historicAttrKey) {
|
|
17068
|
+
cacheKey += params.historicInterpolation ? "true" : "false";
|
|
17069
|
+
}
|
|
17070
|
+
// This could potentially crash, but if it crashes here then it would crash during API request anyways.
|
|
17071
|
+
cacheKey += JSON.stringify(params.attrFilter ? params.attrFilter : {});
|
|
17072
|
+
return cacheKey;
|
|
17073
|
+
}
|
|
17074
|
+
var SharedGetters;
|
|
17075
|
+
(function (SharedGetters) {
|
|
17076
|
+
class Cache {
|
|
17077
|
+
constructor() {
|
|
17078
|
+
this.data = {};
|
|
16871
17079
|
}
|
|
16872
|
-
|
|
16873
|
-
|
|
16874
|
-
|
|
16875
|
-
|
|
16876
|
-
|
|
16877
|
-
|
|
16878
|
-
|
|
16879
|
-
|
|
16880
|
-
|
|
16881
|
-
|
|
16882
|
-
|
|
16883
|
-
|
|
16884
|
-
|
|
16885
|
-
|
|
16886
|
-
|
|
16887
|
-
|
|
16888
|
-
|
|
16889
|
-
|
|
16890
|
-
|
|
16891
|
-
|
|
16892
|
-
|
|
16893
|
-
|
|
16894
|
-
|
|
16895
|
-
|
|
16896
|
-
|
|
16897
|
-
|
|
17080
|
+
GetOrCreateFilterGetter(params) {
|
|
17081
|
+
params.cdn = Boolean(params.cdn);
|
|
17082
|
+
const cacheKey = createFilterGetterCacheKey(params);
|
|
17083
|
+
let getter = this.data[cacheKey];
|
|
17084
|
+
if (!getter) {
|
|
17085
|
+
getter = new EntityFilterGetter.Getter({
|
|
17086
|
+
api: params.api,
|
|
17087
|
+
viewer: params.viewer,
|
|
17088
|
+
viewPort: params.monitor,
|
|
17089
|
+
typeIds: !params.typeId ? null : typeof params.typeId == "string" ? [params.typeId] : params.typeId,
|
|
17090
|
+
schemaId: params.schemaId,
|
|
17091
|
+
batchSize: params.batchSize,
|
|
17092
|
+
attrFilter: params.attrFilter,
|
|
17093
|
+
historic: params.historic,
|
|
17094
|
+
historicAttrKey: params.historicAttrKey,
|
|
17095
|
+
historicInterpolation: params.historicInterpolation,
|
|
17096
|
+
viaCdn: params.cdn,
|
|
17097
|
+
scenario: params.scenario,
|
|
17098
|
+
});
|
|
17099
|
+
this.data[cacheKey] = getter;
|
|
17100
|
+
/**
|
|
17101
|
+
* Debug option.
|
|
17102
|
+
* This will display the bounds of the cells that are being fetched.
|
|
17103
|
+
*/
|
|
17104
|
+
if (params.viewer && params.debugShowBounds) {
|
|
17105
|
+
// Cell id -> entity.
|
|
17106
|
+
const cellCache = {};
|
|
17107
|
+
const cellPrefix = ObjectUtils.UId(10) + "_";
|
|
17108
|
+
getter.OnScanUpdate.Subscribe((cells) => {
|
|
17109
|
+
if (window.ON_SCAN_UPDATE_PAUSED == true) {
|
|
17110
|
+
return;
|
|
17111
|
+
}
|
|
17112
|
+
const curCellIds = [];
|
|
17113
|
+
let fetchingCellId = null;
|
|
17114
|
+
const fetchedCells = {};
|
|
17115
|
+
cells.forEach((cell) => {
|
|
17116
|
+
var _a;
|
|
17117
|
+
const bounds = cell.GetBounds();
|
|
17118
|
+
const id = cellPrefix + bounds.east + "_" + bounds.north + "_" + bounds.south + "_" + bounds.west;
|
|
17119
|
+
curCellIds.push(id);
|
|
17120
|
+
fetchedCells[id] = cell.IsFetched();
|
|
17121
|
+
fetchingCellId = cell.Fetching ? id : fetchingCellId;
|
|
17122
|
+
let material = null;
|
|
17123
|
+
if (fetchedCells[id]) {
|
|
17124
|
+
material = Color.LIGHTGREEN.clone().withAlpha(0.3);
|
|
16898
17125
|
}
|
|
16899
|
-
if (
|
|
16900
|
-
|
|
17126
|
+
else if (fetchingCellId == id) {
|
|
17127
|
+
material = Color.LIGHTBLUE.clone().withAlpha(0.3);
|
|
16901
17128
|
}
|
|
16902
|
-
|
|
16903
|
-
|
|
16904
|
-
const entityId = batch[i];
|
|
16905
|
-
const index = this.recordCheckQueue.findIndex(x => x == entityId);
|
|
16906
|
-
if (index > -1) {
|
|
16907
|
-
this.recordCheckQueue.splice(index, 1);
|
|
17129
|
+
else {
|
|
17130
|
+
material = Color.GOLD.clone().withAlpha(0.3);
|
|
16908
17131
|
}
|
|
16909
|
-
|
|
16910
|
-
|
|
16911
|
-
|
|
16912
|
-
|
|
16913
|
-
|
|
16914
|
-
|
|
16915
|
-
if (entity) {
|
|
16916
|
-
this.queueTilesetFeatureStyle(entity, false);
|
|
17132
|
+
if (cellCache[id]) {
|
|
17133
|
+
const rect = (_a = cellCache[id]) === null || _a === void 0 ? void 0 : _a.rectangle;
|
|
17134
|
+
if (rect) {
|
|
17135
|
+
rect.material = material;
|
|
17136
|
+
}
|
|
17137
|
+
return;
|
|
16917
17138
|
}
|
|
16918
|
-
|
|
16919
|
-
|
|
16920
|
-
|
|
16921
|
-
|
|
16922
|
-
|
|
16923
|
-
|
|
16924
|
-
|
|
16925
|
-
|
|
16926
|
-
|
|
16927
|
-
|
|
16928
|
-
|
|
16929
|
-
|
|
16930
|
-
|
|
16931
|
-
|
|
16932
|
-
|
|
16933
|
-
|
|
16934
|
-
|
|
16935
|
-
|
|
16936
|
-
|
|
16937
|
-
|
|
16938
|
-
|
|
16939
|
-
|
|
16940
|
-
|
|
16941
|
-
|
|
16942
|
-
|
|
16943
|
-
|
|
16944
|
-
|
|
16945
|
-
|
|
16946
|
-
|
|
16947
|
-
|
|
16948
|
-
}
|
|
16949
|
-
else {
|
|
16950
|
-
this.recordCheckQueue.push(entity.entityId);
|
|
16951
|
-
}
|
|
16952
|
-
}
|
|
16953
|
-
}
|
|
16954
|
-
styleTilesetFeature(entity) {
|
|
16955
|
-
this.styleTilesetFeatureFullData(entity, null, []);
|
|
16956
|
-
}
|
|
16957
|
-
styleTilesetFeatureFullData(entity, data, tags) {
|
|
16958
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
16959
|
-
const visual = entity.visual;
|
|
16960
|
-
if (!visual || !(visual instanceof Cesium3DTileFeature)) {
|
|
16961
|
-
return;
|
|
16962
|
-
}
|
|
16963
|
-
const style = this.getTilesetFeatureStyle(entity.entityId, entity.entityTypeId);
|
|
16964
|
-
const bColor = style && ((_a = style.modelStyle) === null || _a === void 0 ? void 0 : _a.fillColor) ? Calculator.GetColor(style.modelStyle.fillColor, data, tags) : null;
|
|
16965
|
-
let cColor = null;
|
|
16966
|
-
if (bColor == null) {
|
|
16967
|
-
cColor = Color.WHITE;
|
|
16968
|
-
}
|
|
16969
|
-
else {
|
|
16970
|
-
cColor = colorToCColor$3(bColor);
|
|
16971
|
-
}
|
|
16972
|
-
const override = this.styledEntityIds[entity.entityId] == true;
|
|
16973
|
-
CesiumEntityStyler.SetDefaultColor({
|
|
16974
|
-
color: cColor,
|
|
16975
|
-
entity: visual,
|
|
16976
|
-
viewer: this.viewer,
|
|
16977
|
-
override: override
|
|
16978
|
-
});
|
|
16979
|
-
this.styledEntityIds[entity.entityId] = true;
|
|
16980
|
-
if (data) {
|
|
16981
|
-
this.styledWithAttrEntityIds[entity.entityId] = true;
|
|
16982
|
-
}
|
|
16983
|
-
else {
|
|
16984
|
-
delete this.styledWithAttrEntityIds[entity.entityId];
|
|
16985
|
-
}
|
|
16986
|
-
this._styleProgressQueue.Call();
|
|
16987
|
-
// Since we only need to update it for scenarios right now.
|
|
16988
|
-
// We'll avoid doing it if not needed, eg: first render and no scenario (same state as default).
|
|
16989
|
-
if (this.shouldUpdateRegoStates && (override || ((_b = data === null || data === void 0 ? void 0 : data.Bruce) === null || _b === void 0 ? void 0 : _b.Scenario) || this.historic)) {
|
|
16990
|
-
// Update the Entity's rego state.
|
|
16991
|
-
let changed = false;
|
|
16992
|
-
// Changed scenario.
|
|
16993
|
-
if (entity.scenario != ((_c = data === null || data === void 0 ? void 0 : data.Bruce) === null || _c === void 0 ? void 0 : _c.Scenario)) {
|
|
16994
|
-
entity.scenario = (_d = data === null || data === void 0 ? void 0 : data.Bruce) === null || _d === void 0 ? void 0 : _d.Scenario;
|
|
16995
|
-
changed = true;
|
|
16996
|
-
}
|
|
16997
|
-
// Changed historic.
|
|
16998
|
-
if ((data && isHistoricMetadataChanged(entity, data)) || (!data && ((_e = entity.historicLayers) === null || _e === void 0 ? void 0 : _e.length) && !((_g = (_f = data.Bruce) === null || _f === void 0 ? void 0 : _f.HistoricLayers) === null || _g === void 0 ? void 0 : _g.length))) {
|
|
16999
|
-
entity.historicLayers = (_h = data === null || data === void 0 ? void 0 : data.Bruce) === null || _h === void 0 ? void 0 : _h.HistoricLayers;
|
|
17000
|
-
changed = true;
|
|
17001
|
-
}
|
|
17002
|
-
// Something changed, trigger a rego update.
|
|
17003
|
-
// This lets UI know when the rego has changed.
|
|
17004
|
-
if (changed) {
|
|
17005
|
-
this.register.OnUpdate.Trigger({
|
|
17006
|
-
type: VisualsRegister.EVisualUpdateType.Update,
|
|
17007
|
-
entityId: entity.entityId,
|
|
17008
|
-
rego: entity
|
|
17139
|
+
const rect = new Rectangle(Math$1.toRadians(bounds.west), Math$1.toRadians(bounds.south), Math$1.toRadians(bounds.east), Math$1.toRadians(bounds.north));
|
|
17140
|
+
const entity = params.viewer.entities.add(new Entity({
|
|
17141
|
+
id: id,
|
|
17142
|
+
rectangle: {
|
|
17143
|
+
coordinates: rect,
|
|
17144
|
+
fill: true,
|
|
17145
|
+
//material: Cesium.Color.fromRandom().withAlpha(0.3),
|
|
17146
|
+
material: material,
|
|
17147
|
+
zIndex: 0
|
|
17148
|
+
},
|
|
17149
|
+
// point: {
|
|
17150
|
+
// pixelSize: 15,
|
|
17151
|
+
// outlineColor: Cesium.Color.WHITE,
|
|
17152
|
+
// outlineWidth: 2,
|
|
17153
|
+
// color: Cesium.Color.fromRandom().withAlpha(0.5),
|
|
17154
|
+
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
|
17155
|
+
// },
|
|
17156
|
+
position: Cartesian3.fromRadians((rect.east + rect.west) / 2, (rect.north + rect.south) / 2)
|
|
17157
|
+
}));
|
|
17158
|
+
cellCache[id] = entity;
|
|
17159
|
+
});
|
|
17160
|
+
Object.keys(cellCache).forEach((id) => {
|
|
17161
|
+
if (curCellIds.indexOf(id) == -1) {
|
|
17162
|
+
const entity = cellCache[id];
|
|
17163
|
+
if (entity && params.viewer.entities.contains(entity)) {
|
|
17164
|
+
params.viewer.entities.remove(entity);
|
|
17165
|
+
}
|
|
17166
|
+
delete cellCache[id];
|
|
17167
|
+
}
|
|
17168
|
+
});
|
|
17009
17169
|
});
|
|
17010
17170
|
}
|
|
17011
17171
|
}
|
|
17012
|
-
|
|
17013
|
-
getTilesetFeatureStyle(entityId, entityTypeId) {
|
|
17014
|
-
var _a, _b, _c, _d;
|
|
17015
|
-
// Locate what style is applicable to the feature.
|
|
17016
|
-
let style = null;
|
|
17017
|
-
if (entityTypeId) {
|
|
17018
|
-
style = ((_b = (_a = this.styleMapping.find(x => x.EntityTypeID == entityTypeId)) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.Settings);
|
|
17019
|
-
}
|
|
17020
|
-
if (!style) {
|
|
17021
|
-
style = ((_c = this.fallbackStyle) === null || _c === void 0 ? void 0 : _c.Settings);
|
|
17022
|
-
}
|
|
17023
|
-
if (!style || !((_d = style === null || style === void 0 ? void 0 : style.modelStyle) === null || _d === void 0 ? void 0 : _d.customize)) {
|
|
17024
|
-
return null;
|
|
17025
|
-
}
|
|
17026
|
-
return style;
|
|
17027
|
-
}
|
|
17028
|
-
getTilesetFeatureNeedsFullData(entityId, entityTypeId) {
|
|
17029
|
-
var _a;
|
|
17030
|
-
if (this.historic) {
|
|
17031
|
-
// Unfortunately when we are working with historic we have to request the entity.
|
|
17032
|
-
// This is because we need to know if a record exists at the point in time.
|
|
17033
|
-
return true;
|
|
17034
|
-
}
|
|
17035
|
-
const style = this.getTilesetFeatureStyle(entityId, entityTypeId);
|
|
17036
|
-
if (!style) {
|
|
17037
|
-
return false;
|
|
17038
|
-
}
|
|
17039
|
-
const fill = (_a = style === null || style === void 0 ? void 0 : style.modelStyle) === null || _a === void 0 ? void 0 : _a.fillColor;
|
|
17040
|
-
if (!fill || fill.length <= 0) {
|
|
17041
|
-
return false;
|
|
17042
|
-
}
|
|
17043
|
-
return fill[0].type != 0;
|
|
17172
|
+
return getter;
|
|
17044
17173
|
}
|
|
17045
17174
|
}
|
|
17046
|
-
|
|
17047
|
-
/**
|
|
17048
|
-
* The maximum memory in MB that can be used by all tilesets.
|
|
17049
|
-
* This is distributed evenly between all loaded tilesets.
|
|
17050
|
-
*/
|
|
17051
|
-
TilesetRenderEngine.MAX_TILESET_MEMORY = 1024;
|
|
17175
|
+
SharedGetters.Cache = Cache;
|
|
17052
17176
|
/**
|
|
17053
|
-
*
|
|
17054
|
-
*
|
|
17055
|
-
* As more get watched their memory will be reduced.
|
|
17177
|
+
* To avoid performing multiple expensive queries at the same time,
|
|
17178
|
+
* we'll have the getters work through a queue of requests.
|
|
17056
17179
|
*/
|
|
17057
|
-
|
|
17058
|
-
|
|
17059
|
-
|
|
17060
|
-
|
|
17061
|
-
}
|
|
17062
|
-
distributeMemory() {
|
|
17063
|
-
this.clean();
|
|
17064
|
-
// Total 1gb as default.
|
|
17065
|
-
// We'll need to allow user to change this somehow.
|
|
17066
|
-
const maxMemory = TilesetRenderEngine.MAX_TILESET_MEMORY;
|
|
17067
|
-
// Minimum memory in MB per tileset.
|
|
17068
|
-
const minMemory = 80;
|
|
17069
|
-
const totalPerTileset = Math.max(this.watched.length ? maxMemory / this.watched.length : maxMemory, minMemory);
|
|
17070
|
-
this.watched.forEach(x => {
|
|
17071
|
-
// Newer Cesium killed this property.
|
|
17072
|
-
// TODO: Check if it's needed then.
|
|
17073
|
-
x["maximumMemoryUsage"] = totalPerTileset;
|
|
17074
|
-
});
|
|
17075
|
-
}
|
|
17076
|
-
destroy() {
|
|
17077
|
-
this.watched = [];
|
|
17078
|
-
}
|
|
17180
|
+
let Queue;
|
|
17181
|
+
(function (Queue) {
|
|
17182
|
+
const queue = [];
|
|
17183
|
+
let isProcessing = false;
|
|
17079
17184
|
/**
|
|
17080
|
-
*
|
|
17185
|
+
* Called to run a provided function.
|
|
17186
|
+
* When the function is complete, the next function in the queue will be called.
|
|
17187
|
+
* This function will resolve when the provided function is complete.
|
|
17188
|
+
* If the provided function crashes, the error bubbles up to the caller.
|
|
17189
|
+
* @param name
|
|
17190
|
+
* @param call
|
|
17081
17191
|
*/
|
|
17082
|
-
|
|
17083
|
-
//
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
|
|
17087
|
-
|
|
17088
|
-
|
|
17089
|
-
|
|
17090
|
-
|
|
17091
|
-
|
|
17092
|
-
|
|
17093
|
-
|
|
17094
|
-
|
|
17095
|
-
|
|
17096
|
-
|
|
17097
|
-
|
|
17098
|
-
|
|
17099
|
-
|
|
17100
|
-
|
|
17101
|
-
|
|
17102
|
-
|
|
17192
|
+
function Run(name, call) {
|
|
17193
|
+
// console.debug(`Queueing: ${name}`);
|
|
17194
|
+
return new Promise((resolve, reject) => {
|
|
17195
|
+
queue.push(async () => {
|
|
17196
|
+
try {
|
|
17197
|
+
// console.debug(`Running: ${name}`);
|
|
17198
|
+
const result = await call();
|
|
17199
|
+
resolve(result);
|
|
17200
|
+
}
|
|
17201
|
+
catch (error) {
|
|
17202
|
+
reject(error);
|
|
17203
|
+
}
|
|
17204
|
+
finally {
|
|
17205
|
+
// Process the next function in the queue.
|
|
17206
|
+
queue.shift();
|
|
17207
|
+
// If there are more functions in the queue, process the next one.
|
|
17208
|
+
if (queue.length > 0) {
|
|
17209
|
+
processNext();
|
|
17210
|
+
}
|
|
17211
|
+
// No more items to process.
|
|
17212
|
+
else {
|
|
17213
|
+
isProcessing = false;
|
|
17214
|
+
}
|
|
17215
|
+
}
|
|
17216
|
+
});
|
|
17217
|
+
if (!isProcessing) {
|
|
17218
|
+
// If not currently processing, start processing the queue.
|
|
17219
|
+
isProcessing = true;
|
|
17220
|
+
processNext();
|
|
17221
|
+
}
|
|
17222
|
+
});
|
|
17103
17223
|
}
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
17107
|
-
|
|
17108
|
-
|
|
17109
|
-
|
|
17110
|
-
}
|
|
17111
|
-
const index = this.watched.findIndex(x => (x === null || x === void 0 ? void 0 : x[WATCH_KEY]) === tileset[WATCH_KEY]);
|
|
17112
|
-
if (index > -1) {
|
|
17113
|
-
this.watched.splice(index, 1);
|
|
17224
|
+
Queue.Run = Run;
|
|
17225
|
+
async function processNext() {
|
|
17226
|
+
const nextCall = queue[0];
|
|
17227
|
+
if (nextCall) {
|
|
17228
|
+
// Call the next function in the queue.
|
|
17229
|
+
await nextCall();
|
|
17114
17230
|
}
|
|
17115
|
-
this.distributeMemory();
|
|
17116
|
-
}
|
|
17117
|
-
}
|
|
17118
|
-
TilesetRenderEngine.MemoryWatcher = MemoryWatcher;
|
|
17119
|
-
function GetMemoryWatcher(viewer) {
|
|
17120
|
-
// If viewer is dead return nothing.
|
|
17121
|
-
if (!viewer || viewer.isDestroyed()) {
|
|
17122
|
-
return null;
|
|
17123
|
-
}
|
|
17124
|
-
if (!viewer[VIEWER_WATCH_KEY]) {
|
|
17125
|
-
viewer[VIEWER_WATCH_KEY] = new MemoryWatcher(viewer);
|
|
17126
17231
|
}
|
|
17127
|
-
|
|
17128
|
-
|
|
17129
|
-
TilesetRenderEngine.GetMemoryWatcher = GetMemoryWatcher;
|
|
17130
|
-
})(TilesetRenderEngine || (TilesetRenderEngine = {}));
|
|
17232
|
+
})(Queue = SharedGetters.Queue || (SharedGetters.Queue = {}));
|
|
17233
|
+
})(SharedGetters || (SharedGetters = {}));
|
|
17131
17234
|
|
|
17132
17235
|
/**
|
|
17133
17236
|
* Manager for rendering CAD tilesets.
|
|
@@ -17353,6 +17456,7 @@ var TilesetCadRenderManager;
|
|
|
17353
17456
|
if (!content) {
|
|
17354
17457
|
return;
|
|
17355
17458
|
}
|
|
17459
|
+
const regosToQueue = new Map();
|
|
17356
17460
|
for (let i = 0; i < content.featuresLength; i++) {
|
|
17357
17461
|
const feature = content.getFeature(i);
|
|
17358
17462
|
let rego = this.mapTilesetFeature(feature, load);
|
|
@@ -17361,9 +17465,10 @@ var TilesetCadRenderManager;
|
|
|
17361
17465
|
feature.show = true;
|
|
17362
17466
|
continue;
|
|
17363
17467
|
}
|
|
17364
|
-
|
|
17365
|
-
|
|
17366
|
-
|
|
17468
|
+
regosToQueue.set(rego.entityId, rego);
|
|
17469
|
+
}
|
|
17470
|
+
if (this.styler && regosToQueue.size) {
|
|
17471
|
+
this.styler.QueueEntities(Array.from(regosToQueue.values()));
|
|
17367
17472
|
}
|
|
17368
17473
|
this.viewer.scene.requestRender();
|
|
17369
17474
|
}
|
|
@@ -17636,6 +17741,9 @@ var TilesetCadRenderManager;
|
|
|
17636
17741
|
const api = this.getters.GetBruceApi({
|
|
17637
17742
|
accountId: accountId
|
|
17638
17743
|
});
|
|
17744
|
+
// Time padding in milliseconds (15 seconds).
|
|
17745
|
+
// Helps account for desync between client and server.
|
|
17746
|
+
const TIME_PADDING_MS = 15000;
|
|
17639
17747
|
// 'start-stop' time string that maps to a pending request.
|
|
17640
17748
|
// Helps us avoid repeated requests that are the same.
|
|
17641
17749
|
const pendingRequests = new Map();
|
|
@@ -17679,29 +17787,32 @@ var TilesetCadRenderManager;
|
|
|
17679
17787
|
* @returns
|
|
17680
17788
|
*/
|
|
17681
17789
|
const checkTimelineRange = async () => {
|
|
17682
|
-
|
|
17683
|
-
const
|
|
17790
|
+
// Current timeline range.
|
|
17791
|
+
const minDateTime = new Date(this.viewer.clock.startTime.toString()).getTime();
|
|
17792
|
+
const maxDateTime = new Date(this.viewer.clock.stopTime.toString()).getTime();
|
|
17793
|
+
// What we have loaded.
|
|
17794
|
+
const range = this.historicAnimation.getDateRange();
|
|
17795
|
+
const foundMinDateTime = (range === null || range === void 0 ? void 0 : range.minDate) ? range.minDate.getTime() : null;
|
|
17796
|
+
const foundMaxDateTime = (range === null || range === void 0 ? void 0 : range.maxDate) ? range.maxDate.getTime() : null;
|
|
17684
17797
|
// See if the current range is within the range we already have.
|
|
17685
17798
|
if (this.historicPosses.length > 0 &&
|
|
17686
|
-
|
|
17687
|
-
|
|
17688
|
-
minDateTime >=
|
|
17689
|
-
maxDateTime <=
|
|
17799
|
+
foundMinDateTime &&
|
|
17800
|
+
foundMaxDateTime &&
|
|
17801
|
+
minDateTime >= foundMinDateTime &&
|
|
17802
|
+
maxDateTime <= foundMaxDateTime) {
|
|
17690
17803
|
return;
|
|
17691
17804
|
}
|
|
17692
17805
|
// See if the requested range is before or after the range we have.
|
|
17693
|
-
const fetchBefore = !
|
|
17694
|
-
const fetchAfter = !
|
|
17806
|
+
const fetchBefore = !foundMinDateTime || minDateTime < foundMinDateTime;
|
|
17807
|
+
const fetchAfter = !foundMaxDateTime || maxDateTime > foundMaxDateTime;
|
|
17695
17808
|
if (!fetchBefore && !fetchAfter) {
|
|
17696
17809
|
// Already have the data we need.
|
|
17697
17810
|
return;
|
|
17698
17811
|
}
|
|
17699
17812
|
// No known range so we need to fetch the whole thing.
|
|
17700
|
-
if (!
|
|
17701
|
-
const
|
|
17702
|
-
const
|
|
17703
|
-
const startStr = new Date(startTmp.getTime() - 1000).toISOString();
|
|
17704
|
-
const stopStr = new Date(stopTmp.getTime() + 1000).toISOString();
|
|
17813
|
+
if (!foundMinDateTime || !foundMaxDateTime) {
|
|
17814
|
+
const startStr = new Date(minDateTime - TIME_PADDING_MS).toISOString();
|
|
17815
|
+
const stopStr = new Date(maxDateTime + TIME_PADDING_MS).toISOString();
|
|
17705
17816
|
const newPositions = await getPossesForRange(startStr, stopStr);
|
|
17706
17817
|
if (this.disposed) {
|
|
17707
17818
|
return;
|
|
@@ -17709,22 +17820,17 @@ var TilesetCadRenderManager;
|
|
|
17709
17820
|
if (this.historicAnimation && this.historicAnimation.addPositions) {
|
|
17710
17821
|
this.historicAnimation.addPositions(newPositions);
|
|
17711
17822
|
}
|
|
17712
|
-
this.historicPossesMinDateTime = minDateTime;
|
|
17713
|
-
this.historicPossesMaxDateTime = maxDateTime;
|
|
17714
17823
|
}
|
|
17715
17824
|
else {
|
|
17716
17825
|
// The data we want is before the range we've currently loaded.
|
|
17717
17826
|
if (fetchBefore) {
|
|
17718
17827
|
// Calculate the missing difference and request it.
|
|
17719
|
-
const
|
|
17720
|
-
const
|
|
17721
|
-
|
|
17722
|
-
const stopStr = stopTmp.toISOString();
|
|
17723
|
-
getPossesForRange(startStr, stopStr).then(newPositions => {
|
|
17828
|
+
const startStr = new Date(minDateTime - TIME_PADDING_MS).toISOString();
|
|
17829
|
+
const stopStr = new Date(foundMinDateTime + TIME_PADDING_MS).toISOString();
|
|
17830
|
+
getPossesForRange(startStr, stopStr).then((newPositions) => {
|
|
17724
17831
|
if (this.disposed) {
|
|
17725
17832
|
return;
|
|
17726
17833
|
}
|
|
17727
|
-
this.historicPossesMinDateTime = minDateTime;
|
|
17728
17834
|
if (this.historicAnimation && this.historicAnimation.addPositions) {
|
|
17729
17835
|
this.historicAnimation.addPositions(newPositions);
|
|
17730
17836
|
}
|
|
@@ -17733,15 +17839,12 @@ var TilesetCadRenderManager;
|
|
|
17733
17839
|
// The data we want is after the range we've currently loaded.
|
|
17734
17840
|
if (fetchAfter) {
|
|
17735
17841
|
// Calculate the missing difference and request it.
|
|
17736
|
-
const
|
|
17737
|
-
const
|
|
17738
|
-
|
|
17739
|
-
const stopStr = new Date(stopTmp.getTime() + 1000).toISOString();
|
|
17740
|
-
getPossesForRange(startStr, stopStr).then(newPositions => {
|
|
17842
|
+
const startStr = new Date(foundMaxDateTime - TIME_PADDING_MS).toISOString();
|
|
17843
|
+
const stopStr = new Date(maxDateTime + TIME_PADDING_MS).toISOString();
|
|
17844
|
+
getPossesForRange(startStr, stopStr).then((newPositions) => {
|
|
17741
17845
|
if (this.disposed) {
|
|
17742
17846
|
return;
|
|
17743
17847
|
}
|
|
17744
|
-
this.historicPossesMaxDateTime = maxDateTime;
|
|
17745
17848
|
if (this.historicAnimation && this.historicAnimation.addPositions) {
|
|
17746
17849
|
this.historicAnimation.addPositions(newPositions);
|
|
17747
17850
|
}
|
|
@@ -17755,8 +17858,6 @@ var TilesetCadRenderManager;
|
|
|
17755
17858
|
* @returns
|
|
17756
17859
|
*/
|
|
17757
17860
|
const getInitialPosses = async () => {
|
|
17758
|
-
const minDateTime = this.viewer.clock.startTime.toString();
|
|
17759
|
-
const maxDateTime = this.viewer.clock.stopTime.toString();
|
|
17760
17861
|
this.historicPossesLoadingProm = new Promise(async (res) => {
|
|
17761
17862
|
try {
|
|
17762
17863
|
if (this.disposed) {
|
|
@@ -17773,8 +17874,6 @@ var TilesetCadRenderManager;
|
|
|
17773
17874
|
return;
|
|
17774
17875
|
}
|
|
17775
17876
|
this.historicPosses = positions;
|
|
17776
|
-
this.historicPossesMinDateTime = minDateTime;
|
|
17777
|
-
this.historicPossesMaxDateTime = maxDateTime;
|
|
17778
17877
|
res(positions);
|
|
17779
17878
|
}
|
|
17780
17879
|
catch (e) {
|
|
@@ -17800,6 +17899,13 @@ var TilesetCadRenderManager;
|
|
|
17800
17899
|
if (this.disposed) {
|
|
17801
17900
|
return;
|
|
17802
17901
|
}
|
|
17902
|
+
// Reverse heading .
|
|
17903
|
+
// Not sure if calc or model is the issue.
|
|
17904
|
+
// This is all for a single demo until we figure out how we configure assemblies for this anyways.
|
|
17905
|
+
heading = heading + 180;
|
|
17906
|
+
if (heading > 360) {
|
|
17907
|
+
heading = heading - 360;
|
|
17908
|
+
}
|
|
17803
17909
|
// Jank code that hacks the position to be different.
|
|
17804
17910
|
// This can mess up our panels so we'll need to disable editing until a better system is in place.
|
|
17805
17911
|
const location = Cartographic.fromCartesian(pos3d);
|
|
@@ -18592,13 +18698,17 @@ var TilesetEntitiesRenderManager;
|
|
|
18592
18698
|
if (!content) {
|
|
18593
18699
|
return;
|
|
18594
18700
|
}
|
|
18701
|
+
const regosToQueue = new Map();
|
|
18595
18702
|
for (let i = 0; i < content.featuresLength; i++) {
|
|
18596
18703
|
const feature = content.getFeature(i);
|
|
18597
18704
|
const rego = this.mapTilesetFeature(feature);
|
|
18598
|
-
if (
|
|
18599
|
-
|
|
18705
|
+
if (rego === null || rego === void 0 ? void 0 : rego.entityId) {
|
|
18706
|
+
regosToQueue.set(rego.entityId, rego);
|
|
18600
18707
|
}
|
|
18601
18708
|
}
|
|
18709
|
+
if (this.styler && regosToQueue.size) {
|
|
18710
|
+
this.styler.QueueEntities(Array.from(regosToQueue.values()));
|
|
18711
|
+
}
|
|
18602
18712
|
this.viewer.scene.requestRender();
|
|
18603
18713
|
}
|
|
18604
18714
|
mapTilesetFeature(feature) {
|
|
@@ -19151,13 +19261,17 @@ var TilesetArbRenderManager;
|
|
|
19151
19261
|
if (!content) {
|
|
19152
19262
|
return;
|
|
19153
19263
|
}
|
|
19264
|
+
const regosToQueue = new Map();
|
|
19154
19265
|
for (let i = 0; i < content.featuresLength; i++) {
|
|
19155
19266
|
const feature = content.getFeature(i);
|
|
19156
19267
|
let rego = this.mapTilesetFeature(feature);
|
|
19157
|
-
if (
|
|
19158
|
-
|
|
19268
|
+
if (rego === null || rego === void 0 ? void 0 : rego.entityId) {
|
|
19269
|
+
regosToQueue.set(rego.entityId, rego);
|
|
19159
19270
|
}
|
|
19160
19271
|
}
|
|
19272
|
+
if (this.styler && regosToQueue.size) {
|
|
19273
|
+
this.styler.QueueEntities(Array.from(regosToQueue.values()));
|
|
19274
|
+
}
|
|
19161
19275
|
this.viewer.scene.requestRender();
|
|
19162
19276
|
}
|
|
19163
19277
|
mapTilesetFeature(feature) {
|
|
@@ -30644,7 +30758,7 @@ class WidgetViewBar extends Widget.AWidget {
|
|
|
30644
30758
|
}
|
|
30645
30759
|
}
|
|
30646
30760
|
|
|
30647
|
-
const VERSION = "5.4.
|
|
30761
|
+
const VERSION = "5.4.7";
|
|
30648
30762
|
|
|
30649
30763
|
export { VERSION, CesiumViewMonitor, ViewerUtils, ViewerEventTracker, MenuItemManager, isHistoricMetadataChanged, EntityRenderEngine, EntityRenderEnginePoint, EntityRenderEnginePolyline, EntityRenderEnginePolygon, EntityRenderEngineModel3d, MenuItemCreator, VisualsRegister, RenderManager, EntitiesIdsRenderManager, DataLabRenderManager, EntitiesLoadedRenderManager, EntitiesRenderManager, EntityRenderManager, TilesetCadRenderManager, TilesetArbRenderManager, TilesetEntitiesRenderManager, TilesetOsmRenderManager, TilesetPointcloudRenderManager, TilesetGooglePhotosRenderManager, DataSourceStaticKmlManager, GoogleSearchRenderManager, RelationsRenderManager, SharedGetters, CesiumParabola, EntityLabel, ViewRenderEngine, TileRenderEngine, TilesetRenderEngine, CESIUM_INSPECTOR_KEY, CESIUM_TIMELINE_KEY, CESIUM_TIMELINE_LIVE_KEY, CESIUM_TIMELINE_LIVE_PADDING_FORWARD_KEY, CESIUM_TIMELINE_LIVE_PADDING_BACKWARD_KEY, CESIUM_TIMELINE_INTERVAL_KEY, 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 };
|
|
30650
30764
|
//# sourceMappingURL=bruce-cesium.es5.js.map
|