bruce-cesium 5.4.4 → 5.4.6
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 +1772 -1782
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +1770 -1780
- package/dist/bruce-cesium.umd.js.map +1 -1
- package/dist/lib/bruce-cesium.js +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/render-managers/entities/entities-ids-render-manager.js +7 -4
- 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 +5 -3
- 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/lib/utils/entity-utils.js +11 -11
- package/dist/lib/utils/entity-utils.js.map +1 -1
- package/dist/types/bruce-cesium.d.ts +1 -1
- package/dist/types/rendering/entity-gatherer.d.ts +36 -0
- 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, ColorBlendMode, HeadingPitchRoll, Transforms, Model, HorizontalOrigin, VerticalOrigin, Primitive, Cesium3DTileFeature, SceneMode, GeoJsonDataSource, Cesium3DTileStyle, Cesium3DTileColorBlendMode, HeadingPitchRange, Ion, KmlDataSource, SceneTransforms, Cesium3DTileset, Matrix4, Matrix3, IonResource, EllipsoidTerrainProvider, CesiumInspector, OrthographicFrustum, defined, ClockRange, EasingFunction, NearFarScalar, EllipsoidGeodesic, sampleTerrainMostDetailed, PolygonPipeline, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, BoundingSphere, GeometryInstance, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, ScreenSpaceEventHandler, ScreenSpaceEventType, Quaternion, CzmlDataSource, Intersect, Fullscreen } from 'cesium';
|
|
4
4
|
|
|
5
5
|
const TIME_LAG = 300;
|
|
6
6
|
const POSITION_CHECK_TIMER = 950;
|
|
@@ -2809,8 +2809,8 @@ var EntityUtils;
|
|
|
2809
2809
|
if (location) {
|
|
2810
2810
|
const latitude = EnsureNumber(location.latitude);
|
|
2811
2811
|
const longitude = EnsureNumber(location.longitude);
|
|
2812
|
-
// Disallowing
|
|
2813
|
-
if (latitude
|
|
2812
|
+
// Disallowing 0.
|
|
2813
|
+
if (latitude && longitude) {
|
|
2814
2814
|
const pos3d = Cartesian3.fromDegrees(longitude, latitude, EnsureNumber(location.altitude));
|
|
2815
2815
|
const toAdjust = [pos3d];
|
|
2816
2816
|
await ensureHeightRefs(toAdjust, sample);
|
|
@@ -2982,8 +2982,8 @@ var EntityUtils;
|
|
|
2982
2982
|
if (location && typeof location == "object" && Carto.ValidateCarto(location)) {
|
|
2983
2983
|
const latitude = EnsureNumber(location.latitude);
|
|
2984
2984
|
const longitude = EnsureNumber(location.longitude);
|
|
2985
|
-
// Disallowing
|
|
2986
|
-
if (latitude
|
|
2985
|
+
// Disallowing 0.
|
|
2986
|
+
if (latitude && longitude) {
|
|
2987
2987
|
const pos3d = Cartesian3.fromDegrees(longitude, latitude, EnsureNumber(location.altitude));
|
|
2988
2988
|
posses.push(pos3d);
|
|
2989
2989
|
}
|
|
@@ -3034,8 +3034,8 @@ var EntityUtils;
|
|
|
3034
3034
|
longitude: (EnsureNumber(boundaries.minLongitude) + EnsureNumber(boundaries.maxLongitude)) / 2,
|
|
3035
3035
|
altitude: 0
|
|
3036
3036
|
};
|
|
3037
|
-
// Disallowing
|
|
3038
|
-
if (point.latitude
|
|
3037
|
+
// Disallowing 0.
|
|
3038
|
+
if (point.latitude && point.longitude) {
|
|
3039
3039
|
const bPosses = [
|
|
3040
3040
|
Cartesian3.fromDegrees(EnsureNumber(boundaries.minLongitude), EnsureNumber(boundaries.minLatitude), EnsureNumber(boundaries.minAltitude)),
|
|
3041
3041
|
Cartesian3.fromDegrees(EnsureNumber(boundaries.maxLongitude), EnsureNumber(boundaries.maxLatitude), EnsureNumber(boundaries.maxAltitude))
|
|
@@ -3297,8 +3297,8 @@ var EntityUtils;
|
|
|
3297
3297
|
if (location && typeof location == "object" && Carto.ValidateCarto(location)) {
|
|
3298
3298
|
const latitude = EnsureNumber(location.latitude);
|
|
3299
3299
|
const longitude = EnsureNumber(location.longitude);
|
|
3300
|
-
// Disallowing
|
|
3301
|
-
if (latitude
|
|
3300
|
+
// Disallowing 0.
|
|
3301
|
+
if (latitude && longitude) {
|
|
3302
3302
|
return Cartesian3.fromDegrees(longitude, latitude, EnsureNumber(location.altitude));
|
|
3303
3303
|
}
|
|
3304
3304
|
}
|
|
@@ -3360,8 +3360,8 @@ var EntityUtils;
|
|
|
3360
3360
|
longitude: (EnsureNumber(boundaries.minLongitude) + EnsureNumber(boundaries.maxLongitude)) / 2,
|
|
3361
3361
|
altitude: 0
|
|
3362
3362
|
};
|
|
3363
|
-
// Disallowing
|
|
3364
|
-
if (point.latitude
|
|
3363
|
+
// Disallowing 0.
|
|
3364
|
+
if (point.latitude && point.longitude) {
|
|
3365
3365
|
if (Carto.ValidateCarto(point)) {
|
|
3366
3366
|
return Cartesian3.fromDegrees(point.longitude, point.latitude, point.altitude);
|
|
3367
3367
|
}
|
|
@@ -3417,7 +3417,7 @@ var EntityUtils;
|
|
|
3417
3417
|
catch (e) {
|
|
3418
3418
|
console.error(e);
|
|
3419
3419
|
}
|
|
3420
|
-
if (entity && (isNaN(lat) || isNaN(lon) || (lat == 0
|
|
3420
|
+
if (entity && (isNaN(lat) || isNaN(lon) || (lat == 0 || lon == 0))) {
|
|
3421
3421
|
try {
|
|
3422
3422
|
entity = (await Entity$1.Get({
|
|
3423
3423
|
api,
|
|
@@ -14314,8 +14314,11 @@ var EntitiesIdsRenderManager;
|
|
|
14314
14314
|
return;
|
|
14315
14315
|
}
|
|
14316
14316
|
let entitiesHistoric = {};
|
|
14317
|
+
let changed = false;
|
|
14317
14318
|
if ((this.item.BruceEntity.historic || this.item.BruceEntity.historicAttrKey) && entities.length) {
|
|
14318
|
-
|
|
14319
|
+
const res = await this.getHistoricInfo(entities);
|
|
14320
|
+
changed = res[0];
|
|
14321
|
+
entitiesHistoric = res[1];
|
|
14319
14322
|
}
|
|
14320
14323
|
const { updated, entities: cEntities } = await EntityRenderEngine.Render({
|
|
14321
14324
|
viewer: this.viewer,
|
|
@@ -14326,7 +14329,7 @@ var EntitiesIdsRenderManager;
|
|
|
14326
14329
|
entitiesHistoric: entitiesHistoric,
|
|
14327
14330
|
entityHistoricDrawTrack: this.item.historicDrawTrack,
|
|
14328
14331
|
zoomControl: this.item.CameraZoomSettings,
|
|
14329
|
-
force
|
|
14332
|
+
force: force || changed
|
|
14330
14333
|
});
|
|
14331
14334
|
for (let i = 0; i < entities.length; i++) {
|
|
14332
14335
|
if (this.disposed) {
|
|
@@ -14406,7 +14409,7 @@ var EntitiesIdsRenderManager;
|
|
|
14406
14409
|
const newStop = stopTmp.getTime();
|
|
14407
14410
|
// Complete overlap - we already have all the data.
|
|
14408
14411
|
if (newStart >= cachedStart && newStop <= cachedStop) {
|
|
14409
|
-
return this.entitiesHistoric;
|
|
14412
|
+
return [false, this.entitiesHistoric];
|
|
14410
14413
|
}
|
|
14411
14414
|
// Calculate missing ranges.
|
|
14412
14415
|
rangesToRequest = [];
|
|
@@ -14481,7 +14484,7 @@ var EntitiesIdsRenderManager;
|
|
|
14481
14484
|
this.lastHistoricMax = stopTmp.toISOString();
|
|
14482
14485
|
this.entitiesHistoric = combined;
|
|
14483
14486
|
}
|
|
14484
|
-
return combined;
|
|
14487
|
+
return [rangesToRequest.length > 0, combined];
|
|
14485
14488
|
}
|
|
14486
14489
|
viewerDateTimeSub() {
|
|
14487
14490
|
var _a, _b;
|
|
@@ -14700,1002 +14703,890 @@ var EntityRenderManager;
|
|
|
14700
14703
|
EntityRenderManager.Manager = Manager;
|
|
14701
14704
|
})(EntityRenderManager || (EntityRenderManager = {}));
|
|
14702
14705
|
|
|
14703
|
-
|
|
14704
|
-
|
|
14705
|
-
|
|
14706
|
-
|
|
14707
|
-
*/
|
|
14708
|
-
var EntityGlobe;
|
|
14709
|
-
(function (EntityGlobe) {
|
|
14710
|
-
class Cell {
|
|
14711
|
-
constructor() {
|
|
14712
|
-
this.Fetched = false;
|
|
14713
|
-
this.IsFetched = null;
|
|
14714
|
-
this.FetchPageIndex = 0;
|
|
14715
|
-
// Optional URL to use instead of default URL generation.
|
|
14716
|
-
// This is typically a response from the API to use this specific URL for the next page.
|
|
14717
|
-
this.FetchURL = null;
|
|
14718
|
-
this.Boundaries = null;
|
|
14719
|
-
this.Fetching = false;
|
|
14706
|
+
class EntityGatherer {
|
|
14707
|
+
get OnQueueProgress() {
|
|
14708
|
+
if (!this._onQueueProgress) {
|
|
14709
|
+
this._onQueueProgress = new BruceEvent();
|
|
14720
14710
|
}
|
|
14721
|
-
|
|
14722
|
-
|
|
14723
|
-
|
|
14724
|
-
|
|
14725
|
-
|
|
14711
|
+
return this._onQueueProgress;
|
|
14712
|
+
}
|
|
14713
|
+
constructor(api, viewer, emitEntities) {
|
|
14714
|
+
this.disposed = false;
|
|
14715
|
+
this.expandSources = false;
|
|
14716
|
+
this.historic = null;
|
|
14717
|
+
this.hDisposals = [];
|
|
14718
|
+
// Last date-time taken from the clock.
|
|
14719
|
+
this.lastDateTime = null;
|
|
14720
|
+
// Last date-time range taken from the clock.
|
|
14721
|
+
this.lastDateTimeMin = null;
|
|
14722
|
+
this.lastDateTimeMax = null;
|
|
14723
|
+
// Entity ID -> last resolved date time.
|
|
14724
|
+
// Helps determine if a slow resolved request can still be applied while we wait for the next one.
|
|
14725
|
+
this.lastFoundDateTimes = new Map();
|
|
14726
|
+
// ID of Entity IDs that need to be requested.
|
|
14727
|
+
this.eIdQueue = [];
|
|
14728
|
+
// All IDs that have ever been queued.
|
|
14729
|
+
// When nothing is in queue, we'll re-request the existing IDs based on timeline changes.
|
|
14730
|
+
this.allEIds = new Set();
|
|
14731
|
+
// Indicates a tick is active.
|
|
14732
|
+
// When true, we won't bother calling onTick again.
|
|
14733
|
+
this.runningTick = false;
|
|
14734
|
+
// Entity ID -> Entity blob.
|
|
14735
|
+
// This is a tool that lets developers set their own JSON blobs instead of requesting data from API.
|
|
14736
|
+
this.entityDataOverrides = new Map();
|
|
14737
|
+
// 0 - 100 % progress callback for the queue.
|
|
14738
|
+
// Only called if at least 1 Entity is in the queue at start of the tick.
|
|
14739
|
+
this._onQueueProgress = null;
|
|
14740
|
+
this.api = api;
|
|
14741
|
+
this.viewer = viewer;
|
|
14742
|
+
this.emitEntities = emitEntities;
|
|
14743
|
+
}
|
|
14744
|
+
SetEntityDataOverride(eId, entity) {
|
|
14745
|
+
if (this.disposed) {
|
|
14746
|
+
return;
|
|
14747
|
+
}
|
|
14748
|
+
if (entity) {
|
|
14749
|
+
this.entityDataOverrides.set(eId, entity);
|
|
14750
|
+
}
|
|
14751
|
+
else {
|
|
14752
|
+
this.entityDataOverrides.delete(eId);
|
|
14753
|
+
}
|
|
14754
|
+
}
|
|
14755
|
+
/**
|
|
14756
|
+
* Initializes or updates the manager with given new state settings.
|
|
14757
|
+
* @param historic
|
|
14758
|
+
* @param expandSources
|
|
14759
|
+
* @returns
|
|
14760
|
+
*/
|
|
14761
|
+
Init(historic, expandSources) {
|
|
14762
|
+
if (historic == null || historic == undefined) {
|
|
14763
|
+
historic = this.historic;
|
|
14764
|
+
}
|
|
14765
|
+
if (expandSources == null || expandSources == undefined) {
|
|
14766
|
+
expandSources = this.expandSources;
|
|
14767
|
+
}
|
|
14768
|
+
if (historic === this.historic && expandSources === this.expandSources) {
|
|
14769
|
+
return;
|
|
14770
|
+
}
|
|
14771
|
+
this.historic = historic;
|
|
14772
|
+
this.expandSources = expandSources;
|
|
14773
|
+
if (this.historic) {
|
|
14774
|
+
// 4 ticks per second.
|
|
14775
|
+
// The fastest data we are working with is 5 times per second.
|
|
14776
|
+
let tickDelay = new DelayQueue(() => {
|
|
14777
|
+
this.onTick(false);
|
|
14778
|
+
}, 250, true);
|
|
14779
|
+
this.hDisposals.push(() => {
|
|
14780
|
+
if (tickDelay) {
|
|
14781
|
+
tickDelay.Dispose();
|
|
14782
|
+
}
|
|
14783
|
+
tickDelay = null;
|
|
14784
|
+
});
|
|
14785
|
+
// React to clock changes and request new Entities.
|
|
14786
|
+
this.hDisposals.push(this.viewer.clock.onTick.addEventListener(() => {
|
|
14787
|
+
if (tickDelay) {
|
|
14788
|
+
tickDelay.Call();
|
|
14726
14789
|
}
|
|
14727
|
-
|
|
14728
|
-
|
|
14729
|
-
|
|
14730
|
-
|
|
14731
|
-
|
|
14732
|
-
|
|
14733
|
-
|
|
14734
|
-
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
|
|
14739
|
-
|
|
14790
|
+
}));
|
|
14791
|
+
// Since the timeline range can change even without it ticking we have to check it occasionally.
|
|
14792
|
+
let rangeCheckInterval = setInterval(() => {
|
|
14793
|
+
this.checkRange(false);
|
|
14794
|
+
}, 800);
|
|
14795
|
+
this.hDisposals.push(() => {
|
|
14796
|
+
if (rangeCheckInterval) {
|
|
14797
|
+
clearInterval(rangeCheckInterval);
|
|
14798
|
+
}
|
|
14799
|
+
rangeCheckInterval = null;
|
|
14800
|
+
});
|
|
14801
|
+
}
|
|
14802
|
+
else {
|
|
14803
|
+
this.hDisposals.forEach((d) => d());
|
|
14804
|
+
this.hDisposals = [];
|
|
14740
14805
|
}
|
|
14806
|
+
this.checkRange(true);
|
|
14741
14807
|
}
|
|
14742
|
-
|
|
14743
|
-
|
|
14744
|
-
|
|
14745
|
-
this.cells = {};
|
|
14808
|
+
Empty() {
|
|
14809
|
+
if (this.disposed) {
|
|
14810
|
+
return;
|
|
14746
14811
|
}
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
|
|
14753
|
-
|
|
14754
|
-
|
|
14755
|
-
|
|
14756
|
-
|
|
14757
|
-
|
|
14758
|
-
|
|
14759
|
-
|
|
14760
|
-
|
|
14761
|
-
|
|
14762
|
-
|
|
14763
|
-
|
|
14764
|
-
|
|
14765
|
-
|
|
14766
|
-
|
|
14767
|
-
|
|
14768
|
-
|
|
14769
|
-
|
|
14770
|
-
let height = Math.ceil((maxLat - curMinLat) / cellDegreeSize);
|
|
14771
|
-
// For larger views we add additional padding because our view-area culling is too strong.
|
|
14772
|
-
if (cellDegreeSize >= 2) {
|
|
14773
|
-
width += 1;
|
|
14774
|
-
height += 1;
|
|
14775
|
-
}
|
|
14776
|
-
const cellDistances = [];
|
|
14777
|
-
for (let x = 0; x < width; x++) {
|
|
14778
|
-
for (let y = 0; y < height; y++) {
|
|
14779
|
-
const lon = x * cellDegreeSize + curMinLon;
|
|
14780
|
-
const lat = y * cellDegreeSize + curMinLat;
|
|
14781
|
-
const cellCenterX = lon + cellDegreeSize / 2;
|
|
14782
|
-
const cellCenterY = lat + cellDegreeSize / 2;
|
|
14783
|
-
const dist = Math.sqrt(Math.pow(cellCenterX - centerX, 2) + Math.pow(cellCenterY - centerY, 2));
|
|
14784
|
-
cellDistances.push({ x, y, dist });
|
|
14812
|
+
this.eIdQueue = [];
|
|
14813
|
+
this.allEIds.clear();
|
|
14814
|
+
this.lastFoundDateTimes.clear();
|
|
14815
|
+
this.lastDateTime = null;
|
|
14816
|
+
}
|
|
14817
|
+
ReQueueAll() {
|
|
14818
|
+
if (this.disposed) {
|
|
14819
|
+
return;
|
|
14820
|
+
}
|
|
14821
|
+
this.eIdQueue = Array.from(this.allEIds);
|
|
14822
|
+
}
|
|
14823
|
+
Queue(entityIds, topOfQueue = false) {
|
|
14824
|
+
if (this.disposed || !(entityIds === null || entityIds === void 0 ? void 0 : entityIds.length)) {
|
|
14825
|
+
return;
|
|
14826
|
+
}
|
|
14827
|
+
let changes = 0;
|
|
14828
|
+
for (let i = 0; i < entityIds.length; i++) {
|
|
14829
|
+
const eId = entityIds[i];
|
|
14830
|
+
const index = this.eIdQueue.indexOf(eId);
|
|
14831
|
+
if (topOfQueue) {
|
|
14832
|
+
// If we want it to be at the top of the queue, remove it from the queue first.
|
|
14833
|
+
if (index !== -1) {
|
|
14834
|
+
this.eIdQueue.splice(index, 1);
|
|
14785
14835
|
}
|
|
14836
|
+
this.eIdQueue.unshift(eId);
|
|
14837
|
+
changes += 1;
|
|
14786
14838
|
}
|
|
14787
|
-
|
|
14788
|
-
|
|
14789
|
-
|
|
14790
|
-
const lat = y * cellDegreeSize + curMinLat;
|
|
14791
|
-
const [id, cell] = getOrCreateCell(this.cells, cellDegreeSize, lon, lon + cellDegreeSize, lat, lat + cellDegreeSize);
|
|
14792
|
-
cells.push(cell);
|
|
14793
|
-
if (cells.length >= MAX_CELLS) {
|
|
14794
|
-
break;
|
|
14795
|
-
}
|
|
14839
|
+
else if (index === -1) {
|
|
14840
|
+
this.eIdQueue.push(eId);
|
|
14841
|
+
changes += 1;
|
|
14796
14842
|
}
|
|
14797
|
-
|
|
14843
|
+
// Flag that we've seen this ID.
|
|
14844
|
+
this.allEIds.add(entityIds[i]);
|
|
14798
14845
|
}
|
|
14846
|
+
if (!changes) {
|
|
14847
|
+
return;
|
|
14848
|
+
}
|
|
14849
|
+
this.onTick(false);
|
|
14799
14850
|
}
|
|
14800
|
-
|
|
14801
|
-
|
|
14802
|
-
|
|
14803
|
-
|
|
14804
|
-
|
|
14805
|
-
|
|
14806
|
-
|
|
14807
|
-
return 0.01;
|
|
14808
|
-
}
|
|
14809
|
-
if (height < 5000) {
|
|
14810
|
-
return 0.04;
|
|
14851
|
+
Dispose() {
|
|
14852
|
+
if (this.disposed) {
|
|
14853
|
+
return;
|
|
14854
|
+
}
|
|
14855
|
+
this.disposed = true;
|
|
14856
|
+
this.hDisposals.forEach((d) => d());
|
|
14857
|
+
this.hDisposals = [];
|
|
14811
14858
|
}
|
|
14812
|
-
|
|
14813
|
-
|
|
14859
|
+
checkRange(force) {
|
|
14860
|
+
const min = this.viewer.clock.startTime.toString();
|
|
14861
|
+
const max = this.viewer.clock.stopTime.toString();
|
|
14862
|
+
if (force || this.lastDateTimeMin !== min || this.lastDateTimeMax !== max) {
|
|
14863
|
+
this.lastDateTimeMin = min;
|
|
14864
|
+
this.lastDateTimeMax = max;
|
|
14865
|
+
// Changed, so we can pretend it's a clock tick and request new Entities.
|
|
14866
|
+
this.onTick(true);
|
|
14867
|
+
}
|
|
14814
14868
|
}
|
|
14815
|
-
|
|
14816
|
-
|
|
14869
|
+
onTick(force) {
|
|
14870
|
+
if (this.runningTick) {
|
|
14871
|
+
return;
|
|
14872
|
+
}
|
|
14873
|
+
const rTime = this.viewer.clock.currentTime.toString();
|
|
14874
|
+
if (!force && !this.eIdQueue.length && this.historic && this.lastDateTime === rTime) {
|
|
14875
|
+
return;
|
|
14876
|
+
}
|
|
14877
|
+
this.lastDateTime = rTime;
|
|
14878
|
+
(async () => {
|
|
14879
|
+
this.runningTick = true;
|
|
14880
|
+
let rerun = false;
|
|
14881
|
+
try {
|
|
14882
|
+
const handleResponse = async (entities) => {
|
|
14883
|
+
var _a, _b;
|
|
14884
|
+
if (!(entities === null || entities === void 0 ? void 0 : entities.length)) {
|
|
14885
|
+
return;
|
|
14886
|
+
}
|
|
14887
|
+
// Lazy substitution of the entity data overrides.
|
|
14888
|
+
if (this.entityDataOverrides.size) {
|
|
14889
|
+
for (let i = 0; i < entities.length; i++) {
|
|
14890
|
+
const entity = entities[i];
|
|
14891
|
+
const eId = entity.Bruce.ID;
|
|
14892
|
+
if (this.entityDataOverrides.has(eId)) {
|
|
14893
|
+
entities[i] = this.entityDataOverrides.get(eId);
|
|
14894
|
+
}
|
|
14895
|
+
}
|
|
14896
|
+
}
|
|
14897
|
+
// Gather all Tag IDs from found Entities.
|
|
14898
|
+
let tagIds = new Set();
|
|
14899
|
+
for (let i = 0; i < entities.length; i++) {
|
|
14900
|
+
const entity = entities[i];
|
|
14901
|
+
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) {
|
|
14902
|
+
const eTagIds = entity.Bruce["Layer.ID"];
|
|
14903
|
+
for (let j = 0; j < eTagIds.length; j++) {
|
|
14904
|
+
const tagId = eTagIds[j];
|
|
14905
|
+
if (tagId) {
|
|
14906
|
+
tagIds.add(tagId);
|
|
14907
|
+
}
|
|
14908
|
+
}
|
|
14909
|
+
}
|
|
14910
|
+
}
|
|
14911
|
+
// Gather records.
|
|
14912
|
+
let tags = [];
|
|
14913
|
+
if (tagIds.size) {
|
|
14914
|
+
tags = (await EntityTag.GetListByIds({
|
|
14915
|
+
tagIds: Array.from(tagIds),
|
|
14916
|
+
api: this.api
|
|
14917
|
+
})).tags;
|
|
14918
|
+
}
|
|
14919
|
+
// 0 = rTime is still the current time.
|
|
14920
|
+
// 1 = rTime is in the future.
|
|
14921
|
+
// -1 = rTime is in the past.
|
|
14922
|
+
let changeDir = 0;
|
|
14923
|
+
if (this.lastDateTime !== this.viewer.clock.currentTime.toString()) {
|
|
14924
|
+
changeDir = this.lastDateTime < this.viewer.clock.currentTime.toString() ? 1 : -1;
|
|
14925
|
+
}
|
|
14926
|
+
let toEmit;
|
|
14927
|
+
if (this.historic) {
|
|
14928
|
+
// We can emit Entities if the last resolved time (per Entity) isn't newer than rTime.
|
|
14929
|
+
// We compare using the changeDir to determine if we should emit or not.
|
|
14930
|
+
toEmit = entities.filter((e) => {
|
|
14931
|
+
const lastFoundDateTime = this.lastFoundDateTimes.get(e.id);
|
|
14932
|
+
if (lastFoundDateTime) {
|
|
14933
|
+
if (changeDir === 1) {
|
|
14934
|
+
return lastFoundDateTime <= rTime;
|
|
14935
|
+
}
|
|
14936
|
+
else if (changeDir === -1) {
|
|
14937
|
+
return lastFoundDateTime >= rTime;
|
|
14938
|
+
}
|
|
14939
|
+
}
|
|
14940
|
+
return true;
|
|
14941
|
+
});
|
|
14942
|
+
// Update the last found date times for the filtered Entities.
|
|
14943
|
+
toEmit.forEach((e) => {
|
|
14944
|
+
this.lastFoundDateTimes.set(e.id, rTime);
|
|
14945
|
+
});
|
|
14946
|
+
}
|
|
14947
|
+
else {
|
|
14948
|
+
// If we're not historic, we can just emit everything.
|
|
14949
|
+
toEmit = entities;
|
|
14950
|
+
}
|
|
14951
|
+
this.emitEntities(toEmit, tags);
|
|
14952
|
+
};
|
|
14953
|
+
const QUEUE_BATCH_SIZE = 500;
|
|
14954
|
+
const requestedIds = [];
|
|
14955
|
+
// If we have a queue, we need to request those first.
|
|
14956
|
+
if (this.eIdQueue.length) {
|
|
14957
|
+
const total = this.eIdQueue.length;
|
|
14958
|
+
let done = 0;
|
|
14959
|
+
while (this.eIdQueue.length && !this.disposed) {
|
|
14960
|
+
if (this.historic && this.lastDateTime !== rTime) {
|
|
14961
|
+
break;
|
|
14962
|
+
}
|
|
14963
|
+
const batch = this.eIdQueue.splice(0, QUEUE_BATCH_SIZE);
|
|
14964
|
+
const { entities } = await Entity$1.GetListByIds({
|
|
14965
|
+
entityIds: batch,
|
|
14966
|
+
historicPoint: this.historic ? rTime : null,
|
|
14967
|
+
expandSources: this.expandSources,
|
|
14968
|
+
api: this.api
|
|
14969
|
+
});
|
|
14970
|
+
handleResponse(entities);
|
|
14971
|
+
requestedIds.push(...batch);
|
|
14972
|
+
done += batch.length;
|
|
14973
|
+
if (this._onQueueProgress) {
|
|
14974
|
+
let progress = (done / total) * 100;
|
|
14975
|
+
if (progress > 100) {
|
|
14976
|
+
progress = 100;
|
|
14977
|
+
}
|
|
14978
|
+
if (progress < 0) {
|
|
14979
|
+
progress = 0;
|
|
14980
|
+
}
|
|
14981
|
+
this._onQueueProgress.Trigger(progress);
|
|
14982
|
+
}
|
|
14983
|
+
}
|
|
14984
|
+
if (this._onQueueProgress) {
|
|
14985
|
+
this._onQueueProgress.Trigger(100);
|
|
14986
|
+
}
|
|
14987
|
+
}
|
|
14988
|
+
// Now run through all IDs that we've seen and request them.
|
|
14989
|
+
// We'll skip those that we just requested.
|
|
14990
|
+
let allEIds = Array.from(this.allEIds);
|
|
14991
|
+
if (requestedIds.length) {
|
|
14992
|
+
allEIds = allEIds.filter((eId) => requestedIds.indexOf(eId) === -1);
|
|
14993
|
+
}
|
|
14994
|
+
if (allEIds.length) {
|
|
14995
|
+
while (allEIds.length && !this.disposed && !this.eIdQueue.length) {
|
|
14996
|
+
if (this.historic && this.lastDateTime !== rTime) {
|
|
14997
|
+
break;
|
|
14998
|
+
}
|
|
14999
|
+
const batch = allEIds.splice(0, QUEUE_BATCH_SIZE);
|
|
15000
|
+
const { entities } = await Entity$1.GetListByIds({
|
|
15001
|
+
entityIds: batch,
|
|
15002
|
+
historicPoint: this.historic ? rTime : null,
|
|
15003
|
+
expandSources: this.expandSources,
|
|
15004
|
+
api: this.api
|
|
15005
|
+
});
|
|
15006
|
+
handleResponse(entities);
|
|
15007
|
+
requestedIds.push(...batch);
|
|
15008
|
+
}
|
|
15009
|
+
}
|
|
15010
|
+
// If we had leftovers because we stopped early, we need to re-run the tick.
|
|
15011
|
+
if (this.eIdQueue.length || allEIds.length) {
|
|
15012
|
+
rerun = true;
|
|
15013
|
+
}
|
|
15014
|
+
}
|
|
15015
|
+
catch (e) {
|
|
15016
|
+
console.error(e);
|
|
15017
|
+
}
|
|
15018
|
+
finally {
|
|
15019
|
+
this.runningTick = false;
|
|
15020
|
+
}
|
|
15021
|
+
if (rerun) {
|
|
15022
|
+
this.onTick(true);
|
|
15023
|
+
}
|
|
15024
|
+
})();
|
|
14817
15025
|
}
|
|
14818
|
-
|
|
14819
|
-
|
|
15026
|
+
}
|
|
15027
|
+
|
|
15028
|
+
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
15029
|
+
// We have some evil hard-coded style mappings that need to be fixed.
|
|
15030
|
+
// These exist within legacy project views.
|
|
15031
|
+
function correctStyle(style) {
|
|
15032
|
+
if (style && !style.Settings && !style.ID) {
|
|
15033
|
+
return {
|
|
15034
|
+
ID: -1,
|
|
15035
|
+
Name: "Unknown",
|
|
15036
|
+
Settings: {
|
|
15037
|
+
...style
|
|
15038
|
+
},
|
|
15039
|
+
Type: Style.EType.Entity
|
|
15040
|
+
};
|
|
14820
15041
|
}
|
|
14821
|
-
|
|
14822
|
-
|
|
15042
|
+
return style;
|
|
15043
|
+
}
|
|
15044
|
+
function colorToCColor$3(color) {
|
|
15045
|
+
return new Color(color.red ? color.red / 255 : 0, color.green ? color.green / 255 : 0, color.blue ? color.blue / 255 : 0, color.alpha);
|
|
15046
|
+
}
|
|
15047
|
+
class TilesetStyler {
|
|
15048
|
+
constructor() {
|
|
15049
|
+
this.disposed = false;
|
|
15050
|
+
// Indicates if the styler has been loaded/initialized and is ready to style.
|
|
15051
|
+
this.loaded = false;
|
|
15052
|
+
// Indicates that all mappings have been loaded.
|
|
15053
|
+
this.styleMappingLoaded = false;
|
|
15054
|
+
// Map of Entity Type ID -> boolean to indicate if the style mapping has been loaded.
|
|
15055
|
+
this.styleMappingsLoaded = new Map();
|
|
15056
|
+
// Dictionary of Entity Type ID -> Set of Entity IDs that are pending styling.
|
|
15057
|
+
// Once the style is loaded, we can queue the set for styling.
|
|
15058
|
+
this.stylePendingEntityIds = new Map();
|
|
15059
|
+
this.fallbackStyle = null;
|
|
15060
|
+
this.loadingCounter = 0;
|
|
15061
|
+
// Entity IDs -> boolean to indicate if we should override the feature colour.
|
|
15062
|
+
this.overrideFeatureColor = new Map();
|
|
15063
|
+
this.scenario = 0;
|
|
15064
|
+
// Indicates that we should expand the sources of the Entity.
|
|
15065
|
+
this.expandSources = false;
|
|
15066
|
+
// Indicates that we are retrieving historic records.
|
|
15067
|
+
// This means that the current scene's time is included in the request.
|
|
15068
|
+
this.historic = false;
|
|
15069
|
+
// More expensive process.
|
|
15070
|
+
// When an Entity is styled, the rego is reviewed and updated if needed.
|
|
15071
|
+
// This is currently used for scenarios, and off by default to keep other processes faster.
|
|
15072
|
+
this.shouldUpdateRegoStates = false;
|
|
15073
|
+
// Entity ID -> styled status.
|
|
15074
|
+
// Helps us emit progress events.
|
|
15075
|
+
this.styledEntityIds = new Map();
|
|
15076
|
+
// % progress for how many Entities have been styled so far.
|
|
15077
|
+
// This can change as Tiles load in and more queue.
|
|
15078
|
+
this._styleProgress = 0;
|
|
15079
|
+
this._styleProgressQueue = new DelayQueue(() => {
|
|
15080
|
+
this.updateStyleProgress();
|
|
15081
|
+
}, 250);
|
|
15082
|
+
// Event for when the style progress changes.
|
|
15083
|
+
this.OnStyleProgress = new BruceEvent();
|
|
14823
15084
|
}
|
|
14824
|
-
|
|
14825
|
-
return
|
|
15085
|
+
get Disposed() {
|
|
15086
|
+
return this.disposed;
|
|
14826
15087
|
}
|
|
14827
|
-
|
|
14828
|
-
return
|
|
15088
|
+
get Loaded() {
|
|
15089
|
+
return this.loaded;
|
|
14829
15090
|
}
|
|
14830
|
-
|
|
14831
|
-
return
|
|
15091
|
+
get StyleProgress() {
|
|
15092
|
+
return this._styleProgress;
|
|
14832
15093
|
}
|
|
14833
|
-
|
|
14834
|
-
|
|
15094
|
+
Init(params) {
|
|
15095
|
+
var _a;
|
|
15096
|
+
let { viewer, api, cTileset, fallbackStyleId, styleMapping, expandSources, menuItemId, register, scenario, historic } = params;
|
|
15097
|
+
this.viewer = viewer;
|
|
15098
|
+
this.api = api;
|
|
15099
|
+
this.cTileset = cTileset;
|
|
15100
|
+
this.register = register;
|
|
15101
|
+
this.menuItemId = menuItemId;
|
|
15102
|
+
this.historic = Boolean(historic);
|
|
15103
|
+
if (expandSources != null) {
|
|
15104
|
+
this.expandSources = expandSources;
|
|
15105
|
+
}
|
|
15106
|
+
if (fallbackStyleId != null) {
|
|
15107
|
+
this.fallbackStyleId = fallbackStyleId;
|
|
15108
|
+
}
|
|
15109
|
+
if (styleMapping) {
|
|
15110
|
+
this.styleMapping = styleMapping;
|
|
15111
|
+
if (this.styleMapping) {
|
|
15112
|
+
// Dereference.
|
|
15113
|
+
this.styleMapping = JSON.parse(JSON.stringify(this.styleMapping));
|
|
15114
|
+
}
|
|
15115
|
+
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
15116
|
+
// We have some evil hard-coded style mappings that need to be fixed.
|
|
15117
|
+
// These exist within legacy project views.
|
|
15118
|
+
// Update: This now also lets people have a style mapping without a real style record.
|
|
15119
|
+
if ((_a = this.styleMapping) === null || _a === void 0 ? void 0 : _a.length) {
|
|
15120
|
+
for (let i = 0; i < this.styleMapping.length; i++) {
|
|
15121
|
+
const mapItem = this.styleMapping[i];
|
|
15122
|
+
const mapStyle = mapItem.style ? mapItem.style : mapItem.Style;
|
|
15123
|
+
this.styleMapping[i].style = correctStyle(mapStyle);
|
|
15124
|
+
}
|
|
15125
|
+
}
|
|
15126
|
+
}
|
|
15127
|
+
if (scenario != null) {
|
|
15128
|
+
this.scenario = scenario;
|
|
15129
|
+
}
|
|
15130
|
+
if (!!scenario) {
|
|
15131
|
+
this.shouldUpdateRegoStates = true;
|
|
15132
|
+
}
|
|
15133
|
+
else if (this.historic) {
|
|
15134
|
+
this.shouldUpdateRegoStates = true;
|
|
15135
|
+
}
|
|
15136
|
+
this.entityGatherer = new EntityGatherer(this.api, this.viewer, (entities, tags) => {
|
|
15137
|
+
if (!(entities === null || entities === void 0 ? void 0 : entities.length)) {
|
|
15138
|
+
return;
|
|
15139
|
+
}
|
|
15140
|
+
for (let i = 0; i < entities.length; i++) {
|
|
15141
|
+
const entity = entities[i];
|
|
15142
|
+
const feature = this.getEntityRego(entity.Bruce.ID);
|
|
15143
|
+
if (feature) {
|
|
15144
|
+
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)); });
|
|
15145
|
+
this.styleTilesetFeatureFullData(feature, entity, eTags);
|
|
15146
|
+
}
|
|
15147
|
+
}
|
|
15148
|
+
});
|
|
15149
|
+
this.loaded = true;
|
|
15150
|
+
this.loadStyles();
|
|
14835
15151
|
}
|
|
14836
|
-
|
|
14837
|
-
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
|
|
14841
|
-
|
|
14842
|
-
|
|
14843
|
-
|
|
14844
|
-
|
|
14845
|
-
|
|
14846
|
-
|
|
14847
|
-
|
|
14848
|
-
|
|
14849
|
-
|
|
14850
|
-
|
|
14851
|
-
|
|
14852
|
-
|
|
14853
|
-
|
|
14854
|
-
|
|
14855
|
-
|
|
14856
|
-
|
|
14857
|
-
const id = cellSize + "_" + lon + "_" + maxLon + "_" + lat + "_" + maxLat;
|
|
14858
|
-
let cell = cells[id];
|
|
14859
|
-
if (!cell) {
|
|
14860
|
-
cell = cells[id] = new EntityGlobe.Cell();
|
|
14861
|
-
cell.Boundaries = {
|
|
14862
|
-
minLatitude: lat,
|
|
14863
|
-
maxLatitude: maxLat,
|
|
14864
|
-
minLongitude: lon,
|
|
14865
|
-
maxLongitude: maxLon
|
|
14866
|
-
};
|
|
14867
|
-
cell.IsFetched = () => isCellFetched(cell);
|
|
14868
|
-
}
|
|
14869
|
-
return [id, cell];
|
|
14870
|
-
}
|
|
14871
|
-
|
|
14872
|
-
const MAX_AREA_IN_DEGREES$1 = 90;
|
|
14873
|
-
const MAX_RETRY_ATTEMPTS = 1;
|
|
14874
|
-
const RETRY_DELAY_INCREMENT = 500;
|
|
14875
|
-
const REQUEST_PAGE_DELAY = 50;
|
|
14876
|
-
class regMenuItemGetter {
|
|
14877
|
-
constructor(typeId, tagIds, minHeight, maxHeight) {
|
|
14878
|
-
this.TypeId = typeId;
|
|
14879
|
-
this.TagIds = tagIds;
|
|
14880
|
-
this.MinHeight = minHeight;
|
|
14881
|
-
this.MaxHeight = maxHeight;
|
|
14882
|
-
}
|
|
14883
|
-
}
|
|
14884
|
-
async function delay(milliseconds) {
|
|
14885
|
-
return new Promise((res) => {
|
|
14886
|
-
setTimeout(() => {
|
|
14887
|
-
res();
|
|
14888
|
-
}, milliseconds);
|
|
14889
|
-
});
|
|
14890
|
-
}
|
|
14891
|
-
/**
|
|
14892
|
-
* This is a batched entity getter.
|
|
14893
|
-
* It will scan for entity records in a view-area and emit them in batches.
|
|
14894
|
-
* It will restart scanning if the camera moves.
|
|
14895
|
-
*/
|
|
14896
|
-
var EntityFilterGetter;
|
|
14897
|
-
(function (EntityFilterGetter) {
|
|
14898
|
-
let EStatus;
|
|
14899
|
-
(function (EStatus) {
|
|
14900
|
-
EStatus["Scanning"] = "SCANNING";
|
|
14901
|
-
EStatus["Loading"] = "LOADING";
|
|
14902
|
-
})(EStatus = EntityFilterGetter.EStatus || (EntityFilterGetter.EStatus = {}));
|
|
14903
|
-
class Getter {
|
|
14904
|
-
get OnUpdate() {
|
|
14905
|
-
if (!this.onUpdate) {
|
|
14906
|
-
this.onUpdate = new BruceEvent();
|
|
15152
|
+
/**
|
|
15153
|
+
* Updates style mapping and fallback style.
|
|
15154
|
+
* This will trigger a re-style of all entities, and will stop existing style loads.
|
|
15155
|
+
* @param params
|
|
15156
|
+
*/
|
|
15157
|
+
UpdateStyleMapping(params) {
|
|
15158
|
+
var _a;
|
|
15159
|
+
if (params.styleMapping) {
|
|
15160
|
+
// Dereference.
|
|
15161
|
+
params.styleMapping = JSON.parse(JSON.stringify(params.styleMapping));
|
|
15162
|
+
this.styleMapping = params.styleMapping;
|
|
15163
|
+
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
15164
|
+
// We have some evil hard-coded style mappings that need to be fixed.
|
|
15165
|
+
// These exist within legacy project views.
|
|
15166
|
+
// Update: This now also lets people have a style mapping without a real style record.
|
|
15167
|
+
if ((_a = this.styleMapping) === null || _a === void 0 ? void 0 : _a.length) {
|
|
15168
|
+
for (let i = 0; i < this.styleMapping.length; i++) {
|
|
15169
|
+
const mapItem = this.styleMapping[i];
|
|
15170
|
+
const mapStyle = mapItem.style ? mapItem.style : mapItem.Style;
|
|
15171
|
+
this.styleMapping[i].style = correctStyle(mapStyle);
|
|
15172
|
+
}
|
|
14907
15173
|
}
|
|
14908
|
-
return this.onUpdate;
|
|
14909
15174
|
}
|
|
14910
|
-
|
|
14911
|
-
|
|
14912
|
-
|
|
15175
|
+
if (!isNaN(params.fallbackStyleId) && params.fallbackStyleId != null) {
|
|
15176
|
+
this.fallbackStyleId = params.fallbackStyleId;
|
|
15177
|
+
}
|
|
15178
|
+
if (params.fallbackStyle) {
|
|
15179
|
+
this.fallbackStyle = params.fallbackStyle;
|
|
15180
|
+
}
|
|
15181
|
+
else {
|
|
15182
|
+
this.fallbackStyle = null;
|
|
15183
|
+
}
|
|
15184
|
+
if (params.scenario != null) {
|
|
15185
|
+
this.scenario = params.scenario;
|
|
15186
|
+
if (!this.shouldUpdateRegoStates && !!this.scenario) {
|
|
15187
|
+
this.shouldUpdateRegoStates = true;
|
|
14913
15188
|
}
|
|
14914
|
-
return this.onStateUpdate;
|
|
14915
15189
|
}
|
|
14916
|
-
|
|
14917
|
-
|
|
14918
|
-
|
|
15190
|
+
if (params.historic != null) {
|
|
15191
|
+
this.historic = params.historic;
|
|
15192
|
+
if (params.historic || this.historic != params.historic) {
|
|
15193
|
+
this.shouldUpdateRegoStates = true;
|
|
14919
15194
|
}
|
|
14920
|
-
return this.onScanUpdate;
|
|
14921
15195
|
}
|
|
14922
|
-
|
|
14923
|
-
|
|
15196
|
+
// Reload styles.
|
|
15197
|
+
if (this.loaded) {
|
|
15198
|
+
this.styledEntityIds.clear();
|
|
15199
|
+
this.styleMappingsLoaded.clear();
|
|
15200
|
+
this.loadStyles();
|
|
15201
|
+
this._styleProgressQueue.Call(true);
|
|
15202
|
+
// Putting all rendered things back into the queue.
|
|
15203
|
+
const regos = this.register.GetRegos({
|
|
15204
|
+
menuItemId: this.menuItemId
|
|
15205
|
+
});
|
|
15206
|
+
this.QueueEntities(regos);
|
|
14924
15207
|
}
|
|
14925
|
-
|
|
14926
|
-
|
|
14927
|
-
|
|
14928
|
-
|
|
14929
|
-
|
|
14930
|
-
|
|
14931
|
-
|
|
14932
|
-
|
|
14933
|
-
|
|
14934
|
-
|
|
14935
|
-
|
|
14936
|
-
|
|
14937
|
-
|
|
14938
|
-
|
|
14939
|
-
|
|
14940
|
-
|
|
14941
|
-
|
|
14942
|
-
this.viewCenter = null;
|
|
14943
|
-
this.scenario = 0;
|
|
14944
|
-
this.historicRefreshAbortController = null;
|
|
14945
|
-
// Entity IDs found for the latest integrity.
|
|
14946
|
-
// We use this for refreshing historic data without having to repeat geographic queries.
|
|
14947
|
-
this.gatheredIntegrity = null;
|
|
14948
|
-
this.gatheredEntityIds = [];
|
|
14949
|
-
const { api, viewer, viewPort, typeIds, schemaId, batchSize, attrFilter, historicAttrKey, historicInterpolation, historic, viaCdn, scenario } = params;
|
|
14950
|
-
this.api = api;
|
|
14951
|
-
this.typeIds = typeIds;
|
|
14952
|
-
this.schemaId = schemaId;
|
|
14953
|
-
this.historic = Boolean(historic);
|
|
14954
|
-
this.historicAttrKey = historicAttrKey;
|
|
14955
|
-
this.historicInterpolation = Boolean(historicInterpolation);
|
|
14956
|
-
this.viaCdn = Boolean(viaCdn);
|
|
14957
|
-
this.batchSize = isNaN(batchSize) ? 300 : batchSize;
|
|
14958
|
-
this.viewPort = viewPort;
|
|
14959
|
-
this.attrFilter = attrFilter;
|
|
14960
|
-
this.viewer = viewer;
|
|
14961
|
-
this.scenario = scenario ? scenario : 0;
|
|
14962
|
-
this.updateBounds();
|
|
15208
|
+
}
|
|
15209
|
+
/**
|
|
15210
|
+
* Updates a cache of Entity objects to use when styling.
|
|
15211
|
+
* When a cache is available, a request won't be performed to get that Entity's data.
|
|
15212
|
+
* @param entityIds
|
|
15213
|
+
* @param entities If an object is not available for a supplied Entity ID, then the cache for it is removed.
|
|
15214
|
+
*/
|
|
15215
|
+
SetEntityCache(entityIds, entities) {
|
|
15216
|
+
// Turn the Entities array into an accessible dictionary.
|
|
15217
|
+
const newDataMap = new Map();
|
|
15218
|
+
if (entities) {
|
|
15219
|
+
for (let i = 0; i < entities.length; i++) {
|
|
15220
|
+
const entity = entities[i];
|
|
15221
|
+
if (entity.Bruce) {
|
|
15222
|
+
newDataMap.set(entity.Bruce.ID, entity);
|
|
15223
|
+
}
|
|
15224
|
+
}
|
|
14963
15225
|
}
|
|
14964
|
-
|
|
14965
|
-
|
|
14966
|
-
|
|
14967
|
-
|
|
14968
|
-
|
|
14969
|
-
|
|
14970
|
-
|
|
14971
|
-
|
|
14972
|
-
|
|
14973
|
-
|
|
15226
|
+
// Update the cache for each supplied Entity ID.
|
|
15227
|
+
for (let i = 0; i < entityIds.length; i++) {
|
|
15228
|
+
const entityId = entityIds[i];
|
|
15229
|
+
this.entityGatherer.SetEntityDataOverride(entityId, newDataMap.get(entityId));
|
|
15230
|
+
}
|
|
15231
|
+
}
|
|
15232
|
+
QueueEntities(regos, highPriority = false) {
|
|
15233
|
+
if (!this.loaded) {
|
|
15234
|
+
// Mark as pending?
|
|
15235
|
+
return;
|
|
15236
|
+
}
|
|
15237
|
+
for (let i = 0; i < regos.length; i++) {
|
|
15238
|
+
const rego = regos[i];
|
|
15239
|
+
this.overrideFeatureColor.set(rego.entityId, true);
|
|
15240
|
+
// We set a default colour right away to avoid race conditions at later times.
|
|
15241
|
+
CesiumEntityStyler.BakeDefaultColor({
|
|
15242
|
+
entity: rego.visual,
|
|
15243
|
+
viewer: this.viewer,
|
|
15244
|
+
override: false
|
|
15245
|
+
});
|
|
15246
|
+
}
|
|
15247
|
+
this.queueTilesetFeatureStyle(regos, highPriority);
|
|
15248
|
+
}
|
|
15249
|
+
/**
|
|
15250
|
+
* Calculates the current progress % and updates the progress if there is a change.
|
|
15251
|
+
*/
|
|
15252
|
+
updateStyleProgress() {
|
|
15253
|
+
if (this.disposed) {
|
|
15254
|
+
return;
|
|
15255
|
+
}
|
|
15256
|
+
const total = this.overrideFeatureColor.size;
|
|
15257
|
+
const styled = this.styledEntityIds.size;
|
|
15258
|
+
let progress = 100;
|
|
15259
|
+
if (styled < total) {
|
|
15260
|
+
progress = Math.round((styled / total) * 100);
|
|
15261
|
+
if (progress < 0) {
|
|
15262
|
+
progress = 0;
|
|
14974
15263
|
}
|
|
14975
|
-
else if (
|
|
14976
|
-
|
|
15264
|
+
else if (progress > 100) {
|
|
15265
|
+
progress = 100;
|
|
14977
15266
|
}
|
|
14978
|
-
|
|
14979
|
-
|
|
15267
|
+
}
|
|
15268
|
+
if (this._styleProgress != progress) {
|
|
15269
|
+
this._styleProgress = progress;
|
|
15270
|
+
this.OnStyleProgress.Trigger(progress);
|
|
15271
|
+
}
|
|
15272
|
+
}
|
|
15273
|
+
getEntityRego(entityId) {
|
|
15274
|
+
return this.register.GetRego({
|
|
15275
|
+
entityId,
|
|
15276
|
+
menuItemId: this.menuItemId
|
|
15277
|
+
});
|
|
15278
|
+
}
|
|
15279
|
+
Dispose() {
|
|
15280
|
+
if (this.disposed) {
|
|
15281
|
+
return;
|
|
15282
|
+
}
|
|
15283
|
+
this.disposed = true;
|
|
15284
|
+
this._styleProgressQueue.Dispose();
|
|
15285
|
+
this.disposeGatherer();
|
|
15286
|
+
}
|
|
15287
|
+
async loadStyles() {
|
|
15288
|
+
var _a, _b;
|
|
15289
|
+
const counter = ++this.loadingCounter;
|
|
15290
|
+
this.styleMappingLoaded = false;
|
|
15291
|
+
this.styleMappingsLoaded.clear();
|
|
15292
|
+
// Apply state changes.
|
|
15293
|
+
this.entityGatherer.Empty();
|
|
15294
|
+
this.entityGatherer.Init(this.historic, this.expandSources);
|
|
15295
|
+
let fallbackStyleId = this.fallbackStyleId;
|
|
15296
|
+
if (fallbackStyleId && fallbackStyleId > 0) {
|
|
15297
|
+
try {
|
|
15298
|
+
let { style: data } = await Style.Get({
|
|
15299
|
+
api: this.api,
|
|
15300
|
+
styleId: fallbackStyleId
|
|
15301
|
+
});
|
|
15302
|
+
this.fallbackStyle = data;
|
|
14980
15303
|
}
|
|
14981
|
-
|
|
14982
|
-
|
|
15304
|
+
catch (e) {
|
|
15305
|
+
console.error(e);
|
|
14983
15306
|
}
|
|
14984
|
-
return integrity;
|
|
14985
15307
|
}
|
|
14986
|
-
|
|
14987
|
-
|
|
14988
|
-
// We'll avoid restarting the scanner too often.
|
|
14989
|
-
this.viewPortDelayQueue = new DelayQueue(() => {
|
|
14990
|
-
this.updateBounds();
|
|
14991
|
-
this.startGetterLoop();
|
|
14992
|
-
}, 2000);
|
|
14993
|
-
this.viewPortChangeRemoval = this.viewPort.Updated().Subscribe(() => {
|
|
14994
|
-
var _a;
|
|
14995
|
-
(_a = this.viewPortDelayQueue) === null || _a === void 0 ? void 0 : _a.Call();
|
|
14996
|
-
});
|
|
15308
|
+
if (this.loadingCounter != counter) {
|
|
15309
|
+
return;
|
|
14997
15310
|
}
|
|
14998
|
-
|
|
14999
|
-
|
|
15000
|
-
|
|
15001
|
-
|
|
15002
|
-
(_b = this.viewPortDelayQueue) === null || _b === void 0 ? void 0 : _b.Dispose();
|
|
15003
|
-
this.viewPortDelayQueue = null;
|
|
15311
|
+
// Load styles in the style mapping
|
|
15312
|
+
let styleMapping = this.styleMapping;
|
|
15313
|
+
if (!styleMapping) {
|
|
15314
|
+
styleMapping = [];
|
|
15004
15315
|
}
|
|
15005
|
-
|
|
15006
|
-
|
|
15007
|
-
|
|
15008
|
-
|
|
15009
|
-
|
|
15010
|
-
if (
|
|
15011
|
-
|
|
15316
|
+
this.styleMapping = styleMapping;
|
|
15317
|
+
// Append all found entity-types.
|
|
15318
|
+
// That way we can mark them as loaded instead of just the ones in the style mapping.
|
|
15319
|
+
try {
|
|
15320
|
+
const modelTree = (_b = (_a = this.cTileset) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.modelTree;
|
|
15321
|
+
if (modelTree) {
|
|
15322
|
+
const entityTypeIds = this.getEntityTypeIdsFromModelTree(modelTree);
|
|
15323
|
+
for (let i = 0; i < entityTypeIds.length; i++) {
|
|
15324
|
+
const entityTypeId = entityTypeIds[i];
|
|
15325
|
+
if (styleMapping.findIndex(x => x.EntityTypeID == entityTypeId) <= -1) {
|
|
15326
|
+
styleMapping.push({
|
|
15327
|
+
EntityTypeID: entityTypeId,
|
|
15328
|
+
StyleID: this.fallbackStyle ? fallbackStyleId : 0,
|
|
15329
|
+
style: this.fallbackStyle
|
|
15330
|
+
});
|
|
15331
|
+
}
|
|
15332
|
+
}
|
|
15012
15333
|
}
|
|
15013
|
-
|
|
15014
|
-
|
|
15015
|
-
|
|
15016
|
-
|
|
15017
|
-
|
|
15018
|
-
|
|
15019
|
-
|
|
15334
|
+
}
|
|
15335
|
+
catch (e) {
|
|
15336
|
+
console.error(e);
|
|
15337
|
+
}
|
|
15338
|
+
// Before we start the loop we'll do a single request for the needed Entity Types.
|
|
15339
|
+
// This will be aimed at rows that don't specify a Style and if the default fallback-
|
|
15340
|
+
//is set to 0 (using the default of the Entity Type).
|
|
15341
|
+
const typeMap = new Map();
|
|
15342
|
+
const typeIds = styleMapping.map(x => x.StyleID == -1 || Boolean(x.style) ? null : x.EntityTypeID).filter(x => !!x);
|
|
15343
|
+
if (typeIds.length) {
|
|
15344
|
+
// We'll split up into batches of 50.
|
|
15345
|
+
// Since we add the type IDs as query params I am paranoid of hitting the limit.
|
|
15346
|
+
const splits = Math.ceil(typeIds.length / 50);
|
|
15347
|
+
const batchSize = 50;
|
|
15348
|
+
for (let i = 0; i < splits; i++) {
|
|
15349
|
+
const batch = typeIds.slice(i * batchSize, (i + 1) * batchSize);
|
|
15350
|
+
const { entityTypes } = await EntityType.GetList({
|
|
15351
|
+
api: this.api,
|
|
15352
|
+
entityTypeIds: batch
|
|
15353
|
+
});
|
|
15354
|
+
for (let i = 0; i < entityTypes.length; i++) {
|
|
15355
|
+
const entityType = entityTypes[i];
|
|
15356
|
+
typeMap.set(entityType.ID, entityType);
|
|
15357
|
+
}
|
|
15020
15358
|
}
|
|
15021
|
-
|
|
15022
|
-
|
|
15023
|
-
|
|
15024
|
-
|
|
15025
|
-
|
|
15026
|
-
|
|
15027
|
-
|
|
15359
|
+
}
|
|
15360
|
+
for (let i = 0; i < styleMapping.length; i++) {
|
|
15361
|
+
if (this.disposed) {
|
|
15362
|
+
break;
|
|
15363
|
+
}
|
|
15364
|
+
let styleMap = styleMapping[i];
|
|
15365
|
+
if (!styleMap.style && styleMap.StyleID != -1) {
|
|
15366
|
+
let styleId = styleMap.StyleID;
|
|
15367
|
+
// Get default style of the entity type, if
|
|
15368
|
+
//no default is already specified.
|
|
15369
|
+
if (!styleId && !this.fallbackStyle) {
|
|
15370
|
+
try {
|
|
15371
|
+
let entityType = typeMap.get(styleMap.EntityTypeID);
|
|
15372
|
+
// If the map excluded the type for whatever reason we'll load it now.
|
|
15373
|
+
if (!entityType) {
|
|
15374
|
+
entityType = (await EntityType.Get({
|
|
15375
|
+
api: this.api,
|
|
15376
|
+
entityTypeId: styleMap.EntityTypeID
|
|
15377
|
+
})).entityType;
|
|
15028
15378
|
}
|
|
15379
|
+
styleId = entityType === null || entityType === void 0 ? void 0 : entityType["DisplaySetting.ID"];
|
|
15029
15380
|
}
|
|
15030
|
-
|
|
15031
|
-
|
|
15032
|
-
if (current != this.historicAttrDateTime) {
|
|
15033
|
-
this.emitHistoricData();
|
|
15381
|
+
catch (e) {
|
|
15382
|
+
console.error(e);
|
|
15034
15383
|
}
|
|
15035
15384
|
}
|
|
15036
|
-
|
|
15037
|
-
|
|
15385
|
+
if (styleId) {
|
|
15386
|
+
try {
|
|
15387
|
+
let { style: data } = await Style.Get({
|
|
15388
|
+
api: this.api,
|
|
15389
|
+
styleId
|
|
15390
|
+
});
|
|
15391
|
+
if (data) {
|
|
15392
|
+
styleMap.style = data;
|
|
15393
|
+
styleMap.StyleID = styleId;
|
|
15394
|
+
}
|
|
15395
|
+
}
|
|
15396
|
+
catch (e) {
|
|
15397
|
+
console.error(e);
|
|
15398
|
+
}
|
|
15038
15399
|
}
|
|
15039
|
-
|
|
15040
|
-
|
|
15041
|
-
if (delayQueue) {
|
|
15042
|
-
delayQueue.Call();
|
|
15400
|
+
if (this.loadingCounter != counter) {
|
|
15401
|
+
return;
|
|
15043
15402
|
}
|
|
15044
|
-
});
|
|
15045
|
-
this.viewerDateTimeChangeRemoval = () => {
|
|
15046
|
-
delayQueue === null || delayQueue === void 0 ? void 0 : delayQueue.Dispose();
|
|
15047
|
-
postUpdateRemoval === null || postUpdateRemoval === void 0 ? void 0 : postUpdateRemoval();
|
|
15048
|
-
delayQueue = null;
|
|
15049
|
-
postUpdateRemoval = null;
|
|
15050
|
-
};
|
|
15051
|
-
}
|
|
15052
|
-
updateHistoricDateTime() {
|
|
15053
|
-
if (!this.historicAttrKey && !this.historic) {
|
|
15054
|
-
this.historicAttrDateTime = null;
|
|
15055
|
-
return;
|
|
15056
15403
|
}
|
|
15057
|
-
|
|
15058
|
-
|
|
15059
|
-
|
|
15060
|
-
|
|
15061
|
-
|
|
15062
|
-
|
|
15404
|
+
this.styleMappingsLoaded.set(styleMap.EntityTypeID, true);
|
|
15405
|
+
if (this.loaded) {
|
|
15406
|
+
// If we have a bunch of Entities that were waiting for the style to load,
|
|
15407
|
+
// then we can pass them to the gatherer now.
|
|
15408
|
+
const relatedIds = this.stylePendingEntityIds.get(styleMap.EntityTypeID);
|
|
15409
|
+
if (relatedIds) {
|
|
15410
|
+
this.entityGatherer.Queue(Array.from(relatedIds));
|
|
15411
|
+
this.stylePendingEntityIds.delete(styleMap.EntityTypeID);
|
|
15063
15412
|
}
|
|
15064
|
-
// Change must be at least 0.1 seconds.
|
|
15065
|
-
return Math.abs(before.getTime() - after.getTime()) > 100;
|
|
15066
|
-
};
|
|
15067
|
-
const oldDateTime = this.historicAttrDateTime ? new Date(this.historicAttrDateTime) : null;
|
|
15068
|
-
const newDateTime = JulianDate.toDate(this.viewer.clock.currentTime);
|
|
15069
|
-
if (isChanged(oldDateTime, newDateTime)) {
|
|
15070
|
-
this.historicAttrDateTime = newDateTime.toISOString();
|
|
15071
15413
|
}
|
|
15072
15414
|
}
|
|
15073
|
-
|
|
15074
|
-
|
|
15075
|
-
(_a = this.viewerDateTimeChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
15076
|
-
this.viewerDateTimeChangeRemoval = null;
|
|
15077
|
-
}
|
|
15078
|
-
GetMenuItems() {
|
|
15079
|
-
return Object.keys(this.registeredItems);
|
|
15415
|
+
if (this.loadingCounter != counter) {
|
|
15416
|
+
return;
|
|
15080
15417
|
}
|
|
15081
|
-
|
|
15082
|
-
|
|
15083
|
-
this.
|
|
15418
|
+
this.styleMappingLoaded = true;
|
|
15419
|
+
if (!this.disposed && this.loaded) {
|
|
15420
|
+
if (this.loadingCounter != counter) {
|
|
15421
|
+
return;
|
|
15422
|
+
}
|
|
15423
|
+
// Queue all Entities that are pending styling.
|
|
15424
|
+
const pendingKeys = this.stylePendingEntityIds.keys();
|
|
15425
|
+
for (const key of pendingKeys) {
|
|
15426
|
+
const relatedIds = this.stylePendingEntityIds[key];
|
|
15427
|
+
if (relatedIds) {
|
|
15428
|
+
this.entityGatherer.Queue(Array.from(relatedIds));
|
|
15429
|
+
}
|
|
15430
|
+
}
|
|
15431
|
+
this.stylePendingEntityIds.clear();
|
|
15084
15432
|
}
|
|
15085
|
-
|
|
15086
|
-
|
|
15087
|
-
|
|
15088
|
-
this.
|
|
15433
|
+
}
|
|
15434
|
+
disposeGatherer() {
|
|
15435
|
+
if (this.entityGatherer) {
|
|
15436
|
+
this.entityGatherer.Dispose();
|
|
15437
|
+
this.entityGatherer = null;
|
|
15089
15438
|
}
|
|
15090
|
-
|
|
15091
|
-
|
|
15092
|
-
|
|
15093
|
-
|
|
15094
|
-
|
|
15095
|
-
|
|
15096
|
-
|
|
15097
|
-
|
|
15098
|
-
|
|
15439
|
+
}
|
|
15440
|
+
getEntityTypeIdsFromModelTree(modelTree) {
|
|
15441
|
+
const entityTypeIds = [];
|
|
15442
|
+
this.digEntityTypeIdsFromModelTreeBranch(modelTree, entityTypeIds);
|
|
15443
|
+
return entityTypeIds;
|
|
15444
|
+
}
|
|
15445
|
+
digEntityTypeIdsFromModelTreeBranch(branch, arr) {
|
|
15446
|
+
if (branch) {
|
|
15447
|
+
// Does not yet include this entity type id.
|
|
15448
|
+
if (branch.typeId && !arr.includes(branch.typeId)) {
|
|
15449
|
+
arr.push(branch.typeId);
|
|
15450
|
+
}
|
|
15451
|
+
if (branch.children) {
|
|
15452
|
+
for (let i = 0; i < branch.children.length; i++) {
|
|
15453
|
+
let child = branch.children[i];
|
|
15454
|
+
this.digEntityTypeIdsFromModelTreeBranch(child, arr);
|
|
15099
15455
|
}
|
|
15100
|
-
this.viewRect = viewRect;
|
|
15101
|
-
this.viewCenter = poi;
|
|
15102
15456
|
}
|
|
15103
15457
|
}
|
|
15104
|
-
|
|
15105
|
-
|
|
15106
|
-
|
|
15107
|
-
|
|
15108
|
-
|
|
15109
|
-
|
|
15110
|
-
for (let i = 0; i < menuItemIds.length; i++) {
|
|
15111
|
-
const menuItem = this.registeredItems[menuItemIds[i]];
|
|
15112
|
-
if (menuItem) {
|
|
15113
|
-
if (maxHeight == null || maxHeight < menuItem.MaxHeight) {
|
|
15114
|
-
maxHeight = menuItem.MaxHeight;
|
|
15115
|
-
}
|
|
15116
|
-
if (minHeight == null || minHeight > menuItem.MinHeight) {
|
|
15117
|
-
minHeight = menuItem.MinHeight;
|
|
15118
|
-
}
|
|
15119
|
-
const itemLayerIds = menuItem.TagIds;
|
|
15120
|
-
if (itemLayerIds) {
|
|
15121
|
-
for (let j = 0; j < itemLayerIds.length; j++) {
|
|
15122
|
-
const itemLayerId = itemLayerIds[j];
|
|
15123
|
-
if (!tagIds.includes(itemLayerId)) {
|
|
15124
|
-
tagIds.push(itemLayerId);
|
|
15125
|
-
}
|
|
15126
|
-
}
|
|
15127
|
-
}
|
|
15128
|
-
const itemTypeId = menuItem.TypeId;
|
|
15129
|
-
if (itemTypeId) {
|
|
15130
|
-
if (!typeIds.includes(itemTypeId)) {
|
|
15131
|
-
typeIds.push(itemTypeId);
|
|
15132
|
-
}
|
|
15133
|
-
}
|
|
15134
|
-
}
|
|
15458
|
+
}
|
|
15459
|
+
queueTilesetFeatureStyle(entities, highPriority) {
|
|
15460
|
+
const needsDataIds = [];
|
|
15461
|
+
for (const rego of entities) {
|
|
15462
|
+
if (!this.overrideFeatureColor.has(rego.entityId)) {
|
|
15463
|
+
this.overrideFeatureColor.set(rego.entityId, false);
|
|
15135
15464
|
}
|
|
15136
|
-
|
|
15137
|
-
|
|
15138
|
-
this.
|
|
15139
|
-
|
|
15140
|
-
|
|
15141
|
-
|
|
15142
|
-
|
|
15143
|
-
|
|
15144
|
-
this.updateHistoricDateTime();
|
|
15145
|
-
this.startGetterLoop();
|
|
15146
|
-
this.viewAreaSub();
|
|
15147
|
-
this.viewerDateTimeSub();
|
|
15465
|
+
const typeId = rego.entityTypeId || "";
|
|
15466
|
+
if (this.styleMappingLoaded || this.styleMappingsLoaded.get(typeId)) {
|
|
15467
|
+
if (this.getTilesetFeatureNeedsFullData(typeId)) {
|
|
15468
|
+
needsDataIds.push(rego.entityId);
|
|
15469
|
+
}
|
|
15470
|
+
else {
|
|
15471
|
+
this.styleTilesetFeature(rego);
|
|
15472
|
+
}
|
|
15148
15473
|
}
|
|
15149
15474
|
else {
|
|
15150
|
-
this.
|
|
15151
|
-
|
|
15152
|
-
|
|
15475
|
+
if (!this.stylePendingEntityIds.has(typeId)) {
|
|
15476
|
+
this.stylePendingEntityIds.set(typeId, new Set());
|
|
15477
|
+
}
|
|
15478
|
+
this.stylePendingEntityIds.get(typeId).add(rego.entityId);
|
|
15153
15479
|
}
|
|
15154
15480
|
}
|
|
15155
|
-
|
|
15156
|
-
|
|
15157
|
-
this.LastStateUpdates[status.msg] = status;
|
|
15158
|
-
(_a = this.onStateUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(status);
|
|
15481
|
+
if (needsDataIds.length) {
|
|
15482
|
+
this.entityGatherer.Queue(needsDataIds, highPriority);
|
|
15159
15483
|
}
|
|
15160
|
-
|
|
15161
|
-
|
|
15162
|
-
|
|
15163
|
-
|
|
15164
|
-
|
|
15165
|
-
|
|
15166
|
-
|
|
15167
|
-
|
|
15168
|
-
|
|
15169
|
-
|
|
15170
|
-
|
|
15171
|
-
|
|
15172
|
-
|
|
15173
|
-
|
|
15174
|
-
|
|
15484
|
+
}
|
|
15485
|
+
styleTilesetFeature(entity) {
|
|
15486
|
+
this.styleTilesetFeatureFullData(entity, null, []);
|
|
15487
|
+
}
|
|
15488
|
+
styleTilesetFeatureFullData(entity, data, tags) {
|
|
15489
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
15490
|
+
const visual = entity.visual;
|
|
15491
|
+
if (!visual || !(visual instanceof Cesium3DTileFeature)) {
|
|
15492
|
+
return;
|
|
15493
|
+
}
|
|
15494
|
+
const style = this.getTilesetFeatureStyle(entity.entityTypeId);
|
|
15495
|
+
const bColor = style && ((_a = style.modelStyle) === null || _a === void 0 ? void 0 : _a.fillColor) ? Calculator.GetColor(style.modelStyle.fillColor, data, tags) : null;
|
|
15496
|
+
let cColor = null;
|
|
15497
|
+
if (bColor == null) {
|
|
15498
|
+
cColor = Color.WHITE;
|
|
15499
|
+
}
|
|
15500
|
+
else {
|
|
15501
|
+
cColor = colorToCColor$3(bColor);
|
|
15502
|
+
}
|
|
15503
|
+
const override = this.overrideFeatureColor.get(entity.entityId) == true;
|
|
15504
|
+
CesiumEntityStyler.SetDefaultColor({
|
|
15505
|
+
color: cColor,
|
|
15506
|
+
entity: visual,
|
|
15507
|
+
viewer: this.viewer,
|
|
15508
|
+
override: override
|
|
15509
|
+
});
|
|
15510
|
+
this.overrideFeatureColor.set(entity.entityId, true);
|
|
15511
|
+
this.styledEntityIds.set(entity.entityId, true);
|
|
15512
|
+
this._styleProgressQueue.Call();
|
|
15513
|
+
// Since we only need to update it for scenarios right now.
|
|
15514
|
+
// We'll avoid doing it if not needed, eg: first render and no scenario (same state as default).
|
|
15515
|
+
if (this.shouldUpdateRegoStates && (override || ((_b = data === null || data === void 0 ? void 0 : data.Bruce) === null || _b === void 0 ? void 0 : _b.Scenario) || this.historic)) {
|
|
15516
|
+
// Update the Entity's rego state.
|
|
15517
|
+
let changed = false;
|
|
15518
|
+
// Changed scenario.
|
|
15519
|
+
if (entity.scenario != ((_c = data === null || data === void 0 ? void 0 : data.Bruce) === null || _c === void 0 ? void 0 : _c.Scenario)) {
|
|
15520
|
+
entity.scenario = (_d = data === null || data === void 0 ? void 0 : data.Bruce) === null || _d === void 0 ? void 0 : _d.Scenario;
|
|
15521
|
+
changed = true;
|
|
15175
15522
|
}
|
|
15176
|
-
|
|
15177
|
-
|
|
15178
|
-
|
|
15179
|
-
|
|
15180
|
-
// Larger initial delay for the first loops because terrain is likely loading in.
|
|
15181
|
-
// We also delay because if we enable 50 Menu Items at the same time, common requests we be made if we wait a bit.
|
|
15182
|
-
// Eg: same entity type will be grouped into the same filter getter instance.
|
|
15183
|
-
await delay(loopId <= 3 ? 800 : 300);
|
|
15184
|
-
const MIN_HEIGHT = this.minHeight;
|
|
15185
|
-
const MAX_HEIGHT = this.maxHeight;
|
|
15186
|
-
const PAGE_SIZE = this.batchSize;
|
|
15187
|
-
let retryAttempts = MAX_RETRY_ATTEMPTS;
|
|
15188
|
-
let retryDelay = 0;
|
|
15189
|
-
let prevFirstId = "";
|
|
15190
|
-
let prevLastId = "";
|
|
15191
|
-
let prevTicks = 0;
|
|
15192
|
-
while ((!this.viewCenter || !this.viewRect) && this.getterLoopId == loopId) {
|
|
15193
|
-
await delay(RETRY_DELAY_INCREMENT);
|
|
15194
|
-
}
|
|
15195
|
-
if (this.getterLoopId != loopId) {
|
|
15196
|
-
return;
|
|
15197
|
-
}
|
|
15198
|
-
const alt = this.viewRect.alt;
|
|
15199
|
-
if (alt > MAX_HEIGHT || (alt < MIN_HEIGHT && MIN_HEIGHT > 0)) {
|
|
15200
|
-
return;
|
|
15201
|
-
}
|
|
15202
|
-
const cells = this.cells.GetCellsForView(this.viewCenter, this.viewRect);
|
|
15203
|
-
(_a = this.onScanUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(cells);
|
|
15204
|
-
let curCellIndex = cells.length > 0 ? 0 : null;
|
|
15205
|
-
let postedScanning = false;
|
|
15206
|
-
let postedLoading = false;
|
|
15207
|
-
let total = 0;
|
|
15208
|
-
while (retryAttempts > 0 && curCellIndex != null) {
|
|
15209
|
-
if (retryDelay > 0) {
|
|
15210
|
-
await delay(retryDelay);
|
|
15211
|
-
}
|
|
15212
|
-
if (this.getterLoopId != loopId) {
|
|
15213
|
-
break;
|
|
15214
|
-
}
|
|
15215
|
-
if (!postedScanning) {
|
|
15216
|
-
this.postStatus({ msg: EStatus.Scanning, revoking: false });
|
|
15217
|
-
postedScanning = true;
|
|
15218
|
-
}
|
|
15219
|
-
const curCell = cells[curCellIndex];
|
|
15220
|
-
if (curCell.IsFetched()) {
|
|
15221
|
-
curCell.Fetching = false;
|
|
15222
|
-
curCellIndex += 1;
|
|
15223
|
-
if (cells[curCellIndex]) {
|
|
15224
|
-
cells[curCellIndex].Fetching = true;
|
|
15225
|
-
}
|
|
15226
|
-
else {
|
|
15227
|
-
curCellIndex = null;
|
|
15228
|
-
}
|
|
15229
|
-
(_b = this.onScanUpdate) === null || _b === void 0 ? void 0 : _b.Trigger(cells);
|
|
15230
|
-
continue;
|
|
15231
|
-
}
|
|
15232
|
-
try {
|
|
15233
|
-
let response = {
|
|
15234
|
-
entities: [],
|
|
15235
|
-
nextPage: false,
|
|
15236
|
-
nextPageUrl: null
|
|
15237
|
-
};
|
|
15238
|
-
await SharedGetters.Queue.Run("Loading Entities from Menu Item that loads Entity Type: " + this.typeIds, async () => {
|
|
15239
|
-
var _a;
|
|
15240
|
-
if (abortController.signal.aborted || !((_a = this.GetMenuItems()) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
15241
|
-
return;
|
|
15242
|
-
}
|
|
15243
|
-
// API gave us a URL to use.
|
|
15244
|
-
if (curCell.FetchURL) {
|
|
15245
|
-
const tmpResponse = await this.api.get(curCell.FetchURL, {
|
|
15246
|
-
abortSignal: abortController.signal,
|
|
15247
|
-
noCache: true
|
|
15248
|
-
});
|
|
15249
|
-
// Same mapping as bruce-models doing Entity.GetList.
|
|
15250
|
-
response = {
|
|
15251
|
-
entities: tmpResponse.Items ? tmpResponse.Items : [],
|
|
15252
|
-
nextPage: tmpResponse.NextPage,
|
|
15253
|
-
nextPageUrl: tmpResponse.NextPageURL
|
|
15254
|
-
};
|
|
15255
|
-
}
|
|
15256
|
-
else {
|
|
15257
|
-
response = await Entity$1.GetList({
|
|
15258
|
-
api: this.api,
|
|
15259
|
-
scenario: this.scenario,
|
|
15260
|
-
historicKey: this.historicAttrKey,
|
|
15261
|
-
historicPoint: (this.historicAttrKey || this.historic) ? this.historicAttrDateTime : null,
|
|
15262
|
-
schemaId: this.schemaId,
|
|
15263
|
-
filter: {
|
|
15264
|
-
pageSize: PAGE_SIZE,
|
|
15265
|
-
pageIndex: curCell.FetchPageIndex,
|
|
15266
|
-
entityTypeId: this.typeIds,
|
|
15267
|
-
layerIds: this.tagIds,
|
|
15268
|
-
// Any tag specified will be allowed.
|
|
15269
|
-
layerIdsOperator: "in",
|
|
15270
|
-
bounds: curCell.GetBounds(),
|
|
15271
|
-
sortOrder: Api.ESortOrder.Asc,
|
|
15272
|
-
entityTypeConditions: this.attrFilter
|
|
15273
|
-
},
|
|
15274
|
-
viaCdn: this.viaCdn,
|
|
15275
|
-
migrated: true,
|
|
15276
|
-
// If we're taking 2+ minutes to make a query, it's a dud.
|
|
15277
|
-
// This is a timeout imposed on our DB and not external sources.
|
|
15278
|
-
// Honestly could lower down to 30 seconds, but we'll keep it high for now.
|
|
15279
|
-
maxSearchTimeSec: 60 * 2,
|
|
15280
|
-
req: {
|
|
15281
|
-
// If we are passing in an abort, we MUST pass in noCache.
|
|
15282
|
-
// Otherwise we will cache an aborted request.
|
|
15283
|
-
noCache: true,
|
|
15284
|
-
abortSignal: abortController.signal
|
|
15285
|
-
}
|
|
15286
|
-
});
|
|
15287
|
-
}
|
|
15288
|
-
});
|
|
15289
|
-
const entities = response.entities;
|
|
15290
|
-
const integrity = this.getIntegrityId();
|
|
15291
|
-
if (loopIntegrity == integrity && entities) {
|
|
15292
|
-
(_c = this.onUpdate) === null || _c === void 0 ? void 0 : _c.Trigger(entities);
|
|
15293
|
-
}
|
|
15294
|
-
if (this.gatheredIntegrity != integrity) {
|
|
15295
|
-
this.gatheredIntegrity = integrity;
|
|
15296
|
-
this.gatheredEntityIds = [];
|
|
15297
|
-
}
|
|
15298
|
-
// Add to the integrity list for any new IDs found.
|
|
15299
|
-
// This lets us keep track of all IDs we've found within the same integrity for historic data.
|
|
15300
|
-
if (this.historicAttrKey || this.historic) {
|
|
15301
|
-
for (let i = 0; i < entities.length; i++) {
|
|
15302
|
-
const entity = entities[i];
|
|
15303
|
-
if (!this.gatheredEntityIds.includes(entity.Bruce.ID)) {
|
|
15304
|
-
this.gatheredEntityIds.push(entity.Bruce.ID);
|
|
15305
|
-
}
|
|
15306
|
-
}
|
|
15307
|
-
}
|
|
15308
|
-
if (this.getterLoopId != loopId) {
|
|
15309
|
-
break;
|
|
15310
|
-
}
|
|
15311
|
-
if (entities.length) {
|
|
15312
|
-
total += entities.length;
|
|
15313
|
-
}
|
|
15314
|
-
if (!postedLoading) {
|
|
15315
|
-
this.postStatus({ msg: EStatus.Loading, revoking: false });
|
|
15316
|
-
postedLoading = true;
|
|
15317
|
-
}
|
|
15318
|
-
// Only mark as fetched when ALL pages are done.
|
|
15319
|
-
// Known issue where external sources may return less than page size.
|
|
15320
|
-
// Right now we're making it as fetched as we're siding with the majority use-case.
|
|
15321
|
-
if (
|
|
15322
|
-
// API explicity says no more pages.
|
|
15323
|
-
response.nextPage === false ||
|
|
15324
|
-
// API didn't explicity say anything so we guess based on size of response.
|
|
15325
|
-
(response.nextPage == null &&
|
|
15326
|
-
(entities.length <= 0 || entities.length < PAGE_SIZE))) {
|
|
15327
|
-
curCell.Fetched = true;
|
|
15328
|
-
curCell.Fetching = false;
|
|
15329
|
-
(_d = this.onScanUpdate) === null || _d === void 0 ? void 0 : _d.Trigger(cells);
|
|
15330
|
-
continue;
|
|
15331
|
-
}
|
|
15332
|
-
// Checking to make sure it's not just the same batch over and over again.
|
|
15333
|
-
if (entities.length > 0) {
|
|
15334
|
-
const first = (_f = (_e = entities[0]) === null || _e === void 0 ? void 0 : _e.Bruce) === null || _f === void 0 ? void 0 : _f.ID;
|
|
15335
|
-
const last = (_h = (_g = entities[entities.length - 1]) === null || _g === void 0 ? void 0 : _g.Bruce) === null || _h === void 0 ? void 0 : _h.ID;
|
|
15336
|
-
if (prevFirstId == first && prevLastId == last) {
|
|
15337
|
-
prevTicks += 1;
|
|
15338
|
-
if (prevTicks > 3) {
|
|
15339
|
-
break;
|
|
15340
|
-
}
|
|
15341
|
-
}
|
|
15342
|
-
else {
|
|
15343
|
-
prevFirstId = first;
|
|
15344
|
-
prevLastId = last;
|
|
15345
|
-
prevTicks = 0;
|
|
15346
|
-
}
|
|
15347
|
-
}
|
|
15348
|
-
// Using URL if specified.
|
|
15349
|
-
// If not then we'll just manually paginate.
|
|
15350
|
-
curCell.FetchURL = response.nextPageUrl;
|
|
15351
|
-
curCell.FetchPageIndex++;
|
|
15352
|
-
// Request passed so let's assume it was server hiccup and refresh counts.
|
|
15353
|
-
retryAttempts = MAX_RETRY_ATTEMPTS;
|
|
15354
|
-
retryDelay = 0;
|
|
15355
|
-
}
|
|
15356
|
-
catch (e) {
|
|
15357
|
-
// Ignore abort errors.
|
|
15358
|
-
if (e && typeof e === "object" && e.name == "AbortError") {
|
|
15359
|
-
// console.debug("Aborted entity-filter-getter request.");
|
|
15360
|
-
break;
|
|
15361
|
-
}
|
|
15362
|
-
console.error(e);
|
|
15363
|
-
if (this.getterLoopId != loopId) {
|
|
15364
|
-
break;
|
|
15365
|
-
}
|
|
15366
|
-
// Request failed so let's add a delay and try again soon.
|
|
15367
|
-
retryDelay += RETRY_DELAY_INCREMENT;
|
|
15368
|
-
retryAttempts -= 1;
|
|
15369
|
-
}
|
|
15370
|
-
await delay(REQUEST_PAGE_DELAY);
|
|
15371
|
-
}
|
|
15372
|
-
if (postedLoading) {
|
|
15373
|
-
this.postStatus({ msg: EStatus.Loading, revoking: true });
|
|
15374
|
-
}
|
|
15375
|
-
if (postedScanning) {
|
|
15376
|
-
this.postStatus({ msg: EStatus.Scanning, revoking: true });
|
|
15377
|
-
}
|
|
15378
|
-
})().then(() => {
|
|
15379
|
-
this.looping -= 1;
|
|
15380
|
-
}).catch(() => {
|
|
15381
|
-
this.looping -= 1;
|
|
15382
|
-
});
|
|
15383
|
-
}
|
|
15384
|
-
/**
|
|
15385
|
-
* Gets the historic state of found Entities for the current date times and emits them.
|
|
15386
|
-
* Since geometry searches are tied to the base Entity, we don't have to re-scan the viewport.
|
|
15387
|
-
*/
|
|
15388
|
-
emitHistoricData() {
|
|
15389
|
-
if (!this.GetMenuItems().length) {
|
|
15390
|
-
return;
|
|
15391
|
-
}
|
|
15392
|
-
let integrity = this.getIntegrityId();
|
|
15393
|
-
// Gathered ID does't match current one.
|
|
15394
|
-
if (this.gatheredIntegrity != integrity) {
|
|
15395
|
-
return;
|
|
15523
|
+
// Changed historic.
|
|
15524
|
+
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))) {
|
|
15525
|
+
entity.historicLayers = (_h = data === null || data === void 0 ? void 0 : data.Bruce) === null || _h === void 0 ? void 0 : _h.HistoricLayers;
|
|
15526
|
+
changed = true;
|
|
15396
15527
|
}
|
|
15397
|
-
|
|
15398
|
-
|
|
15399
|
-
if (
|
|
15400
|
-
this.
|
|
15401
|
-
|
|
15528
|
+
// Something changed, trigger a rego update.
|
|
15529
|
+
// This lets UI know when the rego has changed.
|
|
15530
|
+
if (changed) {
|
|
15531
|
+
this.register.OnUpdate.Trigger({
|
|
15532
|
+
type: VisualsRegister.EVisualUpdateType.Update,
|
|
15533
|
+
entityId: entity.entityId,
|
|
15534
|
+
rego: entity
|
|
15535
|
+
});
|
|
15402
15536
|
}
|
|
15403
|
-
(async () => {
|
|
15404
|
-
var _a;
|
|
15405
|
-
try {
|
|
15406
|
-
// Loop through all IDs we've found and get their historic records.
|
|
15407
|
-
for (let i = 0; i < this.gatheredEntityIds.length; i += SCAN_BATCH_SIZE) {
|
|
15408
|
-
let batch = this.gatheredEntityIds.slice(i, i + SCAN_BATCH_SIZE);
|
|
15409
|
-
if (!batch.length) {
|
|
15410
|
-
break;
|
|
15411
|
-
}
|
|
15412
|
-
// Controller we can use to abort the request when a new loop starts.
|
|
15413
|
-
const controller = this.historicRefreshAbortController = new AbortController();
|
|
15414
|
-
let entities = [];
|
|
15415
|
-
await SharedGetters.Queue.Run("Refreshing historic data in Menu Item that loads Entity Type: " + this.typeIds, async () => {
|
|
15416
|
-
var _a;
|
|
15417
|
-
if (controller.signal.aborted || !((_a = this.GetMenuItems()) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
15418
|
-
return;
|
|
15419
|
-
}
|
|
15420
|
-
entities = (await Entity$1.GetList({
|
|
15421
|
-
api: this.api,
|
|
15422
|
-
scenario: this.scenario,
|
|
15423
|
-
historicKey: this.historicAttrKey,
|
|
15424
|
-
historicPoint: historicAttrDateTime,
|
|
15425
|
-
schemaId: this.schemaId,
|
|
15426
|
-
filter: {
|
|
15427
|
-
pageSize: batch.length,
|
|
15428
|
-
pageIndex: 0,
|
|
15429
|
-
entityTypeId: this.typeIds,
|
|
15430
|
-
layerIds: this.tagIds,
|
|
15431
|
-
layerIdsOperator: "in",
|
|
15432
|
-
sortOrder: Api.ESortOrder.Asc,
|
|
15433
|
-
entityTypeConditions: {
|
|
15434
|
-
"ID": {
|
|
15435
|
-
"in": batch
|
|
15436
|
-
}
|
|
15437
|
-
},
|
|
15438
|
-
},
|
|
15439
|
-
viaCdn: this.viaCdn,
|
|
15440
|
-
migrated: true,
|
|
15441
|
-
// If we're taking 5+ minutes to make a query, it's a dud.
|
|
15442
|
-
// This is a timeout imposed on our DB and not external sources.
|
|
15443
|
-
// Honestly could lower down to 30 seconds, but we'll keep it high for now.
|
|
15444
|
-
maxSearchTimeSec: 60 * 5,
|
|
15445
|
-
req: {
|
|
15446
|
-
// If we are passing in an abort, we MUST pass in noCache.
|
|
15447
|
-
// Otherwise we will cache an aborted request.
|
|
15448
|
-
noCache: true,
|
|
15449
|
-
abortSignal: controller.signal
|
|
15450
|
-
}
|
|
15451
|
-
})).entities;
|
|
15452
|
-
});
|
|
15453
|
-
// Date changed.
|
|
15454
|
-
if (this.historicAttrDateTime != historicAttrDateTime) {
|
|
15455
|
-
break;
|
|
15456
|
-
}
|
|
15457
|
-
// Integrity changed.
|
|
15458
|
-
if (this.gatheredIntegrity != integrity) {
|
|
15459
|
-
break;
|
|
15460
|
-
}
|
|
15461
|
-
// No Menu Items.
|
|
15462
|
-
if (!this.GetMenuItems().length) {
|
|
15463
|
-
break;
|
|
15464
|
-
}
|
|
15465
|
-
(_a = this.onUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(entities);
|
|
15466
|
-
}
|
|
15467
|
-
}
|
|
15468
|
-
catch (e) {
|
|
15469
|
-
// Ignore abort errors.
|
|
15470
|
-
if (e && typeof e === "object" && e.name == "AbortError") {
|
|
15471
|
-
// console.debug("Aborted entity-filter-getter historic refresh request.");
|
|
15472
|
-
return;
|
|
15473
|
-
}
|
|
15474
|
-
console.error(e);
|
|
15475
|
-
}
|
|
15476
|
-
})();
|
|
15477
15537
|
}
|
|
15478
15538
|
}
|
|
15479
|
-
|
|
15480
|
-
|
|
15539
|
+
getTilesetFeatureStyle(entityTypeId) {
|
|
15540
|
+
var _a, _b, _c, _d;
|
|
15541
|
+
// Locate what style is applicable to the feature.
|
|
15542
|
+
let style = null;
|
|
15543
|
+
if (entityTypeId) {
|
|
15544
|
+
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);
|
|
15545
|
+
}
|
|
15546
|
+
if (!style) {
|
|
15547
|
+
style = ((_c = this.fallbackStyle) === null || _c === void 0 ? void 0 : _c.Settings);
|
|
15548
|
+
}
|
|
15549
|
+
if (!style || !((_d = style === null || style === void 0 ? void 0 : style.modelStyle) === null || _d === void 0 ? void 0 : _d.customize)) {
|
|
15550
|
+
return null;
|
|
15551
|
+
}
|
|
15552
|
+
return style;
|
|
15553
|
+
}
|
|
15554
|
+
getTilesetFeatureNeedsFullData(entityTypeId) {
|
|
15555
|
+
var _a;
|
|
15556
|
+
if (this.historic) {
|
|
15557
|
+
// Unfortunately when we are working with historic we have to request the entity.
|
|
15558
|
+
// This is because we need to know if a record exists at the point in time.
|
|
15559
|
+
return true;
|
|
15560
|
+
}
|
|
15561
|
+
const style = this.getTilesetFeatureStyle(entityTypeId);
|
|
15562
|
+
if (!style) {
|
|
15563
|
+
return false;
|
|
15564
|
+
}
|
|
15565
|
+
const fill = (_a = style === null || style === void 0 ? void 0 : style.modelStyle) === null || _a === void 0 ? void 0 : _a.fillColor;
|
|
15566
|
+
if (!fill || fill.length <= 0) {
|
|
15567
|
+
return false;
|
|
15568
|
+
}
|
|
15569
|
+
return fill[0].type != 0;
|
|
15570
|
+
}
|
|
15571
|
+
}
|
|
15481
15572
|
|
|
15482
|
-
|
|
15483
|
-
|
|
15484
|
-
|
|
15485
|
-
|
|
15486
|
-
|
|
15487
|
-
|
|
15488
|
-
|
|
15489
|
-
|
|
15490
|
-
|
|
15491
|
-
cacheKey += JSON.stringify(params.tagIds ? params.tagIds : []);
|
|
15492
|
-
cacheKey += params.historicAttrKey ? params.historicAttrKey : "";
|
|
15493
|
-
cacheKey += params.historic ? "true" : "false";
|
|
15494
|
-
cacheKey += params.scenario ? params.scenario : 0;
|
|
15495
|
-
if (params.historicAttrKey) {
|
|
15496
|
-
cacheKey += params.historicInterpolation ? "true" : "false";
|
|
15573
|
+
/**
|
|
15574
|
+
* Returns if a given tileset is alive and in the scene.
|
|
15575
|
+
* @param viewer
|
|
15576
|
+
* @param cTileset
|
|
15577
|
+
* @returns
|
|
15578
|
+
*/
|
|
15579
|
+
function isAlive$2(viewer, cTileset) {
|
|
15580
|
+
if (!(viewer === null || viewer === void 0 ? void 0 : viewer.scene)) {
|
|
15581
|
+
return false;
|
|
15497
15582
|
}
|
|
15498
|
-
|
|
15499
|
-
|
|
15500
|
-
|
|
15501
|
-
|
|
15502
|
-
|
|
15503
|
-
|
|
15504
|
-
|
|
15505
|
-
constructor() {
|
|
15506
|
-
this.data = {};
|
|
15507
|
-
}
|
|
15508
|
-
GetOrCreateFilterGetter(params) {
|
|
15509
|
-
params.cdn = Boolean(params.cdn);
|
|
15510
|
-
const cacheKey = createFilterGetterCacheKey(params);
|
|
15511
|
-
let getter = this.data[cacheKey];
|
|
15512
|
-
if (!getter) {
|
|
15513
|
-
getter = new EntityFilterGetter.Getter({
|
|
15514
|
-
api: params.api,
|
|
15515
|
-
viewer: params.viewer,
|
|
15516
|
-
viewPort: params.monitor,
|
|
15517
|
-
typeIds: !params.typeId ? null : typeof params.typeId == "string" ? [params.typeId] : params.typeId,
|
|
15518
|
-
schemaId: params.schemaId,
|
|
15519
|
-
batchSize: params.batchSize,
|
|
15520
|
-
attrFilter: params.attrFilter,
|
|
15521
|
-
historic: params.historic,
|
|
15522
|
-
historicAttrKey: params.historicAttrKey,
|
|
15523
|
-
historicInterpolation: params.historicInterpolation,
|
|
15524
|
-
viaCdn: params.cdn,
|
|
15525
|
-
scenario: params.scenario,
|
|
15526
|
-
});
|
|
15527
|
-
this.data[cacheKey] = getter;
|
|
15528
|
-
/**
|
|
15529
|
-
* Debug option.
|
|
15530
|
-
* This will display the bounds of the cells that are being fetched.
|
|
15531
|
-
*/
|
|
15532
|
-
if (params.viewer && params.debugShowBounds) {
|
|
15533
|
-
// Cell id -> entity.
|
|
15534
|
-
const cellCache = {};
|
|
15535
|
-
const cellPrefix = ObjectUtils.UId(10) + "_";
|
|
15536
|
-
getter.OnScanUpdate.Subscribe((cells) => {
|
|
15537
|
-
if (window.ON_SCAN_UPDATE_PAUSED == true) {
|
|
15538
|
-
return;
|
|
15539
|
-
}
|
|
15540
|
-
const curCellIds = [];
|
|
15541
|
-
let fetchingCellId = null;
|
|
15542
|
-
const fetchedCells = {};
|
|
15543
|
-
cells.forEach((cell) => {
|
|
15544
|
-
var _a;
|
|
15545
|
-
const bounds = cell.GetBounds();
|
|
15546
|
-
const id = cellPrefix + bounds.east + "_" + bounds.north + "_" + bounds.south + "_" + bounds.west;
|
|
15547
|
-
curCellIds.push(id);
|
|
15548
|
-
fetchedCells[id] = cell.IsFetched();
|
|
15549
|
-
fetchingCellId = cell.Fetching ? id : fetchingCellId;
|
|
15550
|
-
let material = null;
|
|
15551
|
-
if (fetchedCells[id]) {
|
|
15552
|
-
material = Color.LIGHTGREEN.clone().withAlpha(0.3);
|
|
15553
|
-
}
|
|
15554
|
-
else if (fetchingCellId == id) {
|
|
15555
|
-
material = Color.LIGHTBLUE.clone().withAlpha(0.3);
|
|
15556
|
-
}
|
|
15557
|
-
else {
|
|
15558
|
-
material = Color.GOLD.clone().withAlpha(0.3);
|
|
15559
|
-
}
|
|
15560
|
-
if (cellCache[id]) {
|
|
15561
|
-
const rect = (_a = cellCache[id]) === null || _a === void 0 ? void 0 : _a.rectangle;
|
|
15562
|
-
if (rect) {
|
|
15563
|
-
rect.material = material;
|
|
15564
|
-
}
|
|
15565
|
-
return;
|
|
15566
|
-
}
|
|
15567
|
-
const rect = new Rectangle(Math$1.toRadians(bounds.west), Math$1.toRadians(bounds.south), Math$1.toRadians(bounds.east), Math$1.toRadians(bounds.north));
|
|
15568
|
-
const entity = params.viewer.entities.add(new Entity({
|
|
15569
|
-
id: id,
|
|
15570
|
-
rectangle: {
|
|
15571
|
-
coordinates: rect,
|
|
15572
|
-
fill: true,
|
|
15573
|
-
//material: Cesium.Color.fromRandom().withAlpha(0.3),
|
|
15574
|
-
material: material,
|
|
15575
|
-
zIndex: 0
|
|
15576
|
-
},
|
|
15577
|
-
// point: {
|
|
15578
|
-
// pixelSize: 15,
|
|
15579
|
-
// outlineColor: Cesium.Color.WHITE,
|
|
15580
|
-
// outlineWidth: 2,
|
|
15581
|
-
// color: Cesium.Color.fromRandom().withAlpha(0.5),
|
|
15582
|
-
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
|
15583
|
-
// },
|
|
15584
|
-
position: Cartesian3.fromRadians((rect.east + rect.west) / 2, (rect.north + rect.south) / 2)
|
|
15585
|
-
}));
|
|
15586
|
-
cellCache[id] = entity;
|
|
15587
|
-
});
|
|
15588
|
-
Object.keys(cellCache).forEach((id) => {
|
|
15589
|
-
if (curCellIds.indexOf(id) == -1) {
|
|
15590
|
-
const entity = cellCache[id];
|
|
15591
|
-
if (entity && params.viewer.entities.contains(entity)) {
|
|
15592
|
-
params.viewer.entities.remove(entity);
|
|
15593
|
-
}
|
|
15594
|
-
delete cellCache[id];
|
|
15595
|
-
}
|
|
15596
|
-
});
|
|
15597
|
-
});
|
|
15598
|
-
}
|
|
15599
|
-
}
|
|
15600
|
-
return getter;
|
|
15601
|
-
}
|
|
15602
|
-
}
|
|
15603
|
-
SharedGetters.Cache = Cache;
|
|
15604
|
-
/**
|
|
15605
|
-
* To avoid performing multiple expensive queries at the same time,
|
|
15606
|
-
* we'll have the getters work through a queue of requests.
|
|
15607
|
-
*/
|
|
15608
|
-
let Queue;
|
|
15609
|
-
(function (Queue) {
|
|
15610
|
-
const queue = [];
|
|
15611
|
-
let isProcessing = false;
|
|
15612
|
-
/**
|
|
15613
|
-
* Called to run a provided function.
|
|
15614
|
-
* When the function is complete, the next function in the queue will be called.
|
|
15615
|
-
* This function will resolve when the provided function is complete.
|
|
15616
|
-
* If the provided function crashes, the error bubbles up to the caller.
|
|
15617
|
-
* @param name
|
|
15618
|
-
* @param call
|
|
15619
|
-
*/
|
|
15620
|
-
function Run(name, call) {
|
|
15621
|
-
// console.debug(`Queueing: ${name}`);
|
|
15622
|
-
return new Promise((resolve, reject) => {
|
|
15623
|
-
queue.push(async () => {
|
|
15624
|
-
try {
|
|
15625
|
-
// console.debug(`Running: ${name}`);
|
|
15626
|
-
const result = await call();
|
|
15627
|
-
resolve(result);
|
|
15628
|
-
}
|
|
15629
|
-
catch (error) {
|
|
15630
|
-
reject(error);
|
|
15631
|
-
}
|
|
15632
|
-
finally {
|
|
15633
|
-
// Process the next function in the queue.
|
|
15634
|
-
queue.shift();
|
|
15635
|
-
// If there are more functions in the queue, process the next one.
|
|
15636
|
-
if (queue.length > 0) {
|
|
15637
|
-
processNext();
|
|
15638
|
-
}
|
|
15639
|
-
// No more items to process.
|
|
15640
|
-
else {
|
|
15641
|
-
isProcessing = false;
|
|
15642
|
-
}
|
|
15643
|
-
}
|
|
15644
|
-
});
|
|
15645
|
-
if (!isProcessing) {
|
|
15646
|
-
// If not currently processing, start processing the queue.
|
|
15647
|
-
isProcessing = true;
|
|
15648
|
-
processNext();
|
|
15649
|
-
}
|
|
15650
|
-
});
|
|
15651
|
-
}
|
|
15652
|
-
Queue.Run = Run;
|
|
15653
|
-
async function processNext() {
|
|
15654
|
-
const nextCall = queue[0];
|
|
15655
|
-
if (nextCall) {
|
|
15656
|
-
// Call the next function in the queue.
|
|
15657
|
-
await nextCall();
|
|
15658
|
-
}
|
|
15659
|
-
}
|
|
15660
|
-
})(Queue = SharedGetters.Queue || (SharedGetters.Queue = {}));
|
|
15661
|
-
})(SharedGetters || (SharedGetters = {}));
|
|
15662
|
-
|
|
15663
|
-
function colorToCColor$3(color) {
|
|
15664
|
-
return new Color(color.red ? color.red / 255 : 0, color.green ? color.green / 255 : 0, color.blue ? color.blue / 255 : 0, color.alpha);
|
|
15665
|
-
}
|
|
15666
|
-
/**
|
|
15667
|
-
* Returns if a given tileset is alive and in the scene.
|
|
15668
|
-
* @param viewer
|
|
15669
|
-
* @param cTileset
|
|
15670
|
-
* @returns
|
|
15671
|
-
*/
|
|
15672
|
-
function isAlive$2(viewer, cTileset) {
|
|
15673
|
-
if (!(viewer === null || viewer === void 0 ? void 0 : viewer.scene)) {
|
|
15674
|
-
return false;
|
|
15675
|
-
}
|
|
15676
|
-
if (viewer.isDestroyed()) {
|
|
15677
|
-
return false;
|
|
15678
|
-
}
|
|
15679
|
-
if (cTileset.isDestroyed()) {
|
|
15680
|
-
return false;
|
|
15681
|
-
}
|
|
15682
|
-
return viewer.scene.primitives.contains(cTileset);
|
|
15683
|
-
}
|
|
15684
|
-
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
15685
|
-
// We have some evil hard-coded style mappings that need to be fixed.
|
|
15686
|
-
// These exist within legacy project views.
|
|
15687
|
-
function correctStyle(style) {
|
|
15688
|
-
if (style && !style.Settings && !style.ID) {
|
|
15689
|
-
return {
|
|
15690
|
-
ID: -1,
|
|
15691
|
-
Name: "Unknown",
|
|
15692
|
-
Settings: {
|
|
15693
|
-
...style
|
|
15694
|
-
},
|
|
15695
|
-
Type: Style.EType.Entity
|
|
15696
|
-
};
|
|
15697
|
-
}
|
|
15698
|
-
return style;
|
|
15583
|
+
if (viewer.isDestroyed()) {
|
|
15584
|
+
return false;
|
|
15585
|
+
}
|
|
15586
|
+
if (cTileset.isDestroyed()) {
|
|
15587
|
+
return false;
|
|
15588
|
+
}
|
|
15589
|
+
return viewer.scene.primitives.contains(cTileset);
|
|
15699
15590
|
}
|
|
15700
15591
|
const VIEWER_WATCH_KEY = "bruce-viewer-watch";
|
|
15701
15592
|
const WATCH_KEY = "bruce-tileset-watch";
|
|
@@ -16165,585 +16056,788 @@ var TilesetRenderEngine;
|
|
|
16165
16056
|
return cTileset;
|
|
16166
16057
|
}
|
|
16167
16058
|
TilesetRenderEngine.RenderLegacy = RenderLegacy;
|
|
16168
|
-
|
|
16059
|
+
// Util for styling Tileset features.
|
|
16060
|
+
// Also used to flag historic metadata based on timeline changes.
|
|
16061
|
+
class Styler extends TilesetStyler {
|
|
16062
|
+
}
|
|
16063
|
+
TilesetRenderEngine.Styler = Styler;
|
|
16064
|
+
/**
|
|
16065
|
+
* The maximum memory in MB that can be used by all tilesets.
|
|
16066
|
+
* This is distributed evenly between all loaded tilesets.
|
|
16067
|
+
*/
|
|
16068
|
+
TilesetRenderEngine.MAX_TILESET_MEMORY = 1024;
|
|
16069
|
+
/**
|
|
16070
|
+
* Watches tilesets in the viewer.
|
|
16071
|
+
* This will regulate their max memory param.
|
|
16072
|
+
* As more get watched their memory will be reduced.
|
|
16073
|
+
*/
|
|
16074
|
+
class MemoryWatcher {
|
|
16075
|
+
constructor(viewer) {
|
|
16076
|
+
this.watched = [];
|
|
16077
|
+
this.viewer = viewer;
|
|
16078
|
+
}
|
|
16079
|
+
distributeMemory() {
|
|
16080
|
+
this.clean();
|
|
16081
|
+
// Total 1gb as default.
|
|
16082
|
+
// We'll need to allow user to change this somehow.
|
|
16083
|
+
const maxMemory = TilesetRenderEngine.MAX_TILESET_MEMORY;
|
|
16084
|
+
// Minimum memory in MB per tileset.
|
|
16085
|
+
const minMemory = 80;
|
|
16086
|
+
const totalPerTileset = Math.max(this.watched.length ? maxMemory / this.watched.length : maxMemory, minMemory);
|
|
16087
|
+
this.watched.forEach(x => {
|
|
16088
|
+
// Newer Cesium killed this property.
|
|
16089
|
+
// TODO: Check if it's needed then.
|
|
16090
|
+
x["maximumMemoryUsage"] = totalPerTileset;
|
|
16091
|
+
});
|
|
16092
|
+
}
|
|
16093
|
+
destroy() {
|
|
16094
|
+
this.watched = [];
|
|
16095
|
+
}
|
|
16096
|
+
/**
|
|
16097
|
+
* Remove all dead tilesets.
|
|
16098
|
+
*/
|
|
16099
|
+
clean() {
|
|
16100
|
+
// Remove all dead tilesets.
|
|
16101
|
+
this.watched = this.watched.filter(x => isAlive$2(this.viewer, x));
|
|
16102
|
+
// Check if viewer is destroyed.
|
|
16103
|
+
if (!this.viewer || this.viewer.isDestroyed()) {
|
|
16104
|
+
this.destroy();
|
|
16105
|
+
}
|
|
16106
|
+
}
|
|
16107
|
+
Watch(tileset) {
|
|
16108
|
+
if (!tileset) {
|
|
16109
|
+
return;
|
|
16110
|
+
}
|
|
16111
|
+
if (!tileset[WATCH_KEY]) {
|
|
16112
|
+
tileset[WATCH_KEY] = ObjectUtils.UId();
|
|
16113
|
+
}
|
|
16114
|
+
const index = this.watched.findIndex(x => x[WATCH_KEY] === tileset[WATCH_KEY]);
|
|
16115
|
+
if (index >= 0) {
|
|
16116
|
+
return;
|
|
16117
|
+
}
|
|
16118
|
+
this.watched.push(tileset);
|
|
16119
|
+
this.distributeMemory();
|
|
16120
|
+
}
|
|
16121
|
+
Unwatch(tileset) {
|
|
16122
|
+
if (!tileset) {
|
|
16123
|
+
return;
|
|
16124
|
+
}
|
|
16125
|
+
if (!tileset[WATCH_KEY]) {
|
|
16126
|
+
tileset[WATCH_KEY] = ObjectUtils.UId();
|
|
16127
|
+
}
|
|
16128
|
+
const index = this.watched.findIndex(x => (x === null || x === void 0 ? void 0 : x[WATCH_KEY]) === tileset[WATCH_KEY]);
|
|
16129
|
+
if (index > -1) {
|
|
16130
|
+
this.watched.splice(index, 1);
|
|
16131
|
+
}
|
|
16132
|
+
this.distributeMemory();
|
|
16133
|
+
}
|
|
16134
|
+
}
|
|
16135
|
+
TilesetRenderEngine.MemoryWatcher = MemoryWatcher;
|
|
16136
|
+
function GetMemoryWatcher(viewer) {
|
|
16137
|
+
// If viewer is dead return nothing.
|
|
16138
|
+
if (!viewer || viewer.isDestroyed()) {
|
|
16139
|
+
return null;
|
|
16140
|
+
}
|
|
16141
|
+
if (!viewer[VIEWER_WATCH_KEY]) {
|
|
16142
|
+
viewer[VIEWER_WATCH_KEY] = new MemoryWatcher(viewer);
|
|
16143
|
+
}
|
|
16144
|
+
return viewer[VIEWER_WATCH_KEY];
|
|
16145
|
+
}
|
|
16146
|
+
TilesetRenderEngine.GetMemoryWatcher = GetMemoryWatcher;
|
|
16147
|
+
})(TilesetRenderEngine || (TilesetRenderEngine = {}));
|
|
16148
|
+
|
|
16149
|
+
/**
|
|
16150
|
+
* This is a helper for making entity requests based on a grid area.
|
|
16151
|
+
* It will return grid cells based on given view-area then will remember when stuff-
|
|
16152
|
+
* was fully-fetched for those cells to avoid making duplicate requests.
|
|
16153
|
+
*/
|
|
16154
|
+
var EntityGlobe;
|
|
16155
|
+
(function (EntityGlobe) {
|
|
16156
|
+
class Cell {
|
|
16169
16157
|
constructor() {
|
|
16170
|
-
this.
|
|
16171
|
-
|
|
16172
|
-
this.
|
|
16173
|
-
|
|
16174
|
-
this
|
|
16175
|
-
this.
|
|
16176
|
-
this.
|
|
16177
|
-
this.
|
|
16178
|
-
|
|
16179
|
-
|
|
16180
|
-
|
|
16181
|
-
|
|
16182
|
-
|
|
16183
|
-
|
|
16184
|
-
|
|
16185
|
-
|
|
16186
|
-
|
|
16187
|
-
|
|
16188
|
-
|
|
16189
|
-
|
|
16190
|
-
|
|
16191
|
-
|
|
16192
|
-
|
|
16193
|
-
|
|
16194
|
-
|
|
16195
|
-
|
|
16196
|
-
|
|
16197
|
-
|
|
16198
|
-
|
|
16199
|
-
|
|
16200
|
-
|
|
16201
|
-
|
|
16202
|
-
|
|
16203
|
-
|
|
16204
|
-
|
|
16205
|
-
|
|
16206
|
-
|
|
16158
|
+
this.Fetched = false;
|
|
16159
|
+
this.IsFetched = null;
|
|
16160
|
+
this.FetchPageIndex = 0;
|
|
16161
|
+
// Optional URL to use instead of default URL generation.
|
|
16162
|
+
// This is typically a response from the API to use this specific URL for the next page.
|
|
16163
|
+
this.FetchURL = null;
|
|
16164
|
+
this.Boundaries = null;
|
|
16165
|
+
this.Fetching = false;
|
|
16166
|
+
}
|
|
16167
|
+
GetBounds() {
|
|
16168
|
+
// Entity data works in -180 to 180 range.
|
|
16169
|
+
function prepareRangeForBounds(range) {
|
|
16170
|
+
if (range > 180) {
|
|
16171
|
+
return range - 360;
|
|
16172
|
+
}
|
|
16173
|
+
return range;
|
|
16174
|
+
}
|
|
16175
|
+
// Add minor decimal as API crashes when giving it whole numbers.
|
|
16176
|
+
const maxLon = prepareRangeForBounds(this.Boundaries.maxLongitude);
|
|
16177
|
+
const minLon = prepareRangeForBounds(this.Boundaries.minLongitude);
|
|
16178
|
+
const maxLat = prepareRangeForBounds(this.Boundaries.maxLatitude);
|
|
16179
|
+
const minLat = prepareRangeForBounds(this.Boundaries.minLatitude);
|
|
16180
|
+
return {
|
|
16181
|
+
east: maxLon,
|
|
16182
|
+
north: maxLat,
|
|
16183
|
+
south: minLat,
|
|
16184
|
+
west: minLon
|
|
16185
|
+
};
|
|
16186
|
+
}
|
|
16187
|
+
}
|
|
16188
|
+
EntityGlobe.Cell = Cell;
|
|
16189
|
+
class Grid {
|
|
16190
|
+
constructor() {
|
|
16191
|
+
this.cells = {};
|
|
16192
|
+
}
|
|
16193
|
+
GetCellsForView(cameraPos, viewRect) {
|
|
16194
|
+
const cells = [];
|
|
16195
|
+
const minLat = viewRect.south;
|
|
16196
|
+
const minLon = viewRect.west;
|
|
16197
|
+
const maxLat = viewRect.north;
|
|
16198
|
+
const maxLon = viewRect.east;
|
|
16199
|
+
const MAX_CELLS = 150;
|
|
16200
|
+
const cellDegreeSize = getCellSizeFromHeight(viewRect.alt);
|
|
16201
|
+
// console.log("cell size", cellDegreeSize, "height", viewRect.alt);
|
|
16202
|
+
let curMinLon = floorValueToCellSize(cellDegreeSize, minLon);
|
|
16203
|
+
let curMinLat = floorValueToCellSize(cellDegreeSize, minLat);
|
|
16204
|
+
// For larger views we add additional padding because our view-area culling is too strong.
|
|
16205
|
+
if (cellDegreeSize >= 2) {
|
|
16206
|
+
curMinLon -= cellDegreeSize;
|
|
16207
|
+
curMinLat -= cellDegreeSize;
|
|
16208
|
+
}
|
|
16209
|
+
let centerX = cameraPos === null || cameraPos === void 0 ? void 0 : cameraPos.longitude;
|
|
16210
|
+
let centerY = cameraPos === null || cameraPos === void 0 ? void 0 : cameraPos.latitude;
|
|
16211
|
+
if (isNaN(centerX) || isNaN(centerY)) {
|
|
16212
|
+
centerX = (minLon + maxLon) / 2;
|
|
16213
|
+
centerY = (minLat + maxLat) / 2;
|
|
16214
|
+
}
|
|
16215
|
+
let width = Math.ceil((maxLon - curMinLon) / cellDegreeSize);
|
|
16216
|
+
let height = Math.ceil((maxLat - curMinLat) / cellDegreeSize);
|
|
16217
|
+
// For larger views we add additional padding because our view-area culling is too strong.
|
|
16218
|
+
if (cellDegreeSize >= 2) {
|
|
16219
|
+
width += 1;
|
|
16220
|
+
height += 1;
|
|
16221
|
+
}
|
|
16222
|
+
const cellDistances = [];
|
|
16223
|
+
for (let x = 0; x < width; x++) {
|
|
16224
|
+
for (let y = 0; y < height; y++) {
|
|
16225
|
+
const lon = x * cellDegreeSize + curMinLon;
|
|
16226
|
+
const lat = y * cellDegreeSize + curMinLat;
|
|
16227
|
+
const cellCenterX = lon + cellDegreeSize / 2;
|
|
16228
|
+
const cellCenterY = lat + cellDegreeSize / 2;
|
|
16229
|
+
const dist = Math.sqrt(Math.pow(cellCenterX - centerX, 2) + Math.pow(cellCenterY - centerY, 2));
|
|
16230
|
+
cellDistances.push({ x, y, dist });
|
|
16231
|
+
}
|
|
16232
|
+
}
|
|
16233
|
+
cellDistances.sort((a, b) => a.dist - b.dist);
|
|
16234
|
+
for (const { x, y } of cellDistances) {
|
|
16235
|
+
const lon = x * cellDegreeSize + curMinLon;
|
|
16236
|
+
const lat = y * cellDegreeSize + curMinLat;
|
|
16237
|
+
const [id, cell] = getOrCreateCell(this.cells, cellDegreeSize, lon, lon + cellDegreeSize, lat, lat + cellDegreeSize);
|
|
16238
|
+
cells.push(cell);
|
|
16239
|
+
if (cells.length >= MAX_CELLS) {
|
|
16240
|
+
break;
|
|
16241
|
+
}
|
|
16242
|
+
}
|
|
16243
|
+
return cells;
|
|
16244
|
+
}
|
|
16245
|
+
}
|
|
16246
|
+
EntityGlobe.Grid = Grid;
|
|
16247
|
+
})(EntityGlobe || (EntityGlobe = {}));
|
|
16248
|
+
function floorValueToCellSize(size, value) {
|
|
16249
|
+
return Math.floor(value / size) * size;
|
|
16250
|
+
}
|
|
16251
|
+
function getCellSizeFromHeight(height) {
|
|
16252
|
+
if (height < 1000) {
|
|
16253
|
+
return 0.01;
|
|
16254
|
+
}
|
|
16255
|
+
if (height < 5000) {
|
|
16256
|
+
return 0.04;
|
|
16257
|
+
}
|
|
16258
|
+
else if (height < 10000) {
|
|
16259
|
+
return 0.15;
|
|
16260
|
+
}
|
|
16261
|
+
else if (height < 30000) {
|
|
16262
|
+
return 0.5;
|
|
16263
|
+
}
|
|
16264
|
+
else if (height < 70000) {
|
|
16265
|
+
return 0.5;
|
|
16266
|
+
}
|
|
16267
|
+
else if (height < 100000) {
|
|
16268
|
+
return 1;
|
|
16269
|
+
}
|
|
16270
|
+
else if (height < 150000) {
|
|
16271
|
+
return 1;
|
|
16272
|
+
}
|
|
16273
|
+
else if (height < 200000) {
|
|
16274
|
+
return 1.5;
|
|
16275
|
+
}
|
|
16276
|
+
else if (height < 300000) {
|
|
16277
|
+
return 1.5;
|
|
16278
|
+
}
|
|
16279
|
+
else if (height < 500000) {
|
|
16280
|
+
return 3;
|
|
16281
|
+
}
|
|
16282
|
+
else if (height < 1000000) {
|
|
16283
|
+
return 3;
|
|
16284
|
+
}
|
|
16285
|
+
else if (height < 1200000) {
|
|
16286
|
+
return 4;
|
|
16287
|
+
}
|
|
16288
|
+
else if (height < 2000000) {
|
|
16289
|
+
return 6;
|
|
16290
|
+
}
|
|
16291
|
+
else if (height < 3000000) {
|
|
16292
|
+
return 20;
|
|
16293
|
+
}
|
|
16294
|
+
return 35;
|
|
16295
|
+
}
|
|
16296
|
+
function isCellFetched(cell) {
|
|
16297
|
+
if (cell.Fetched) {
|
|
16298
|
+
return true;
|
|
16299
|
+
}
|
|
16300
|
+
return false;
|
|
16301
|
+
}
|
|
16302
|
+
function getOrCreateCell(cells, cellSize, lon, maxLon, lat, maxLat) {
|
|
16303
|
+
const id = cellSize + "_" + lon + "_" + maxLon + "_" + lat + "_" + maxLat;
|
|
16304
|
+
let cell = cells[id];
|
|
16305
|
+
if (!cell) {
|
|
16306
|
+
cell = cells[id] = new EntityGlobe.Cell();
|
|
16307
|
+
cell.Boundaries = {
|
|
16308
|
+
minLatitude: lat,
|
|
16309
|
+
maxLatitude: maxLat,
|
|
16310
|
+
minLongitude: lon,
|
|
16311
|
+
maxLongitude: maxLon
|
|
16312
|
+
};
|
|
16313
|
+
cell.IsFetched = () => isCellFetched(cell);
|
|
16314
|
+
}
|
|
16315
|
+
return [id, cell];
|
|
16316
|
+
}
|
|
16317
|
+
|
|
16318
|
+
const MAX_AREA_IN_DEGREES$1 = 90;
|
|
16319
|
+
const MAX_RETRY_ATTEMPTS = 1;
|
|
16320
|
+
const RETRY_DELAY_INCREMENT = 500;
|
|
16321
|
+
const REQUEST_PAGE_DELAY = 50;
|
|
16322
|
+
class regMenuItemGetter {
|
|
16323
|
+
constructor(typeId, tagIds, minHeight, maxHeight) {
|
|
16324
|
+
this.TypeId = typeId;
|
|
16325
|
+
this.TagIds = tagIds;
|
|
16326
|
+
this.MinHeight = minHeight;
|
|
16327
|
+
this.MaxHeight = maxHeight;
|
|
16328
|
+
}
|
|
16329
|
+
}
|
|
16330
|
+
async function delay(milliseconds) {
|
|
16331
|
+
return new Promise((res) => {
|
|
16332
|
+
setTimeout(() => {
|
|
16333
|
+
res();
|
|
16334
|
+
}, milliseconds);
|
|
16335
|
+
});
|
|
16336
|
+
}
|
|
16337
|
+
/**
|
|
16338
|
+
* This is a batched entity getter.
|
|
16339
|
+
* It will scan for entity records in a view-area and emit them in batches.
|
|
16340
|
+
* It will restart scanning if the camera moves.
|
|
16341
|
+
*/
|
|
16342
|
+
var EntityFilterGetter;
|
|
16343
|
+
(function (EntityFilterGetter) {
|
|
16344
|
+
let EStatus;
|
|
16345
|
+
(function (EStatus) {
|
|
16346
|
+
EStatus["Scanning"] = "SCANNING";
|
|
16347
|
+
EStatus["Loading"] = "LOADING";
|
|
16348
|
+
})(EStatus = EntityFilterGetter.EStatus || (EntityFilterGetter.EStatus = {}));
|
|
16349
|
+
class Getter {
|
|
16350
|
+
get OnUpdate() {
|
|
16351
|
+
if (!this.onUpdate) {
|
|
16352
|
+
this.onUpdate = new BruceEvent();
|
|
16353
|
+
}
|
|
16354
|
+
return this.onUpdate;
|
|
16207
16355
|
}
|
|
16208
|
-
get
|
|
16209
|
-
|
|
16356
|
+
get OnStateUpdate() {
|
|
16357
|
+
if (!this.onStateUpdate) {
|
|
16358
|
+
this.onStateUpdate = new BruceEvent();
|
|
16359
|
+
}
|
|
16360
|
+
return this.onStateUpdate;
|
|
16210
16361
|
}
|
|
16211
|
-
get
|
|
16212
|
-
|
|
16362
|
+
get OnScanUpdate() {
|
|
16363
|
+
if (!this.onScanUpdate) {
|
|
16364
|
+
this.onScanUpdate = new BruceEvent();
|
|
16365
|
+
}
|
|
16366
|
+
return this.onScanUpdate;
|
|
16213
16367
|
}
|
|
16214
|
-
get
|
|
16215
|
-
return this.
|
|
16368
|
+
get isLooping() {
|
|
16369
|
+
return this.looping > 0;
|
|
16216
16370
|
}
|
|
16217
|
-
|
|
16218
|
-
|
|
16219
|
-
|
|
16220
|
-
this.
|
|
16371
|
+
constructor(params) {
|
|
16372
|
+
this.onUpdate = null;
|
|
16373
|
+
this.LastStateUpdates = {};
|
|
16374
|
+
this.onStateUpdate = null;
|
|
16375
|
+
this.onScanUpdate = null;
|
|
16376
|
+
this.viewPortChangeRemoval = null;
|
|
16377
|
+
this.viewPortDelayQueue = null;
|
|
16378
|
+
this.viewerDateTimeChangeRemoval = null;
|
|
16379
|
+
this.cells = null;
|
|
16380
|
+
this.registeredItems = {};
|
|
16381
|
+
this.getterLoopId = 0;
|
|
16382
|
+
this.getterLoopAbortControllers = {};
|
|
16383
|
+
this.looping = 0;
|
|
16384
|
+
this.tagIds = null;
|
|
16385
|
+
this.minHeight = 0;
|
|
16386
|
+
this.maxHeight = 100000;
|
|
16387
|
+
this.viewRect = null;
|
|
16388
|
+
this.viewCenter = null;
|
|
16389
|
+
this.scenario = 0;
|
|
16390
|
+
this.historicRefreshAbortController = null;
|
|
16391
|
+
// Entity IDs found for the latest integrity.
|
|
16392
|
+
// We use this for refreshing historic data without having to repeat geographic queries.
|
|
16393
|
+
this.gatheredIntegrity = null;
|
|
16394
|
+
this.gatheredEntityIds = [];
|
|
16395
|
+
const { api, viewer, viewPort, typeIds, schemaId, batchSize, attrFilter, historicAttrKey, historicInterpolation, historic, viaCdn, scenario } = params;
|
|
16221
16396
|
this.api = api;
|
|
16222
|
-
this.
|
|
16223
|
-
this.
|
|
16224
|
-
this.menuItemId = menuItemId;
|
|
16397
|
+
this.typeIds = typeIds;
|
|
16398
|
+
this.schemaId = schemaId;
|
|
16225
16399
|
this.historic = Boolean(historic);
|
|
16226
|
-
|
|
16227
|
-
|
|
16228
|
-
|
|
16229
|
-
|
|
16230
|
-
|
|
16231
|
-
|
|
16232
|
-
|
|
16233
|
-
|
|
16234
|
-
|
|
16235
|
-
// Dereference.
|
|
16236
|
-
this.styleMapping = JSON.parse(JSON.stringify(this.styleMapping));
|
|
16237
|
-
}
|
|
16238
|
-
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
16239
|
-
// We have some evil hard-coded style mappings that need to be fixed.
|
|
16240
|
-
// These exist within legacy project views.
|
|
16241
|
-
// Update: This now also lets people have a style mapping without a real style record.
|
|
16242
|
-
if ((_a = this.styleMapping) === null || _a === void 0 ? void 0 : _a.length) {
|
|
16243
|
-
for (let i = 0; i < this.styleMapping.length; i++) {
|
|
16244
|
-
const mapItem = this.styleMapping[i];
|
|
16245
|
-
const mapStyle = mapItem.style ? mapItem.style : mapItem.Style;
|
|
16246
|
-
this.styleMapping[i].style = correctStyle(mapStyle);
|
|
16247
|
-
}
|
|
16248
|
-
}
|
|
16249
|
-
}
|
|
16250
|
-
if (scenario != null) {
|
|
16251
|
-
this.scenario = scenario;
|
|
16252
|
-
}
|
|
16253
|
-
if (!!scenario) {
|
|
16254
|
-
this.shouldUpdateRegoStates = true;
|
|
16255
|
-
}
|
|
16256
|
-
else if (this.historic) {
|
|
16257
|
-
this.shouldUpdateRegoStates = true;
|
|
16258
|
-
}
|
|
16259
|
-
this.loadStyles();
|
|
16260
|
-
this.viewerDateTimeSub();
|
|
16261
|
-
this.loaded = true;
|
|
16400
|
+
this.historicAttrKey = historicAttrKey;
|
|
16401
|
+
this.historicInterpolation = Boolean(historicInterpolation);
|
|
16402
|
+
this.viaCdn = Boolean(viaCdn);
|
|
16403
|
+
this.batchSize = isNaN(batchSize) ? 300 : batchSize;
|
|
16404
|
+
this.viewPort = viewPort;
|
|
16405
|
+
this.attrFilter = attrFilter;
|
|
16406
|
+
this.viewer = viewer;
|
|
16407
|
+
this.scenario = scenario ? scenario : 0;
|
|
16408
|
+
this.updateBounds();
|
|
16262
16409
|
}
|
|
16263
16410
|
/**
|
|
16264
|
-
*
|
|
16265
|
-
*
|
|
16266
|
-
* @
|
|
16411
|
+
* Returns id that represents the combined menu item parameters.
|
|
16412
|
+
* If integrity changes while a request is running, the request will not emit a response.
|
|
16413
|
+
* @returns
|
|
16267
16414
|
*/
|
|
16268
|
-
|
|
16269
|
-
|
|
16270
|
-
if (
|
|
16271
|
-
|
|
16272
|
-
|
|
16273
|
-
this.styleMapping = params.styleMapping;
|
|
16274
|
-
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
16275
|
-
// We have some evil hard-coded style mappings that need to be fixed.
|
|
16276
|
-
// These exist within legacy project views.
|
|
16277
|
-
// Update: This now also lets people have a style mapping without a real style record.
|
|
16278
|
-
if ((_a = this.styleMapping) === null || _a === void 0 ? void 0 : _a.length) {
|
|
16279
|
-
for (let i = 0; i < this.styleMapping.length; i++) {
|
|
16280
|
-
const mapItem = this.styleMapping[i];
|
|
16281
|
-
const mapStyle = mapItem.style ? mapItem.style : mapItem.Style;
|
|
16282
|
-
this.styleMapping[i].style = correctStyle(mapStyle);
|
|
16283
|
-
}
|
|
16284
|
-
}
|
|
16285
|
-
}
|
|
16286
|
-
if (!isNaN(params.fallbackStyleId) && params.fallbackStyleId != null) {
|
|
16287
|
-
this.fallbackStyleId = params.fallbackStyleId;
|
|
16288
|
-
}
|
|
16289
|
-
if (params.fallbackStyle) {
|
|
16290
|
-
this.fallbackStyle = params.fallbackStyle;
|
|
16291
|
-
}
|
|
16292
|
-
else {
|
|
16293
|
-
this.fallbackStyle = null;
|
|
16294
|
-
}
|
|
16295
|
-
if (params.expandSources != null) {
|
|
16296
|
-
this.expandSources = params.expandSources;
|
|
16415
|
+
getIntegrityId() {
|
|
16416
|
+
let integrity = this.tagIds == null ? "" : this.tagIds.join();
|
|
16417
|
+
if (this.historicAttrKey) {
|
|
16418
|
+
integrity += "isHistoric";
|
|
16419
|
+
integrity += this.historicAttrKey;
|
|
16297
16420
|
}
|
|
16298
|
-
if (
|
|
16299
|
-
|
|
16300
|
-
if (!this.shouldUpdateRegoStates && !!this.scenario) {
|
|
16301
|
-
this.shouldUpdateRegoStates = true;
|
|
16302
|
-
}
|
|
16421
|
+
else if (this.historic) {
|
|
16422
|
+
integrity += "isHistoric";
|
|
16303
16423
|
}
|
|
16304
|
-
if (
|
|
16305
|
-
|
|
16306
|
-
if (params.historic || this.historic != params.historic) {
|
|
16307
|
-
this.shouldUpdateRegoStates = true;
|
|
16308
|
-
}
|
|
16309
|
-
if (params.historic) {
|
|
16310
|
-
this.viewerDateTimeSub();
|
|
16311
|
-
}
|
|
16312
|
-
else {
|
|
16313
|
-
this.viewerDateTimeDispose();
|
|
16314
|
-
}
|
|
16424
|
+
if (this.scenario) {
|
|
16425
|
+
integrity += this.scenario;
|
|
16315
16426
|
}
|
|
16316
|
-
if (this.
|
|
16317
|
-
|
|
16318
|
-
// Requeue all.
|
|
16319
|
-
this.recordLoadQueue = [];
|
|
16320
|
-
this.recordCheckQueue = [];
|
|
16321
|
-
const regos = this.register.GetRegos({
|
|
16322
|
-
menuItemId: this.menuItemId
|
|
16323
|
-
});
|
|
16324
|
-
// Reset progress.
|
|
16325
|
-
this._styleProgressQueue.Call(true);
|
|
16326
|
-
this.styleMappingLoaded = false;
|
|
16327
|
-
this.styleMappingsLoaded = {};
|
|
16328
|
-
this.QueueEntities(regos);
|
|
16329
|
-
this.loadStyles();
|
|
16427
|
+
if (this.typeIds) {
|
|
16428
|
+
integrity += this.typeIds.join();
|
|
16330
16429
|
}
|
|
16430
|
+
return integrity;
|
|
16431
|
+
}
|
|
16432
|
+
viewAreaSub() {
|
|
16433
|
+
this.viewAreaDispose();
|
|
16434
|
+
// We'll avoid restarting the scanner too often.
|
|
16435
|
+
this.viewPortDelayQueue = new DelayQueue(() => {
|
|
16436
|
+
this.updateBounds();
|
|
16437
|
+
this.startGetterLoop();
|
|
16438
|
+
}, 2000);
|
|
16439
|
+
this.viewPortChangeRemoval = this.viewPort.Updated().Subscribe(() => {
|
|
16440
|
+
var _a;
|
|
16441
|
+
(_a = this.viewPortDelayQueue) === null || _a === void 0 ? void 0 : _a.Call();
|
|
16442
|
+
});
|
|
16443
|
+
}
|
|
16444
|
+
viewAreaDispose() {
|
|
16445
|
+
var _a, _b;
|
|
16446
|
+
(_a = this.viewPortChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
16447
|
+
this.viewPortChangeRemoval = null;
|
|
16448
|
+
(_b = this.viewPortDelayQueue) === null || _b === void 0 ? void 0 : _b.Dispose();
|
|
16449
|
+
this.viewPortDelayQueue = null;
|
|
16331
16450
|
}
|
|
16332
16451
|
/**
|
|
16333
|
-
*
|
|
16334
|
-
*
|
|
16335
|
-
* @param entityIds
|
|
16336
|
-
* @param entities If an object is not available for a supplied Entity ID, then the cache for it is removed.
|
|
16452
|
+
* Monitors the Cesium viewer and updates the historic data filter values.
|
|
16453
|
+
* If there is no historic attr set, this will do nothing.
|
|
16337
16454
|
*/
|
|
16338
|
-
|
|
16339
|
-
|
|
16340
|
-
|
|
16341
|
-
|
|
16342
|
-
|
|
16343
|
-
|
|
16344
|
-
|
|
16345
|
-
|
|
16455
|
+
viewerDateTimeSub() {
|
|
16456
|
+
if ((!this.historicAttrKey && !this.historic) || this.viewerDateTimeChangeRemoval) {
|
|
16457
|
+
return;
|
|
16458
|
+
}
|
|
16459
|
+
// This is multiplied by the speed of animation to figure
|
|
16460
|
+
// out how many animation "ticks" before we allow an update.
|
|
16461
|
+
let INTERVAL_WHILE_ANIMATING = 2.5 * 1000;
|
|
16462
|
+
let INTERVAL_WHILE_NOT_ANIMATING = 1000;
|
|
16463
|
+
if (this.historicInterpolation) {
|
|
16464
|
+
INTERVAL_WHILE_ANIMATING = 6 * 1000;
|
|
16465
|
+
INTERVAL_WHILE_NOT_ANIMATING = 3.5 * 1000;
|
|
16466
|
+
}
|
|
16467
|
+
let lastUpdateTime = null;
|
|
16468
|
+
let delayQueue = new DelayQueue(() => {
|
|
16469
|
+
try {
|
|
16470
|
+
// If the timeline is animating then we'll wait longer to update.
|
|
16471
|
+
if (this.viewer.clock.shouldAnimate && lastUpdateTime) {
|
|
16472
|
+
if (Math.abs(new Date().getTime() - lastUpdateTime) < INTERVAL_WHILE_ANIMATING) {
|
|
16473
|
+
return;
|
|
16474
|
+
}
|
|
16475
|
+
}
|
|
16476
|
+
const current = this.historicAttrDateTime;
|
|
16477
|
+
this.updateHistoricDateTime();
|
|
16478
|
+
if (current != this.historicAttrDateTime) {
|
|
16479
|
+
this.emitHistoricData();
|
|
16346
16480
|
}
|
|
16347
16481
|
}
|
|
16348
|
-
|
|
16349
|
-
|
|
16350
|
-
for (let i = 0; i < entityIds.length; i++) {
|
|
16351
|
-
const entityId = entityIds[i];
|
|
16352
|
-
if (newDataMap[entityId]) {
|
|
16353
|
-
this.entityDataCache[entityId] = newDataMap[entityId];
|
|
16482
|
+
catch (e) {
|
|
16483
|
+
console.error(e);
|
|
16354
16484
|
}
|
|
16355
|
-
|
|
16356
|
-
|
|
16485
|
+
}, INTERVAL_WHILE_NOT_ANIMATING);
|
|
16486
|
+
let postUpdateRemoval = this.viewer.scene.postUpdate.addEventListener(() => {
|
|
16487
|
+
if (delayQueue) {
|
|
16488
|
+
delayQueue.Call();
|
|
16357
16489
|
}
|
|
16358
|
-
}
|
|
16490
|
+
});
|
|
16491
|
+
this.viewerDateTimeChangeRemoval = () => {
|
|
16492
|
+
delayQueue === null || delayQueue === void 0 ? void 0 : delayQueue.Dispose();
|
|
16493
|
+
postUpdateRemoval === null || postUpdateRemoval === void 0 ? void 0 : postUpdateRemoval();
|
|
16494
|
+
delayQueue = null;
|
|
16495
|
+
postUpdateRemoval = null;
|
|
16496
|
+
};
|
|
16359
16497
|
}
|
|
16360
|
-
|
|
16361
|
-
if (!this.
|
|
16498
|
+
updateHistoricDateTime() {
|
|
16499
|
+
if (!this.historicAttrKey && !this.historic) {
|
|
16500
|
+
this.historicAttrDateTime = null;
|
|
16362
16501
|
return;
|
|
16363
16502
|
}
|
|
16364
|
-
|
|
16365
|
-
|
|
16366
|
-
|
|
16367
|
-
|
|
16368
|
-
|
|
16369
|
-
|
|
16370
|
-
|
|
16371
|
-
|
|
16372
|
-
|
|
16373
|
-
}
|
|
16374
|
-
|
|
16375
|
-
|
|
16376
|
-
|
|
16377
|
-
|
|
16378
|
-
if (this.recordLoadQueue.length > 0) {
|
|
16379
|
-
this.processQueue();
|
|
16503
|
+
const isChanged = (before, after) => {
|
|
16504
|
+
if (before && !after) {
|
|
16505
|
+
return true;
|
|
16506
|
+
}
|
|
16507
|
+
if (!before && after) {
|
|
16508
|
+
return true;
|
|
16509
|
+
}
|
|
16510
|
+
// Change must be at least 0.1 seconds.
|
|
16511
|
+
return Math.abs(before.getTime() - after.getTime()) > 100;
|
|
16512
|
+
};
|
|
16513
|
+
const oldDateTime = this.historicAttrDateTime ? new Date(this.historicAttrDateTime) : null;
|
|
16514
|
+
const newDateTime = JulianDate.toDate(this.viewer.clock.currentTime);
|
|
16515
|
+
if (isChanged(oldDateTime, newDateTime)) {
|
|
16516
|
+
this.historicAttrDateTime = newDateTime.toISOString();
|
|
16380
16517
|
}
|
|
16381
16518
|
}
|
|
16382
|
-
|
|
16383
|
-
var _a
|
|
16384
|
-
|
|
16385
|
-
|
|
16386
|
-
|
|
16387
|
-
|
|
16388
|
-
|
|
16389
|
-
|
|
16390
|
-
|
|
16519
|
+
viewerDateTimeDispose() {
|
|
16520
|
+
var _a;
|
|
16521
|
+
(_a = this.viewerDateTimeChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
16522
|
+
this.viewerDateTimeChangeRemoval = null;
|
|
16523
|
+
}
|
|
16524
|
+
GetMenuItems() {
|
|
16525
|
+
return Object.keys(this.registeredItems);
|
|
16526
|
+
}
|
|
16527
|
+
IncludeMenuItem(menuItemId, typeId, layerIds, minHeight, maxHeight) {
|
|
16528
|
+
this.registeredItems[menuItemId] = new regMenuItemGetter(typeId, layerIds, minHeight, maxHeight);
|
|
16529
|
+
this.updateState();
|
|
16530
|
+
}
|
|
16531
|
+
ExcludeMenuItem(menuItemId) {
|
|
16532
|
+
this.registeredItems[menuItemId] = null;
|
|
16533
|
+
delete this.registeredItems[menuItemId];
|
|
16534
|
+
this.updateState(true);
|
|
16535
|
+
}
|
|
16536
|
+
updateBounds() {
|
|
16537
|
+
const viewRect = this.viewPort.GetBounds();
|
|
16538
|
+
const poi = this.viewPort.GetTarget();
|
|
16539
|
+
if (viewRect && poi) {
|
|
16540
|
+
if (Math.abs(viewRect.west - viewRect.east) > MAX_AREA_IN_DEGREES$1) {
|
|
16541
|
+
return;
|
|
16542
|
+
}
|
|
16543
|
+
if (Math.abs(viewRect.south - viewRect.north) > MAX_AREA_IN_DEGREES$1) {
|
|
16544
|
+
return;
|
|
16545
|
+
}
|
|
16546
|
+
this.viewRect = viewRect;
|
|
16547
|
+
this.viewCenter = poi;
|
|
16391
16548
|
}
|
|
16392
|
-
|
|
16393
|
-
|
|
16394
|
-
|
|
16395
|
-
|
|
16396
|
-
|
|
16397
|
-
|
|
16398
|
-
|
|
16399
|
-
|
|
16400
|
-
|
|
16401
|
-
|
|
16402
|
-
|
|
16403
|
-
|
|
16404
|
-
const entityId = batch[i];
|
|
16405
|
-
const entity = this.entityDataCache[entityId];
|
|
16406
|
-
if (entity) {
|
|
16407
|
-
entities.push(entity);
|
|
16408
|
-
}
|
|
16409
|
-
else {
|
|
16410
|
-
batchToRequest.push(entityId);
|
|
16411
|
-
}
|
|
16412
|
-
}
|
|
16413
|
-
if (batchToRequest.length) {
|
|
16414
|
-
const dateTime = this.historic ? this.historicAttrDateTime : null;
|
|
16415
|
-
const { entities: response } = await Entity$1.GetListByIds({
|
|
16416
|
-
api: this.api,
|
|
16417
|
-
entityIds: batchToRequest,
|
|
16418
|
-
migrated: true,
|
|
16419
|
-
expandSources: this.expandSources,
|
|
16420
|
-
scenario: this.scenario,
|
|
16421
|
-
historicPoint: dateTime
|
|
16422
|
-
});
|
|
16423
|
-
// See if the historic date is the same.
|
|
16424
|
-
// If not, then we have to re-add the Entities to the queue and re-run.
|
|
16425
|
-
const curDateTime = this.historic ? this.historicAttrDateTime : null;
|
|
16426
|
-
if (curDateTime == dateTime) {
|
|
16427
|
-
// Add all found Entities to the list.
|
|
16428
|
-
entities.push(...response);
|
|
16429
|
-
}
|
|
16430
|
-
else {
|
|
16431
|
-
rerun = true;
|
|
16432
|
-
}
|
|
16433
|
-
}
|
|
16549
|
+
}
|
|
16550
|
+
updateState(onlyIfLooping = false) {
|
|
16551
|
+
const tagIds = [];
|
|
16552
|
+
const typeIds = [];
|
|
16553
|
+
const menuItemIds = this.GetMenuItems();
|
|
16554
|
+
let minHeight = null;
|
|
16555
|
+
let maxHeight = null;
|
|
16556
|
+
for (let i = 0; i < menuItemIds.length; i++) {
|
|
16557
|
+
const menuItem = this.registeredItems[menuItemIds[i]];
|
|
16558
|
+
if (menuItem) {
|
|
16559
|
+
if (maxHeight == null || maxHeight < menuItem.MaxHeight) {
|
|
16560
|
+
maxHeight = menuItem.MaxHeight;
|
|
16434
16561
|
}
|
|
16435
|
-
if (
|
|
16436
|
-
|
|
16562
|
+
if (minHeight == null || minHeight > menuItem.MinHeight) {
|
|
16563
|
+
minHeight = menuItem.MinHeight;
|
|
16437
16564
|
}
|
|
16438
|
-
|
|
16439
|
-
|
|
16440
|
-
|
|
16441
|
-
|
|
16442
|
-
|
|
16443
|
-
|
|
16444
|
-
const entity = entities[i];
|
|
16445
|
-
entityMap[entity.Bruce.ID] = entity;
|
|
16446
|
-
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) {
|
|
16447
|
-
const eTagIds = entity.Bruce["Layer.ID"];
|
|
16448
|
-
for (let j = 0; j < eTagIds.length; j++) {
|
|
16449
|
-
tagIds.push(eTagIds[j]);
|
|
16450
|
-
}
|
|
16565
|
+
const itemLayerIds = menuItem.TagIds;
|
|
16566
|
+
if (itemLayerIds) {
|
|
16567
|
+
for (let j = 0; j < itemLayerIds.length; j++) {
|
|
16568
|
+
const itemLayerId = itemLayerIds[j];
|
|
16569
|
+
if (!tagIds.includes(itemLayerId)) {
|
|
16570
|
+
tagIds.push(itemLayerId);
|
|
16451
16571
|
}
|
|
16452
16572
|
}
|
|
16453
|
-
|
|
16454
|
-
|
|
16455
|
-
|
|
16456
|
-
|
|
16457
|
-
|
|
16458
|
-
let tags = [];
|
|
16459
|
-
if (tagIds.length) {
|
|
16460
|
-
tags = (await EntityTag.GetListByIds({
|
|
16461
|
-
tagIds: tagIds,
|
|
16462
|
-
api: this.api
|
|
16463
|
-
})).tags;
|
|
16464
|
-
}
|
|
16465
|
-
for (let i = 0; i < batch.length; i++) {
|
|
16466
|
-
const entityId = batch[i];
|
|
16467
|
-
const record = entityMap[entityId];
|
|
16468
|
-
const feature = this.getEntityRego(entityId);
|
|
16469
|
-
if (feature) {
|
|
16470
|
-
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)); });
|
|
16471
|
-
this.styleTilesetFeatureFullData(feature, record, eTags);
|
|
16472
|
-
}
|
|
16573
|
+
}
|
|
16574
|
+
const itemTypeId = menuItem.TypeId;
|
|
16575
|
+
if (itemTypeId) {
|
|
16576
|
+
if (!typeIds.includes(itemTypeId)) {
|
|
16577
|
+
typeIds.push(itemTypeId);
|
|
16473
16578
|
}
|
|
16474
|
-
rerun = rerun || batch.length > 0;
|
|
16475
|
-
this.viewer.scene.requestRender();
|
|
16476
16579
|
}
|
|
16477
16580
|
}
|
|
16478
16581
|
}
|
|
16479
|
-
|
|
16480
|
-
|
|
16481
|
-
|
|
16482
|
-
|
|
16483
|
-
|
|
16484
|
-
|
|
16485
|
-
|
|
16486
|
-
|
|
16487
|
-
|
|
16488
|
-
|
|
16489
|
-
|
|
16490
|
-
|
|
16491
|
-
return this.recordLoadQueue.splice(0, BATCH_SIZE);
|
|
16492
|
-
}
|
|
16493
|
-
/**
|
|
16494
|
-
* Calculates the current progress % and updates the progress if there is a change.
|
|
16495
|
-
*/
|
|
16496
|
-
updateStyleProgress() {
|
|
16497
|
-
if (this.disposed) {
|
|
16498
|
-
return;
|
|
16499
|
-
}
|
|
16500
|
-
let progress = 100; // Done when idling.
|
|
16501
|
-
if (this.recordCheckQueue.length || this.recordLoadQueue.length) {
|
|
16502
|
-
const total = Object.keys(this.styledEntityIds).length;
|
|
16503
|
-
// Done is the total minus the amount left.
|
|
16504
|
-
// We have to ensure the same ID isn't counted within or across these arrays as well.
|
|
16505
|
-
const uniqueSet = new Set(this.recordCheckQueue.concat(this.recordLoadQueue));
|
|
16506
|
-
const done = total - uniqueSet.size;
|
|
16507
|
-
progress = done / total * 100;
|
|
16508
|
-
// Round to 2dp, 0, or 100.
|
|
16509
|
-
if (progress < 0) {
|
|
16510
|
-
progress = 0;
|
|
16511
|
-
}
|
|
16512
|
-
else if (progress < 100) {
|
|
16513
|
-
progress = Math.round(progress * 100) / 100;
|
|
16514
|
-
}
|
|
16515
|
-
else if (progress > 100) {
|
|
16516
|
-
progress = 100;
|
|
16517
|
-
}
|
|
16582
|
+
if (menuItemIds.length > 0 && (!onlyIfLooping || this.isLooping)) {
|
|
16583
|
+
// Reset cells so none are marked as fetched.
|
|
16584
|
+
this.cells = new EntityGlobe.Grid();
|
|
16585
|
+
this.tagIds = tagIds;
|
|
16586
|
+
this.typeIds = typeIds;
|
|
16587
|
+
this.minHeight = minHeight;
|
|
16588
|
+
this.maxHeight = maxHeight;
|
|
16589
|
+
this.updateBounds();
|
|
16590
|
+
this.updateHistoricDateTime();
|
|
16591
|
+
this.startGetterLoop();
|
|
16592
|
+
this.viewAreaSub();
|
|
16593
|
+
this.viewerDateTimeSub();
|
|
16518
16594
|
}
|
|
16519
|
-
|
|
16520
|
-
this.
|
|
16521
|
-
this.
|
|
16595
|
+
else {
|
|
16596
|
+
this.getterLoopId += 1;
|
|
16597
|
+
this.viewAreaDispose();
|
|
16598
|
+
this.viewerDateTimeDispose();
|
|
16522
16599
|
}
|
|
16523
16600
|
}
|
|
16524
|
-
|
|
16525
|
-
|
|
16526
|
-
|
|
16527
|
-
|
|
16528
|
-
});
|
|
16529
|
-
}
|
|
16530
|
-
Dispose() {
|
|
16531
|
-
if (this.disposed) {
|
|
16532
|
-
return;
|
|
16533
|
-
}
|
|
16534
|
-
this.disposed = true;
|
|
16535
|
-
clearInterval(this.queueLoadInterval);
|
|
16536
|
-
clearInterval(this.queueCheckInterval);
|
|
16537
|
-
this._styleProgressQueue.Dispose();
|
|
16538
|
-
this.viewerDateTimeDispose();
|
|
16601
|
+
postStatus(status) {
|
|
16602
|
+
var _a;
|
|
16603
|
+
this.LastStateUpdates[status.msg] = status;
|
|
16604
|
+
(_a = this.onStateUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(status);
|
|
16539
16605
|
}
|
|
16540
|
-
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
|
|
16544
|
-
|
|
16545
|
-
|
|
16546
|
-
|
|
16547
|
-
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
this.
|
|
16553
|
-
}
|
|
16554
|
-
catch (e) {
|
|
16555
|
-
console.error(e);
|
|
16606
|
+
startGetterLoop() {
|
|
16607
|
+
// Increase id so that existing loops stop.
|
|
16608
|
+
this.getterLoopId += 1;
|
|
16609
|
+
const loopId = this.getterLoopId;
|
|
16610
|
+
const loopIntegrity = this.getIntegrityId();
|
|
16611
|
+
// Abort any existing loops that don't match the current loop.
|
|
16612
|
+
// We tried using integrity, however we want to interrupt when user moves camera quickly.
|
|
16613
|
+
// So it's better to use the loop ID.
|
|
16614
|
+
const abortId = String(loopId);
|
|
16615
|
+
{
|
|
16616
|
+
const newAbortControllers = {};
|
|
16617
|
+
for (const key in this.getterLoopAbortControllers) {
|
|
16618
|
+
this.getterLoopAbortControllers[key].abort();
|
|
16556
16619
|
}
|
|
16620
|
+
this.getterLoopAbortControllers = newAbortControllers;
|
|
16557
16621
|
}
|
|
16558
|
-
|
|
16559
|
-
|
|
16560
|
-
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
|
|
16565
|
-
|
|
16566
|
-
|
|
16567
|
-
|
|
16568
|
-
|
|
16569
|
-
|
|
16570
|
-
|
|
16571
|
-
|
|
16572
|
-
|
|
16573
|
-
|
|
16574
|
-
|
|
16575
|
-
|
|
16576
|
-
styleMapping.push({
|
|
16577
|
-
EntityTypeID: entityTypeId,
|
|
16578
|
-
StyleID: this.fallbackStyle ? fallbackStyleId : 0,
|
|
16579
|
-
style: this.fallbackStyle
|
|
16580
|
-
});
|
|
16581
|
-
}
|
|
16582
|
-
}
|
|
16622
|
+
const abortController = this.getterLoopAbortControllers[abortId] = new AbortController();
|
|
16623
|
+
this.looping += 1;
|
|
16624
|
+
(async () => {
|
|
16625
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
16626
|
+
// Larger initial delay for the first loops because terrain is likely loading in.
|
|
16627
|
+
// We also delay because if we enable 50 Menu Items at the same time, common requests we be made if we wait a bit.
|
|
16628
|
+
// Eg: same entity type will be grouped into the same filter getter instance.
|
|
16629
|
+
await delay(loopId <= 3 ? 800 : 300);
|
|
16630
|
+
const MIN_HEIGHT = this.minHeight;
|
|
16631
|
+
const MAX_HEIGHT = this.maxHeight;
|
|
16632
|
+
const PAGE_SIZE = this.batchSize;
|
|
16633
|
+
let retryAttempts = MAX_RETRY_ATTEMPTS;
|
|
16634
|
+
let retryDelay = 0;
|
|
16635
|
+
let prevFirstId = "";
|
|
16636
|
+
let prevLastId = "";
|
|
16637
|
+
let prevTicks = 0;
|
|
16638
|
+
while ((!this.viewCenter || !this.viewRect) && this.getterLoopId == loopId) {
|
|
16639
|
+
await delay(RETRY_DELAY_INCREMENT);
|
|
16583
16640
|
}
|
|
16584
|
-
|
|
16585
|
-
|
|
16586
|
-
console.error(e);
|
|
16587
|
-
}
|
|
16588
|
-
// Before we start the loop we'll do a single request for the needed Entity Types.
|
|
16589
|
-
// This will be aimed at rows that don't specify a Style and if the default fallback-
|
|
16590
|
-
//is set to 0 (using the default of the Entity Type).
|
|
16591
|
-
const typeMap = new Map();
|
|
16592
|
-
const typeIds = styleMapping.map(x => x.StyleID == -1 || Boolean(x.style) ? null : x.EntityTypeID).filter(x => !!x);
|
|
16593
|
-
if (typeIds.length) {
|
|
16594
|
-
// We'll split up into batches of 50.
|
|
16595
|
-
// Since we add the type IDs as query params I am paranoid of hitting the limit.
|
|
16596
|
-
const splits = Math.ceil(typeIds.length / 50);
|
|
16597
|
-
const batchSize = 50;
|
|
16598
|
-
for (let i = 0; i < splits; i++) {
|
|
16599
|
-
const batch = typeIds.slice(i * batchSize, (i + 1) * batchSize);
|
|
16600
|
-
const { entityTypes } = await EntityType.GetList({
|
|
16601
|
-
api: this.api,
|
|
16602
|
-
entityTypeIds: batch
|
|
16603
|
-
});
|
|
16604
|
-
for (let i = 0; i < entityTypes.length; i++) {
|
|
16605
|
-
const entityType = entityTypes[i];
|
|
16606
|
-
typeMap.set(entityType.ID, entityType);
|
|
16607
|
-
}
|
|
16641
|
+
if (this.getterLoopId != loopId) {
|
|
16642
|
+
return;
|
|
16608
16643
|
}
|
|
16609
|
-
|
|
16610
|
-
|
|
16611
|
-
|
|
16612
|
-
break;
|
|
16644
|
+
const alt = this.viewRect.alt;
|
|
16645
|
+
if (alt > MAX_HEIGHT || (alt < MIN_HEIGHT && MIN_HEIGHT > 0)) {
|
|
16646
|
+
return;
|
|
16613
16647
|
}
|
|
16614
|
-
|
|
16615
|
-
|
|
16616
|
-
|
|
16617
|
-
|
|
16618
|
-
|
|
16619
|
-
|
|
16620
|
-
|
|
16621
|
-
|
|
16622
|
-
|
|
16623
|
-
|
|
16624
|
-
|
|
16648
|
+
const cells = this.cells.GetCellsForView(this.viewCenter, this.viewRect);
|
|
16649
|
+
(_a = this.onScanUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(cells);
|
|
16650
|
+
let curCellIndex = cells.length > 0 ? 0 : null;
|
|
16651
|
+
let postedScanning = false;
|
|
16652
|
+
let postedLoading = false;
|
|
16653
|
+
let total = 0;
|
|
16654
|
+
while (retryAttempts > 0 && curCellIndex != null) {
|
|
16655
|
+
if (retryDelay > 0) {
|
|
16656
|
+
await delay(retryDelay);
|
|
16657
|
+
}
|
|
16658
|
+
if (this.getterLoopId != loopId) {
|
|
16659
|
+
break;
|
|
16660
|
+
}
|
|
16661
|
+
if (!postedScanning) {
|
|
16662
|
+
this.postStatus({ msg: EStatus.Scanning, revoking: false });
|
|
16663
|
+
postedScanning = true;
|
|
16664
|
+
}
|
|
16665
|
+
const curCell = cells[curCellIndex];
|
|
16666
|
+
if (curCell.IsFetched()) {
|
|
16667
|
+
curCell.Fetching = false;
|
|
16668
|
+
curCellIndex += 1;
|
|
16669
|
+
if (cells[curCellIndex]) {
|
|
16670
|
+
cells[curCellIndex].Fetching = true;
|
|
16671
|
+
}
|
|
16672
|
+
else {
|
|
16673
|
+
curCellIndex = null;
|
|
16674
|
+
}
|
|
16675
|
+
(_b = this.onScanUpdate) === null || _b === void 0 ? void 0 : _b.Trigger(cells);
|
|
16676
|
+
continue;
|
|
16677
|
+
}
|
|
16678
|
+
try {
|
|
16679
|
+
let response = {
|
|
16680
|
+
entities: [],
|
|
16681
|
+
nextPage: false,
|
|
16682
|
+
nextPageUrl: null
|
|
16683
|
+
};
|
|
16684
|
+
await SharedGetters.Queue.Run("Loading Entities from Menu Item that loads Entity Type: " + this.typeIds, async () => {
|
|
16685
|
+
var _a;
|
|
16686
|
+
if (abortController.signal.aborted || !((_a = this.GetMenuItems()) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
16687
|
+
return;
|
|
16688
|
+
}
|
|
16689
|
+
// API gave us a URL to use.
|
|
16690
|
+
if (curCell.FetchURL) {
|
|
16691
|
+
const tmpResponse = await this.api.get(curCell.FetchURL, {
|
|
16692
|
+
abortSignal: abortController.signal,
|
|
16693
|
+
noCache: true
|
|
16694
|
+
});
|
|
16695
|
+
// Same mapping as bruce-models doing Entity.GetList.
|
|
16696
|
+
response = {
|
|
16697
|
+
entities: tmpResponse.Items ? tmpResponse.Items : [],
|
|
16698
|
+
nextPage: tmpResponse.NextPage,
|
|
16699
|
+
nextPageUrl: tmpResponse.NextPageURL
|
|
16700
|
+
};
|
|
16701
|
+
}
|
|
16702
|
+
else {
|
|
16703
|
+
response = await Entity$1.GetList({
|
|
16625
16704
|
api: this.api,
|
|
16626
|
-
|
|
16627
|
-
|
|
16705
|
+
scenario: this.scenario,
|
|
16706
|
+
historicKey: this.historicAttrKey,
|
|
16707
|
+
historicPoint: (this.historicAttrKey || this.historic) ? this.historicAttrDateTime : null,
|
|
16708
|
+
schemaId: this.schemaId,
|
|
16709
|
+
filter: {
|
|
16710
|
+
pageSize: PAGE_SIZE,
|
|
16711
|
+
pageIndex: curCell.FetchPageIndex,
|
|
16712
|
+
entityTypeId: this.typeIds,
|
|
16713
|
+
layerIds: this.tagIds,
|
|
16714
|
+
// Any tag specified will be allowed.
|
|
16715
|
+
layerIdsOperator: "in",
|
|
16716
|
+
bounds: curCell.GetBounds(),
|
|
16717
|
+
sortOrder: Api.ESortOrder.Asc,
|
|
16718
|
+
entityTypeConditions: this.attrFilter
|
|
16719
|
+
},
|
|
16720
|
+
viaCdn: this.viaCdn,
|
|
16721
|
+
migrated: true,
|
|
16722
|
+
// If we're taking 2+ minutes to make a query, it's a dud.
|
|
16723
|
+
// This is a timeout imposed on our DB and not external sources.
|
|
16724
|
+
// Honestly could lower down to 30 seconds, but we'll keep it high for now.
|
|
16725
|
+
maxSearchTimeSec: 60 * 2,
|
|
16726
|
+
req: {
|
|
16727
|
+
// If we are passing in an abort, we MUST pass in noCache.
|
|
16728
|
+
// Otherwise we will cache an aborted request.
|
|
16729
|
+
noCache: true,
|
|
16730
|
+
abortSignal: abortController.signal
|
|
16731
|
+
}
|
|
16732
|
+
});
|
|
16628
16733
|
}
|
|
16629
|
-
|
|
16734
|
+
});
|
|
16735
|
+
const entities = response.entities;
|
|
16736
|
+
const integrity = this.getIntegrityId();
|
|
16737
|
+
if (loopIntegrity == integrity && entities) {
|
|
16738
|
+
(_c = this.onUpdate) === null || _c === void 0 ? void 0 : _c.Trigger(entities);
|
|
16630
16739
|
}
|
|
16631
|
-
|
|
16632
|
-
|
|
16740
|
+
if (this.gatheredIntegrity != integrity) {
|
|
16741
|
+
this.gatheredIntegrity = integrity;
|
|
16742
|
+
this.gatheredEntityIds = [];
|
|
16743
|
+
}
|
|
16744
|
+
// Add to the integrity list for any new IDs found.
|
|
16745
|
+
// This lets us keep track of all IDs we've found within the same integrity for historic data.
|
|
16746
|
+
if (this.historicAttrKey || this.historic) {
|
|
16747
|
+
for (let i = 0; i < entities.length; i++) {
|
|
16748
|
+
const entity = entities[i];
|
|
16749
|
+
if (!this.gatheredEntityIds.includes(entity.Bruce.ID)) {
|
|
16750
|
+
this.gatheredEntityIds.push(entity.Bruce.ID);
|
|
16751
|
+
}
|
|
16752
|
+
}
|
|
16753
|
+
}
|
|
16754
|
+
if (this.getterLoopId != loopId) {
|
|
16755
|
+
break;
|
|
16756
|
+
}
|
|
16757
|
+
if (entities.length) {
|
|
16758
|
+
total += entities.length;
|
|
16759
|
+
}
|
|
16760
|
+
if (!postedLoading) {
|
|
16761
|
+
this.postStatus({ msg: EStatus.Loading, revoking: false });
|
|
16762
|
+
postedLoading = true;
|
|
16763
|
+
}
|
|
16764
|
+
// Only mark as fetched when ALL pages are done.
|
|
16765
|
+
// Known issue where external sources may return less than page size.
|
|
16766
|
+
// Right now we're making it as fetched as we're siding with the majority use-case.
|
|
16767
|
+
if (
|
|
16768
|
+
// API explicity says no more pages.
|
|
16769
|
+
response.nextPage === false ||
|
|
16770
|
+
// API didn't explicity say anything so we guess based on size of response.
|
|
16771
|
+
(response.nextPage == null &&
|
|
16772
|
+
(entities.length <= 0 || entities.length < PAGE_SIZE))) {
|
|
16773
|
+
curCell.Fetched = true;
|
|
16774
|
+
curCell.Fetching = false;
|
|
16775
|
+
(_d = this.onScanUpdate) === null || _d === void 0 ? void 0 : _d.Trigger(cells);
|
|
16776
|
+
continue;
|
|
16633
16777
|
}
|
|
16634
|
-
|
|
16635
|
-
|
|
16636
|
-
|
|
16637
|
-
|
|
16638
|
-
|
|
16639
|
-
|
|
16640
|
-
|
|
16641
|
-
|
|
16642
|
-
|
|
16643
|
-
|
|
16778
|
+
// Checking to make sure it's not just the same batch over and over again.
|
|
16779
|
+
if (entities.length > 0) {
|
|
16780
|
+
const first = (_f = (_e = entities[0]) === null || _e === void 0 ? void 0 : _e.Bruce) === null || _f === void 0 ? void 0 : _f.ID;
|
|
16781
|
+
const last = (_h = (_g = entities[entities.length - 1]) === null || _g === void 0 ? void 0 : _g.Bruce) === null || _h === void 0 ? void 0 : _h.ID;
|
|
16782
|
+
if (prevFirstId == first && prevLastId == last) {
|
|
16783
|
+
prevTicks += 1;
|
|
16784
|
+
if (prevTicks > 3) {
|
|
16785
|
+
break;
|
|
16786
|
+
}
|
|
16787
|
+
}
|
|
16788
|
+
else {
|
|
16789
|
+
prevFirstId = first;
|
|
16790
|
+
prevLastId = last;
|
|
16791
|
+
prevTicks = 0;
|
|
16644
16792
|
}
|
|
16645
16793
|
}
|
|
16646
|
-
|
|
16647
|
-
|
|
16648
|
-
|
|
16649
|
-
|
|
16650
|
-
|
|
16651
|
-
|
|
16794
|
+
// Using URL if specified.
|
|
16795
|
+
// If not then we'll just manually paginate.
|
|
16796
|
+
curCell.FetchURL = response.nextPageUrl;
|
|
16797
|
+
curCell.FetchPageIndex++;
|
|
16798
|
+
// Request passed so let's assume it was server hiccup and refresh counts.
|
|
16799
|
+
retryAttempts = MAX_RETRY_ATTEMPTS;
|
|
16800
|
+
retryDelay = 0;
|
|
16652
16801
|
}
|
|
16653
|
-
|
|
16654
|
-
|
|
16655
|
-
|
|
16656
|
-
|
|
16657
|
-
|
|
16658
|
-
}
|
|
16659
|
-
}
|
|
16660
|
-
if (this.loadingCounter != counter) {
|
|
16661
|
-
return;
|
|
16662
|
-
}
|
|
16663
|
-
this.styleMappingLoaded = true;
|
|
16664
|
-
if (!this.disposed && this.loaded) {
|
|
16665
|
-
await this.processTilesetFeatureCheckQueue();
|
|
16666
|
-
if (this.loadingCounter != counter) {
|
|
16667
|
-
return;
|
|
16668
|
-
}
|
|
16669
|
-
this.processQueue();
|
|
16670
|
-
}
|
|
16671
|
-
}
|
|
16672
|
-
/**
|
|
16673
|
-
* Monitors the Cesium viewer and updates the historic data filter values.
|
|
16674
|
-
* If there is no historic attr set, this will do nothing.
|
|
16675
|
-
*/
|
|
16676
|
-
viewerDateTimeSub() {
|
|
16677
|
-
if (!this.historic || this.viewerDateTimeChangeRemoval) {
|
|
16678
|
-
return;
|
|
16679
|
-
}
|
|
16680
|
-
// This is multiplied by the speed of animation to figure
|
|
16681
|
-
// out how many animation "ticks" before we allow an update.
|
|
16682
|
-
const INTERVAL_WHILE_ANIMATING = 2.5 * 1000;
|
|
16683
|
-
const INTERVAL_WHILE_NOT_ANIMATING = 1000;
|
|
16684
|
-
let lastUpdateTime = null;
|
|
16685
|
-
let delayQueue = new DelayQueue(() => {
|
|
16686
|
-
try {
|
|
16687
|
-
// If the timeline is animating then we'll wait longer to update.
|
|
16688
|
-
if (this.viewer.clock.shouldAnimate && lastUpdateTime) {
|
|
16689
|
-
if (Math.abs(new Date().getTime() - lastUpdateTime) < INTERVAL_WHILE_ANIMATING) {
|
|
16690
|
-
return;
|
|
16802
|
+
catch (e) {
|
|
16803
|
+
// Ignore abort errors.
|
|
16804
|
+
if (e && typeof e === "object" && e.name == "AbortError") {
|
|
16805
|
+
// console.debug("Aborted entity-filter-getter request.");
|
|
16806
|
+
break;
|
|
16691
16807
|
}
|
|
16808
|
+
console.error(e);
|
|
16809
|
+
if (this.getterLoopId != loopId) {
|
|
16810
|
+
break;
|
|
16811
|
+
}
|
|
16812
|
+
// Request failed so let's add a delay and try again soon.
|
|
16813
|
+
retryDelay += RETRY_DELAY_INCREMENT;
|
|
16814
|
+
retryAttempts -= 1;
|
|
16692
16815
|
}
|
|
16693
|
-
|
|
16694
|
-
this.updateHistoricDateTime();
|
|
16695
|
-
if (current != this.historicAttrDateTime) {
|
|
16696
|
-
this.emitHistoricData();
|
|
16697
|
-
}
|
|
16816
|
+
await delay(REQUEST_PAGE_DELAY);
|
|
16698
16817
|
}
|
|
16699
|
-
|
|
16700
|
-
|
|
16818
|
+
if (postedLoading) {
|
|
16819
|
+
this.postStatus({ msg: EStatus.Loading, revoking: true });
|
|
16701
16820
|
}
|
|
16702
|
-
|
|
16703
|
-
|
|
16704
|
-
if (delayQueue) {
|
|
16705
|
-
delayQueue.Call();
|
|
16821
|
+
if (postedScanning) {
|
|
16822
|
+
this.postStatus({ msg: EStatus.Scanning, revoking: true });
|
|
16706
16823
|
}
|
|
16824
|
+
})().then(() => {
|
|
16825
|
+
this.looping -= 1;
|
|
16826
|
+
}).catch(() => {
|
|
16827
|
+
this.looping -= 1;
|
|
16707
16828
|
});
|
|
16708
|
-
this.viewerDateTimeChangeRemoval = () => {
|
|
16709
|
-
delayQueue === null || delayQueue === void 0 ? void 0 : delayQueue.Dispose();
|
|
16710
|
-
postUpdateRemoval === null || postUpdateRemoval === void 0 ? void 0 : postUpdateRemoval();
|
|
16711
|
-
delayQueue = null;
|
|
16712
|
-
postUpdateRemoval = null;
|
|
16713
|
-
};
|
|
16714
|
-
}
|
|
16715
|
-
updateHistoricDateTime() {
|
|
16716
|
-
if (!this.historic) {
|
|
16717
|
-
this.historicAttrDateTime = null;
|
|
16718
|
-
return;
|
|
16719
|
-
}
|
|
16720
|
-
const isChanged = (before, after) => {
|
|
16721
|
-
if (before && !after) {
|
|
16722
|
-
return true;
|
|
16723
|
-
}
|
|
16724
|
-
if (!before && after) {
|
|
16725
|
-
return true;
|
|
16726
|
-
}
|
|
16727
|
-
// Change must be at least 0.1 seconds.
|
|
16728
|
-
return Math.abs(before.getTime() - after.getTime()) > 100;
|
|
16729
|
-
};
|
|
16730
|
-
const oldDateTime = this.historicAttrDateTime ? new Date(this.historicAttrDateTime) : null;
|
|
16731
|
-
const newDateTime = JulianDate.toDate(this.viewer.clock.currentTime);
|
|
16732
|
-
if (isChanged(oldDateTime, newDateTime)) {
|
|
16733
|
-
this.historicAttrDateTime = newDateTime.toISOString();
|
|
16734
|
-
}
|
|
16735
|
-
}
|
|
16736
|
-
viewerDateTimeDispose() {
|
|
16737
|
-
var _a;
|
|
16738
|
-
(_a = this.viewerDateTimeChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
16739
|
-
this.viewerDateTimeChangeRemoval = null;
|
|
16740
16829
|
}
|
|
16741
16830
|
/**
|
|
16742
16831
|
* Gets the historic state of found Entities for the current date times and emits them.
|
|
16743
16832
|
* Since geometry searches are tied to the base Entity, we don't have to re-scan the viewport.
|
|
16744
16833
|
*/
|
|
16745
16834
|
emitHistoricData() {
|
|
16746
|
-
if (this.
|
|
16835
|
+
if (!this.GetMenuItems().length) {
|
|
16836
|
+
return;
|
|
16837
|
+
}
|
|
16838
|
+
let integrity = this.getIntegrityId();
|
|
16839
|
+
// Gathered ID does't match current one.
|
|
16840
|
+
if (this.gatheredIntegrity != integrity) {
|
|
16747
16841
|
return;
|
|
16748
16842
|
}
|
|
16749
16843
|
const historicAttrDateTime = this.historicAttrDateTime;
|
|
@@ -16753,29 +16847,34 @@ var TilesetRenderEngine;
|
|
|
16753
16847
|
this.historicRefreshAbortController = null;
|
|
16754
16848
|
}
|
|
16755
16849
|
(async () => {
|
|
16756
|
-
var _a
|
|
16850
|
+
var _a;
|
|
16757
16851
|
try {
|
|
16758
|
-
const gatheredEntityIds = Object.keys(this.styledWithAttrEntityIds);
|
|
16759
16852
|
// Loop through all IDs we've found and get their historic records.
|
|
16760
|
-
for (let i = 0; i < gatheredEntityIds.length; i += SCAN_BATCH_SIZE) {
|
|
16761
|
-
let batch = gatheredEntityIds.slice(i, i + SCAN_BATCH_SIZE);
|
|
16853
|
+
for (let i = 0; i < this.gatheredEntityIds.length; i += SCAN_BATCH_SIZE) {
|
|
16854
|
+
let batch = this.gatheredEntityIds.slice(i, i + SCAN_BATCH_SIZE);
|
|
16762
16855
|
if (!batch.length) {
|
|
16763
16856
|
break;
|
|
16764
16857
|
}
|
|
16765
16858
|
// Controller we can use to abort the request when a new loop starts.
|
|
16766
16859
|
const controller = this.historicRefreshAbortController = new AbortController();
|
|
16767
16860
|
let entities = [];
|
|
16768
|
-
await SharedGetters.Queue.Run("Refreshing historic data in Menu Item that loads
|
|
16769
|
-
|
|
16861
|
+
await SharedGetters.Queue.Run("Refreshing historic data in Menu Item that loads Entity Type: " + this.typeIds, async () => {
|
|
16862
|
+
var _a;
|
|
16863
|
+
if (controller.signal.aborted || !((_a = this.GetMenuItems()) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
16770
16864
|
return;
|
|
16771
16865
|
}
|
|
16772
16866
|
entities = (await Entity$1.GetList({
|
|
16773
16867
|
api: this.api,
|
|
16774
16868
|
scenario: this.scenario,
|
|
16869
|
+
historicKey: this.historicAttrKey,
|
|
16775
16870
|
historicPoint: historicAttrDateTime,
|
|
16871
|
+
schemaId: this.schemaId,
|
|
16776
16872
|
filter: {
|
|
16777
16873
|
pageSize: batch.length,
|
|
16778
16874
|
pageIndex: 0,
|
|
16875
|
+
entityTypeId: this.typeIds,
|
|
16876
|
+
layerIds: this.tagIds,
|
|
16877
|
+
layerIdsOperator: "in",
|
|
16779
16878
|
sortOrder: Api.ESortOrder.Asc,
|
|
16780
16879
|
entityTypeConditions: {
|
|
16781
16880
|
"ID": {
|
|
@@ -16783,6 +16882,7 @@ var TilesetRenderEngine;
|
|
|
16783
16882
|
}
|
|
16784
16883
|
},
|
|
16785
16884
|
},
|
|
16885
|
+
viaCdn: this.viaCdn,
|
|
16786
16886
|
migrated: true,
|
|
16787
16887
|
// If we're taking 5+ minutes to make a query, it's a dud.
|
|
16788
16888
|
// This is a timeout imposed on our DB and not external sources.
|
|
@@ -16800,331 +16900,211 @@ var TilesetRenderEngine;
|
|
|
16800
16900
|
if (this.historicAttrDateTime != historicAttrDateTime) {
|
|
16801
16901
|
break;
|
|
16802
16902
|
}
|
|
16803
|
-
//
|
|
16804
|
-
|
|
16805
|
-
|
|
16806
|
-
const entity = entities[i];
|
|
16807
|
-
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) {
|
|
16808
|
-
const eTagIds = entity.Bruce["Layer.ID"];
|
|
16809
|
-
for (let j = 0; j < eTagIds.length; j++) {
|
|
16810
|
-
tagIds.push(eTagIds[j]);
|
|
16811
|
-
}
|
|
16812
|
-
}
|
|
16813
|
-
}
|
|
16814
|
-
// Turn into unique list.
|
|
16815
|
-
if (tagIds.length) {
|
|
16816
|
-
tagIds = tagIds.filter((v, i, a) => a.indexOf(v) === i);
|
|
16817
|
-
}
|
|
16818
|
-
// Gather records.
|
|
16819
|
-
let tags = [];
|
|
16820
|
-
if (tagIds.length) {
|
|
16821
|
-
tags = (await EntityTag.GetListByIds({
|
|
16822
|
-
tagIds: tagIds,
|
|
16823
|
-
api: this.api
|
|
16824
|
-
})).tags;
|
|
16903
|
+
// Integrity changed.
|
|
16904
|
+
if (this.gatheredIntegrity != integrity) {
|
|
16905
|
+
break;
|
|
16825
16906
|
}
|
|
16826
|
-
//
|
|
16827
|
-
if (this.
|
|
16907
|
+
// No Menu Items.
|
|
16908
|
+
if (!this.GetMenuItems().length) {
|
|
16828
16909
|
break;
|
|
16829
16910
|
}
|
|
16830
|
-
|
|
16831
|
-
|
|
16832
|
-
|
|
16833
|
-
|
|
16834
|
-
|
|
16835
|
-
|
|
16836
|
-
|
|
16911
|
+
(_a = this.onUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(entities);
|
|
16912
|
+
}
|
|
16913
|
+
}
|
|
16914
|
+
catch (e) {
|
|
16915
|
+
// Ignore abort errors.
|
|
16916
|
+
if (e && typeof e === "object" && e.name == "AbortError") {
|
|
16917
|
+
// console.debug("Aborted entity-filter-getter historic refresh request.");
|
|
16918
|
+
return;
|
|
16919
|
+
}
|
|
16920
|
+
console.error(e);
|
|
16921
|
+
}
|
|
16922
|
+
})();
|
|
16923
|
+
}
|
|
16924
|
+
}
|
|
16925
|
+
EntityFilterGetter.Getter = Getter;
|
|
16926
|
+
})(EntityFilterGetter || (EntityFilterGetter = {}));
|
|
16927
|
+
|
|
16928
|
+
function createFilterGetterCacheKey(params) {
|
|
16929
|
+
let cacheKey = "";
|
|
16930
|
+
cacheKey += params.api.GetBaseUrl();
|
|
16931
|
+
// Not including Type ID in the cache key now.
|
|
16932
|
+
// This allows us to re-use the same getter between Entity Types.
|
|
16933
|
+
// cacheKey += params.typeId;
|
|
16934
|
+
cacheKey += params.batchSize;
|
|
16935
|
+
cacheKey += String(params.cdn);
|
|
16936
|
+
cacheKey += params.schemaId ? params.schemaId : "";
|
|
16937
|
+
cacheKey += JSON.stringify(params.tagIds ? params.tagIds : []);
|
|
16938
|
+
cacheKey += params.historicAttrKey ? params.historicAttrKey : "";
|
|
16939
|
+
cacheKey += params.historic ? "true" : "false";
|
|
16940
|
+
cacheKey += params.scenario ? params.scenario : 0;
|
|
16941
|
+
if (params.historicAttrKey) {
|
|
16942
|
+
cacheKey += params.historicInterpolation ? "true" : "false";
|
|
16943
|
+
}
|
|
16944
|
+
// This could potentially crash, but if it crashes here then it would crash during API request anyways.
|
|
16945
|
+
cacheKey += JSON.stringify(params.attrFilter ? params.attrFilter : {});
|
|
16946
|
+
return cacheKey;
|
|
16947
|
+
}
|
|
16948
|
+
var SharedGetters;
|
|
16949
|
+
(function (SharedGetters) {
|
|
16950
|
+
class Cache {
|
|
16951
|
+
constructor() {
|
|
16952
|
+
this.data = {};
|
|
16953
|
+
}
|
|
16954
|
+
GetOrCreateFilterGetter(params) {
|
|
16955
|
+
params.cdn = Boolean(params.cdn);
|
|
16956
|
+
const cacheKey = createFilterGetterCacheKey(params);
|
|
16957
|
+
let getter = this.data[cacheKey];
|
|
16958
|
+
if (!getter) {
|
|
16959
|
+
getter = new EntityFilterGetter.Getter({
|
|
16960
|
+
api: params.api,
|
|
16961
|
+
viewer: params.viewer,
|
|
16962
|
+
viewPort: params.monitor,
|
|
16963
|
+
typeIds: !params.typeId ? null : typeof params.typeId == "string" ? [params.typeId] : params.typeId,
|
|
16964
|
+
schemaId: params.schemaId,
|
|
16965
|
+
batchSize: params.batchSize,
|
|
16966
|
+
attrFilter: params.attrFilter,
|
|
16967
|
+
historic: params.historic,
|
|
16968
|
+
historicAttrKey: params.historicAttrKey,
|
|
16969
|
+
historicInterpolation: params.historicInterpolation,
|
|
16970
|
+
viaCdn: params.cdn,
|
|
16971
|
+
scenario: params.scenario,
|
|
16972
|
+
});
|
|
16973
|
+
this.data[cacheKey] = getter;
|
|
16974
|
+
/**
|
|
16975
|
+
* Debug option.
|
|
16976
|
+
* This will display the bounds of the cells that are being fetched.
|
|
16977
|
+
*/
|
|
16978
|
+
if (params.viewer && params.debugShowBounds) {
|
|
16979
|
+
// Cell id -> entity.
|
|
16980
|
+
const cellCache = {};
|
|
16981
|
+
const cellPrefix = ObjectUtils.UId(10) + "_";
|
|
16982
|
+
getter.OnScanUpdate.Subscribe((cells) => {
|
|
16983
|
+
if (window.ON_SCAN_UPDATE_PAUSED == true) {
|
|
16984
|
+
return;
|
|
16985
|
+
}
|
|
16986
|
+
const curCellIds = [];
|
|
16987
|
+
let fetchingCellId = null;
|
|
16988
|
+
const fetchedCells = {};
|
|
16989
|
+
cells.forEach((cell) => {
|
|
16990
|
+
var _a;
|
|
16991
|
+
const bounds = cell.GetBounds();
|
|
16992
|
+
const id = cellPrefix + bounds.east + "_" + bounds.north + "_" + bounds.south + "_" + bounds.west;
|
|
16993
|
+
curCellIds.push(id);
|
|
16994
|
+
fetchedCells[id] = cell.IsFetched();
|
|
16995
|
+
fetchingCellId = cell.Fetching ? id : fetchingCellId;
|
|
16996
|
+
let material = null;
|
|
16997
|
+
if (fetchedCells[id]) {
|
|
16998
|
+
material = Color.LIGHTGREEN.clone().withAlpha(0.3);
|
|
16837
16999
|
}
|
|
16838
|
-
|
|
16839
|
-
|
|
16840
|
-
}
|
|
16841
|
-
catch (e) {
|
|
16842
|
-
// Ignore abort errors.
|
|
16843
|
-
if (e && typeof e === "object" && e.name == "AbortError") {
|
|
16844
|
-
return;
|
|
16845
|
-
}
|
|
16846
|
-
console.error(e);
|
|
16847
|
-
}
|
|
16848
|
-
})();
|
|
16849
|
-
}
|
|
16850
|
-
getEntityTypeIdsFromModelTree(modelTree) {
|
|
16851
|
-
const entityTypeIds = [];
|
|
16852
|
-
this.digEntityTypeIdsFromModelTreeBranch(modelTree, entityTypeIds);
|
|
16853
|
-
return entityTypeIds;
|
|
16854
|
-
}
|
|
16855
|
-
digEntityTypeIdsFromModelTreeBranch(branch, arr) {
|
|
16856
|
-
if (branch) {
|
|
16857
|
-
// Does not yet include this entity type id.
|
|
16858
|
-
if (branch.typeId && !arr.includes(branch.typeId)) {
|
|
16859
|
-
arr.push(branch.typeId);
|
|
16860
|
-
}
|
|
16861
|
-
if (branch.children) {
|
|
16862
|
-
for (let i = 0; i < branch.children.length; i++) {
|
|
16863
|
-
let child = branch.children[i];
|
|
16864
|
-
this.digEntityTypeIdsFromModelTreeBranch(child, arr);
|
|
16865
|
-
}
|
|
16866
|
-
}
|
|
16867
|
-
}
|
|
16868
|
-
}
|
|
16869
|
-
async processTilesetFeatureCheckQueue() {
|
|
16870
|
-
const BATCH_CHECK_SIZE = 1000;
|
|
16871
|
-
return new Promise((res) => {
|
|
16872
|
-
clearInterval(this.queueCheckInterval);
|
|
16873
|
-
this.queueCheckInterval = setInterval(() => {
|
|
16874
|
-
if (this.disposed) {
|
|
16875
|
-
clearInterval(this.queueCheckInterval);
|
|
16876
|
-
res();
|
|
16877
|
-
return;
|
|
16878
|
-
}
|
|
16879
|
-
// Construct batch for loaded styles.
|
|
16880
|
-
let batch = [];
|
|
16881
|
-
if (this.styleMappingLoaded) {
|
|
16882
|
-
batch = this.recordCheckQueue.splice(0, BATCH_CHECK_SIZE);
|
|
16883
|
-
}
|
|
16884
|
-
else {
|
|
16885
|
-
for (let i = 0; i < this.recordCheckQueue.length; i++) {
|
|
16886
|
-
const entityId = this.recordCheckQueue[i];
|
|
16887
|
-
const entity = this.getEntityRego(entityId);
|
|
16888
|
-
if (entity) {
|
|
16889
|
-
const entityTypeId = entity.entityTypeId;
|
|
16890
|
-
if (entityTypeId) {
|
|
16891
|
-
if (this.styleMappingsLoaded[entityTypeId] == true) {
|
|
16892
|
-
batch.push(entityId);
|
|
16893
|
-
}
|
|
16894
|
-
}
|
|
17000
|
+
else if (fetchingCellId == id) {
|
|
17001
|
+
material = Color.LIGHTBLUE.clone().withAlpha(0.3);
|
|
16895
17002
|
}
|
|
16896
|
-
|
|
16897
|
-
|
|
17003
|
+
else {
|
|
17004
|
+
material = Color.GOLD.clone().withAlpha(0.3);
|
|
16898
17005
|
}
|
|
16899
|
-
|
|
16900
|
-
|
|
16901
|
-
|
|
16902
|
-
|
|
16903
|
-
|
|
16904
|
-
|
|
17006
|
+
if (cellCache[id]) {
|
|
17007
|
+
const rect = (_a = cellCache[id]) === null || _a === void 0 ? void 0 : _a.rectangle;
|
|
17008
|
+
if (rect) {
|
|
17009
|
+
rect.material = material;
|
|
17010
|
+
}
|
|
17011
|
+
return;
|
|
16905
17012
|
}
|
|
16906
|
-
|
|
16907
|
-
|
|
16908
|
-
|
|
16909
|
-
|
|
16910
|
-
|
|
16911
|
-
|
|
16912
|
-
|
|
16913
|
-
|
|
17013
|
+
const rect = new Rectangle(Math$1.toRadians(bounds.west), Math$1.toRadians(bounds.south), Math$1.toRadians(bounds.east), Math$1.toRadians(bounds.north));
|
|
17014
|
+
const entity = params.viewer.entities.add(new Entity({
|
|
17015
|
+
id: id,
|
|
17016
|
+
rectangle: {
|
|
17017
|
+
coordinates: rect,
|
|
17018
|
+
fill: true,
|
|
17019
|
+
//material: Cesium.Color.fromRandom().withAlpha(0.3),
|
|
17020
|
+
material: material,
|
|
17021
|
+
zIndex: 0
|
|
17022
|
+
},
|
|
17023
|
+
// point: {
|
|
17024
|
+
// pixelSize: 15,
|
|
17025
|
+
// outlineColor: Cesium.Color.WHITE,
|
|
17026
|
+
// outlineWidth: 2,
|
|
17027
|
+
// color: Cesium.Color.fromRandom().withAlpha(0.5),
|
|
17028
|
+
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
|
17029
|
+
// },
|
|
17030
|
+
position: Cartesian3.fromRadians((rect.east + rect.west) / 2, (rect.north + rect.south) / 2)
|
|
17031
|
+
}));
|
|
17032
|
+
cellCache[id] = entity;
|
|
17033
|
+
});
|
|
17034
|
+
Object.keys(cellCache).forEach((id) => {
|
|
17035
|
+
if (curCellIds.indexOf(id) == -1) {
|
|
17036
|
+
const entity = cellCache[id];
|
|
17037
|
+
if (entity && params.viewer.entities.contains(entity)) {
|
|
17038
|
+
params.viewer.entities.remove(entity);
|
|
17039
|
+
}
|
|
17040
|
+
delete cellCache[id];
|
|
16914
17041
|
}
|
|
16915
|
-
}
|
|
16916
|
-
this.viewer.scene.requestRender();
|
|
16917
|
-
}
|
|
16918
|
-
else {
|
|
16919
|
-
clearInterval(this.queueCheckInterval);
|
|
16920
|
-
res();
|
|
16921
|
-
}
|
|
16922
|
-
}, 50);
|
|
16923
|
-
});
|
|
16924
|
-
}
|
|
16925
|
-
queueTilesetFeatureStyle(entity, highPriority) {
|
|
16926
|
-
// Add to the style dict if not already there.
|
|
16927
|
-
// This helps us know the styling progress for things that have loaded in so far.
|
|
16928
|
-
if (!this.styledEntityIds[entity.entityId]) {
|
|
16929
|
-
this.styledEntityIds[entity.entityId] = null;
|
|
16930
|
-
}
|
|
16931
|
-
if (this.styleMappingLoaded || this.styleMappingsLoaded[entity.entityTypeId] == true) {
|
|
16932
|
-
const needsData = this.getTilesetFeatureNeedsFullData(entity.entityId, entity.entityTypeId);
|
|
16933
|
-
if (needsData) {
|
|
16934
|
-
if (!this.recordLoadQueue.find(x => x == entity.entityId)) {
|
|
16935
|
-
this.recordLoadQueue.push(entity.entityId);
|
|
16936
|
-
}
|
|
16937
|
-
}
|
|
16938
|
-
else {
|
|
16939
|
-
this.styleTilesetFeature(entity);
|
|
16940
|
-
}
|
|
16941
|
-
}
|
|
16942
|
-
else {
|
|
16943
|
-
if (highPriority) {
|
|
16944
|
-
this.recordCheckQueue.unshift(entity.entityId);
|
|
16945
|
-
}
|
|
16946
|
-
else {
|
|
16947
|
-
this.recordCheckQueue.push(entity.entityId);
|
|
16948
|
-
}
|
|
16949
|
-
}
|
|
16950
|
-
}
|
|
16951
|
-
styleTilesetFeature(entity) {
|
|
16952
|
-
this.styleTilesetFeatureFullData(entity, null, []);
|
|
16953
|
-
}
|
|
16954
|
-
styleTilesetFeatureFullData(entity, data, tags) {
|
|
16955
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
16956
|
-
const visual = entity.visual;
|
|
16957
|
-
if (!visual || !(visual instanceof Cesium3DTileFeature)) {
|
|
16958
|
-
return;
|
|
16959
|
-
}
|
|
16960
|
-
const style = this.getTilesetFeatureStyle(entity.entityId, entity.entityTypeId);
|
|
16961
|
-
const bColor = style && ((_a = style.modelStyle) === null || _a === void 0 ? void 0 : _a.fillColor) ? Calculator.GetColor(style.modelStyle.fillColor, data, tags) : null;
|
|
16962
|
-
let cColor = null;
|
|
16963
|
-
if (bColor == null) {
|
|
16964
|
-
cColor = Color.WHITE;
|
|
16965
|
-
}
|
|
16966
|
-
else {
|
|
16967
|
-
cColor = colorToCColor$3(bColor);
|
|
16968
|
-
}
|
|
16969
|
-
const override = this.styledEntityIds[entity.entityId] == true;
|
|
16970
|
-
CesiumEntityStyler.SetDefaultColor({
|
|
16971
|
-
color: cColor,
|
|
16972
|
-
entity: visual,
|
|
16973
|
-
viewer: this.viewer,
|
|
16974
|
-
override: override
|
|
16975
|
-
});
|
|
16976
|
-
this.styledEntityIds[entity.entityId] = true;
|
|
16977
|
-
if (data) {
|
|
16978
|
-
this.styledWithAttrEntityIds[entity.entityId] = true;
|
|
16979
|
-
}
|
|
16980
|
-
else {
|
|
16981
|
-
delete this.styledWithAttrEntityIds[entity.entityId];
|
|
16982
|
-
}
|
|
16983
|
-
this._styleProgressQueue.Call();
|
|
16984
|
-
// Since we only need to update it for scenarios right now.
|
|
16985
|
-
// We'll avoid doing it if not needed, eg: first render and no scenario (same state as default).
|
|
16986
|
-
if (this.shouldUpdateRegoStates && (override || ((_b = data === null || data === void 0 ? void 0 : data.Bruce) === null || _b === void 0 ? void 0 : _b.Scenario) || this.historic)) {
|
|
16987
|
-
// Update the Entity's rego state.
|
|
16988
|
-
let changed = false;
|
|
16989
|
-
// Changed scenario.
|
|
16990
|
-
if (entity.scenario != ((_c = data === null || data === void 0 ? void 0 : data.Bruce) === null || _c === void 0 ? void 0 : _c.Scenario)) {
|
|
16991
|
-
entity.scenario = (_d = data === null || data === void 0 ? void 0 : data.Bruce) === null || _d === void 0 ? void 0 : _d.Scenario;
|
|
16992
|
-
changed = true;
|
|
16993
|
-
}
|
|
16994
|
-
// Changed historic.
|
|
16995
|
-
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))) {
|
|
16996
|
-
entity.historicLayers = (_h = data === null || data === void 0 ? void 0 : data.Bruce) === null || _h === void 0 ? void 0 : _h.HistoricLayers;
|
|
16997
|
-
changed = true;
|
|
16998
|
-
}
|
|
16999
|
-
// Something changed, trigger a rego update.
|
|
17000
|
-
// This lets UI know when the rego has changed.
|
|
17001
|
-
if (changed) {
|
|
17002
|
-
this.register.OnUpdate.Trigger({
|
|
17003
|
-
type: VisualsRegister.EVisualUpdateType.Update,
|
|
17004
|
-
entityId: entity.entityId,
|
|
17005
|
-
rego: entity
|
|
17042
|
+
});
|
|
17006
17043
|
});
|
|
17007
17044
|
}
|
|
17008
17045
|
}
|
|
17009
|
-
|
|
17010
|
-
getTilesetFeatureStyle(entityId, entityTypeId) {
|
|
17011
|
-
var _a, _b, _c, _d;
|
|
17012
|
-
// Locate what style is applicable to the feature.
|
|
17013
|
-
let style = null;
|
|
17014
|
-
if (entityTypeId) {
|
|
17015
|
-
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);
|
|
17016
|
-
}
|
|
17017
|
-
if (!style) {
|
|
17018
|
-
style = ((_c = this.fallbackStyle) === null || _c === void 0 ? void 0 : _c.Settings);
|
|
17019
|
-
}
|
|
17020
|
-
if (!style || !((_d = style === null || style === void 0 ? void 0 : style.modelStyle) === null || _d === void 0 ? void 0 : _d.customize)) {
|
|
17021
|
-
return null;
|
|
17022
|
-
}
|
|
17023
|
-
return style;
|
|
17024
|
-
}
|
|
17025
|
-
getTilesetFeatureNeedsFullData(entityId, entityTypeId) {
|
|
17026
|
-
var _a;
|
|
17027
|
-
if (this.historic) {
|
|
17028
|
-
// Unfortunately when we are working with historic we have to request the entity.
|
|
17029
|
-
// This is because we need to know if a record exists at the point in time.
|
|
17030
|
-
return true;
|
|
17031
|
-
}
|
|
17032
|
-
const style = this.getTilesetFeatureStyle(entityId, entityTypeId);
|
|
17033
|
-
if (!style) {
|
|
17034
|
-
return false;
|
|
17035
|
-
}
|
|
17036
|
-
const fill = (_a = style === null || style === void 0 ? void 0 : style.modelStyle) === null || _a === void 0 ? void 0 : _a.fillColor;
|
|
17037
|
-
if (!fill || fill.length <= 0) {
|
|
17038
|
-
return false;
|
|
17039
|
-
}
|
|
17040
|
-
return fill[0].type != 0;
|
|
17046
|
+
return getter;
|
|
17041
17047
|
}
|
|
17042
17048
|
}
|
|
17043
|
-
|
|
17044
|
-
/**
|
|
17045
|
-
* The maximum memory in MB that can be used by all tilesets.
|
|
17046
|
-
* This is distributed evenly between all loaded tilesets.
|
|
17047
|
-
*/
|
|
17048
|
-
TilesetRenderEngine.MAX_TILESET_MEMORY = 1024;
|
|
17049
|
+
SharedGetters.Cache = Cache;
|
|
17049
17050
|
/**
|
|
17050
|
-
*
|
|
17051
|
-
*
|
|
17052
|
-
* As more get watched their memory will be reduced.
|
|
17051
|
+
* To avoid performing multiple expensive queries at the same time,
|
|
17052
|
+
* we'll have the getters work through a queue of requests.
|
|
17053
17053
|
*/
|
|
17054
|
-
|
|
17055
|
-
|
|
17056
|
-
|
|
17057
|
-
|
|
17058
|
-
}
|
|
17059
|
-
distributeMemory() {
|
|
17060
|
-
this.clean();
|
|
17061
|
-
// Total 1gb as default.
|
|
17062
|
-
// We'll need to allow user to change this somehow.
|
|
17063
|
-
const maxMemory = TilesetRenderEngine.MAX_TILESET_MEMORY;
|
|
17064
|
-
// Minimum memory in MB per tileset.
|
|
17065
|
-
const minMemory = 80;
|
|
17066
|
-
const totalPerTileset = Math.max(this.watched.length ? maxMemory / this.watched.length : maxMemory, minMemory);
|
|
17067
|
-
this.watched.forEach(x => {
|
|
17068
|
-
// Newer Cesium killed this property.
|
|
17069
|
-
// TODO: Check if it's needed then.
|
|
17070
|
-
x["maximumMemoryUsage"] = totalPerTileset;
|
|
17071
|
-
});
|
|
17072
|
-
}
|
|
17073
|
-
destroy() {
|
|
17074
|
-
this.watched = [];
|
|
17075
|
-
}
|
|
17054
|
+
let Queue;
|
|
17055
|
+
(function (Queue) {
|
|
17056
|
+
const queue = [];
|
|
17057
|
+
let isProcessing = false;
|
|
17076
17058
|
/**
|
|
17077
|
-
*
|
|
17059
|
+
* Called to run a provided function.
|
|
17060
|
+
* When the function is complete, the next function in the queue will be called.
|
|
17061
|
+
* This function will resolve when the provided function is complete.
|
|
17062
|
+
* If the provided function crashes, the error bubbles up to the caller.
|
|
17063
|
+
* @param name
|
|
17064
|
+
* @param call
|
|
17078
17065
|
*/
|
|
17079
|
-
|
|
17080
|
-
//
|
|
17081
|
-
|
|
17082
|
-
|
|
17083
|
-
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
|
|
17087
|
-
|
|
17088
|
-
|
|
17089
|
-
|
|
17090
|
-
|
|
17091
|
-
|
|
17092
|
-
|
|
17093
|
-
|
|
17094
|
-
|
|
17095
|
-
|
|
17096
|
-
|
|
17097
|
-
|
|
17098
|
-
|
|
17099
|
-
|
|
17066
|
+
function Run(name, call) {
|
|
17067
|
+
// console.debug(`Queueing: ${name}`);
|
|
17068
|
+
return new Promise((resolve, reject) => {
|
|
17069
|
+
queue.push(async () => {
|
|
17070
|
+
try {
|
|
17071
|
+
// console.debug(`Running: ${name}`);
|
|
17072
|
+
const result = await call();
|
|
17073
|
+
resolve(result);
|
|
17074
|
+
}
|
|
17075
|
+
catch (error) {
|
|
17076
|
+
reject(error);
|
|
17077
|
+
}
|
|
17078
|
+
finally {
|
|
17079
|
+
// Process the next function in the queue.
|
|
17080
|
+
queue.shift();
|
|
17081
|
+
// If there are more functions in the queue, process the next one.
|
|
17082
|
+
if (queue.length > 0) {
|
|
17083
|
+
processNext();
|
|
17084
|
+
}
|
|
17085
|
+
// No more items to process.
|
|
17086
|
+
else {
|
|
17087
|
+
isProcessing = false;
|
|
17088
|
+
}
|
|
17089
|
+
}
|
|
17090
|
+
});
|
|
17091
|
+
if (!isProcessing) {
|
|
17092
|
+
// If not currently processing, start processing the queue.
|
|
17093
|
+
isProcessing = true;
|
|
17094
|
+
processNext();
|
|
17095
|
+
}
|
|
17096
|
+
});
|
|
17100
17097
|
}
|
|
17101
|
-
|
|
17102
|
-
|
|
17103
|
-
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
17107
|
-
}
|
|
17108
|
-
const index = this.watched.findIndex(x => (x === null || x === void 0 ? void 0 : x[WATCH_KEY]) === tileset[WATCH_KEY]);
|
|
17109
|
-
if (index > -1) {
|
|
17110
|
-
this.watched.splice(index, 1);
|
|
17098
|
+
Queue.Run = Run;
|
|
17099
|
+
async function processNext() {
|
|
17100
|
+
const nextCall = queue[0];
|
|
17101
|
+
if (nextCall) {
|
|
17102
|
+
// Call the next function in the queue.
|
|
17103
|
+
await nextCall();
|
|
17111
17104
|
}
|
|
17112
|
-
this.distributeMemory();
|
|
17113
|
-
}
|
|
17114
|
-
}
|
|
17115
|
-
TilesetRenderEngine.MemoryWatcher = MemoryWatcher;
|
|
17116
|
-
function GetMemoryWatcher(viewer) {
|
|
17117
|
-
// If viewer is dead return nothing.
|
|
17118
|
-
if (!viewer || viewer.isDestroyed()) {
|
|
17119
|
-
return null;
|
|
17120
|
-
}
|
|
17121
|
-
if (!viewer[VIEWER_WATCH_KEY]) {
|
|
17122
|
-
viewer[VIEWER_WATCH_KEY] = new MemoryWatcher(viewer);
|
|
17123
17105
|
}
|
|
17124
|
-
|
|
17125
|
-
|
|
17126
|
-
TilesetRenderEngine.GetMemoryWatcher = GetMemoryWatcher;
|
|
17127
|
-
})(TilesetRenderEngine || (TilesetRenderEngine = {}));
|
|
17106
|
+
})(Queue = SharedGetters.Queue || (SharedGetters.Queue = {}));
|
|
17107
|
+
})(SharedGetters || (SharedGetters = {}));
|
|
17128
17108
|
|
|
17129
17109
|
/**
|
|
17130
17110
|
* Manager for rendering CAD tilesets.
|
|
@@ -17350,6 +17330,7 @@ var TilesetCadRenderManager;
|
|
|
17350
17330
|
if (!content) {
|
|
17351
17331
|
return;
|
|
17352
17332
|
}
|
|
17333
|
+
const regosToQueue = new Map();
|
|
17353
17334
|
for (let i = 0; i < content.featuresLength; i++) {
|
|
17354
17335
|
const feature = content.getFeature(i);
|
|
17355
17336
|
let rego = this.mapTilesetFeature(feature, load);
|
|
@@ -17358,9 +17339,10 @@ var TilesetCadRenderManager;
|
|
|
17358
17339
|
feature.show = true;
|
|
17359
17340
|
continue;
|
|
17360
17341
|
}
|
|
17361
|
-
|
|
17362
|
-
|
|
17363
|
-
|
|
17342
|
+
regosToQueue.set(rego.entityId, rego);
|
|
17343
|
+
}
|
|
17344
|
+
if (this.styler && regosToQueue.size) {
|
|
17345
|
+
this.styler.QueueEntities(Array.from(regosToQueue.values()));
|
|
17364
17346
|
}
|
|
17365
17347
|
this.viewer.scene.requestRender();
|
|
17366
17348
|
}
|
|
@@ -18589,13 +18571,17 @@ var TilesetEntitiesRenderManager;
|
|
|
18589
18571
|
if (!content) {
|
|
18590
18572
|
return;
|
|
18591
18573
|
}
|
|
18574
|
+
const regosToQueue = new Map();
|
|
18592
18575
|
for (let i = 0; i < content.featuresLength; i++) {
|
|
18593
18576
|
const feature = content.getFeature(i);
|
|
18594
18577
|
const rego = this.mapTilesetFeature(feature);
|
|
18595
|
-
if (
|
|
18596
|
-
|
|
18578
|
+
if (rego === null || rego === void 0 ? void 0 : rego.entityId) {
|
|
18579
|
+
regosToQueue.set(rego.entityId, rego);
|
|
18597
18580
|
}
|
|
18598
18581
|
}
|
|
18582
|
+
if (this.styler && regosToQueue.size) {
|
|
18583
|
+
this.styler.QueueEntities(Array.from(regosToQueue.values()));
|
|
18584
|
+
}
|
|
18599
18585
|
this.viewer.scene.requestRender();
|
|
18600
18586
|
}
|
|
18601
18587
|
mapTilesetFeature(feature) {
|
|
@@ -19148,13 +19134,17 @@ var TilesetArbRenderManager;
|
|
|
19148
19134
|
if (!content) {
|
|
19149
19135
|
return;
|
|
19150
19136
|
}
|
|
19137
|
+
const regosToQueue = new Map();
|
|
19151
19138
|
for (let i = 0; i < content.featuresLength; i++) {
|
|
19152
19139
|
const feature = content.getFeature(i);
|
|
19153
19140
|
let rego = this.mapTilesetFeature(feature);
|
|
19154
|
-
if (
|
|
19155
|
-
|
|
19141
|
+
if (rego === null || rego === void 0 ? void 0 : rego.entityId) {
|
|
19142
|
+
regosToQueue.set(rego.entityId, rego);
|
|
19156
19143
|
}
|
|
19157
19144
|
}
|
|
19145
|
+
if (this.styler && regosToQueue.size) {
|
|
19146
|
+
this.styler.QueueEntities(Array.from(regosToQueue.values()));
|
|
19147
|
+
}
|
|
19158
19148
|
this.viewer.scene.requestRender();
|
|
19159
19149
|
}
|
|
19160
19150
|
mapTilesetFeature(feature) {
|
|
@@ -30641,7 +30631,7 @@ class WidgetViewBar extends Widget.AWidget {
|
|
|
30641
30631
|
}
|
|
30642
30632
|
}
|
|
30643
30633
|
|
|
30644
|
-
const VERSION = "5.4.
|
|
30634
|
+
const VERSION = "5.4.6";
|
|
30645
30635
|
|
|
30646
30636
|
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 };
|
|
30647
30637
|
//# sourceMappingURL=bruce-cesium.es5.js.map
|