bruce-cesium 7.2.3 → 7.2.5
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 +344 -39
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +342 -37
- package/dist/bruce-cesium.umd.js.map +1 -1
- package/dist/lib/bruce-cesium.js +1 -1
- package/dist/lib/internal/cesium-utils.js +32 -1
- package/dist/lib/internal/cesium-utils.js.map +1 -1
- package/dist/lib/rendering/entity-gatherer.js +111 -0
- package/dist/lib/rendering/entity-gatherer.js.map +1 -1
- package/dist/lib/rendering/entity-render-engine-polygon.js +4 -3
- package/dist/lib/rendering/entity-render-engine-polygon.js.map +1 -1
- package/dist/lib/rendering/menu-item-manager.js +1 -0
- package/dist/lib/rendering/menu-item-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/common/historic-utils.js +91 -24
- package/dist/lib/rendering/render-managers/common/historic-utils.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entities-ids-render-manager.js +1 -0
- package/dist/lib/rendering/render-managers/entities/entities-ids-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entities-render-manager.js +1 -0
- package/dist/lib/rendering/render-managers/entities/entities-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js +61 -3
- package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js.map +1 -1
- package/dist/lib/rendering/texture-frame-series-animator.js +28 -3
- package/dist/lib/rendering/texture-frame-series-animator.js.map +1 -1
- package/dist/lib/rendering/texture-value-labels.js +6 -2
- package/dist/lib/rendering/texture-value-labels.js.map +1 -1
- package/dist/lib/rendering/tileset-styler.js +10 -1
- package/dist/lib/rendering/tileset-styler.js.map +1 -1
- package/dist/types/bruce-cesium.d.ts +1 -1
- package/dist/types/internal/cesium-utils.d.ts +9 -0
- package/dist/types/rendering/entity-gatherer.d.ts +23 -0
- package/dist/types/rendering/render-managers/common/historic-utils.d.ts +30 -5
- package/dist/types/rendering/render-managers/tilesets/tileset-entities-render-manager.d.ts +5 -0
- package/dist/types/rendering/texture-frame-series-animator.d.ts +6 -0
- package/dist/types/rendering/tileset-styler.d.ts +3 -0
- package/package.json +1 -1
package/dist/bruce-cesium.es5.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as Cesium from 'cesium';
|
|
2
|
-
import { Cartographic, ColorMaterialProperty, Entity, Color, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature, Math as Math$1, Cartesian3, JulianDate, Quaternion, Transforms, HeadingPitchRoll, Matrix4, ShaderSource, Ellipsoid, Geometry, GeometryAttribute, ComponentDatatype, PrimitiveType, BoundingSphere, GeometryPipeline, sampleTerrain, Texture, PixelFormat, Sampler, TextureWrap, TextureMinificationFilter, TextureMagnificationFilter, VertexArray, BufferUsage, ShaderProgram, RenderState, BlendingState, DrawCommand, Pass, Cartesian2, HeightReference,
|
|
3
|
-
import { Cartes, Entity as Entity$1, ProjectViewTile, ENVIRONMENT, Calculator, ClientFile,
|
|
2
|
+
import { Cartographic, ColorMaterialProperty, Entity, Color, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature, Math as Math$1, Cartesian3, JulianDate, Quaternion, Transforms, HeadingPitchRoll, Matrix4, ShaderSource, Ellipsoid, Geometry, GeometryAttribute, ComponentDatatype, PrimitiveType, BoundingSphere, GeometryPipeline, sampleTerrain, Texture, PixelFormat, Sampler, TextureWrap, TextureMinificationFilter, TextureMagnificationFilter, VertexArray, BufferUsage, ShaderProgram, RenderState, BlendingState, DrawCommand, Pass, Cartesian2, DistanceDisplayCondition, HeightReference, HorizontalOrigin, VerticalOrigin, ClassificationType, ConstantPositionProperty, ArcType, CornerType, ShadowMode, ColorBlendMode, Model, SceneTransforms, ImageMaterialProperty, PolygonHierarchy, PolylineGraphics, Rectangle, NearFarScalar, Matrix3, KmlDataSource, GeoJsonDataSource, SceneMode, Cesium3DTileStyle, HeadingPitchRange, Ion, IonResource, Cesium3DTileset, Cesium3DTileColorBlendMode, OrthographicFrustum, EasingFunction, Intersect, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, EllipsoidGeodesic, sampleTerrainMostDetailed, defined, PolygonPipeline, CesiumInspector, ClockRange, DynamicEnvironmentMapManager, GeometryInstance, CustomDataSource, ScreenSpaceEventHandler, ScreenSpaceEventType, Fullscreen, CzmlDataSource } from 'cesium';
|
|
3
|
+
import { Cartes, Entity as Entity$1, ProjectViewTile, ENVIRONMENT, Api, Calculator, ClientFile, EntityTag, EntityType, LRUCache, ObjectUtils, Style, Carto, Geometry as Geometry$1, EntityLod, Color as Color$1, Bounds, MenuItem, ProjectView, ProjectViewBookmark, Tileset, ZoomControl, BruceEvent, EntityCoords, DelayQueue, DataLab, BruceApi, EntityRelation, AccountConcept, RecordChangeFeed, EntitySource, Camera, ProgramKey, ProjectViewLegacyTile, Account, AccountLimits, Session, UrlUtils, ProjectViewBookmarkGroup, EntityAttachment, EntityAttachmentType, EntityAttribute, MathUtils, EntityRelationType, EntityHistoricData } from 'bruce-models';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Ensures a number is returned from a given value.
|
|
@@ -2889,6 +2889,36 @@ function SetCPropIfChanged(params) {
|
|
|
2889
2889
|
function ColorToCColor(color) {
|
|
2890
2890
|
return new Color(color.red ? color.red / 255 : 0, color.green ? color.green / 255 : 0, color.blue ? color.blue / 255 : 0, color.alpha);
|
|
2891
2891
|
}
|
|
2892
|
+
const degreesCache = new WeakMap();
|
|
2893
|
+
/**
|
|
2894
|
+
* Returns a world position's latitude and longitude in degrees, or null when it has none.
|
|
2895
|
+
* @param pos
|
|
2896
|
+
*/
|
|
2897
|
+
function CartesianToDegrees(pos) {
|
|
2898
|
+
if (!pos) {
|
|
2899
|
+
return null;
|
|
2900
|
+
}
|
|
2901
|
+
const cached = degreesCache.get(pos);
|
|
2902
|
+
if (cached) {
|
|
2903
|
+
return cached;
|
|
2904
|
+
}
|
|
2905
|
+
let carto;
|
|
2906
|
+
try {
|
|
2907
|
+
carto = Cartographic.fromCartesian(pos);
|
|
2908
|
+
}
|
|
2909
|
+
catch {
|
|
2910
|
+
return null;
|
|
2911
|
+
}
|
|
2912
|
+
if (!carto) {
|
|
2913
|
+
return null;
|
|
2914
|
+
}
|
|
2915
|
+
const degrees = {
|
|
2916
|
+
lat: Math$1.toDegrees(carto.latitude),
|
|
2917
|
+
lon: Math$1.toDegrees(carto.longitude)
|
|
2918
|
+
};
|
|
2919
|
+
degreesCache.set(pos, degrees);
|
|
2920
|
+
return degrees;
|
|
2921
|
+
}
|
|
2892
2922
|
/**
|
|
2893
2923
|
* Removes duplicate points in a row and returns a new array.
|
|
2894
2924
|
* Passed array is not mutated.
|
|
@@ -10758,41 +10788,107 @@ var HistoricFetchOrder;
|
|
|
10758
10788
|
return Math.round(minMs + ((maxMs - minMs) * progress));
|
|
10759
10789
|
}
|
|
10760
10790
|
HistoricFetchOrder.IntervalFor = IntervalFor;
|
|
10791
|
+
// Upper bounds in metres for the distance bands, nearest first.
|
|
10792
|
+
HistoricFetchOrder.DEFAULT_BANDS = [500, 2000, 10000, 50000];
|
|
10761
10793
|
/**
|
|
10762
|
-
*
|
|
10763
|
-
*
|
|
10764
|
-
* Bands rather than a true sort, so a small camera move does not reshuffle the whole queue and
|
|
10765
|
-
* restart it. What the user is looking at resolves first either way.
|
|
10794
|
+
* Resolves what to order by from the view monitor, falling back to the camera itself.
|
|
10766
10795
|
*/
|
|
10767
|
-
function
|
|
10796
|
+
function FocusFrom(params) {
|
|
10768
10797
|
var _a;
|
|
10769
|
-
const { viewer,
|
|
10770
|
-
|
|
10771
|
-
|
|
10798
|
+
const { viewer, monitor } = params;
|
|
10799
|
+
let origin = null;
|
|
10800
|
+
let bounds = null;
|
|
10801
|
+
try {
|
|
10802
|
+
// Null whenever the view has no ground intersection, eg. a camera aimed at the sky.
|
|
10803
|
+
const target = monitor === null || monitor === void 0 ? void 0 : monitor.GetTarget();
|
|
10804
|
+
if (target && isFinite(target.latitude) && isFinite(target.longitude)) {
|
|
10805
|
+
origin = Cartesian3.fromDegrees(target.longitude, target.latitude);
|
|
10806
|
+
}
|
|
10807
|
+
bounds = (monitor === null || monitor === void 0 ? void 0 : monitor.GetBounds()) || null;
|
|
10808
|
+
}
|
|
10809
|
+
catch {
|
|
10810
|
+
origin = null;
|
|
10811
|
+
bounds = null;
|
|
10812
|
+
}
|
|
10813
|
+
if (!origin) {
|
|
10814
|
+
origin = (_a = viewer === null || viewer === void 0 ? void 0 : viewer.camera) === null || _a === void 0 ? void 0 : _a.position;
|
|
10815
|
+
}
|
|
10816
|
+
if (!origin) {
|
|
10817
|
+
return null;
|
|
10818
|
+
}
|
|
10819
|
+
return bounds ? { origin, bounds } : { origin };
|
|
10820
|
+
}
|
|
10821
|
+
HistoricFetchOrder.FocusFrom = FocusFrom;
|
|
10822
|
+
/**
|
|
10823
|
+
* Returns the Entities grouped nearest first, on screen ahead of off screen.
|
|
10824
|
+
*/
|
|
10825
|
+
function ByCameraDistance(params) {
|
|
10826
|
+
const { viewer, entities, monitor } = params;
|
|
10827
|
+
return ByCameraDistanceOf({
|
|
10828
|
+
focus: FocusFrom({ viewer, monitor }),
|
|
10829
|
+
items: entities,
|
|
10830
|
+
posOf: (entity) => SafePos(entity, viewer),
|
|
10831
|
+
bands: params.bands
|
|
10832
|
+
});
|
|
10833
|
+
}
|
|
10834
|
+
HistoricFetchOrder.ByCameraDistance = ByCameraDistance;
|
|
10835
|
+
/**
|
|
10836
|
+
* Bands anything that can name its own world position, on the same bounds as the Entity form.
|
|
10837
|
+
*/
|
|
10838
|
+
function ByCameraDistanceOf(params) {
|
|
10839
|
+
const { focus, items, posOf } = params;
|
|
10840
|
+
const bands = params.bands || HistoricFetchOrder.DEFAULT_BANDS;
|
|
10841
|
+
if (!(items === null || items === void 0 ? void 0 : items.length)) {
|
|
10772
10842
|
return [];
|
|
10773
10843
|
}
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
return [entities];
|
|
10844
|
+
if (!(focus === null || focus === void 0 ? void 0 : focus.origin)) {
|
|
10845
|
+
return [items];
|
|
10777
10846
|
}
|
|
10778
|
-
// One band past the named bounds, for everything beyond the last of them.
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10847
|
+
// One band past the named bounds, for everything beyond the last of them. Then the same
|
|
10848
|
+
// again for what is off screen, so nothing visible waits behind something that is not.
|
|
10849
|
+
const perTier = bands.length + 1;
|
|
10850
|
+
const offScreenTier = focus.bounds ? perTier : 0;
|
|
10851
|
+
const placeless = offScreenTier + perTier;
|
|
10852
|
+
const grouped = [];
|
|
10853
|
+
for (let i = 0; i <= placeless; i++) {
|
|
10854
|
+
grouped.push([]);
|
|
10855
|
+
}
|
|
10856
|
+
for (const item of items) {
|
|
10857
|
+
// An item with no position falls to the last group rather than blocking the near ones.
|
|
10858
|
+
const pos = posOf(item);
|
|
10782
10859
|
if (!pos) {
|
|
10783
|
-
|
|
10860
|
+
grouped[placeless].push(item);
|
|
10784
10861
|
continue;
|
|
10785
10862
|
}
|
|
10786
|
-
const distance = Cartesian3.distance(
|
|
10787
|
-
let
|
|
10788
|
-
if (
|
|
10789
|
-
|
|
10863
|
+
const distance = Cartesian3.distance(focus.origin, pos);
|
|
10864
|
+
let band = bands.findIndex(bound => distance <= bound);
|
|
10865
|
+
if (band < 0) {
|
|
10866
|
+
band = bands.length;
|
|
10790
10867
|
}
|
|
10791
|
-
|
|
10868
|
+
grouped[(focus.bounds && !InBounds(pos, focus.bounds)) ? offScreenTier + band : band].push(item);
|
|
10792
10869
|
}
|
|
10793
|
-
return
|
|
10870
|
+
return grouped.filter(group => group.length > 0);
|
|
10794
10871
|
}
|
|
10795
|
-
HistoricFetchOrder.
|
|
10872
|
+
HistoricFetchOrder.ByCameraDistanceOf = ByCameraDistanceOf;
|
|
10873
|
+
/*
|
|
10874
|
+
* Returns whether a world position sits inside a ground rectangle given in degrees.
|
|
10875
|
+
*/
|
|
10876
|
+
function InBounds(pos, bounds) {
|
|
10877
|
+
const degrees = CartesianToDegrees(pos);
|
|
10878
|
+
if (!degrees) {
|
|
10879
|
+
return false;
|
|
10880
|
+
}
|
|
10881
|
+
const { lat, lon } = degrees;
|
|
10882
|
+
if (lat < bounds.south || lat > bounds.north) {
|
|
10883
|
+
return false;
|
|
10884
|
+
}
|
|
10885
|
+
// A view straddling the antimeridian reports west east of east, so the span is the outside.
|
|
10886
|
+
if (bounds.west > bounds.east) {
|
|
10887
|
+
return lon >= bounds.west || lon <= bounds.east;
|
|
10888
|
+
}
|
|
10889
|
+
return lon >= bounds.west && lon <= bounds.east;
|
|
10890
|
+
}
|
|
10891
|
+
HistoricFetchOrder.InBounds = InBounds;
|
|
10796
10892
|
/*
|
|
10797
10893
|
* Returns an Entity's world position, or null when it has none to place it by.
|
|
10798
10894
|
*/
|
|
@@ -11110,7 +11206,7 @@ class HistoricGatherer {
|
|
|
11110
11206
|
}
|
|
11111
11207
|
if (plan.detail) {
|
|
11112
11208
|
const bands = entities.length > HistoricFetchOrder.SMALL_SET
|
|
11113
|
-
? HistoricFetchOrder.ByCameraDistance({ viewer, entities })
|
|
11209
|
+
? HistoricFetchOrder.ByCameraDistance({ viewer, entities, monitor: this.params.monitor })
|
|
11114
11210
|
: [entities];
|
|
11115
11211
|
for (const range of this.cache.MissingRanges(plan.detail.start, plan.detail.stop)) {
|
|
11116
11212
|
if (this.disposed) {
|
|
@@ -11279,6 +11375,7 @@ var EntitiesRenderManager;
|
|
|
11279
11375
|
this.onSeriesDiscovered = onSeriesDiscovered;
|
|
11280
11376
|
this.historicGatherer = new HistoricGatherer({
|
|
11281
11377
|
viewer: this.viewer,
|
|
11378
|
+
monitor: this.monitor,
|
|
11282
11379
|
getApi: () => this.apiGetter.getApi(),
|
|
11283
11380
|
getAttrKey: () => { var _a; return (_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historicAttrKey; },
|
|
11284
11381
|
// A second either side, to take in records sitting exactly on the boundary.
|
|
@@ -13395,6 +13492,7 @@ var EntitiesIdsRenderManager;
|
|
|
13395
13492
|
this.visualsManager = visualsManager;
|
|
13396
13493
|
this.historicGatherer = new HistoricGatherer({
|
|
13397
13494
|
viewer: this.viewer,
|
|
13495
|
+
monitor: this.monitor,
|
|
13398
13496
|
getApi: () => this.apiGetter.getApi(),
|
|
13399
13497
|
getAttrKey: () => { var _a; return (_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historicAttrKey; },
|
|
13400
13498
|
// Padding either side of a requested range, for clock desync between us and the server.
|
|
@@ -14033,6 +14131,16 @@ class EntityGatherer {
|
|
|
14033
14131
|
this.lastFoundDateTimes = new Map();
|
|
14034
14132
|
// ID of Entity IDs that need to be requested.
|
|
14035
14133
|
this.eIdQueue = [];
|
|
14134
|
+
// Resolves where an Entity sits without reading its record, when the caller can say.
|
|
14135
|
+
// Unset leaves the queue in insertion order, which is what sources that bake no coordinates get.
|
|
14136
|
+
this.positionOf = null;
|
|
14137
|
+
// How many IDs at the front of the queue were explicitly asked for first.
|
|
14138
|
+
// Camera ordering leaves those alone, since an explicit re-render outranks proximity.
|
|
14139
|
+
this.priorityCount = 0;
|
|
14140
|
+
// View focus the queue was last banded from.
|
|
14141
|
+
this.lastOrderFocus = null;
|
|
14142
|
+
// Reports what the camera is aimed at, rather than only where it sits.
|
|
14143
|
+
this.monitor = null;
|
|
14036
14144
|
// All IDs that have ever been queued.
|
|
14037
14145
|
// When nothing is in queue, we'll re-request the existing IDs based on timeline changes.
|
|
14038
14146
|
this.allEIds = new Set();
|
|
@@ -14132,6 +14240,8 @@ class EntityGatherer {
|
|
|
14132
14240
|
return;
|
|
14133
14241
|
}
|
|
14134
14242
|
this.eIdQueue = [];
|
|
14243
|
+
this.priorityCount = 0;
|
|
14244
|
+
this.lastOrderFocus = null;
|
|
14135
14245
|
this.allEIds.clear();
|
|
14136
14246
|
this.lastFoundDateTimes.clear();
|
|
14137
14247
|
this.lastDateTime = null;
|
|
@@ -14141,6 +14251,89 @@ class EntityGatherer {
|
|
|
14141
14251
|
return;
|
|
14142
14252
|
}
|
|
14143
14253
|
this.eIdQueue = Array.from(this.allEIds);
|
|
14254
|
+
this.priorityCount = 0;
|
|
14255
|
+
this.lastOrderFocus = null;
|
|
14256
|
+
}
|
|
14257
|
+
/**
|
|
14258
|
+
* Supplies a lookup from Entity ID to world position, letting the queue resolve what the camera
|
|
14259
|
+
* is nearest first. Sources that cannot answer should not call this, and are served in order.
|
|
14260
|
+
*/
|
|
14261
|
+
SetPositionSource(positionOf) {
|
|
14262
|
+
this.positionOf = positionOf;
|
|
14263
|
+
this.lastOrderFocus = null;
|
|
14264
|
+
}
|
|
14265
|
+
/**
|
|
14266
|
+
* Supplies the view monitor, so the order follows the ground the camera is aimed at and prefers
|
|
14267
|
+
* what is on screen. Without one the ordering falls back to distance from the camera itself.
|
|
14268
|
+
*/
|
|
14269
|
+
SetViewMonitor(monitor) {
|
|
14270
|
+
this.monitor = monitor;
|
|
14271
|
+
this.lastOrderFocus = null;
|
|
14272
|
+
}
|
|
14273
|
+
/**
|
|
14274
|
+
* Re-bands the pending queue so the nearest Entities are requested first.
|
|
14275
|
+
*/
|
|
14276
|
+
orderQueueByCamera() {
|
|
14277
|
+
if (!this.positionOf || this.eIdQueue.length < EntityGatherer.MIN_ORDER_QUEUE) {
|
|
14278
|
+
return;
|
|
14279
|
+
}
|
|
14280
|
+
const focus = HistoricFetchOrder.FocusFrom({ viewer: this.viewer, monitor: this.monitor });
|
|
14281
|
+
if (!focus) {
|
|
14282
|
+
return;
|
|
14283
|
+
}
|
|
14284
|
+
// Re-banding on every batch would cost a full pass per request for no change in the answer.
|
|
14285
|
+
// Measured on the focus, so panning across the ground counts even when the eye barely moves.
|
|
14286
|
+
if (this.lastOrderFocus && !EntityGatherer.boundsChanged(this.lastOrderFocus, focus) &&
|
|
14287
|
+
Cartesian3.distance(this.lastOrderFocus.origin, focus.origin) < EntityGatherer.REORDER_MOVE_METRES) {
|
|
14288
|
+
return;
|
|
14289
|
+
}
|
|
14290
|
+
this.lastOrderFocus = focus;
|
|
14291
|
+
const priority = this.priorityCount > 0 ? this.eIdQueue.slice(0, this.priorityCount) : [];
|
|
14292
|
+
const rest = this.priorityCount > 0 ? this.eIdQueue.slice(this.priorityCount) : this.eIdQueue;
|
|
14293
|
+
if (!rest.length) {
|
|
14294
|
+
return;
|
|
14295
|
+
}
|
|
14296
|
+
this.eIdQueue = priority.concat(this.bandIds(rest, focus));
|
|
14297
|
+
}
|
|
14298
|
+
/*
|
|
14299
|
+
* Returns whether the visible rectangle differs enough to change what counts as on screen.
|
|
14300
|
+
*/
|
|
14301
|
+
static boundsChanged(a, b) {
|
|
14302
|
+
if (!a.bounds || !b.bounds) {
|
|
14303
|
+
return Boolean(a.bounds) !== Boolean(b.bounds);
|
|
14304
|
+
}
|
|
14305
|
+
return (a.bounds.north !== b.bounds.north ||
|
|
14306
|
+
a.bounds.south !== b.bounds.south ||
|
|
14307
|
+
a.bounds.east !== b.bounds.east ||
|
|
14308
|
+
a.bounds.west !== b.bounds.west);
|
|
14309
|
+
}
|
|
14310
|
+
/*
|
|
14311
|
+
* Returns the IDs reordered nearest band first, or unchanged when there is nothing to order by.
|
|
14312
|
+
*/
|
|
14313
|
+
bandIds(entityIds, focus) {
|
|
14314
|
+
const from = focus || HistoricFetchOrder.FocusFrom({ viewer: this.viewer, monitor: this.monitor });
|
|
14315
|
+
if (!this.positionOf || !from || !entityIds.length) {
|
|
14316
|
+
return entityIds;
|
|
14317
|
+
}
|
|
14318
|
+
const banded = HistoricFetchOrder.ByCameraDistanceOf({
|
|
14319
|
+
focus: from,
|
|
14320
|
+
items: entityIds,
|
|
14321
|
+
posOf: (entityId) => {
|
|
14322
|
+
try {
|
|
14323
|
+
return this.positionOf(entityId);
|
|
14324
|
+
}
|
|
14325
|
+
catch {
|
|
14326
|
+
return null;
|
|
14327
|
+
}
|
|
14328
|
+
}
|
|
14329
|
+
});
|
|
14330
|
+
const ordered = [];
|
|
14331
|
+
for (const band of banded) {
|
|
14332
|
+
for (const entityId of band) {
|
|
14333
|
+
ordered.push(entityId);
|
|
14334
|
+
}
|
|
14335
|
+
}
|
|
14336
|
+
return ordered;
|
|
14144
14337
|
}
|
|
14145
14338
|
Queue(entityIds, topOfQueue = false) {
|
|
14146
14339
|
if (this.disposed || !(entityIds === null || entityIds === void 0 ? void 0 : entityIds.length)) {
|
|
@@ -14154,8 +14347,12 @@ class EntityGatherer {
|
|
|
14154
14347
|
// If we want it to be at the top of the queue, remove it from the queue first.
|
|
14155
14348
|
if (index !== -1) {
|
|
14156
14349
|
this.eIdQueue.splice(index, 1);
|
|
14350
|
+
if (index < this.priorityCount) {
|
|
14351
|
+
this.priorityCount -= 1;
|
|
14352
|
+
}
|
|
14157
14353
|
}
|
|
14158
14354
|
this.eIdQueue.unshift(eId);
|
|
14355
|
+
this.priorityCount += 1;
|
|
14159
14356
|
changes += 1;
|
|
14160
14357
|
}
|
|
14161
14358
|
else if (index === -1) {
|
|
@@ -14306,7 +14503,9 @@ class EntityGatherer {
|
|
|
14306
14503
|
if (this.historic && this.lastDateTime !== rTime) {
|
|
14307
14504
|
break;
|
|
14308
14505
|
}
|
|
14506
|
+
this.orderQueueByCamera();
|
|
14309
14507
|
const batch = this.eIdQueue.splice(0, QUEUE_BATCH_SIZE);
|
|
14508
|
+
this.priorityCount = Math.max(0, this.priorityCount - batch.length);
|
|
14310
14509
|
const { entities } = await Entity$1.GetListByIds({
|
|
14311
14510
|
entityIds: batch,
|
|
14312
14511
|
historicPoint: this.historic ? rTime : null,
|
|
@@ -14339,6 +14538,9 @@ class EntityGatherer {
|
|
|
14339
14538
|
allEIds = allEIds.filter((eId) => requestedIds.indexOf(eId) === -1);
|
|
14340
14539
|
}
|
|
14341
14540
|
if (allEIds.length) {
|
|
14541
|
+
// A historic tick re-reads the whole set, so the near ones are worth resolving
|
|
14542
|
+
// first here even more than in the queue above.
|
|
14543
|
+
allEIds = this.bandIds(allEIds);
|
|
14342
14544
|
while (allEIds.length && !this.disposed && !this.eIdQueue.length) {
|
|
14343
14545
|
if (this.historic && this.lastDateTime !== rTime) {
|
|
14344
14546
|
break;
|
|
@@ -14372,6 +14574,11 @@ class EntityGatherer {
|
|
|
14372
14574
|
})();
|
|
14373
14575
|
}
|
|
14374
14576
|
}
|
|
14577
|
+
// Below this the whole queue clears in one or two requests, so ordering it buys nothing.
|
|
14578
|
+
EntityGatherer.MIN_ORDER_QUEUE = 500;
|
|
14579
|
+
// How far the point being looked at has to move before the queue is worth re-banding, in metres.
|
|
14580
|
+
// Under the nearest band's width, so a move that could change what is nearest still triggers one.
|
|
14581
|
+
EntityGatherer.REORDER_MOVE_METRES = 250;
|
|
14375
14582
|
|
|
14376
14583
|
// ND-1641. BOOKMARKS - (DEMO) View does not match bookmark.
|
|
14377
14584
|
// We have some evil hard-coded style mappings that need to be fixed.
|
|
@@ -14495,7 +14702,8 @@ class TilesetStyler {
|
|
|
14495
14702
|
}
|
|
14496
14703
|
Init(params) {
|
|
14497
14704
|
var _a, _b;
|
|
14498
|
-
let { viewer, api, cTileset, fallbackStyleId, styleMapping, expandSources, menuItemId, register, scenario, historic, applyStyles } = params;
|
|
14705
|
+
let { viewer, api, cTileset, fallbackStyleId, styleMapping, expandSources, menuItemId, register, scenario, historic, applyStyles, monitor } = params;
|
|
14706
|
+
this.monitor = monitor;
|
|
14499
14707
|
this.viewer = viewer;
|
|
14500
14708
|
this.api = api;
|
|
14501
14709
|
this.cTileset = cTileset;
|
|
@@ -14551,6 +14759,14 @@ class TilesetStyler {
|
|
|
14551
14759
|
}
|
|
14552
14760
|
}
|
|
14553
14761
|
});
|
|
14762
|
+
// Only Entities Sets bake coordinates into their features, so for any other source this
|
|
14763
|
+
// resolves nothing and the gather stays in insertion order.
|
|
14764
|
+
this.entityGatherer.SetViewMonitor(this.monitor);
|
|
14765
|
+
this.entityGatherer.SetPositionSource((entityId) => {
|
|
14766
|
+
var _a;
|
|
14767
|
+
const visual = (_a = this.getEntityRego(entityId)) === null || _a === void 0 ? void 0 : _a.visual;
|
|
14768
|
+
return (visual === null || visual === void 0 ? void 0 : visual._bakedPos) || null;
|
|
14769
|
+
});
|
|
14554
14770
|
this.loaded = true;
|
|
14555
14771
|
this.loadStyles();
|
|
14556
14772
|
const feed = (_b = this.api) === null || _b === void 0 ? void 0 : _b.RecordChangeFeed;
|
|
@@ -19774,7 +19990,8 @@ var TilesetEntitiesRenderManager;
|
|
|
19774
19990
|
// Saves having to do a case-insensitive lookup every time.
|
|
19775
19991
|
this.featurePropCache = new Map();
|
|
19776
19992
|
this.featurePropsChecked = 0;
|
|
19777
|
-
const { viewer, register: visualsManager, getters: apiGetter, item, initQueue } = params;
|
|
19993
|
+
const { viewer, register: visualsManager, getters: apiGetter, item, initQueue, monitor } = params;
|
|
19994
|
+
this.monitor = monitor;
|
|
19778
19995
|
this.viewer = viewer;
|
|
19779
19996
|
this.getters = apiGetter;
|
|
19780
19997
|
this.item = item;
|
|
@@ -19883,7 +20100,8 @@ var TilesetEntitiesRenderManager;
|
|
|
19883
20100
|
menuItemId: this.item.id,
|
|
19884
20101
|
register: this.visualsManager,
|
|
19885
20102
|
historic: Manager.IsHistoric(this.item),
|
|
19886
|
-
applyStyles: Boolean(this.item.ApplyStyles)
|
|
20103
|
+
applyStyles: Boolean(this.item.ApplyStyles),
|
|
20104
|
+
monitor: this.monitor
|
|
19887
20105
|
});
|
|
19888
20106
|
}
|
|
19889
20107
|
this.onCTilesetLoad();
|
|
@@ -20043,6 +20261,16 @@ var TilesetEntitiesRenderManager;
|
|
|
20043
20261
|
else if (lowered === "internalid") {
|
|
20044
20262
|
this.featurePropCache.set("internalId", prop);
|
|
20045
20263
|
}
|
|
20264
|
+
else if (lowered === "latitude") {
|
|
20265
|
+
this.featurePropCache.set("latitude", prop);
|
|
20266
|
+
}
|
|
20267
|
+
else if (lowered === "longitude") {
|
|
20268
|
+
this.featurePropCache.set("longitude", prop);
|
|
20269
|
+
}
|
|
20270
|
+
// b3dm names the baked height TerrainHeight, the glTF metadata table calls it Altitude.
|
|
20271
|
+
else if (lowered === "terrainheight" || lowered === "altitude") {
|
|
20272
|
+
this.featurePropCache.set("height", prop);
|
|
20273
|
+
}
|
|
20046
20274
|
}
|
|
20047
20275
|
}
|
|
20048
20276
|
Dispose() {
|
|
@@ -20197,7 +20425,8 @@ var TilesetEntitiesRenderManager;
|
|
|
20197
20425
|
menuItemId: this.item.id,
|
|
20198
20426
|
register: this.visualsManager,
|
|
20199
20427
|
historic: Manager.IsHistoric(this.item),
|
|
20200
|
-
applyStyles: Boolean(this.item.ApplyStyles)
|
|
20428
|
+
applyStyles: Boolean(this.item.ApplyStyles),
|
|
20429
|
+
monitor: this.monitor
|
|
20201
20430
|
});
|
|
20202
20431
|
this.queueHandoffRestyle(this.visualsManager.GetRegos({ menuItemId: this.item.id }));
|
|
20203
20432
|
}
|
|
@@ -20240,6 +20469,45 @@ var TilesetEntitiesRenderManager;
|
|
|
20240
20469
|
}
|
|
20241
20470
|
}, 10);
|
|
20242
20471
|
}
|
|
20472
|
+
/*
|
|
20473
|
+
* Reads a numeric feature property, returning null for anything that is not one.
|
|
20474
|
+
*/
|
|
20475
|
+
static readNumber(feature, prop) {
|
|
20476
|
+
const raw = feature.getProperty(prop);
|
|
20477
|
+
// Coercing straight to a number would turn null, undefined and "" into a valid zero,
|
|
20478
|
+
// which for a coordinate is a real place off the coast of Africa.
|
|
20479
|
+
if (raw == null || raw === "" || typeof raw === "boolean") {
|
|
20480
|
+
return null;
|
|
20481
|
+
}
|
|
20482
|
+
const value = +raw;
|
|
20483
|
+
return isFinite(value) ? value : null;
|
|
20484
|
+
}
|
|
20485
|
+
/*
|
|
20486
|
+
* Returns the world position an Entities Set bakes into each feature, or null when it has none.
|
|
20487
|
+
*/
|
|
20488
|
+
readBakedPos(feature) {
|
|
20489
|
+
const latProp = this.featurePropCache.get("latitude");
|
|
20490
|
+
const lonProp = this.featurePropCache.get("longitude");
|
|
20491
|
+
if (!latProp || !lonProp) {
|
|
20492
|
+
return null;
|
|
20493
|
+
}
|
|
20494
|
+
try {
|
|
20495
|
+
const lat = Manager.readNumber(feature, latProp);
|
|
20496
|
+
const lon = Manager.readNumber(feature, lonProp);
|
|
20497
|
+
// Degrees, per the batch table the generator writes. The range check doubles as a
|
|
20498
|
+
// guard against a source that bakes radians, which would otherwise read as valid.
|
|
20499
|
+
if (lat == null || lon == null || Math.abs(lat) > 90 || Math.abs(lon) > 180) {
|
|
20500
|
+
return null;
|
|
20501
|
+
}
|
|
20502
|
+
// A height that will not read is worth losing, the position it belongs to is not.
|
|
20503
|
+
const heightProp = this.featurePropCache.get("height");
|
|
20504
|
+
const height = heightProp ? Manager.readNumber(feature, heightProp) : 0;
|
|
20505
|
+
return Cartesian3.fromDegrees(lon, lat, height !== null && height !== void 0 ? height : 0);
|
|
20506
|
+
}
|
|
20507
|
+
catch {
|
|
20508
|
+
return null;
|
|
20509
|
+
}
|
|
20510
|
+
}
|
|
20243
20511
|
mapTilesetFeature(feature) {
|
|
20244
20512
|
var _a, _b, _c;
|
|
20245
20513
|
this.evaluateFeatureProps(feature);
|
|
@@ -20320,6 +20588,12 @@ var TilesetEntitiesRenderManager;
|
|
|
20320
20588
|
rego.internalId = parsed;
|
|
20321
20589
|
}
|
|
20322
20590
|
}
|
|
20591
|
+
// Stamped on the feature the properties came from, so a sibling keeps its own position
|
|
20592
|
+
// and nothing has to be cleaned up when the tile unloads.
|
|
20593
|
+
const bakedPos = this.readBakedPos(feature);
|
|
20594
|
+
if (bakedPos) {
|
|
20595
|
+
feature._bakedPos = bakedPos;
|
|
20596
|
+
}
|
|
20323
20597
|
this.loadedCesiumEntities[rego.entityId] = rego;
|
|
20324
20598
|
this.visualsManager.AddRego({
|
|
20325
20599
|
rego,
|
|
@@ -24205,6 +24479,7 @@ var MenuItemManager;
|
|
|
24205
24479
|
viewer: this.viewer,
|
|
24206
24480
|
register: this.visualsRegister,
|
|
24207
24481
|
getters: this.getters,
|
|
24482
|
+
monitor: this.sharedMonitor,
|
|
24208
24483
|
item: params.item,
|
|
24209
24484
|
initQueue: this.tilesetInitQueue
|
|
24210
24485
|
});
|
|
@@ -40562,6 +40837,14 @@ var TextureFrameSeriesAnimator;
|
|
|
40562
40837
|
return { scale, offset: SourceValueMin - ValueMin * scale };
|
|
40563
40838
|
}
|
|
40564
40839
|
TextureFrameSeriesAnimator.SourceMap = SourceMap;
|
|
40840
|
+
/**
|
|
40841
|
+
* Whether anything was applied to the values on the way out of the source.
|
|
40842
|
+
* @param metadata the archive's Data.generation
|
|
40843
|
+
*/
|
|
40844
|
+
function IsTransformed(metadata) {
|
|
40845
|
+
return Boolean(metadata && metadata.Transform);
|
|
40846
|
+
}
|
|
40847
|
+
TextureFrameSeriesAnimator.IsTransformed = IsTransformed;
|
|
40565
40848
|
/**
|
|
40566
40849
|
* A delivered value in the source's own terms, or unchanged when it cannot be turned back.
|
|
40567
40850
|
* @param map from SourceMap(), null when the archive does not say enough
|
|
@@ -40991,9 +41274,11 @@ var TextureFrameSeriesAnimator;
|
|
|
40991
41274
|
return;
|
|
40992
41275
|
}
|
|
40993
41276
|
let next = -1;
|
|
41277
|
+
let isTarget = false;
|
|
40994
41278
|
if (this.pendingIndex !== -1) {
|
|
40995
41279
|
next = this.pendingIndex;
|
|
40996
41280
|
this.pendingIndex = -1;
|
|
41281
|
+
isTarget = true;
|
|
40997
41282
|
}
|
|
40998
41283
|
else {
|
|
40999
41284
|
next = this.nearestUncachedFrame();
|
|
@@ -41002,7 +41287,7 @@ var TextureFrameSeriesAnimator;
|
|
|
41002
41287
|
return;
|
|
41003
41288
|
}
|
|
41004
41289
|
this.inFlightIndex = next;
|
|
41005
|
-
this.fetchAndTint(next)
|
|
41290
|
+
this.fetchAndTint(next, isTarget)
|
|
41006
41291
|
.catch(() => {
|
|
41007
41292
|
// Eating it.
|
|
41008
41293
|
})
|
|
@@ -41013,7 +41298,7 @@ var TextureFrameSeriesAnimator;
|
|
|
41013
41298
|
}
|
|
41014
41299
|
});
|
|
41015
41300
|
}
|
|
41016
|
-
async fetchAndTint(idx) {
|
|
41301
|
+
async fetchAndTint(idx, isTarget = true) {
|
|
41017
41302
|
const tiles = this.tiles;
|
|
41018
41303
|
// Every tile's frame for one timestep sits contiguously, because the generator writes
|
|
41019
41304
|
// frame major. So a tiled frame is still ONE range request, not one per tile.
|
|
@@ -41045,10 +41330,25 @@ var TextureFrameSeriesAnimator;
|
|
|
41045
41330
|
this.frameCache[idx] = decoded.pixels;
|
|
41046
41331
|
this.frameDims[idx] = { width: decoded.width, height: decoded.height };
|
|
41047
41332
|
this.valueCache[idx] = decoded.valuePixels || null;
|
|
41048
|
-
if (idx
|
|
41333
|
+
if (this.shouldPresent(idx, isTarget)) {
|
|
41049
41334
|
this.beginCrossfadeTo(idx);
|
|
41050
41335
|
}
|
|
41051
41336
|
}
|
|
41337
|
+
/*
|
|
41338
|
+
* Whether a frame that has just decoded is worth putting on screen.
|
|
41339
|
+
*/
|
|
41340
|
+
shouldPresent(idx, isTarget) {
|
|
41341
|
+
if (idx === this.currentFrameIndex) {
|
|
41342
|
+
return true;
|
|
41343
|
+
}
|
|
41344
|
+
// A prefetch is for a frame nobody asked to see, so it stays in the cache.
|
|
41345
|
+
if (!isTarget) {
|
|
41346
|
+
return false;
|
|
41347
|
+
}
|
|
41348
|
+
// Dragging the timeline retargets faster than a frame can be fetched, so the frame that
|
|
41349
|
+
// lands is rarely the one now under the playhead.
|
|
41350
|
+
return !this.frameCache[this.currentFrameIndex];
|
|
41351
|
+
}
|
|
41052
41352
|
/*
|
|
41053
41353
|
* Draws every tile of one frame into a single raster covering the drape extent.
|
|
41054
41354
|
*/
|
|
@@ -41537,6 +41837,9 @@ var TextureValueLabels;
|
|
|
41537
41837
|
: TextureFrameSeriesAnimator.SourceMap(metadata);
|
|
41538
41838
|
const inSource = (value) => TextureFrameSeriesAnimator.ToSource(toSource, value);
|
|
41539
41839
|
const reading = { value: inSource(lo + normalised * (hi - lo)) };
|
|
41840
|
+
if (TextureFrameSeriesAnimator.IsTransformed(metadata)) {
|
|
41841
|
+
return reading;
|
|
41842
|
+
}
|
|
41540
41843
|
const eLo = metadata && metadata.ExtremesValueMin;
|
|
41541
41844
|
const eHi = metadata && metadata.ExtremesValueMax;
|
|
41542
41845
|
if (typeof eLo === "number" && typeof eHi === "number") {
|
|
@@ -42021,10 +42324,11 @@ var TextureValueLabels;
|
|
|
42021
42324
|
sample.push(valueLine("-000.00", LabelUnits(this.metadata)));
|
|
42022
42325
|
}
|
|
42023
42326
|
const range = [];
|
|
42024
|
-
|
|
42327
|
+
const showsRange = !TextureFrameSeriesAnimator.IsTransformed(this.metadata);
|
|
42328
|
+
if (showsRange && parts.indexOf("floor") >= 0) {
|
|
42025
42329
|
range.push("min: -000.00");
|
|
42026
42330
|
}
|
|
42027
|
-
if (parts.indexOf("ceiling") >= 0) {
|
|
42331
|
+
if (showsRange && parts.indexOf("ceiling") >= 0) {
|
|
42028
42332
|
range.push("max: -000.00");
|
|
42029
42333
|
}
|
|
42030
42334
|
if (range.length) {
|
|
@@ -43954,9 +44258,10 @@ function syncTextureValueLabels(params) {
|
|
|
43954
44258
|
let lastVersion = -1;
|
|
43955
44259
|
let appliedFloor = null;
|
|
43956
44260
|
let appliedCeiling = null;
|
|
43957
|
-
//
|
|
43958
|
-
|
|
43959
|
-
|
|
44261
|
+
// Two extra Range GETs, and worth it only because a label draws the cell's own range from them.
|
|
44262
|
+
if (!TextureFrameSeriesAnimator.IsTransformed(metadata)) {
|
|
44263
|
+
animator.EnsureExtremes();
|
|
44264
|
+
}
|
|
43960
44265
|
const remove = viewer.scene.preRender.addEventListener(() => {
|
|
43961
44266
|
if (animator.IsDisposed()) {
|
|
43962
44267
|
return;
|
|
@@ -45606,7 +45911,7 @@ var StyleUtils;
|
|
|
45606
45911
|
StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
|
|
45607
45912
|
})(StyleUtils || (StyleUtils = {}));
|
|
45608
45913
|
|
|
45609
|
-
const VERSION = "7.2.
|
|
45914
|
+
const VERSION = "7.2.5";
|
|
45610
45915
|
/**
|
|
45611
45916
|
* Updates the environment instance used by bruce-cesium to one specified.
|
|
45612
45917
|
* This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.
|