bruce-cesium 7.0.2 → 7.0.4
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 +1376 -244
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +1374 -242
- package/dist/bruce-cesium.umd.js.map +1 -1
- package/dist/lib/bruce-cesium.js +1 -1
- package/dist/lib/internal/cesium-show-gate.js +100 -0
- package/dist/lib/internal/cesium-show-gate.js.map +1 -0
- package/dist/lib/internal/cesium-utils.js +207 -1
- package/dist/lib/internal/cesium-utils.js.map +1 -1
- package/dist/lib/internal/js-utils.js +25 -1
- package/dist/lib/internal/js-utils.js.map +1 -1
- package/dist/lib/rendering/cesium-animated-in-out.js +66 -7
- package/dist/lib/rendering/cesium-animated-in-out.js.map +1 -1
- package/dist/lib/rendering/entity-render-engine-model3d.js +17 -8
- package/dist/lib/rendering/entity-render-engine-model3d.js.map +1 -1
- package/dist/lib/rendering/entity-render-engine-point.js +46 -12
- package/dist/lib/rendering/entity-render-engine-point.js.map +1 -1
- package/dist/lib/rendering/entity-render-engine-polygon.js +107 -35
- package/dist/lib/rendering/entity-render-engine-polygon.js.map +1 -1
- package/dist/lib/rendering/entity-render-engine-polyline.js +27 -8
- package/dist/lib/rendering/entity-render-engine-polyline.js.map +1 -1
- package/dist/lib/rendering/entity-render-engine.js +86 -14
- package/dist/lib/rendering/entity-render-engine.js.map +1 -1
- package/dist/lib/rendering/menu-item-manager.js +30 -2
- package/dist/lib/rendering/menu-item-manager.js.map +1 -1
- package/dist/lib/rendering/relation-render-engine.js +2 -1
- package/dist/lib/rendering/relation-render-engine.js.map +1 -1
- package/dist/lib/rendering/render-managers/common/entity-label.js +10 -2
- package/dist/lib/rendering/render-managers/common/entity-label.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entities-datalab-render-manager.js +45 -3
- package/dist/lib/rendering/render-managers/entities/entities-datalab-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entities-loaded-render-manager.js +26 -15
- package/dist/lib/rendering/render-managers/entities/entities-loaded-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entities-render-manager.js +50 -3
- package/dist/lib/rendering/render-managers/entities/entities-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/other/legacy-relations-render-manager.js +3 -2
- package/dist/lib/rendering/render-managers/other/legacy-relations-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/other/relations-render-manager.js +3 -2
- package/dist/lib/rendering/render-managers/other/relations-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/render-manager.js +67 -3
- package/dist/lib/rendering/render-managers/render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-arb-render-manager.js +2 -0
- 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 +2 -0
- 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 +2 -0
- package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-pointcloud-render-manager.js +4 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-pointcloud-render-manager.js.map +1 -1
- package/dist/lib/rendering/texture-frame-series-animator.js +7 -0
- package/dist/lib/rendering/texture-frame-series-animator.js.map +1 -1
- package/dist/lib/rendering/tileset-render-engine.js +18 -0
- package/dist/lib/rendering/tileset-render-engine.js.map +1 -1
- package/dist/lib/rendering/visual-register-culler.js +197 -98
- package/dist/lib/rendering/visual-register-culler.js.map +1 -1
- package/dist/lib/rendering/visuals-register.js +263 -25
- package/dist/lib/rendering/visuals-register.js.map +1 -1
- package/dist/lib/utils/cesium-entity-styler.js +7 -3
- package/dist/lib/utils/cesium-entity-styler.js.map +1 -1
- package/dist/types/bruce-cesium.d.ts +1 -1
- package/dist/types/internal/cesium-show-gate.d.ts +29 -0
- package/dist/types/internal/cesium-utils.d.ts +63 -0
- package/dist/types/internal/js-utils.d.ts +10 -0
- package/dist/types/rendering/cesium-animated-in-out.d.ts +5 -0
- package/dist/types/rendering/entity-render-engine-model3d.d.ts +2 -0
- package/dist/types/rendering/entity-render-engine-point.d.ts +2 -0
- package/dist/types/rendering/entity-render-engine-polygon.d.ts +2 -0
- package/dist/types/rendering/entity-render-engine-polyline.d.ts +2 -0
- package/dist/types/rendering/entity-render-engine.d.ts +17 -1
- package/dist/types/rendering/menu-item-manager.d.ts +6 -0
- package/dist/types/rendering/render-managers/entities/entities-datalab-render-manager.d.ts +11 -0
- package/dist/types/rendering/render-managers/entities/entities-render-manager.d.ts +12 -0
- package/dist/types/rendering/render-managers/render-manager.d.ts +33 -0
- package/dist/types/rendering/render-managers/tilesets/tileset-pointcloud-render-manager.d.ts +3 -0
- package/dist/types/rendering/texture-frame-series-animator.d.ts +5 -0
- package/dist/types/rendering/tileset-render-engine.d.ts +14 -0
- package/dist/types/rendering/visual-register-culler.d.ts +7 -0
- package/dist/types/rendering/visuals-register.d.ts +65 -1
- package/dist/types/utils/cesium-entity-styler.d.ts +1 -0
- package/package.json +1 -1
package/dist/bruce-cesium.umd.js
CHANGED
|
@@ -21,6 +21,28 @@
|
|
|
21
21
|
}
|
|
22
22
|
return value;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Returns an entity's own name when it is good enough to use as-is, or null when it has to be resolved properly.
|
|
26
|
+
* @param entity
|
|
27
|
+
*/
|
|
28
|
+
function GetUsableEntityName(entity) {
|
|
29
|
+
var _a;
|
|
30
|
+
return IsUsableEntityName((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.Name) ? String(entity.Bruce.Name).trim() : null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Returns whether a name is a real one rather than empty or a placeholder.
|
|
34
|
+
* @param name
|
|
35
|
+
*/
|
|
36
|
+
function IsUsableEntityName(name) {
|
|
37
|
+
if (typeof name !== "string") {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const trimmed = name.trim();
|
|
41
|
+
if (!trimmed) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return !trimmed.toLowerCase().includes("unnamed");
|
|
45
|
+
}
|
|
24
46
|
|
|
25
47
|
(function (MeasureUtils) {
|
|
26
48
|
/**
|
|
@@ -1955,7 +1977,11 @@
|
|
|
1955
1977
|
}
|
|
1956
1978
|
}
|
|
1957
1979
|
else if (graphic instanceof Cesium.CorridorGraphics) {
|
|
1958
|
-
|
|
1980
|
+
// See if it's changed before applying, same flicker/rebuild concern as the polyline above.
|
|
1981
|
+
const currentColor = calculateCurColor(viewer, graphic);
|
|
1982
|
+
if (currentColor == null || !currentColor.equals(color)) {
|
|
1983
|
+
graphic.material = new Cesium.ColorMaterialProperty(color);
|
|
1984
|
+
}
|
|
1959
1985
|
}
|
|
1960
1986
|
else if (graphic instanceof Cesium.PointGraphics) {
|
|
1961
1987
|
const animateColor = new exports.CesiumAnimatedProperty.AnimateColor({
|
|
@@ -2198,11 +2224,11 @@
|
|
|
2198
2224
|
* @returns
|
|
2199
2225
|
*/
|
|
2200
2226
|
function SetDefaultColor(params) {
|
|
2201
|
-
const { viewer, entity, requestRender, override } = params;
|
|
2227
|
+
const { viewer, entity, requestRender, override, includeSiblings } = params;
|
|
2202
2228
|
if (!entity) {
|
|
2203
2229
|
return;
|
|
2204
2230
|
}
|
|
2205
|
-
const parts = exports.EntityUtils.GatherEntity({
|
|
2231
|
+
const parts = includeSiblings == false ? [entity] : exports.EntityUtils.GatherEntity({
|
|
2206
2232
|
entity: entity,
|
|
2207
2233
|
selectable: true
|
|
2208
2234
|
});
|
|
@@ -3835,6 +3861,202 @@
|
|
|
3835
3861
|
}
|
|
3836
3862
|
return obj;
|
|
3837
3863
|
}
|
|
3864
|
+
/*
|
|
3865
|
+
* Marks an EntityCollection as one this library created and fully controls (a menu item's own data source).
|
|
3866
|
+
*/
|
|
3867
|
+
const OWNED_CCOLLECTION_KEY = "_bruceOwnedCollection";
|
|
3868
|
+
function MarkCCollectionOwned(collection) {
|
|
3869
|
+
if (collection) {
|
|
3870
|
+
collection[OWNED_CCOLLECTION_KEY] = true;
|
|
3871
|
+
}
|
|
3872
|
+
}
|
|
3873
|
+
function IsCCollectionOwned(collection) {
|
|
3874
|
+
return Boolean(collection && collection[OWNED_CCOLLECTION_KEY]);
|
|
3875
|
+
}
|
|
3876
|
+
/**
|
|
3877
|
+
* Runs a bulk collection mutation with every given collection's events suspended, so Cesium raises one
|
|
3878
|
+
* collectionChanged per collection for the whole pass instead of one per entity.
|
|
3879
|
+
*
|
|
3880
|
+
* Takes a set of collections rather than assuming `viewer.entities`, because managed visuals live in their menu
|
|
3881
|
+
* item's own data source: suspending the wrong collection silently does nothing.
|
|
3882
|
+
* @param collections Duplicates and empty entries are ignored.
|
|
3883
|
+
* @param run
|
|
3884
|
+
*/
|
|
3885
|
+
function WithSuspendedCCollections(collections, run) {
|
|
3886
|
+
const unique = [];
|
|
3887
|
+
for (const collection of collections) {
|
|
3888
|
+
if (collection && unique.indexOf(collection) === -1) {
|
|
3889
|
+
unique.push(collection);
|
|
3890
|
+
}
|
|
3891
|
+
}
|
|
3892
|
+
for (const collection of unique) {
|
|
3893
|
+
collection.suspendEvents();
|
|
3894
|
+
}
|
|
3895
|
+
try {
|
|
3896
|
+
return run();
|
|
3897
|
+
}
|
|
3898
|
+
finally {
|
|
3899
|
+
for (const collection of unique) {
|
|
3900
|
+
try {
|
|
3901
|
+
collection.resumeEvents();
|
|
3902
|
+
}
|
|
3903
|
+
catch (e) {
|
|
3904
|
+
console.error(e);
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3908
|
+
}
|
|
3909
|
+
/**
|
|
3910
|
+
* Returns the collection a graphic belongs to, falling back to the viewer's own when it has never been added.
|
|
3911
|
+
* @param viewer
|
|
3912
|
+
* @param entity
|
|
3913
|
+
*/
|
|
3914
|
+
function GetCEntityCollection(viewer, entity) {
|
|
3915
|
+
const owner = entity === null || entity === void 0 ? void 0 : entity.entityCollection;
|
|
3916
|
+
return owner ? owner : viewer === null || viewer === void 0 ? void 0 : viewer.entities;
|
|
3917
|
+
}
|
|
3918
|
+
/**
|
|
3919
|
+
* Returns whether a graphic is currently in the scene, looking in whichever collection owns it.
|
|
3920
|
+
* @param viewer
|
|
3921
|
+
* @param entity
|
|
3922
|
+
*/
|
|
3923
|
+
function IsCEntityInScene(viewer, entity) {
|
|
3924
|
+
const collection = GetCEntityCollection(viewer, entity);
|
|
3925
|
+
return Boolean(collection && entity && collection.contains(entity));
|
|
3926
|
+
}
|
|
3927
|
+
/**
|
|
3928
|
+
* Removes a graphic from whichever collection owns it. Returns whether it removed anything.
|
|
3929
|
+
* @param viewer
|
|
3930
|
+
* @param entity
|
|
3931
|
+
*/
|
|
3932
|
+
function RemoveCEntityFromScene(viewer, entity) {
|
|
3933
|
+
var _a;
|
|
3934
|
+
if (!entity) {
|
|
3935
|
+
return false;
|
|
3936
|
+
}
|
|
3937
|
+
const collection = GetCEntityCollection(viewer, entity);
|
|
3938
|
+
if (collection === null || collection === void 0 ? void 0 : collection.contains(entity)) {
|
|
3939
|
+
return collection.remove(entity);
|
|
3940
|
+
}
|
|
3941
|
+
// A stale owner reference and the graphic ended up in the viewer's collection anyway.
|
|
3942
|
+
if (collection !== (viewer === null || viewer === void 0 ? void 0 : viewer.entities) && ((_a = viewer === null || viewer === void 0 ? void 0 : viewer.entities) === null || _a === void 0 ? void 0 : _a.contains(entity))) {
|
|
3943
|
+
return viewer.entities.remove(entity);
|
|
3944
|
+
}
|
|
3945
|
+
return false;
|
|
3946
|
+
}
|
|
3947
|
+
/**
|
|
3948
|
+
* Adds a graphic back into whichever collection owns it, or the viewer's if it has no owner yet.
|
|
3949
|
+
* @param viewer
|
|
3950
|
+
* @param entity
|
|
3951
|
+
*/
|
|
3952
|
+
function AddCEntityToScene(viewer, entity, fallbackCollection) {
|
|
3953
|
+
if (!entity) {
|
|
3954
|
+
return false;
|
|
3955
|
+
}
|
|
3956
|
+
// An existing owner always wins, so a graphic is never migrated out from under whoever holds it.
|
|
3957
|
+
const owner = entity.entityCollection;
|
|
3958
|
+
const collection = owner ? owner : (fallbackCollection ? fallbackCollection : viewer === null || viewer === void 0 ? void 0 : viewer.entities);
|
|
3959
|
+
if (!collection || collection.contains(entity)) {
|
|
3960
|
+
return false;
|
|
3961
|
+
}
|
|
3962
|
+
collection.add(entity);
|
|
3963
|
+
return true;
|
|
3964
|
+
}
|
|
3965
|
+
/**
|
|
3966
|
+
* Returns whether toggling `show` on these graphics is safe, rather than having to add/remove them from the
|
|
3967
|
+
* entity collection to hide them.
|
|
3968
|
+
*
|
|
3969
|
+
* Toggling show is far cheaper than re-adding the graphic to the viewer however a Cesium bug means we can't always use it.
|
|
3970
|
+
* See: https://github.com/CesiumGS/cesium/issues/9370
|
|
3971
|
+
* @param parts The graphic and any sibling graphics, eg. from EntityUtils.GatherEntity.
|
|
3972
|
+
*/
|
|
3973
|
+
function CanToggleShowSafely(parts) {
|
|
3974
|
+
if (!(parts === null || parts === void 0 ? void 0 : parts.length)) {
|
|
3975
|
+
return false;
|
|
3976
|
+
}
|
|
3977
|
+
for (const part of parts) {
|
|
3978
|
+
if (!(part instanceof Cesium.Entity)) {
|
|
3979
|
+
// Not an Entity, so not something whose `show` we can drive.
|
|
3980
|
+
return false;
|
|
3981
|
+
}
|
|
3982
|
+
if (part.polyline && isTruthyCValue(part.polyline.clampToGround)) {
|
|
3983
|
+
return false;
|
|
3984
|
+
}
|
|
3985
|
+
const materialGraphics = [part.polygon, part.corridor, part.ellipse, part.rectangle, part.wall, part.polylineVolume];
|
|
3986
|
+
for (const graphic of materialGraphics) {
|
|
3987
|
+
if (graphic && !isPlainColorMaterial(graphic.material)) {
|
|
3988
|
+
return false;
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
}
|
|
3992
|
+
return true;
|
|
3993
|
+
}
|
|
3994
|
+
/**
|
|
3995
|
+
* Returns whether a material is a plain colour, which is what keeps a graphic out of Cesium's per-material batches.
|
|
3996
|
+
* Anything unrecognised counts as not plain, so callers stay on the conservative side.
|
|
3997
|
+
* @param material
|
|
3998
|
+
*/
|
|
3999
|
+
function isPlainColorMaterial(material) {
|
|
4000
|
+
if (material == null) {
|
|
4001
|
+
// Cesium defaults an absent material to white, a plain colour.
|
|
4002
|
+
return true;
|
|
4003
|
+
}
|
|
4004
|
+
return material instanceof Cesium.ColorMaterialProperty || material instanceof Cesium.Color;
|
|
4005
|
+
}
|
|
4006
|
+
/**
|
|
4007
|
+
* Resolves a possibly-property boolean without needing a viewer clock, treating anything undeterminable as true
|
|
4008
|
+
* so callers stay on the conservative side.
|
|
4009
|
+
* @param value
|
|
4010
|
+
*/
|
|
4011
|
+
function isTruthyCValue(value) {
|
|
4012
|
+
if (value == null) {
|
|
4013
|
+
return false;
|
|
4014
|
+
}
|
|
4015
|
+
if (typeof value.getValue === "function") {
|
|
4016
|
+
if (value instanceof Cesium.ConstantProperty) {
|
|
4017
|
+
return Boolean(value.valueOf());
|
|
4018
|
+
}
|
|
4019
|
+
// A non-constant property could be true at any moment, so assume it is.
|
|
4020
|
+
return true;
|
|
4021
|
+
}
|
|
4022
|
+
return Boolean(value);
|
|
4023
|
+
}
|
|
4024
|
+
/**
|
|
4025
|
+
* Returns if two resolved Cesium property values are equal, using the value's own equals() when it has one.
|
|
4026
|
+
* @param a
|
|
4027
|
+
* @param b
|
|
4028
|
+
*/
|
|
4029
|
+
function AreCValuesEqual(a, b) {
|
|
4030
|
+
if (a === b) {
|
|
4031
|
+
return true;
|
|
4032
|
+
}
|
|
4033
|
+
// One side is null/undefined and the other isn't.
|
|
4034
|
+
if (a == null || b == null) {
|
|
4035
|
+
return false;
|
|
4036
|
+
}
|
|
4037
|
+
if (typeof a.equals === "function") {
|
|
4038
|
+
return a.equals(b) === true;
|
|
4039
|
+
}
|
|
4040
|
+
return false;
|
|
4041
|
+
}
|
|
4042
|
+
/**
|
|
4043
|
+
* Wraps a value in a ConstantProperty and assigns it to a graphic's property, but only when the resolved
|
|
4044
|
+
* value actually differs. Returns whether it assigned.
|
|
4045
|
+
* @param params
|
|
4046
|
+
*/
|
|
4047
|
+
function SetCPropIfChanged(params) {
|
|
4048
|
+
const { viewer, graphic, property, value, compare } = params;
|
|
4049
|
+
if (!graphic) {
|
|
4050
|
+
return false;
|
|
4051
|
+
}
|
|
4052
|
+
const oldValue = GetCValue(viewer, graphic[property]);
|
|
4053
|
+
const isEqual = compare ? compare(oldValue, value) : AreCValuesEqual(oldValue, value);
|
|
4054
|
+
if (isEqual) {
|
|
4055
|
+
return false;
|
|
4056
|
+
}
|
|
4057
|
+
graphic[property] = new Cesium.ConstantProperty(value);
|
|
4058
|
+
return true;
|
|
4059
|
+
}
|
|
3838
4060
|
function ColorToCColor(color) {
|
|
3839
4061
|
return new Cesium.Color(color.red ? color.red / 255 : 0, color.green ? color.green / 255 : 0, color.blue ? color.blue / 255 : 0, color.alpha);
|
|
3840
4062
|
}
|
|
@@ -4322,6 +4544,85 @@
|
|
|
4322
4544
|
ViewUtils.GetModelSpace = GetModelSpace;
|
|
4323
4545
|
})(exports.ViewUtils || (exports.ViewUtils = {}));
|
|
4324
4546
|
|
|
4547
|
+
/*
|
|
4548
|
+
* Lets something decide WHEN a `show` flag is honoured, without owning WHAT it should be.
|
|
4549
|
+
*/
|
|
4550
|
+
const SHOW_GATE_KEY = "_bruceShowGate";
|
|
4551
|
+
/**
|
|
4552
|
+
* Installs a show gate on an object, or returns the one already installed.
|
|
4553
|
+
* Returns null when the property cannot be intercepted or restored, in which case the caller must leave `show` alone rather than fall back to writing it directly.
|
|
4554
|
+
* @param target Anything with a plain, configurable `show` property.
|
|
4555
|
+
*/
|
|
4556
|
+
function InstallShowGate(target) {
|
|
4557
|
+
if (!target) {
|
|
4558
|
+
return null;
|
|
4559
|
+
}
|
|
4560
|
+
const existing = target[SHOW_GATE_KEY];
|
|
4561
|
+
if (existing) {
|
|
4562
|
+
return existing;
|
|
4563
|
+
}
|
|
4564
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, "show");
|
|
4565
|
+
// An accessor already, or something we could not put back, so refuse rather than half-apply.
|
|
4566
|
+
if (descriptor && (!descriptor.configurable || descriptor.get || descriptor.set)) {
|
|
4567
|
+
return null;
|
|
4568
|
+
}
|
|
4569
|
+
let intended = target.show !== false;
|
|
4570
|
+
let suppressed = false;
|
|
4571
|
+
try {
|
|
4572
|
+
Object.defineProperty(target, "show", {
|
|
4573
|
+
configurable: true,
|
|
4574
|
+
enumerable: descriptor ? descriptor.enumerable : true,
|
|
4575
|
+
get: () => intended && !suppressed,
|
|
4576
|
+
set: (value) => {
|
|
4577
|
+
intended = value !== false;
|
|
4578
|
+
}
|
|
4579
|
+
});
|
|
4580
|
+
}
|
|
4581
|
+
catch (e) {
|
|
4582
|
+
console.error("Failed to install a show gate.", e);
|
|
4583
|
+
return null;
|
|
4584
|
+
}
|
|
4585
|
+
const gate = {
|
|
4586
|
+
get Intended() {
|
|
4587
|
+
return intended;
|
|
4588
|
+
},
|
|
4589
|
+
get Suppressed() {
|
|
4590
|
+
return suppressed;
|
|
4591
|
+
},
|
|
4592
|
+
SetSuppressed(value) {
|
|
4593
|
+
const next = Boolean(value);
|
|
4594
|
+
if (next === suppressed) {
|
|
4595
|
+
return false;
|
|
4596
|
+
}
|
|
4597
|
+
const before = intended && !suppressed;
|
|
4598
|
+
suppressed = next;
|
|
4599
|
+
return (intended && !suppressed) !== before;
|
|
4600
|
+
},
|
|
4601
|
+
Release() {
|
|
4602
|
+
try {
|
|
4603
|
+
delete target[SHOW_GATE_KEY];
|
|
4604
|
+
Object.defineProperty(target, "show", {
|
|
4605
|
+
configurable: true,
|
|
4606
|
+
enumerable: descriptor ? descriptor.enumerable : true,
|
|
4607
|
+
writable: true,
|
|
4608
|
+
// The intent, not the gated value: releasing must not leave something culled forever.
|
|
4609
|
+
value: intended
|
|
4610
|
+
});
|
|
4611
|
+
}
|
|
4612
|
+
catch (e) {
|
|
4613
|
+
console.error("Failed to release a show gate.", e);
|
|
4614
|
+
}
|
|
4615
|
+
}
|
|
4616
|
+
};
|
|
4617
|
+
Object.defineProperty(target, SHOW_GATE_KEY, {
|
|
4618
|
+
value: gate,
|
|
4619
|
+
configurable: true,
|
|
4620
|
+
enumerable: false,
|
|
4621
|
+
writable: true
|
|
4622
|
+
});
|
|
4623
|
+
return gate;
|
|
4624
|
+
}
|
|
4625
|
+
|
|
4325
4626
|
/**
|
|
4326
4627
|
* Returns cesium property's value.
|
|
4327
4628
|
* This will check if it's one that changes over time, or just a fixed value.
|
|
@@ -4395,10 +4696,17 @@
|
|
|
4395
4696
|
* Loads the Entity's name and updates the corresponding visual rego.
|
|
4396
4697
|
*/
|
|
4397
4698
|
async loadName() {
|
|
4699
|
+
var _a;
|
|
4398
4700
|
if (this.loadedName) {
|
|
4399
4701
|
return;
|
|
4400
4702
|
}
|
|
4401
4703
|
try {
|
|
4704
|
+
// A rego that already holds a real name needs no lookup. Placeholders do not count, or a cached
|
|
4705
|
+
// "Unnamed Entity" would stop the real name ever being resolved.
|
|
4706
|
+
if (IsUsableEntityName((_a = this.rego) === null || _a === void 0 ? void 0 : _a.name)) {
|
|
4707
|
+
this.loadedName = true;
|
|
4708
|
+
return;
|
|
4709
|
+
}
|
|
4402
4710
|
if (this.api) {
|
|
4403
4711
|
const rego = this.rego;
|
|
4404
4712
|
this.rego.name = await BModels.Entity.CalculateNameAsync({
|
|
@@ -5585,7 +5893,7 @@
|
|
|
5585
5893
|
return;
|
|
5586
5894
|
}
|
|
5587
5895
|
if (parabola) {
|
|
5588
|
-
const visible = cEntity && cEntity.show != false && params.viewer
|
|
5896
|
+
const visible = cEntity && cEntity.show != false && IsCEntityInScene(params.viewer, cEntity);
|
|
5589
5897
|
parabola.Hidden = !visible;
|
|
5590
5898
|
}
|
|
5591
5899
|
updatePosses();
|
|
@@ -5613,18 +5921,58 @@
|
|
|
5613
5921
|
// If a shape has more than this amount of points, we'll avoid checking it because it will take too long.
|
|
5614
5922
|
// We will put responsibility on the bookmark creator to view shapes they can see.
|
|
5615
5923
|
const DO_NOT_CULL_AT_LEN_POINTS = 5000;
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
const
|
|
5623
|
-
|
|
5924
|
+
const _terrainCache = new BModels.LRUCache(20000);
|
|
5925
|
+
/*
|
|
5926
|
+
* Past this camera distance the terrain sample is skipped entirely (resolving a long-standing TODO here).
|
|
5927
|
+
* The sphere's radius is padded by TERRAIN_SKIP_RADIUS_PAD instead, which covers any plausible unresolved ground height.
|
|
5928
|
+
*/
|
|
5929
|
+
const TERRAIN_SKIP_DISTANCE = 60000;
|
|
5930
|
+
const TERRAIN_SKIP_RADIUS_PAD = 1500;
|
|
5931
|
+
// Edge length of a coarse grid cell, and of the finer cell used where the ground turns out to be varied.
|
|
5932
|
+
const TERRAIN_CELL_SIZE = 400;
|
|
5933
|
+
const TERRAIN_CELL_SIZE_FINE = 50;
|
|
5934
|
+
// A cell spanning more than this much height cannot be answered with a single average.
|
|
5935
|
+
const TERRAIN_CELL_MAX_SPREAD = 25;
|
|
5936
|
+
/**
|
|
5937
|
+
* Builds the grid key for a position at a given cell size.
|
|
5938
|
+
*/
|
|
5939
|
+
function terrainCellKey(terrainId, pos3d, cellSize) {
|
|
5940
|
+
const x = Math.floor(pos3d.x / cellSize);
|
|
5941
|
+
const y = Math.floor(pos3d.y / cellSize);
|
|
5942
|
+
const z = Math.floor(pos3d.z / cellSize);
|
|
5943
|
+
return `${terrainId}_${cellSize}_${x}_${y}_${z}`;
|
|
5944
|
+
}
|
|
5945
|
+
/**
|
|
5946
|
+
* Folds a sample into a cell, refining its estimate and noticing when the region is too varied to average.
|
|
5947
|
+
*/
|
|
5948
|
+
function recordTerrainSample(key, height) {
|
|
5949
|
+
const existing = _terrainCache.Get(key);
|
|
5950
|
+
if (!existing) {
|
|
5951
|
+
const cell = {
|
|
5952
|
+
offset: height,
|
|
5953
|
+
count: 1,
|
|
5954
|
+
min: height,
|
|
5955
|
+
max: height,
|
|
5956
|
+
needsDetail: false
|
|
5957
|
+
};
|
|
5958
|
+
_terrainCache.Set(key, cell);
|
|
5959
|
+
return cell;
|
|
5960
|
+
}
|
|
5961
|
+
existing.count++;
|
|
5962
|
+
// Running mean, so the estimate keeps improving rather than being whatever landed first.
|
|
5963
|
+
existing.offset += (height - existing.offset) / existing.count;
|
|
5964
|
+
existing.min = Math.min(existing.min, height);
|
|
5965
|
+
existing.max = Math.max(existing.max, height);
|
|
5966
|
+
if (existing.max - existing.min > TERRAIN_CELL_MAX_SPREAD) {
|
|
5967
|
+
existing.needsDetail = true;
|
|
5968
|
+
}
|
|
5969
|
+
_terrainCache.Set(key, existing);
|
|
5970
|
+
return existing;
|
|
5971
|
+
}
|
|
5624
5972
|
/**
|
|
5625
5973
|
* Returns the terrain height for a given position.
|
|
5626
5974
|
* This will not sample most-detailed and instead the current state of the terrain.
|
|
5627
|
-
*
|
|
5975
|
+
* Callers past TERRAIN_SKIP_DISTANCE should not be asking at all, see shouldCullEntity.
|
|
5628
5976
|
* @param viewer
|
|
5629
5977
|
* @param pos3d
|
|
5630
5978
|
* @returns
|
|
@@ -5641,37 +5989,36 @@
|
|
|
5641
5989
|
return 0;
|
|
5642
5990
|
}
|
|
5643
5991
|
const terrainId = terrain.tilesetId;
|
|
5644
|
-
//
|
|
5645
|
-
|
|
5646
|
-
const
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
const pos3d2 = new Cesium.Cartesian3(parseFloat(x), parseFloat(y), parseFloat(z));
|
|
5654
|
-
const distance = Cesium.Cartesian3.distance(pos3d, pos3d2);
|
|
5655
|
-
if (distance < tolerance) {
|
|
5656
|
-
return offset;
|
|
5657
|
-
}
|
|
5992
|
+
// Always start coarse and let the region teach us where that is not good enough, rather than guessing from a scene-wide entity count.
|
|
5993
|
+
// A cell that turns out to span varied ground flags itself and its lookups move to the finer grid.
|
|
5994
|
+
const coarseKey = terrainCellKey(terrainId, pos3d, TERRAIN_CELL_SIZE);
|
|
5995
|
+
const coarseCell = _terrainCache.Get(coarseKey);
|
|
5996
|
+
const useFine = Boolean(coarseCell === null || coarseCell === void 0 ? void 0 : coarseCell.needsDetail);
|
|
5997
|
+
const key = useFine ? terrainCellKey(terrainId, pos3d, TERRAIN_CELL_SIZE_FINE) : coarseKey;
|
|
5998
|
+
const cell = useFine ? _terrainCache.Get(key) : coarseCell;
|
|
5999
|
+
if (cell && !cell.needsDetail) {
|
|
6000
|
+
return cell.offset;
|
|
5658
6001
|
}
|
|
5659
|
-
const
|
|
5660
|
-
let
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
catch (e) {
|
|
5668
|
-
// Likely out of rendered area.
|
|
5669
|
-
// This means it's not our problem since the user isn't looking there :)
|
|
5670
|
-
}
|
|
5671
|
-
offset = height;
|
|
5672
|
-
_terrainCache.Set(key, offset);
|
|
6002
|
+
const carto = Cesium.Cartographic.fromCartesian(pos3d);
|
|
6003
|
+
let height = 0;
|
|
6004
|
+
try {
|
|
6005
|
+
height = viewer.scene.globe.getHeight(carto);
|
|
6006
|
+
}
|
|
6007
|
+
catch (e) {
|
|
6008
|
+
// Likely out of rendered area.
|
|
6009
|
+
// This means it's not our problem since the user isn't looking there :)
|
|
5673
6010
|
}
|
|
5674
|
-
|
|
6011
|
+
if (height == null || isNaN(height)) {
|
|
6012
|
+
// Terrain tile not loaded yet. Don't record it, so a later pass can sample it properly.
|
|
6013
|
+
return coarseCell ? coarseCell.offset : 0;
|
|
6014
|
+
}
|
|
6015
|
+
// Always fold into the coarse cell as well, so its spread keeps being learned even while the finer grid is
|
|
6016
|
+
// answering lookups for this region.
|
|
6017
|
+
const recorded = recordTerrainSample(key, height);
|
|
6018
|
+
if (useFine) {
|
|
6019
|
+
recordTerrainSample(coarseKey, height);
|
|
6020
|
+
}
|
|
6021
|
+
return recorded.offset;
|
|
5675
6022
|
};
|
|
5676
6023
|
/**
|
|
5677
6024
|
* Converts given pos3d into a an absolute position.
|
|
@@ -5721,6 +6068,11 @@
|
|
|
5721
6068
|
}
|
|
5722
6069
|
return obj;
|
|
5723
6070
|
}
|
|
6071
|
+
/*
|
|
6072
|
+
* Cache identity for a terrain provider we cannot name, which is anything without our own metadata on it and not
|
|
6073
|
+
* Cesium's own flat ellipsoid. Deliberately not FlatTerrain, see shouldCullEntity.
|
|
6074
|
+
*/
|
|
6075
|
+
const UNRECOGNISED_TERRAIN_ID = "unrecognised-terrain";
|
|
5724
6076
|
const boundingSphereCache = new BModels.LRUCache(100000);
|
|
5725
6077
|
function getPositionsFromEntity(viewer, entity) {
|
|
5726
6078
|
let positions = [];
|
|
@@ -5838,7 +6190,7 @@
|
|
|
5838
6190
|
let boundingSphere;
|
|
5839
6191
|
const terrainId = (_c = (_b = (_a = exports.ViewUtils.GatherTerrainTile({
|
|
5840
6192
|
viewer
|
|
5841
|
-
})) === null || _a === void 0 ? void 0 : _a.terrain) === null || _b === void 0 ? void 0 : _b.tilesetId) !== null && _c !== void 0 ? _c :
|
|
6193
|
+
})) === null || _a === void 0 ? void 0 : _a.terrain) === null || _b === void 0 ? void 0 : _b.tilesetId) !== null && _c !== void 0 ? _c : UNRECOGNISED_TERRAIN_ID;
|
|
5842
6194
|
const cacheKey = terrainId + cEntity.id;
|
|
5843
6195
|
const cacheData = boundingSphereCache.Get(cacheKey);
|
|
5844
6196
|
if (cacheData) {
|
|
@@ -5855,6 +6207,10 @@
|
|
|
5855
6207
|
if (cEntity.model) {
|
|
5856
6208
|
const model = cEntity.model;
|
|
5857
6209
|
if (model._radius && !isNaN(model._radius)) {
|
|
6210
|
+
// _radius is already measured from the model's origin rather than its own centre: the model3d
|
|
6211
|
+
// engine folds the bounding sphere's centre offset into it (plus padding for badly-centred
|
|
6212
|
+
// models), and measures it at the entity's scale. So it can be used as-is against a sphere
|
|
6213
|
+
// centred on the entity position.
|
|
5858
6214
|
sphere.radius = Math.max(model._radius, MODEL_MIN_RADIUS);
|
|
5859
6215
|
}
|
|
5860
6216
|
else {
|
|
@@ -5868,12 +6224,10 @@
|
|
|
5868
6224
|
let radius = getValue$1(viewer, cEntity.ellipse.semiMajorAxis);
|
|
5869
6225
|
const extrusion = getValue$1(viewer, cEntity.ellipse.extrudedHeight);
|
|
5870
6226
|
if (extrusion && !isNaN(extrusion)) {
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
radius = extrusion;
|
|
5876
|
-
}
|
|
6227
|
+
// Expand rather than replace: measured from the base centre, the top rim of an extruded ellipse
|
|
6228
|
+
// sits at sqrt(radius^2 + height^2). Taking whichever of the two is larger leaves the rim outside
|
|
6229
|
+
// the sphere, and for something both wide and tall it would actually shrink it.
|
|
6230
|
+
radius = radius ? Math.sqrt((radius * radius) + (extrusion * extrusion)) : extrusion;
|
|
5877
6231
|
}
|
|
5878
6232
|
if (radius && !isNaN(radius)) {
|
|
5879
6233
|
sphere.radius = radius;
|
|
@@ -5883,12 +6237,11 @@
|
|
|
5883
6237
|
else if (cEntity.polygon) {
|
|
5884
6238
|
const extrusion = getValue$1(viewer, cEntity.polygon.extrudedHeight);
|
|
5885
6239
|
if (extrusion && !isNaN(extrusion)) {
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
}
|
|
6240
|
+
// Same as the ellipse above: the footprint sphere has to grow to reach the extruded top corners,
|
|
6241
|
+
// at sqrt(footprint^2 + height^2) from the footprint centre.
|
|
6242
|
+
sphere.radius = sphere.radius
|
|
6243
|
+
? Math.sqrt((sphere.radius * sphere.radius) + (extrusion * extrusion))
|
|
6244
|
+
: extrusion;
|
|
5892
6245
|
}
|
|
5893
6246
|
}
|
|
5894
6247
|
else if (cEntity.point || cEntity.billboard) {
|
|
@@ -5910,7 +6263,15 @@
|
|
|
5910
6263
|
return false;
|
|
5911
6264
|
}
|
|
5912
6265
|
const adjustedSphere = boundingSphere.sphere.clone();
|
|
5913
|
-
|
|
6266
|
+
// Terrain only matters here because it moves the sphere onto the ground.
|
|
6267
|
+
// Far enough away that a plausible ground height is a rounding error against the viewing distance, sampling it is wasted work.
|
|
6268
|
+
const cameraDistance = Cesium.Cartesian3.distance(camera.position, adjustedSphere.center);
|
|
6269
|
+
if (cameraDistance > TERRAIN_SKIP_DISTANCE) {
|
|
6270
|
+
adjustedSphere.radius += TERRAIN_SKIP_RADIUS_PAD;
|
|
6271
|
+
}
|
|
6272
|
+
else {
|
|
6273
|
+
adjustedSphere.center = adjustPos3d(viewer, boundingSphere.heightRef, adjustedSphere.center);
|
|
6274
|
+
}
|
|
5914
6275
|
const cullingVolume = camera.frustum.computeCullingVolume(camera.position, camera.direction, camera.up);
|
|
5915
6276
|
const visibility = cullingVolume.computeVisibility(adjustedSphere);
|
|
5916
6277
|
return visibility !== Cesium.Intersect.INSIDE && visibility !== Cesium.Intersect.INTERSECTING;
|
|
@@ -5983,38 +6344,67 @@
|
|
|
5983
6344
|
rego.relation != null ||
|
|
5984
6345
|
// Explicitly being either shown or hidden.
|
|
5985
6346
|
rego.overrideShow != null ||
|
|
5986
|
-
// Part of
|
|
5987
|
-
//
|
|
5988
|
-
rego.collection ||
|
|
6347
|
+
// Part of a collection we did not create, eg. a geojson data source, which may have its own rules for
|
|
6348
|
+
// what is in the scene. Our own per-menu-item data sources are fair game.
|
|
6349
|
+
(rego.collection && !IsCCollectionOwned(rego.collection)) ||
|
|
5989
6350
|
// We won't cull historic records as they may be interpolating their locations.
|
|
5990
6351
|
Boolean(rego.outline && rego.outline.some(x => !!x.DateTime))) {
|
|
5991
6352
|
return true;
|
|
5992
6353
|
}
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6354
|
+
return false;
|
|
6355
|
+
}
|
|
6356
|
+
// A tileset's bounds are padded by this fraction before testing, so panning does not immediately evict something
|
|
6357
|
+
// at the edge of view and pay to re-traverse it moments later.
|
|
6358
|
+
const TILESET_CULL_PADDING = 0.25;
|
|
6359
|
+
/**
|
|
6360
|
+
* Suppresses tilesets whose padded bounds are outside the view, and restores ones that come back.
|
|
6361
|
+
*
|
|
6362
|
+
* Worth doing separately from entity culling because Cesium gates a tileset's whole update on its show flag: a
|
|
6363
|
+
* hidden tileset skips traversal, tile selection and request scheduling entirely, where hiding its features still
|
|
6364
|
+
* does all of that and merely draws nothing. There are only ever a handful of tilesets, so this needs no batching.
|
|
6365
|
+
* @param register
|
|
6366
|
+
*/
|
|
6367
|
+
function cullTilesets(register) {
|
|
6368
|
+
var _a;
|
|
6369
|
+
const viewer = register.Viewer;
|
|
6370
|
+
const tilesets = register.GetTilesets();
|
|
6371
|
+
if (!tilesets.length || viewer.isDestroyed() || !viewer.scene) {
|
|
6372
|
+
return;
|
|
6010
6373
|
}
|
|
6011
|
-
|
|
6012
|
-
|
|
6374
|
+
const camera = viewer.scene.camera;
|
|
6375
|
+
const cullingVolume = camera.frustum.computeCullingVolume(camera.position, camera.direction, camera.up);
|
|
6376
|
+
let changed = false;
|
|
6377
|
+
for (const rego of tilesets) {
|
|
6378
|
+
const tileset = rego.tileset;
|
|
6379
|
+
if (!tileset || !rego.gate) {
|
|
6380
|
+
continue;
|
|
6381
|
+
}
|
|
6382
|
+
// A destroyed tileset should not be held onto, let alone culled.
|
|
6383
|
+
if ((_a = tileset.isDestroyed) === null || _a === void 0 ? void 0 : _a.call(tileset)) {
|
|
6384
|
+
register.RemoveTileset(tileset);
|
|
6385
|
+
continue;
|
|
6386
|
+
}
|
|
6387
|
+
let sphere;
|
|
6388
|
+
try {
|
|
6389
|
+
sphere = tileset.boundingSphere;
|
|
6390
|
+
}
|
|
6391
|
+
catch (e) {
|
|
6392
|
+
// Not ready yet. Leave it alone rather than guessing.
|
|
6393
|
+
continue;
|
|
6394
|
+
}
|
|
6395
|
+
if (!sphere || isNaN(sphere.radius) || sphere.radius <= 0) {
|
|
6396
|
+
continue;
|
|
6397
|
+
}
|
|
6398
|
+
const padded = sphere.clone();
|
|
6399
|
+
padded.radius = sphere.radius * (1 + TILESET_CULL_PADDING);
|
|
6400
|
+
const visible = cullingVolume.computeVisibility(padded) !== Cesium.Intersect.OUTSIDE;
|
|
6401
|
+
if (register.SetTilesetCulled(tileset, !visible)) {
|
|
6402
|
+
changed = true;
|
|
6403
|
+
}
|
|
6013
6404
|
}
|
|
6014
|
-
|
|
6015
|
-
|
|
6405
|
+
if (changed) {
|
|
6406
|
+
viewer.scene.requestRender();
|
|
6016
6407
|
}
|
|
6017
|
-
return heightRef != Cesium.HeightReference.CLAMP_TO_GROUND;
|
|
6018
6408
|
}
|
|
6019
6409
|
/**
|
|
6020
6410
|
* Runs through all entities in the register and culls them if they are out of the viewport.
|
|
@@ -6030,6 +6420,7 @@
|
|
|
6030
6420
|
const entityIds = register.GetEntityIds();
|
|
6031
6421
|
// We'll use the terrain cache per culler cycle.
|
|
6032
6422
|
_terrainCache.Clear();
|
|
6423
|
+
cullTilesets(register);
|
|
6033
6424
|
checkInterval = setInterval(() => {
|
|
6034
6425
|
var _a;
|
|
6035
6426
|
if (viewer.isDestroyed() || !viewer.scene) {
|
|
@@ -6082,7 +6473,7 @@
|
|
|
6082
6473
|
else {
|
|
6083
6474
|
delete part[VisualRegisterCuller.VISUAL_CULL_KEY];
|
|
6084
6475
|
if (rego.overrideShow != false &&
|
|
6085
|
-
!viewer
|
|
6476
|
+
!IsCEntityInScene(viewer, part) &&
|
|
6086
6477
|
!state.hidden &&
|
|
6087
6478
|
(!isIsolatedAny || state.isolated)) {
|
|
6088
6479
|
toAdd.push(part);
|
|
@@ -6122,16 +6513,17 @@
|
|
|
6122
6513
|
}
|
|
6123
6514
|
const removal = viewer.scene.postRender.addEventListener(() => {
|
|
6124
6515
|
removal();
|
|
6125
|
-
for
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6516
|
+
// Batched, so Cesium raises one collectionChanged for the whole cull pass instead of one per entity.
|
|
6517
|
+
WithSuspendedCCollections(entities.map(x => GetCEntityCollection(viewer, x)), () => {
|
|
6518
|
+
for (let i = 0; i < entities.length; i++) {
|
|
6519
|
+
const entity = entities[i];
|
|
6520
|
+
if (entityRemoveAddState.get(entity.id) != false) {
|
|
6521
|
+
continue;
|
|
6522
|
+
}
|
|
6523
|
+
entityRemoveAddState.delete(entity.id);
|
|
6524
|
+
RemoveCEntityFromScene(viewer, entity);
|
|
6133
6525
|
}
|
|
6134
|
-
}
|
|
6526
|
+
});
|
|
6135
6527
|
});
|
|
6136
6528
|
}
|
|
6137
6529
|
/**
|
|
@@ -6146,16 +6538,17 @@
|
|
|
6146
6538
|
}
|
|
6147
6539
|
const removal = viewer.scene.postRender.addEventListener(() => {
|
|
6148
6540
|
removal();
|
|
6149
|
-
for
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6541
|
+
// Batched, so Cesium raises one collectionChanged for the whole cull pass instead of one per entity.
|
|
6542
|
+
WithSuspendedCCollections(entities.map(x => GetCEntityCollection(viewer, x)), () => {
|
|
6543
|
+
for (let i = 0; i < entities.length; i++) {
|
|
6544
|
+
const entity = entities[i];
|
|
6545
|
+
if (entityRemoveAddState.get(entity.id) != true) {
|
|
6546
|
+
continue;
|
|
6547
|
+
}
|
|
6548
|
+
entityRemoveAddState.delete(entity.id);
|
|
6549
|
+
AddCEntityToScene(viewer, entity);
|
|
6157
6550
|
}
|
|
6158
|
-
}
|
|
6551
|
+
});
|
|
6159
6552
|
});
|
|
6160
6553
|
}
|
|
6161
6554
|
var VisualRegisterCuller;
|
|
@@ -6226,6 +6619,19 @@
|
|
|
6226
6619
|
};
|
|
6227
6620
|
}
|
|
6228
6621
|
VisualRegisterCuller.Monitor = Monitor;
|
|
6622
|
+
/**
|
|
6623
|
+
* Runs the tileset visibility pass immediately, rather than waiting for the next cull cycle.
|
|
6624
|
+
* Exposed so the behaviour is directly assertable, and for a caller that needs it applied now.
|
|
6625
|
+
* @param register
|
|
6626
|
+
*/
|
|
6627
|
+
function CullTilesets(register) {
|
|
6628
|
+
cullTilesets(register);
|
|
6629
|
+
}
|
|
6630
|
+
VisualRegisterCuller.CullTilesets = CullTilesets;
|
|
6631
|
+
function IsCullingIgnored(viewer, rego) {
|
|
6632
|
+
return isCullingIgnored(viewer, rego);
|
|
6633
|
+
}
|
|
6634
|
+
VisualRegisterCuller.IsCullingIgnored = IsCullingIgnored;
|
|
6229
6635
|
function IsCulled(viewer, rego, visual) {
|
|
6230
6636
|
if (isCullingIgnored(viewer, rego)) {
|
|
6231
6637
|
return false;
|
|
@@ -6273,7 +6679,7 @@
|
|
|
6273
6679
|
return false;
|
|
6274
6680
|
}
|
|
6275
6681
|
if (visual instanceof Cesium.Entity) {
|
|
6276
|
-
return viewer
|
|
6682
|
+
return IsCEntityInScene(viewer, visual);
|
|
6277
6683
|
}
|
|
6278
6684
|
else if (visual instanceof Cesium.Primitive) {
|
|
6279
6685
|
return viewer.scene.primitives.contains(visual);
|
|
@@ -6300,6 +6706,32 @@
|
|
|
6300
6706
|
viewer
|
|
6301
6707
|
});
|
|
6302
6708
|
}
|
|
6709
|
+
/**
|
|
6710
|
+
* Returns the highest zIndex across a graphic and its siblings, or null when none of them set one.
|
|
6711
|
+
* @param viewer
|
|
6712
|
+
* @param visual
|
|
6713
|
+
*/
|
|
6714
|
+
function getHighestZIndex(viewer, visual) {
|
|
6715
|
+
if (!(visual instanceof Cesium.Entity)) {
|
|
6716
|
+
return null;
|
|
6717
|
+
}
|
|
6718
|
+
let highest = null;
|
|
6719
|
+
const parts = exports.EntityUtils.GatherEntity({
|
|
6720
|
+
entity: visual
|
|
6721
|
+
});
|
|
6722
|
+
for (const part of parts) {
|
|
6723
|
+
if (!(part instanceof Cesium.Entity)) {
|
|
6724
|
+
continue;
|
|
6725
|
+
}
|
|
6726
|
+
for (const graphic of [part.polygon, part.polyline, part.corridor, part.ellipse, part.rectangle]) {
|
|
6727
|
+
const zIndex = graphic ? GetCValue(viewer, graphic.zIndex) : null;
|
|
6728
|
+
if (zIndex != null && !isNaN(zIndex) && (highest == null || zIndex > highest)) {
|
|
6729
|
+
highest = zIndex;
|
|
6730
|
+
}
|
|
6731
|
+
}
|
|
6732
|
+
}
|
|
6733
|
+
return highest;
|
|
6734
|
+
}
|
|
6303
6735
|
const MAX_SHOW_DEPTH = 10;
|
|
6304
6736
|
function updateCEntityShow(viewer, visual, rego, show, ignoreParent, depth = 0) {
|
|
6305
6737
|
if (depth > MAX_SHOW_DEPTH) {
|
|
@@ -6318,26 +6750,24 @@
|
|
|
6318
6750
|
updateCEntityShow(viewer, sibling, rego, show, true, depth + 1);
|
|
6319
6751
|
}
|
|
6320
6752
|
}
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
rego.collection.remove(visual);
|
|
6328
|
-
}
|
|
6329
|
-
else if (show && !rego.collection.contains(visual)) {
|
|
6330
|
-
rego.collection.add(visual);
|
|
6753
|
+
if (show) {
|
|
6754
|
+
// Always restore membership on the way back in. Something else may have evicted this graphic while it
|
|
6755
|
+
// was hidden (the culler removes outright), and `show` alone would leave it invisible.
|
|
6756
|
+
AddCEntityToScene(viewer, visual, rego.collection);
|
|
6757
|
+
if (visual.show !== true) {
|
|
6758
|
+
visual.show = true;
|
|
6331
6759
|
}
|
|
6760
|
+
return;
|
|
6332
6761
|
}
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
viewer.entities.add(visual);
|
|
6762
|
+
// Hiding via `show` only updates a per-instance attribute, where leaving the collection rebuilds the whole
|
|
6763
|
+
// geometry batch. But it is not safe for every graphic, see CanToggleShowSafely for exactly why.
|
|
6764
|
+
if (CanToggleShowSafely([visual])) {
|
|
6765
|
+
if (visual.show !== false) {
|
|
6766
|
+
visual.show = false;
|
|
6339
6767
|
}
|
|
6768
|
+
return;
|
|
6340
6769
|
}
|
|
6770
|
+
RemoveCEntityFromScene(viewer, visual);
|
|
6341
6771
|
}
|
|
6342
6772
|
function updateEntityShow(viewer, rego, show) {
|
|
6343
6773
|
const visual = rego.visual;
|
|
@@ -6646,12 +7076,128 @@
|
|
|
6646
7076
|
// This lets us modify the update without re-adding the item to the queue if it's already in it.
|
|
6647
7077
|
this.updateQueueSettings = {};
|
|
6648
7078
|
this.updateQueueInterval = null;
|
|
7079
|
+
// Per menu item collections so we can refresh sets of Entities without affecting others.
|
|
7080
|
+
this.menuItemSources = new Map();
|
|
7081
|
+
// Set when the data source order no longer matches the zIndexes seen, so it is re-applied once.
|
|
7082
|
+
this.sourceOrderDirty = false;
|
|
7083
|
+
/*
|
|
7084
|
+
* Tilesets in the scene, keyed by the tileset itself.
|
|
7085
|
+
*/
|
|
7086
|
+
this.tilesets = new Map();
|
|
6649
7087
|
this.viewer = params.viewer;
|
|
6650
7088
|
this.apiGetters = params.apiGetters;
|
|
6651
7089
|
this.cameraCullerDispose = VisualRegisterCuller.Monitor({
|
|
6652
7090
|
register: this
|
|
6653
7091
|
});
|
|
6654
7092
|
}
|
|
7093
|
+
/**
|
|
7094
|
+
* Returns the collection a menu item's visuals belong in, creating its data source on first use.
|
|
7095
|
+
* Returns null when there is nothing to key off, leaving the caller on the viewer's own collection.
|
|
7096
|
+
* @param menuItemId
|
|
7097
|
+
*/
|
|
7098
|
+
ensureMenuItemCollection(menuItemId) {
|
|
7099
|
+
var _a;
|
|
7100
|
+
if (!menuItemId || this.disposed || !((_a = this.viewer) === null || _a === void 0 ? void 0 : _a.dataSources)) {
|
|
7101
|
+
return null;
|
|
7102
|
+
}
|
|
7103
|
+
const existing = this.menuItemSources.get(menuItemId);
|
|
7104
|
+
if (existing) {
|
|
7105
|
+
return existing.source.entities;
|
|
7106
|
+
}
|
|
7107
|
+
const source = new Cesium.CustomDataSource(`menu-item-${menuItemId}`);
|
|
7108
|
+
const record = {
|
|
7109
|
+
source,
|
|
7110
|
+
maxZIndex: 0,
|
|
7111
|
+
added: false
|
|
7112
|
+
};
|
|
7113
|
+
MarkCCollectionOwned(source.entities);
|
|
7114
|
+
this.menuItemSources.set(menuItemId, record);
|
|
7115
|
+
// Adding is asynchronous, so ordering has to wait until it is actually in the collection.
|
|
7116
|
+
Promise.resolve(this.viewer.dataSources.add(source))
|
|
7117
|
+
.then(() => {
|
|
7118
|
+
record.added = true;
|
|
7119
|
+
this.applySourceOrder();
|
|
7120
|
+
})
|
|
7121
|
+
.catch((e) => {
|
|
7122
|
+
console.error(e);
|
|
7123
|
+
});
|
|
7124
|
+
return source.entities;
|
|
7125
|
+
}
|
|
7126
|
+
/**
|
|
7127
|
+
* Notes the highest zIndex seen for a menu item, since that is what its data source has to sort by.
|
|
7128
|
+
* zIndex orders geometry within a data source but not between them, so a whole layer stacks by the
|
|
7129
|
+
* highest value anything in it asked for.
|
|
7130
|
+
* @param menuItemId
|
|
7131
|
+
* @param visual
|
|
7132
|
+
*/
|
|
7133
|
+
trackSourceZIndex(menuItemId, visual) {
|
|
7134
|
+
const record = this.menuItemSources.get(menuItemId);
|
|
7135
|
+
if (!record) {
|
|
7136
|
+
return;
|
|
7137
|
+
}
|
|
7138
|
+
const zIndex = getHighestZIndex(this.viewer, visual);
|
|
7139
|
+
if (zIndex == null || zIndex <= record.maxZIndex) {
|
|
7140
|
+
return;
|
|
7141
|
+
}
|
|
7142
|
+
record.maxZIndex = zIndex;
|
|
7143
|
+
this.sourceOrderDirty = true;
|
|
7144
|
+
this.applySourceOrder();
|
|
7145
|
+
}
|
|
7146
|
+
/**
|
|
7147
|
+
* Re-stacks the menu item data sources so a higher zIndex sits above a lower one.
|
|
7148
|
+
*/
|
|
7149
|
+
applySourceOrder() {
|
|
7150
|
+
var _a;
|
|
7151
|
+
if (this.disposed || !this.sourceOrderDirty || !((_a = this.viewer) === null || _a === void 0 ? void 0 : _a.dataSources)) {
|
|
7152
|
+
return;
|
|
7153
|
+
}
|
|
7154
|
+
const records = Array.from(this.menuItemSources.values()).filter(x => x.added);
|
|
7155
|
+
if (records.length < 2) {
|
|
7156
|
+
// Nothing to order against yet, so leave the flag set for when there is.
|
|
7157
|
+
return;
|
|
7158
|
+
}
|
|
7159
|
+
this.sourceOrderDirty = false;
|
|
7160
|
+
// Raising each in ascending order leaves the highest on top.
|
|
7161
|
+
records.sort((a, b) => a.maxZIndex - b.maxZIndex);
|
|
7162
|
+
for (const record of records) {
|
|
7163
|
+
try {
|
|
7164
|
+
this.viewer.dataSources.raiseToTop(record.source);
|
|
7165
|
+
}
|
|
7166
|
+
catch (e) {
|
|
7167
|
+
console.error(e);
|
|
7168
|
+
}
|
|
7169
|
+
}
|
|
7170
|
+
}
|
|
7171
|
+
/**
|
|
7172
|
+
* Drops a menu item's data source once nothing is registered under it any more.
|
|
7173
|
+
* @param menuItemId
|
|
7174
|
+
*/
|
|
7175
|
+
releaseMenuItemCollection(menuItemId) {
|
|
7176
|
+
var _a, _b, _c;
|
|
7177
|
+
const record = this.menuItemSources.get(menuItemId);
|
|
7178
|
+
if (!record) {
|
|
7179
|
+
return;
|
|
7180
|
+
}
|
|
7181
|
+
if ((_a = this.entityIdsByMenuItem[menuItemId]) === null || _a === void 0 ? void 0 : _a.size) {
|
|
7182
|
+
return;
|
|
7183
|
+
}
|
|
7184
|
+
this.menuItemSources.delete(menuItemId);
|
|
7185
|
+
try {
|
|
7186
|
+
(_c = (_b = this.viewer) === null || _b === void 0 ? void 0 : _b.dataSources) === null || _c === void 0 ? void 0 : _c.remove(record.source, true);
|
|
7187
|
+
}
|
|
7188
|
+
catch (e) {
|
|
7189
|
+
console.error(e);
|
|
7190
|
+
}
|
|
7191
|
+
}
|
|
7192
|
+
/** Every collection a bulk pass over this register's visuals could mutate. */
|
|
7193
|
+
allSceneCollections() {
|
|
7194
|
+
var _a;
|
|
7195
|
+
const collections = [(_a = this.viewer) === null || _a === void 0 ? void 0 : _a.entities];
|
|
7196
|
+
for (const record of Array.from(this.menuItemSources.values())) {
|
|
7197
|
+
collections.push(record.source.entities);
|
|
7198
|
+
}
|
|
7199
|
+
return collections;
|
|
7200
|
+
}
|
|
6655
7201
|
indexMenuItemEntity(menuItemId, entityId) {
|
|
6656
7202
|
if (!menuItemId) {
|
|
6657
7203
|
return;
|
|
@@ -7241,9 +7787,11 @@
|
|
|
7241
7787
|
return;
|
|
7242
7788
|
}
|
|
7243
7789
|
const end = Math.min(index + BATCH_SIZE, items.length);
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7790
|
+
WithSuspendedCCollections(this.allSceneCollections(), () => {
|
|
7791
|
+
for (; index < end; index++) {
|
|
7792
|
+
perItem(items[index]);
|
|
7793
|
+
}
|
|
7794
|
+
});
|
|
7247
7795
|
this.viewer.scene.requestRender();
|
|
7248
7796
|
if (index >= items.length) {
|
|
7249
7797
|
clearInterval(interval);
|
|
@@ -7400,7 +7948,7 @@
|
|
|
7400
7948
|
markEntity(this, rego, rego.visual, false);
|
|
7401
7949
|
}
|
|
7402
7950
|
Dispose() {
|
|
7403
|
-
var _a;
|
|
7951
|
+
var _a, _b, _c, _d;
|
|
7404
7952
|
(_a = this.cameraCullerDispose) === null || _a === void 0 ? void 0 : _a.call(this, {
|
|
7405
7953
|
uncull: false
|
|
7406
7954
|
});
|
|
@@ -7415,6 +7963,20 @@
|
|
|
7415
7963
|
}
|
|
7416
7964
|
this.activeChunkedIntervals.clear();
|
|
7417
7965
|
this.disposed = true;
|
|
7966
|
+
for (const record of Array.from(this.menuItemSources.values())) {
|
|
7967
|
+
try {
|
|
7968
|
+
(_c = (_b = this.viewer) === null || _b === void 0 ? void 0 : _b.dataSources) === null || _c === void 0 ? void 0 : _c.remove(record.source, true);
|
|
7969
|
+
}
|
|
7970
|
+
catch (e) {
|
|
7971
|
+
console.error(e);
|
|
7972
|
+
}
|
|
7973
|
+
}
|
|
7974
|
+
this.menuItemSources.clear();
|
|
7975
|
+
// Hand every tileset's show flag back to its owner, holding whatever the owner last asked for.
|
|
7976
|
+
for (const rego of Array.from(this.tilesets.values())) {
|
|
7977
|
+
(_d = rego.gate) === null || _d === void 0 ? void 0 : _d.Release();
|
|
7978
|
+
}
|
|
7979
|
+
this.tilesets.clear();
|
|
7418
7980
|
}
|
|
7419
7981
|
ForceUpdate(params) {
|
|
7420
7982
|
var _a;
|
|
@@ -8010,6 +8572,14 @@
|
|
|
8010
8572
|
});
|
|
8011
8573
|
}
|
|
8012
8574
|
const entityId = rego.entityId;
|
|
8575
|
+
// Scope this visual to its menu item's own data source, so a rebuild of it cannot re-tessellate
|
|
8576
|
+
// other layers. A caller that already picked a collection (eg. geojson) keeps its own.
|
|
8577
|
+
if (!rego.collection && rego.menuItemId) {
|
|
8578
|
+
const collection = this.ensureMenuItemCollection(rego.menuItemId);
|
|
8579
|
+
if (collection) {
|
|
8580
|
+
rego.collection = collection;
|
|
8581
|
+
}
|
|
8582
|
+
}
|
|
8013
8583
|
// Add the new visual to the register.
|
|
8014
8584
|
const entityRegos = (_a = this.rego[entityId]) !== null && _a !== void 0 ? _a : [];
|
|
8015
8585
|
entityRegos.push(rego);
|
|
@@ -8017,6 +8587,7 @@
|
|
|
8017
8587
|
this.indexMenuItemEntity(rego.menuItemId, entityId);
|
|
8018
8588
|
// Mark the visual as part of this register so selection works.
|
|
8019
8589
|
markEntity(this, rego, rego.visual, false);
|
|
8590
|
+
this.trackSourceZIndex(rego.menuItemId, rego.visual);
|
|
8020
8591
|
// Run any updates on the visual based on the calculated state.
|
|
8021
8592
|
// Eg: visibility, opacity, selection, etc.
|
|
8022
8593
|
this.queueUpdate({
|
|
@@ -8321,9 +8892,13 @@
|
|
|
8321
8892
|
this.startLazyRemoval(entityIds, removeOne, onComplete);
|
|
8322
8893
|
return;
|
|
8323
8894
|
}
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8895
|
+
WithSuspendedCCollections(this.allSceneCollections(), () => {
|
|
8896
|
+
for (const entityId of entityIds) {
|
|
8897
|
+
removeOne(entityId);
|
|
8898
|
+
}
|
|
8899
|
+
});
|
|
8900
|
+
this.releaseMenuItemCollection(menuItemId);
|
|
8901
|
+
this.RemoveTilesetsByMenuItem(menuItemId);
|
|
8327
8902
|
}
|
|
8328
8903
|
else if (entityId) {
|
|
8329
8904
|
const entityRegos = this.rego[entityId];
|
|
@@ -8506,8 +9081,75 @@
|
|
|
8506
9081
|
};
|
|
8507
9082
|
}
|
|
8508
9083
|
/**
|
|
8509
|
-
*
|
|
9084
|
+
* Registers a tileset so the register can decide when it is worth drawing.
|
|
9085
|
+
* @param params
|
|
9086
|
+
*/
|
|
9087
|
+
AddTileset(params) {
|
|
9088
|
+
const { tileset, menuItemId } = params;
|
|
9089
|
+
if (!tileset || this.disposed) {
|
|
9090
|
+
return;
|
|
9091
|
+
}
|
|
9092
|
+
const existing = this.tilesets.get(tileset);
|
|
9093
|
+
if (existing) {
|
|
9094
|
+
existing.menuItemId = menuItemId !== null && menuItemId !== void 0 ? menuItemId : existing.menuItemId;
|
|
9095
|
+
return;
|
|
9096
|
+
}
|
|
9097
|
+
this.tilesets.set(tileset, {
|
|
9098
|
+
tileset,
|
|
9099
|
+
menuItemId,
|
|
9100
|
+
// Null when the property could not be intercepted, in which case this tileset simply never gets
|
|
9101
|
+
// culled rather than us fighting its owner over the same field.
|
|
9102
|
+
gate: InstallShowGate(tileset),
|
|
9103
|
+
culled: false
|
|
9104
|
+
});
|
|
9105
|
+
}
|
|
9106
|
+
/**
|
|
9107
|
+
* Stops tracking a tileset and hands its show flag back to its owner.
|
|
9108
|
+
* @param tileset
|
|
9109
|
+
*/
|
|
9110
|
+
RemoveTileset(tileset) {
|
|
9111
|
+
var _a;
|
|
9112
|
+
const rego = this.tilesets.get(tileset);
|
|
9113
|
+
if (!rego) {
|
|
9114
|
+
return;
|
|
9115
|
+
}
|
|
9116
|
+
this.tilesets.delete(tileset);
|
|
9117
|
+
(_a = rego.gate) === null || _a === void 0 ? void 0 : _a.Release();
|
|
9118
|
+
}
|
|
9119
|
+
/**
|
|
9120
|
+
* Stops tracking every tileset belonging to a menu item.
|
|
9121
|
+
* @param menuItemId
|
|
8510
9122
|
*/
|
|
9123
|
+
RemoveTilesetsByMenuItem(menuItemId) {
|
|
9124
|
+
if (!menuItemId) {
|
|
9125
|
+
return;
|
|
9126
|
+
}
|
|
9127
|
+
for (const rego of Array.from(this.tilesets.values())) {
|
|
9128
|
+
if (rego.menuItemId === menuItemId) {
|
|
9129
|
+
this.RemoveTileset(rego.tileset);
|
|
9130
|
+
}
|
|
9131
|
+
}
|
|
9132
|
+
}
|
|
9133
|
+
/**
|
|
9134
|
+
* Every tileset currently tracked.
|
|
9135
|
+
*/
|
|
9136
|
+
GetTilesets() {
|
|
9137
|
+
return Array.from(this.tilesets.values());
|
|
9138
|
+
}
|
|
9139
|
+
/**
|
|
9140
|
+
* Suppresses or restores a tileset.
|
|
9141
|
+
* Returns whether its effective visibility changed, so a caller can skip requesting a render when nothing did.
|
|
9142
|
+
* @param tileset
|
|
9143
|
+
* @param culled
|
|
9144
|
+
*/
|
|
9145
|
+
SetTilesetCulled(tileset, culled) {
|
|
9146
|
+
const rego = this.tilesets.get(tileset);
|
|
9147
|
+
if (!(rego === null || rego === void 0 ? void 0 : rego.gate)) {
|
|
9148
|
+
return false;
|
|
9149
|
+
}
|
|
9150
|
+
rego.culled = Boolean(culled);
|
|
9151
|
+
return rego.gate.SetSuppressed(rego.culled);
|
|
9152
|
+
}
|
|
8511
9153
|
GetEntityIds() {
|
|
8512
9154
|
const ids = [];
|
|
8513
9155
|
for (const entityId in this.rego) {
|
|
@@ -9876,7 +10518,11 @@
|
|
|
9876
10518
|
const displayItems = this.zoomControl ? (_d = this.zoomControl) === null || _d === void 0 ? void 0 : _d.filter(x => x.DisplayType != BModels.ZoomControl.EDisplayType.Hidden) : [];
|
|
9877
10519
|
const shouldCheck = displayItems.length > 1;
|
|
9878
10520
|
this.entityCheckQueue = new BModels.DelayQueue(() => {
|
|
9879
|
-
this.
|
|
10521
|
+
// With a single band this pass is not looking for band changes at all, it is the periodic registry cleanup, so it always runs over everything.
|
|
10522
|
+
const ids = shouldCheck
|
|
10523
|
+
? this.filterPossibleBandChanges(Object.keys(this.renderedEntities))
|
|
10524
|
+
: Object.keys(this.renderedEntities);
|
|
10525
|
+
this.doEntityCheck(ids);
|
|
9880
10526
|
}, shouldCheck ? 3000 : 30000);
|
|
9881
10527
|
const feed = (_e = this.apiGetter.getApi()) === null || _e === void 0 ? void 0 : _e.RecordChangeFeed;
|
|
9882
10528
|
if (feed) {
|
|
@@ -10119,6 +10765,30 @@
|
|
|
10119
10765
|
this.doEntityCheck(entityIds);
|
|
10120
10766
|
}
|
|
10121
10767
|
}
|
|
10768
|
+
/**
|
|
10769
|
+
* Narrows a camera-driven check to the entities whose zoom band could actually have changed.
|
|
10770
|
+
* @param ids
|
|
10771
|
+
*/
|
|
10772
|
+
filterPossibleBandChanges(ids) {
|
|
10773
|
+
return ids.filter((id) => {
|
|
10774
|
+
const rego = this.visualsManager.GetRego({
|
|
10775
|
+
entityId: id,
|
|
10776
|
+
menuItemId: this.item.id
|
|
10777
|
+
});
|
|
10778
|
+
// Anything without a live graphic to measure against has to be checked.
|
|
10779
|
+
if (!(rego === null || rego === void 0 ? void 0 : rego.visual) || rego.stale) {
|
|
10780
|
+
return true;
|
|
10781
|
+
}
|
|
10782
|
+
const bandCheck = rego.visual._bandCheck;
|
|
10783
|
+
if (!bandCheck) {
|
|
10784
|
+
return true;
|
|
10785
|
+
}
|
|
10786
|
+
return exports.RenderManager.CouldBandHaveChanged({
|
|
10787
|
+
viewer: this.viewer,
|
|
10788
|
+
bandCheck
|
|
10789
|
+
});
|
|
10790
|
+
});
|
|
10791
|
+
}
|
|
10122
10792
|
async doEntityCheck(ids) {
|
|
10123
10793
|
var _a, _b;
|
|
10124
10794
|
if (this.isRunningCheck) {
|
|
@@ -10790,6 +11460,19 @@
|
|
|
10790
11460
|
optimizeTolerance: (_o = item.optimizeTolerance) !== null && _o !== void 0 ? _o : ""
|
|
10791
11461
|
});
|
|
10792
11462
|
}
|
|
11463
|
+
/**
|
|
11464
|
+
* Everything about a menu item that changes how its entities are drawn, as a comparable string.
|
|
11465
|
+
* Two items with the same signature produce identical graphics, so a hand-off between them needs no
|
|
11466
|
+
* re-render (and so no re-fetch of entity data the hand-off just avoided requesting).
|
|
11467
|
+
* A false mismatch only costs the optimization, so key ordering inside an inline Style is not normalized.
|
|
11468
|
+
*/
|
|
11469
|
+
static GetRenderSignature(item) {
|
|
11470
|
+
return JSON.stringify({
|
|
11471
|
+
zoomControl: exports.RenderManager.GetZoomControlSignature(item.CameraZoomSettings),
|
|
11472
|
+
historicDrawTrack: Boolean(item.historicDrawTrack),
|
|
11473
|
+
historicInterpolation: Boolean(item.historicInterpolation)
|
|
11474
|
+
});
|
|
11475
|
+
}
|
|
10793
11476
|
PrepareHandoff() {
|
|
10794
11477
|
var _a;
|
|
10795
11478
|
if (this.disposed || this.useGeojson || this.item.enableClustering) {
|
|
@@ -10801,7 +11484,8 @@
|
|
|
10801
11484
|
internalByEntityId: new Map(this.internalByEntityId),
|
|
10802
11485
|
allowedTypeIDs: [...this.allowedTypeIDs],
|
|
10803
11486
|
renderQueue: [...this.renderQueue],
|
|
10804
|
-
sourceMenuItemId: this.item.id
|
|
11487
|
+
sourceMenuItemId: this.item.id,
|
|
11488
|
+
renderSignature: Manager.GetRenderSignature(this.item)
|
|
10805
11489
|
};
|
|
10806
11490
|
this.unsetGetter();
|
|
10807
11491
|
(_a = this.viewMonitorRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
@@ -10841,7 +11525,12 @@
|
|
|
10841
11525
|
if ((_a = payload.renderQueue) === null || _a === void 0 ? void 0 : _a.length) {
|
|
10842
11526
|
this.distributeForRender(payload.renderQueue);
|
|
10843
11527
|
}
|
|
10844
|
-
this
|
|
11528
|
+
// Adopted graphics are already drawn the way this item wants them, so re-rendering would only
|
|
11529
|
+
// re-request every entity from the API, which is the cost the hand-off exists to avoid.
|
|
11530
|
+
const needsRestyle = payload.renderSignature !== Manager.GetRenderSignature(this.item);
|
|
11531
|
+
if (needsRestyle) {
|
|
11532
|
+
this.ReRender({ entityIds: Object.keys(this.renderedEntities), force: true });
|
|
11533
|
+
}
|
|
10845
11534
|
this.viewer.scene.requestRender();
|
|
10846
11535
|
}
|
|
10847
11536
|
}
|
|
@@ -11283,7 +11972,7 @@
|
|
|
11283
11972
|
* @param force TODO: This should re-render entities that are already rendered.
|
|
11284
11973
|
*/
|
|
11285
11974
|
async renderAsGeojson(entities, force) {
|
|
11286
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
11975
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
11287
11976
|
entities = entities.filter((entity) => {
|
|
11288
11977
|
var _a;
|
|
11289
11978
|
return !this.renderedEntities[(_a = entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID];
|
|
@@ -11334,38 +12023,42 @@
|
|
|
11334
12023
|
if (!entities.length) {
|
|
11335
12024
|
return;
|
|
11336
12025
|
}
|
|
12026
|
+
// A menu item can declare that nothing about its render may touch the API. Styling then has to come from
|
|
12027
|
+
// the zoom item's inline Style, and names from what the entities already carry.
|
|
12028
|
+
const offline = Boolean((_a = this.item) === null || _a === void 0 ? void 0 : _a.offline);
|
|
11337
12029
|
let style = null;
|
|
11338
|
-
if ((zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.StyleID) && zoomItem.StyleID != -1) {
|
|
12030
|
+
if (!offline && (zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.StyleID) && zoomItem.StyleID != -1) {
|
|
11339
12031
|
try {
|
|
11340
|
-
style = (
|
|
12032
|
+
style = (_b = (await BModels.Style.Get({
|
|
11341
12033
|
api: this.apiGetter.getApi(),
|
|
11342
12034
|
styleId: zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.StyleID
|
|
11343
|
-
})).style) === null ||
|
|
12035
|
+
})).style) === null || _b === void 0 ? void 0 : _b.Settings;
|
|
11344
12036
|
}
|
|
11345
12037
|
// Probably deleted.
|
|
11346
12038
|
catch (e) {
|
|
11347
12039
|
console.error(e);
|
|
11348
12040
|
}
|
|
11349
12041
|
}
|
|
11350
|
-
let entityTypeId = (
|
|
12042
|
+
let entityTypeId = (_c = this.item.BruceEntity) === null || _c === void 0 ? void 0 : _c["EntityType.ID"];
|
|
11351
12043
|
if (!entityTypeId) {
|
|
11352
|
-
entityTypeId = (
|
|
12044
|
+
entityTypeId = (_e = (_d = entities.find(x => { var _a; return !!((_a = x.Bruce) === null || _a === void 0 ? void 0 : _a["EntityType.ID"]); })) === null || _d === void 0 ? void 0 : _d.Bruce) === null || _e === void 0 ? void 0 : _e["EntityType.ID"];
|
|
11353
12045
|
}
|
|
11354
|
-
//
|
|
12046
|
+
// Normally fetched regardless, since name calculation needs it. Offline callers take the names the
|
|
12047
|
+
// entities already carry instead.
|
|
11355
12048
|
let entityType;
|
|
11356
|
-
if (entityTypeId) {
|
|
12049
|
+
if (entityTypeId && !offline) {
|
|
11357
12050
|
// Try using the Entity Type default if one is specified in the menu item.
|
|
11358
12051
|
try {
|
|
11359
|
-
entityType = (
|
|
12052
|
+
entityType = (_f = (await BModels.EntityType.Get({
|
|
11360
12053
|
entityTypeId: entityTypeId,
|
|
11361
12054
|
api: this.apiGetter.getApi()
|
|
11362
|
-
}))) === null ||
|
|
12055
|
+
}))) === null || _f === void 0 ? void 0 : _f.entityType;
|
|
11363
12056
|
if (!style && entityType) {
|
|
11364
12057
|
if (entityType["DisplaySetting.ID"] && entityType["DisplaySetting.ID"] > 0) {
|
|
11365
|
-
style = (
|
|
12058
|
+
style = (_g = (await BModels.Style.Get({
|
|
11366
12059
|
api: this.apiGetter.getApi(),
|
|
11367
12060
|
styleId: entityType["DisplaySetting.ID"]
|
|
11368
|
-
})).style) === null ||
|
|
12061
|
+
})).style) === null || _g === void 0 ? void 0 : _g.Settings;
|
|
11369
12062
|
}
|
|
11370
12063
|
}
|
|
11371
12064
|
}
|
|
@@ -11373,9 +12066,13 @@
|
|
|
11373
12066
|
console.error(e);
|
|
11374
12067
|
}
|
|
11375
12068
|
}
|
|
11376
|
-
|
|
11377
|
-
|
|
11378
|
-
|
|
12069
|
+
// Fall back to whatever the zoom item carried inline, which is the only source offline.
|
|
12070
|
+
if (!style) {
|
|
12071
|
+
style = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.Style;
|
|
12072
|
+
}
|
|
12073
|
+
const pStyle = (_h = style === null || style === void 0 ? void 0 : style.polygonStyle) !== null && _h !== void 0 ? _h : {};
|
|
12074
|
+
const lStyle = (_j = style === null || style === void 0 ? void 0 : style.polylineStyle) !== null && _j !== void 0 ? _j : {};
|
|
12075
|
+
const polygonsClamped = ((_k = pStyle === null || pStyle === void 0 ? void 0 : pStyle.altitudeOption) === null || _k === void 0 ? void 0 : _k.id) == null ? true : ((_l = pStyle === null || pStyle === void 0 ? void 0 : pStyle.altitudeOption) === null || _l === void 0 ? void 0 : _l.id) == 0;
|
|
11379
12076
|
const bFillColor = BModels.Calculator.GetColor(pStyle.fillColor, {}, []);
|
|
11380
12077
|
const cFillColor = bFillColor ? colorToCColor$2(bFillColor) : Cesium.Color.fromCssColorString("rgba(139, 195, 74, 0.8)");
|
|
11381
12078
|
const bLineColor = BModels.Calculator.GetColor(pStyle.lineColor, {}, []);
|
|
@@ -11609,6 +12306,7 @@
|
|
|
11609
12306
|
return next;
|
|
11610
12307
|
}
|
|
11611
12308
|
async doRenderAsIndividuals(entities, force = false) {
|
|
12309
|
+
var _a;
|
|
11612
12310
|
const { updated, entities: cEntities } = await exports.EntityRenderEngine.Render({
|
|
11613
12311
|
viewer: this.viewer,
|
|
11614
12312
|
apiGetter: this.apiGetter,
|
|
@@ -11616,6 +12314,8 @@
|
|
|
11616
12314
|
menuItemId: this.item.id,
|
|
11617
12315
|
visualRegister: this.visualsManager,
|
|
11618
12316
|
zoomControl: this.item.CameraZoomSettings,
|
|
12317
|
+
// Carries the promise through to the engines, which do the rest of the API avoidance.
|
|
12318
|
+
offline: Boolean((_a = this.item) === null || _a === void 0 ? void 0 : _a.offline),
|
|
11619
12319
|
force
|
|
11620
12320
|
});
|
|
11621
12321
|
if (this.disposed) {
|
|
@@ -13836,6 +14536,7 @@
|
|
|
13836
14536
|
}
|
|
13837
14537
|
TilesetRenderEngine.ApplySettings = ApplySettings;
|
|
13838
14538
|
async function Render(params) {
|
|
14539
|
+
var _a, _b, _c;
|
|
13839
14540
|
const api = params.apiGetter.getApi(params.accountId);
|
|
13840
14541
|
// Ensure regional url is loaded.
|
|
13841
14542
|
await api.Loading;
|
|
@@ -13899,6 +14600,10 @@
|
|
|
13899
14600
|
console.error(e);
|
|
13900
14601
|
}
|
|
13901
14602
|
});
|
|
14603
|
+
(_a = params.register) === null || _a === void 0 ? void 0 : _a.AddTileset({
|
|
14604
|
+
tileset: cTileset,
|
|
14605
|
+
menuItemId: params.menuItemId
|
|
14606
|
+
});
|
|
13902
14607
|
return cTileset;
|
|
13903
14608
|
}
|
|
13904
14609
|
else if (params.tileset.type === BModels.Tileset.EType.EntitiesSet) {
|
|
@@ -13915,6 +14620,10 @@
|
|
|
13915
14620
|
const cTileset = await createTileset(loadUrl, null, params.noMemoryLimit);
|
|
13916
14621
|
params.viewer.scene.primitives.add(cTileset);
|
|
13917
14622
|
watchTilesetDateRange(params.viewer, cTileset, params.tileset);
|
|
14623
|
+
(_b = params.register) === null || _b === void 0 ? void 0 : _b.AddTileset({
|
|
14624
|
+
tileset: cTileset,
|
|
14625
|
+
menuItemId: params.menuItemId
|
|
14626
|
+
});
|
|
13918
14627
|
return cTileset;
|
|
13919
14628
|
}
|
|
13920
14629
|
else if (params.tileset.type == BModels.Tileset.EType.PointCloud) {
|
|
@@ -13960,6 +14669,10 @@
|
|
|
13960
14669
|
console.error(e);
|
|
13961
14670
|
}
|
|
13962
14671
|
});
|
|
14672
|
+
(_c = params.register) === null || _c === void 0 ? void 0 : _c.AddTileset({
|
|
14673
|
+
tileset: cTileset,
|
|
14674
|
+
menuItemId: params.menuItemId
|
|
14675
|
+
});
|
|
13963
14676
|
return cTileset;
|
|
13964
14677
|
}
|
|
13965
14678
|
else {
|
|
@@ -13968,6 +14681,7 @@
|
|
|
13968
14681
|
}
|
|
13969
14682
|
TilesetRenderEngine.Render = Render;
|
|
13970
14683
|
async function RenderLegacy(params) {
|
|
14684
|
+
var _a;
|
|
13971
14685
|
let { apiGetter, viewer, tileset, ionId, loadUrl, viaCdn, accountId, noMemoryLimit, backFaceCulling } = params;
|
|
13972
14686
|
let settings = tileset === null || tileset === void 0 ? void 0 : tileset.Settings;
|
|
13973
14687
|
settings = {
|
|
@@ -14090,6 +14804,10 @@
|
|
|
14090
14804
|
console.error(e);
|
|
14091
14805
|
}
|
|
14092
14806
|
});
|
|
14807
|
+
(_a = params.register) === null || _a === void 0 ? void 0 : _a.AddTileset({
|
|
14808
|
+
tileset: cTileset,
|
|
14809
|
+
menuItemId: params.menuItemId
|
|
14810
|
+
});
|
|
14093
14811
|
return cTileset;
|
|
14094
14812
|
}
|
|
14095
14813
|
TilesetRenderEngine.RenderLegacy = RenderLegacy;
|
|
@@ -14599,6 +15317,8 @@
|
|
|
14599
15317
|
}
|
|
14600
15318
|
// Render outside the shared process because we can't control file requests from Cesium.
|
|
14601
15319
|
const cTileset = this.cTileset = await exports.TilesetRenderEngine.Render({
|
|
15320
|
+
register: this.visualsManager,
|
|
15321
|
+
menuItemId: this.item.id,
|
|
14602
15322
|
loadUrl: loadUrl,
|
|
14603
15323
|
apiGetter: this.getters.GetBruceGetter(),
|
|
14604
15324
|
tileset: tileset,
|
|
@@ -16930,7 +17650,12 @@
|
|
|
16930
17650
|
const displayItems = this.zoomControl ? this.zoomControl.filter(x => x.DisplayType != BModels.ZoomControl.EDisplayType.Hidden) : [];
|
|
16931
17651
|
const shouldCheck = displayItems.length > 1;
|
|
16932
17652
|
this.entityCheckQueue = new BModels.DelayQueue(() => {
|
|
16933
|
-
this
|
|
17653
|
+
// With a single band this pass is not looking for band changes at all, so it always runs over
|
|
17654
|
+
// everything. With more than one, most entities can be ruled out without asking the server.
|
|
17655
|
+
const ids = shouldCheck
|
|
17656
|
+
? this.filterPossibleBandChanges(Object.keys(this.renderedEntities))
|
|
17657
|
+
: Object.keys(this.renderedEntities);
|
|
17658
|
+
this.doEntityCheck(ids);
|
|
16934
17659
|
}, shouldCheck ? 3000 : 30000);
|
|
16935
17660
|
(_b = this.viewMonitorRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
16936
17661
|
this.viewMonitorRemoval = this.monitor.Updated().Subscribe(() => {
|
|
@@ -16938,6 +17663,30 @@
|
|
|
16938
17663
|
(_a = this.entityCheckQueue) === null || _a === void 0 ? void 0 : _a.Call();
|
|
16939
17664
|
});
|
|
16940
17665
|
}
|
|
17666
|
+
/**
|
|
17667
|
+
* Narrows a camera-driven check to the entities whose zoom band could actually have changed, so a pan or
|
|
17668
|
+
* zoom stops re-requesting the whole rendered set. See RenderManager.CouldBandHaveChanged.
|
|
17669
|
+
* @param ids
|
|
17670
|
+
*/
|
|
17671
|
+
filterPossibleBandChanges(ids) {
|
|
17672
|
+
return ids.filter((id) => {
|
|
17673
|
+
const rego = this.visualsManager.GetRego({
|
|
17674
|
+
entityId: id,
|
|
17675
|
+
menuItemId: this.item.id
|
|
17676
|
+
});
|
|
17677
|
+
if (!(rego === null || rego === void 0 ? void 0 : rego.visual) || rego.stale) {
|
|
17678
|
+
return true;
|
|
17679
|
+
}
|
|
17680
|
+
const bandCheck = rego.visual._bandCheck;
|
|
17681
|
+
if (!bandCheck) {
|
|
17682
|
+
return true;
|
|
17683
|
+
}
|
|
17684
|
+
return exports.RenderManager.CouldBandHaveChanged({
|
|
17685
|
+
viewer: this.viewer,
|
|
17686
|
+
bandCheck
|
|
17687
|
+
});
|
|
17688
|
+
});
|
|
17689
|
+
}
|
|
16941
17690
|
preventCurrentCheckApiRefresh(entityIds) {
|
|
16942
17691
|
var _a;
|
|
16943
17692
|
this.reRenderState.markSkipForCurrentRun(entityIds, this.isRunningCheck);
|
|
@@ -17264,6 +18013,15 @@
|
|
|
17264
18013
|
}
|
|
17265
18014
|
return `datalab:${queryId}`;
|
|
17266
18015
|
}
|
|
18016
|
+
/**
|
|
18017
|
+
* Everything about this menu item that changes how its entities are drawn, as a comparable string.
|
|
18018
|
+
* The hand-off key is only the query id, so this is what catches a styling difference between two items sharing that query.
|
|
18019
|
+
*/
|
|
18020
|
+
static GetRenderSignature(item) {
|
|
18021
|
+
return JSON.stringify({
|
|
18022
|
+
zoomControl: exports.RenderManager.GetZoomControlSignature(item.CameraZoomSettings)
|
|
18023
|
+
});
|
|
18024
|
+
}
|
|
17267
18025
|
PrepareHandoff() {
|
|
17268
18026
|
var _a, _b, _c;
|
|
17269
18027
|
if (this.disposed || !this.getter) {
|
|
@@ -17284,7 +18042,8 @@
|
|
|
17284
18042
|
getter,
|
|
17285
18043
|
renderedEntities: this.renderedEntities,
|
|
17286
18044
|
renderQueue: [...this.renderQueue],
|
|
17287
|
-
sourceMenuItemId: this.item.id
|
|
18045
|
+
sourceMenuItemId: this.item.id,
|
|
18046
|
+
renderSignature: Manager.GetRenderSignature(this.item)
|
|
17288
18047
|
};
|
|
17289
18048
|
this.renderQueue = [];
|
|
17290
18049
|
this.queryLoadId += 1;
|
|
@@ -17307,7 +18066,10 @@
|
|
|
17307
18066
|
if ((_a = payload.renderQueue) === null || _a === void 0 ? void 0 : _a.length) {
|
|
17308
18067
|
this.distributeForRender(payload.renderQueue);
|
|
17309
18068
|
}
|
|
17310
|
-
|
|
18069
|
+
const needsRestyle = payload.renderSignature !== Manager.GetRenderSignature(this.item);
|
|
18070
|
+
if (needsRestyle) {
|
|
18071
|
+
this.ReRender({ entityIds: Object.keys(this.renderedEntities), force: true });
|
|
18072
|
+
}
|
|
17311
18073
|
this.viewer.scene.requestRender();
|
|
17312
18074
|
}
|
|
17313
18075
|
}
|
|
@@ -18288,6 +19050,8 @@
|
|
|
18288
19050
|
}
|
|
18289
19051
|
}
|
|
18290
19052
|
const cTileset = this.cTileset = await exports.TilesetRenderEngine.Render({
|
|
19053
|
+
register: this.visualsManager,
|
|
19054
|
+
menuItemId: this.item.id,
|
|
18291
19055
|
apiGetter: this.getters.GetBruceGetter(),
|
|
18292
19056
|
tileset: tileset,
|
|
18293
19057
|
viewer: this.viewer,
|
|
@@ -18778,11 +19542,12 @@
|
|
|
18778
19542
|
constructor(params) {
|
|
18779
19543
|
this.disposed = false;
|
|
18780
19544
|
this.cTileset = null;
|
|
18781
|
-
const { viewer, getters: apiGetter, item, initQueue } = params;
|
|
19545
|
+
const { viewer, getters: apiGetter, item, initQueue, register } = params;
|
|
18782
19546
|
this.viewer = viewer;
|
|
18783
19547
|
this.getters = apiGetter;
|
|
18784
19548
|
this.item = item;
|
|
18785
19549
|
this.initQueue = initQueue;
|
|
19550
|
+
this.visualsManager = register;
|
|
18786
19551
|
}
|
|
18787
19552
|
Init() {
|
|
18788
19553
|
var _a;
|
|
@@ -18833,6 +19598,8 @@
|
|
|
18833
19598
|
return;
|
|
18834
19599
|
}
|
|
18835
19600
|
this.cTileset = await exports.TilesetRenderEngine.Render({
|
|
19601
|
+
register: this.visualsManager,
|
|
19602
|
+
menuItemId: this.item.id,
|
|
18836
19603
|
apiGetter: this.getters.GetBruceGetter(),
|
|
18837
19604
|
tileset: tileset,
|
|
18838
19605
|
viewer: this.viewer,
|
|
@@ -19419,6 +20186,8 @@
|
|
|
19419
20186
|
if (!accountId) {
|
|
19420
20187
|
accountId = this.getters.GetAccountId();
|
|
19421
20188
|
}
|
|
20189
|
+
// Deliberately NOT registered with the visuals register, so it is never whole-tileset culled.
|
|
20190
|
+
// An arbitrary tileset can be produced outside our system and its declared bounds cannot be trusted.
|
|
19422
20191
|
this.cTileset = await exports.TilesetRenderEngine.RenderLegacy({
|
|
19423
20192
|
apiGetter: this.getters.GetBruceGetter(),
|
|
19424
20193
|
tileset: legacyTileset,
|
|
@@ -20086,8 +20855,8 @@
|
|
|
20086
20855
|
* @param cEntity
|
|
20087
20856
|
*/
|
|
20088
20857
|
const killCEntity = (cEntity) => {
|
|
20089
|
-
if (cEntity && !this.viewer.isDestroyed()
|
|
20090
|
-
this.viewer
|
|
20858
|
+
if (cEntity && !this.viewer.isDestroyed()) {
|
|
20859
|
+
RemoveCEntityFromScene(this.viewer, cEntity);
|
|
20091
20860
|
}
|
|
20092
20861
|
if (cEntity === null || cEntity === void 0 ? void 0 : cEntity._dispose) {
|
|
20093
20862
|
cEntity._dispose();
|
|
@@ -20565,8 +21334,8 @@
|
|
|
20565
21334
|
* @param cEntity
|
|
20566
21335
|
*/
|
|
20567
21336
|
const killCEntity = (cEntity) => {
|
|
20568
|
-
if (cEntity && !this.viewer.isDestroyed()
|
|
20569
|
-
this.viewer
|
|
21337
|
+
if (cEntity && !this.viewer.isDestroyed()) {
|
|
21338
|
+
RemoveCEntityFromScene(this.viewer, cEntity);
|
|
20570
21339
|
}
|
|
20571
21340
|
if (cEntity === null || cEntity === void 0 ? void 0 : cEntity._dispose) {
|
|
20572
21341
|
cEntity._dispose();
|
|
@@ -22585,6 +23354,7 @@
|
|
|
22585
23354
|
rItem.renderManager = new exports.TilesetPointcloudRenderManager.Manager({
|
|
22586
23355
|
viewer: this.viewer,
|
|
22587
23356
|
getters: this.getters,
|
|
23357
|
+
register: this.visualsRegister,
|
|
22588
23358
|
item: params.item,
|
|
22589
23359
|
initQueue: this.tilesetInitQueue
|
|
22590
23360
|
});
|
|
@@ -22739,6 +23509,8 @@
|
|
|
22739
23509
|
}
|
|
22740
23510
|
if (allowHandoff && this.isHandoffCapable(item.renderManager)) {
|
|
22741
23511
|
this.pendingHandoffPool.push(item);
|
|
23512
|
+
// Series segments stay recorded under the pooled id for now. A claimed hand-off
|
|
23513
|
+
// transfers them to the claiming item, and a flushed one clears them.
|
|
22742
23514
|
}
|
|
22743
23515
|
else {
|
|
22744
23516
|
try {
|
|
@@ -22747,9 +23519,9 @@
|
|
|
22747
23519
|
catch (e) {
|
|
22748
23520
|
console.error(e);
|
|
22749
23521
|
}
|
|
23522
|
+
this.ClearSeriesSegments(item.id);
|
|
22750
23523
|
}
|
|
22751
23524
|
this.items = this.items.filter(x => x.id !== id);
|
|
22752
|
-
this.ClearSeriesSegments(item.id);
|
|
22753
23525
|
(_b = this.onUpdate) === null || _b === void 0 ? void 0 : _b.Trigger({ isEnabling: false, itemId: item.id });
|
|
22754
23526
|
}
|
|
22755
23527
|
}
|
|
@@ -22797,14 +23569,38 @@
|
|
|
22797
23569
|
if (poolIndex < 0) {
|
|
22798
23570
|
return null;
|
|
22799
23571
|
}
|
|
22800
|
-
const
|
|
23572
|
+
const pooledItem = this.pendingHandoffPool[poolIndex];
|
|
23573
|
+
const pooled = pooledItem.renderManager;
|
|
22801
23574
|
const payload = pooled.PrepareHandoff();
|
|
22802
23575
|
if (!payload) {
|
|
22803
23576
|
return null;
|
|
22804
23577
|
}
|
|
22805
23578
|
this.pendingHandoffPool.splice(poolIndex, 1);
|
|
23579
|
+
this.transferSeriesSegments(pooledItem.id, item.id);
|
|
22806
23580
|
return payload;
|
|
22807
23581
|
}
|
|
23582
|
+
/**
|
|
23583
|
+
* Moves any series segments recorded for one menu item over to another, for a claimed hand-off.
|
|
23584
|
+
* The adopting manager may legitimately skip re-rendering (nothing to restyle), and segments are only
|
|
23585
|
+
* ever reported from inside a render, so without this the claiming item would end up with none.
|
|
23586
|
+
*/
|
|
23587
|
+
transferSeriesSegments(fromItemId, toItemId) {
|
|
23588
|
+
const segments = this.seriesSegments.get(fromItemId);
|
|
23589
|
+
if (!(segments === null || segments === void 0 ? void 0 : segments.length)) {
|
|
23590
|
+
this.ClearSeriesSegments(fromItemId);
|
|
23591
|
+
return;
|
|
23592
|
+
}
|
|
23593
|
+
this.seriesSegments.delete(fromItemId);
|
|
23594
|
+
this.OnSeriesUpdated.Trigger({ itemId: fromItemId, segments: [] });
|
|
23595
|
+
const existing = this.seriesSegments.get(toItemId) || [];
|
|
23596
|
+
for (const segment of segments) {
|
|
23597
|
+
if (!existing.some((s) => s.key === segment.key)) {
|
|
23598
|
+
existing.push(segment);
|
|
23599
|
+
}
|
|
23600
|
+
}
|
|
23601
|
+
this.seriesSegments.set(toItemId, existing);
|
|
23602
|
+
this.OnSeriesUpdated.Trigger({ itemId: toItemId, segments: existing });
|
|
23603
|
+
}
|
|
22808
23604
|
// Disposes everything left unclaimed in the pending-hand-off pool.
|
|
22809
23605
|
FlushPendingHandoffs() {
|
|
22810
23606
|
var _a;
|
|
@@ -22820,6 +23616,7 @@
|
|
|
22820
23616
|
catch (e) {
|
|
22821
23617
|
console.error(e);
|
|
22822
23618
|
}
|
|
23619
|
+
this.ClearSeriesSegments(item.id);
|
|
22823
23620
|
}
|
|
22824
23621
|
}
|
|
22825
23622
|
GetEnabledItemIds() {
|
|
@@ -34176,6 +34973,10 @@
|
|
|
34176
34973
|
}
|
|
34177
34974
|
return minDistance;
|
|
34178
34975
|
}
|
|
34976
|
+
// Slack added when proving a zoom band cannot have changed.
|
|
34977
|
+
// See CouldBandHaveChanged: an entity's measured distance can jump by its altitude spread as the camera crosses over its footprint,
|
|
34978
|
+
// so being this close to a band edge means re-checking rather than trusting the bound.
|
|
34979
|
+
const BAND_EDGE_MARGIN_METERS = 500;
|
|
34179
34980
|
// Cache for distance calculations.
|
|
34180
34981
|
// It will keep only the most recent 3000 entries.
|
|
34181
34982
|
const distanceCache = new BModels.LRUCache(3000);
|
|
@@ -34318,7 +35119,7 @@
|
|
|
34318
35119
|
}
|
|
34319
35120
|
(function (RenderManager) {
|
|
34320
35121
|
function DetermineZoomItem(params) {
|
|
34321
|
-
const { viewer, entity, zoomControl } = params;
|
|
35122
|
+
const { viewer, entity, zoomControl, out } = params;
|
|
34322
35123
|
const pos = exports.EntityUtils.GetPos({
|
|
34323
35124
|
viewer,
|
|
34324
35125
|
entity
|
|
@@ -34331,11 +35132,16 @@
|
|
|
34331
35132
|
if (!cameraPos || !cameraPos.latitude) {
|
|
34332
35133
|
return null;
|
|
34333
35134
|
}
|
|
34334
|
-
const
|
|
35135
|
+
const cameraCarto = {
|
|
34335
35136
|
altitude: cameraPos.height,
|
|
34336
35137
|
latitude: Cesium.Math.toDegrees(cameraPos.latitude),
|
|
34337
35138
|
longitude: Cesium.Math.toDegrees(cameraPos.longitude)
|
|
34338
|
-
}
|
|
35139
|
+
};
|
|
35140
|
+
const distance = calculateDistance(cameraCarto, entity);
|
|
35141
|
+
if (out) {
|
|
35142
|
+
out.distance = distance;
|
|
35143
|
+
out.cameraPos = Cesium.Cartesian3.fromDegrees(cameraCarto.longitude, cameraCarto.latitude, cameraCarto.altitude);
|
|
35144
|
+
}
|
|
34339
35145
|
let zoomItem = (!distance && distance != 0) ? null : GetZoomControlFromDistance({
|
|
34340
35146
|
zoomControl,
|
|
34341
35147
|
distance
|
|
@@ -34348,6 +35154,41 @@
|
|
|
34348
35154
|
return zoomItem;
|
|
34349
35155
|
}
|
|
34350
35156
|
RenderManager.DetermineZoomItem = DetermineZoomItem;
|
|
35157
|
+
/**
|
|
35158
|
+
* Returns whether an entity could have moved into a different zoom band since its graphic was rendered,
|
|
35159
|
+
* given where the camera is now.
|
|
35160
|
+
*
|
|
35161
|
+
* Answers true whenever it cannot prove otherwise, so a caller may safely skip only on a false.
|
|
35162
|
+
*/
|
|
35163
|
+
function CouldBandHaveChanged(params) {
|
|
35164
|
+
var _a;
|
|
35165
|
+
const { viewer, bandCheck } = params;
|
|
35166
|
+
if (!bandCheck || bandCheck.distance == null || !bandCheck.cameraPos) {
|
|
35167
|
+
return true;
|
|
35168
|
+
}
|
|
35169
|
+
// An absent range is not something to reason about. Values that ARE present go through EnsureNumber so
|
|
35170
|
+
// this agrees with how GetZoomControlFromDistance matched the band in the first place.
|
|
35171
|
+
if (bandCheck.min == null || bandCheck.max == null) {
|
|
35172
|
+
return true;
|
|
35173
|
+
}
|
|
35174
|
+
const min = EnsureNumber(bandCheck.min);
|
|
35175
|
+
const max = EnsureNumber(bandCheck.max);
|
|
35176
|
+
if (!(max > min)) {
|
|
35177
|
+
return true;
|
|
35178
|
+
}
|
|
35179
|
+
const cameraPos = (_a = viewer.camera) === null || _a === void 0 ? void 0 : _a.positionCartographic;
|
|
35180
|
+
if (!cameraPos || !cameraPos.latitude) {
|
|
35181
|
+
return true;
|
|
35182
|
+
}
|
|
35183
|
+
const nowPos = Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(cameraPos.longitude), Cesium.Math.toDegrees(cameraPos.latitude), cameraPos.height);
|
|
35184
|
+
const travelled = Cesium.Cartesian3.distance(nowPos, bandCheck.cameraPos);
|
|
35185
|
+
if (isNaN(travelled)) {
|
|
35186
|
+
return true;
|
|
35187
|
+
}
|
|
35188
|
+
const slack = travelled + BAND_EDGE_MARGIN_METERS;
|
|
35189
|
+
return (bandCheck.distance - slack) < min || (bandCheck.distance + slack) > max;
|
|
35190
|
+
}
|
|
35191
|
+
RenderManager.CouldBandHaveChanged = CouldBandHaveChanged;
|
|
34351
35192
|
function GetZoomControlFromDistance(params) {
|
|
34352
35193
|
const { zoomControl, distance } = params;
|
|
34353
35194
|
for (let i = 0; i < zoomControl.length; i++) {
|
|
@@ -34359,6 +35200,26 @@
|
|
|
34359
35200
|
return null;
|
|
34360
35201
|
}
|
|
34361
35202
|
RenderManager.GetZoomControlFromDistance = GetZoomControlFromDistance;
|
|
35203
|
+
/**
|
|
35204
|
+
* Everything in a zoom control that changes how an entity is drawn, as a comparable string.
|
|
35205
|
+
* Used to tell whether two menu items would produce identical graphics (see a manager's GetRenderSignature).
|
|
35206
|
+
* A false mismatch only costs an optimization, so key ordering inside an inline Style is not normalized.
|
|
35207
|
+
*/
|
|
35208
|
+
function GetZoomControlSignature(zoomControl) {
|
|
35209
|
+
return JSON.stringify([].concat(zoomControl !== null && zoomControl !== void 0 ? zoomControl : []).map((zoomItem) => {
|
|
35210
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
35211
|
+
return ({
|
|
35212
|
+
MinZoom: (_a = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.MinZoom) !== null && _a !== void 0 ? _a : null,
|
|
35213
|
+
MaxZoom: (_b = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.MaxZoom) !== null && _b !== void 0 ? _b : null,
|
|
35214
|
+
DisplayType: (_c = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.DisplayType) !== null && _c !== void 0 ? _c : null,
|
|
35215
|
+
StyleID: (_d = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.StyleID) !== null && _d !== void 0 ? _d : null,
|
|
35216
|
+
Style: (_e = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.Style) !== null && _e !== void 0 ? _e : null,
|
|
35217
|
+
LODCategoryID: (_f = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.LODCategoryID) !== null && _f !== void 0 ? _f : null,
|
|
35218
|
+
LODLevel: (_g = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.LODLevel) !== null && _g !== void 0 ? _g : null
|
|
35219
|
+
});
|
|
35220
|
+
}));
|
|
35221
|
+
}
|
|
35222
|
+
RenderManager.GetZoomControlSignature = GetZoomControlSignature;
|
|
34362
35223
|
function GetZoomMinMax(params) {
|
|
34363
35224
|
const { zoomControl } = params;
|
|
34364
35225
|
let min = 0;
|
|
@@ -34443,8 +35304,8 @@
|
|
|
34443
35304
|
// We'll remove all that aren't in the allowed (direct) list.
|
|
34444
35305
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
34445
35306
|
const part = parts[i];
|
|
34446
|
-
if (part && part instanceof Cesium.Entity &&
|
|
34447
|
-
params.viewer
|
|
35307
|
+
if (part && part instanceof Cesium.Entity && !cEntity._siblingGraphics.includes(part)) {
|
|
35308
|
+
RemoveCEntityFromScene(params.viewer, part);
|
|
34448
35309
|
}
|
|
34449
35310
|
}
|
|
34450
35311
|
if (cEntity._parentEntity) {
|
|
@@ -34788,7 +35649,6 @@
|
|
|
34788
35649
|
cEntity.ellipse.semiMajorAxis = new Cesium.ConstantProperty(radius);
|
|
34789
35650
|
cEntity.ellipse.semiMinorAxis = new Cesium.ConstantProperty(radius);
|
|
34790
35651
|
}
|
|
34791
|
-
cEntity.ellipse.outlineWidth = undefined;
|
|
34792
35652
|
{
|
|
34793
35653
|
const curHeightRef = GetCValue(params.viewer, cEntity.ellipse.heightReference);
|
|
34794
35654
|
if (curHeightRef != heightRef) {
|
|
@@ -34809,13 +35669,26 @@
|
|
|
34809
35669
|
cEntity.ellipse.extrudedHeight = new Cesium.ConstantProperty(extrusion.value);
|
|
34810
35670
|
}
|
|
34811
35671
|
}
|
|
34812
|
-
|
|
34813
|
-
|
|
35672
|
+
SetCPropIfChanged({
|
|
35673
|
+
viewer: params.viewer,
|
|
35674
|
+
graphic: cEntity.ellipse,
|
|
35675
|
+
property: "zIndex",
|
|
35676
|
+
value: 1
|
|
35677
|
+
});
|
|
35678
|
+
SetCPropIfChanged({
|
|
35679
|
+
viewer: params.viewer,
|
|
35680
|
+
graphic: cEntity.ellipse,
|
|
35681
|
+
property: "distanceDisplayCondition",
|
|
35682
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance)
|
|
35683
|
+
});
|
|
34814
35684
|
const curClassification = GetCValue(params.viewer, cEntity.ellipse.classificationType);
|
|
34815
35685
|
if (curClassification != classification) {
|
|
34816
35686
|
cEntity.ellipse.classificationType = new Cesium.ConstantProperty(classification);
|
|
34817
35687
|
}
|
|
34818
|
-
|
|
35688
|
+
const curPos = GetCValue(params.viewer, cEntity.position);
|
|
35689
|
+
if (!curPos || !pos3d || !Cesium.Cartesian3.equals(curPos, pos3d)) {
|
|
35690
|
+
cEntity.position = new Cesium.ConstantPositionProperty(pos3d === null || pos3d === void 0 ? void 0 : pos3d.clone());
|
|
35691
|
+
}
|
|
34819
35692
|
// We'll use "SetDefaultColor" to updating the internal reference and to allow for an animation.
|
|
34820
35693
|
// WARNING: ellipse does not support animation (yet?).
|
|
34821
35694
|
exports.CesiumEntityStyler.SetDefaultColor({
|
|
@@ -34823,6 +35696,8 @@
|
|
|
34823
35696
|
entity: cEntity,
|
|
34824
35697
|
viewer: params.viewer,
|
|
34825
35698
|
override: true,
|
|
35699
|
+
// Fill colour only. The outline sibling gets its own cOutline baked below.
|
|
35700
|
+
includeSiblings: false,
|
|
34826
35701
|
requestRender: false
|
|
34827
35702
|
});
|
|
34828
35703
|
cEntity.show = true;
|
|
@@ -34861,8 +35736,18 @@
|
|
|
34861
35736
|
outlineEntity.ellipse.extrudedHeight = new Cesium.ConstantProperty(outlineExtrusion.value);
|
|
34862
35737
|
}
|
|
34863
35738
|
}
|
|
34864
|
-
|
|
34865
|
-
|
|
35739
|
+
SetCPropIfChanged({
|
|
35740
|
+
viewer: params.viewer,
|
|
35741
|
+
graphic: outlineEntity.ellipse,
|
|
35742
|
+
property: "zIndex",
|
|
35743
|
+
value: 2
|
|
35744
|
+
});
|
|
35745
|
+
SetCPropIfChanged({
|
|
35746
|
+
viewer: params.viewer,
|
|
35747
|
+
graphic: outlineEntity.ellipse,
|
|
35748
|
+
property: "distanceDisplayCondition",
|
|
35749
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance)
|
|
35750
|
+
});
|
|
34866
35751
|
const curClassification = GetCValue(params.viewer, outlineEntity.ellipse.classificationType);
|
|
34867
35752
|
if (curClassification != classification) {
|
|
34868
35753
|
outlineEntity.ellipse.classificationType = new Cesium.ConstantProperty(classification);
|
|
@@ -34874,6 +35759,7 @@
|
|
|
34874
35759
|
entity: outlineEntity,
|
|
34875
35760
|
viewer: params.viewer,
|
|
34876
35761
|
override: true,
|
|
35762
|
+
includeSiblings: false,
|
|
34877
35763
|
requestRender: false
|
|
34878
35764
|
});
|
|
34879
35765
|
outlineEntity.show = true;
|
|
@@ -35138,7 +36024,7 @@
|
|
|
35138
36024
|
// De-dupe the tag IDs.
|
|
35139
36025
|
tagIds = Array.from(new Set(tagIds));
|
|
35140
36026
|
// Request if at least one then create a quick lookup map for tags.
|
|
35141
|
-
const tags = tagIds.length > 0 ? (await BModels.EntityTag.GetListByIds({
|
|
36027
|
+
const tags = (!params.offline && tagIds.length > 0) ? (await BModels.EntityTag.GetListByIds({
|
|
35142
36028
|
api,
|
|
35143
36029
|
tagIds
|
|
35144
36030
|
})).tags : [];
|
|
@@ -35150,7 +36036,7 @@
|
|
|
35150
36036
|
for (let i = 0; i < params.entities.length; i++) {
|
|
35151
36037
|
const entity = params.entities[i];
|
|
35152
36038
|
const zoomItem = params.zoomItems[entity.Bruce.ID];
|
|
35153
|
-
const style = zoomItem.StyleID != -1 ? (_a = (await getStyle$1(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
36039
|
+
const style = (!params.offline && zoomItem.StyleID != -1) ? (_a = (await getStyle$1(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
35154
36040
|
// Pass through tags that may be needed for styling.
|
|
35155
36041
|
const tagIds = entity.Bruce["Layer.ID"];
|
|
35156
36042
|
const tags = [];
|
|
@@ -35188,7 +36074,7 @@
|
|
|
35188
36074
|
rego: rego
|
|
35189
36075
|
});
|
|
35190
36076
|
if (cEntity) {
|
|
35191
|
-
const name = await getName(api, entity);
|
|
36077
|
+
const name = await getName(api, entity, params.offline);
|
|
35192
36078
|
cEntity.name = name;
|
|
35193
36079
|
cEntity._renderGroup = exports.EntityRenderEngine.GetRenderGroupId(zoomItem);
|
|
35194
36080
|
cEntity.styleId = zoomItem.StyleID == -1 ? -1 : (+zoomItem.StyleID || null);
|
|
@@ -35359,7 +36245,16 @@
|
|
|
35359
36245
|
}
|
|
35360
36246
|
return data;
|
|
35361
36247
|
}
|
|
35362
|
-
async function getName(api, entity) {
|
|
36248
|
+
async function getName(api, entity, offline) {
|
|
36249
|
+
var _a;
|
|
36250
|
+
const ownName = GetUsableEntityName(entity);
|
|
36251
|
+
if (ownName) {
|
|
36252
|
+
return ownName;
|
|
36253
|
+
}
|
|
36254
|
+
if (offline) {
|
|
36255
|
+
// Anything further needs a request, so offline callers take what the entity carries, placeholder or not.
|
|
36256
|
+
return ((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.Name) || "Unnamed Entity";
|
|
36257
|
+
}
|
|
35363
36258
|
try {
|
|
35364
36259
|
const typeId = entity.Bruce["EntityType.ID"];
|
|
35365
36260
|
let type = null;
|
|
@@ -35535,8 +36430,8 @@
|
|
|
35535
36430
|
// We'll remove all that aren't in the allowed (direct) list.
|
|
35536
36431
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
35537
36432
|
const part = parts[i];
|
|
35538
|
-
if (part && part instanceof Cesium.Entity &&
|
|
35539
|
-
params.viewer
|
|
36433
|
+
if (part && part instanceof Cesium.Entity && !cEntity._siblingGraphics.includes(part)) {
|
|
36434
|
+
RemoveCEntityFromScene(params.viewer, part);
|
|
35540
36435
|
}
|
|
35541
36436
|
}
|
|
35542
36437
|
if (cEntity._parentEntity) {
|
|
@@ -36029,7 +36924,7 @@
|
|
|
36029
36924
|
// De-dupe the tag IDs.
|
|
36030
36925
|
tagIds = Array.from(new Set(tagIds));
|
|
36031
36926
|
// Request if at least one then create a quick lookup map for tags.
|
|
36032
|
-
const tags = tagIds.length > 0 ? (await BModels.EntityTag.GetListByIds({
|
|
36927
|
+
const tags = (!params.offline && tagIds.length > 0) ? (await BModels.EntityTag.GetListByIds({
|
|
36033
36928
|
api,
|
|
36034
36929
|
tagIds
|
|
36035
36930
|
})).tags : [];
|
|
@@ -36041,7 +36936,7 @@
|
|
|
36041
36936
|
for (let i = 0; i < params.entities.length; i++) {
|
|
36042
36937
|
const entity = params.entities[i];
|
|
36043
36938
|
const zoomItem = params.zoomItems[entity.Bruce.ID];
|
|
36044
|
-
const style = zoomItem.StyleID != -1 ? (_a = (await getStyle$2(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
36939
|
+
const style = (!params.offline && zoomItem.StyleID != -1) ? (_a = (await getStyle$2(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
36045
36940
|
// Pass through tags that may be needed for styling.
|
|
36046
36941
|
const tagIds = entity.Bruce["Layer.ID"];
|
|
36047
36942
|
const tags = [];
|
|
@@ -36080,8 +36975,8 @@
|
|
|
36080
36975
|
for (let i = 0; i < params.entities.length; i++) {
|
|
36081
36976
|
const entity = params.entities[i];
|
|
36082
36977
|
const zoomItem = params.zoomItems[entity.Bruce.ID];
|
|
36083
|
-
const styleRecord = zoomItem.StyleID != -1 ? (await getStyle$2(api, entity, zoomItem.StyleID)) : null;
|
|
36084
|
-
const style = zoomItem.StyleID != -1 ? styleRecord === null || styleRecord === void 0 ? void 0 : styleRecord.Settings : zoomItem.Style;
|
|
36978
|
+
const styleRecord = (!params.offline && zoomItem.StyleID != -1) ? (await getStyle$2(api, entity, zoomItem.StyleID)) : null;
|
|
36979
|
+
const style = (!params.offline && zoomItem.StyleID != -1) ? styleRecord === null || styleRecord === void 0 ? void 0 : styleRecord.Settings : zoomItem.Style;
|
|
36085
36980
|
const lod = lodData.find(x => x.entityId == entity.Bruce.ID);
|
|
36086
36981
|
if (!(lod === null || lod === void 0 ? void 0 : lod.clientFileId)) {
|
|
36087
36982
|
continue;
|
|
@@ -36127,7 +37022,7 @@
|
|
|
36127
37022
|
rego: rego
|
|
36128
37023
|
});
|
|
36129
37024
|
if (cEntity) {
|
|
36130
|
-
const name = await getName$1(api, entity);
|
|
37025
|
+
const name = await getName$1(api, entity, params.offline);
|
|
36131
37026
|
cEntity.name = name;
|
|
36132
37027
|
cEntity._renderGroup = exports.EntityRenderEngine.GetRenderGroupId(zoomItem);
|
|
36133
37028
|
cEntity.styleId = zoomItem.StyleID == -1 ? -1 : styleRecord === null || styleRecord === void 0 ? void 0 : styleRecord.ID;
|
|
@@ -36153,7 +37048,16 @@
|
|
|
36153
37048
|
}
|
|
36154
37049
|
return heightRef;
|
|
36155
37050
|
}
|
|
36156
|
-
async function getName$1(api, entity) {
|
|
37051
|
+
async function getName$1(api, entity, offline) {
|
|
37052
|
+
var _a;
|
|
37053
|
+
const ownName = GetUsableEntityName(entity);
|
|
37054
|
+
if (ownName) {
|
|
37055
|
+
return ownName;
|
|
37056
|
+
}
|
|
37057
|
+
if (offline) {
|
|
37058
|
+
// Anything further needs a request, so offline callers take what the entity carries, placeholder or not.
|
|
37059
|
+
return ((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.Name) || "Unnamed Entity";
|
|
37060
|
+
}
|
|
36157
37061
|
try {
|
|
36158
37062
|
const typeId = entity.Bruce["EntityType.ID"];
|
|
36159
37063
|
let type = null;
|
|
@@ -36422,8 +37326,8 @@
|
|
|
36422
37326
|
// Kill all expect last part. Last one is the primary entity.
|
|
36423
37327
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
36424
37328
|
const part = parts[i];
|
|
36425
|
-
if (part && part instanceof Cesium.Entity
|
|
36426
|
-
params.viewer
|
|
37329
|
+
if (part && part instanceof Cesium.Entity) {
|
|
37330
|
+
RemoveCEntityFromScene(params.viewer, part);
|
|
36427
37331
|
}
|
|
36428
37332
|
}
|
|
36429
37333
|
cEntity._siblingGraphics = [];
|
|
@@ -36454,7 +37358,12 @@
|
|
|
36454
37358
|
if (oldClampToGround != newClampToGround) {
|
|
36455
37359
|
cEntity.polyline.clampToGround = new Cesium.ConstantProperty(newClampToGround);
|
|
36456
37360
|
}
|
|
36457
|
-
|
|
37361
|
+
SetCPropIfChanged({
|
|
37362
|
+
viewer: params.viewer,
|
|
37363
|
+
graphic: cEntity.polyline,
|
|
37364
|
+
property: "distanceDisplayCondition",
|
|
37365
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance)
|
|
37366
|
+
});
|
|
36458
37367
|
cEntity.corridor = undefined;
|
|
36459
37368
|
}
|
|
36460
37369
|
else {
|
|
@@ -36478,7 +37387,12 @@
|
|
|
36478
37387
|
if (oldZIndex != getZIndex(style, entity, params.tags)) {
|
|
36479
37388
|
cEntity.corridor.zIndex = new Cesium.ConstantProperty(getZIndex(style, entity, params.tags));
|
|
36480
37389
|
}
|
|
36481
|
-
|
|
37390
|
+
SetCPropIfChanged({
|
|
37391
|
+
viewer: params.viewer,
|
|
37392
|
+
graphic: cEntity.corridor,
|
|
37393
|
+
property: "distanceDisplayCondition",
|
|
37394
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width)
|
|
37395
|
+
});
|
|
36482
37396
|
cEntity.polyline = undefined;
|
|
36483
37397
|
}
|
|
36484
37398
|
// We'll use "SetDefaultColor" to updating the internal reference and to allow for an animation.
|
|
@@ -36546,7 +37460,7 @@
|
|
|
36546
37460
|
// De-dupe the tag IDs.
|
|
36547
37461
|
tagIds = Array.from(new Set(tagIds));
|
|
36548
37462
|
// Request if at least one then create a quick lookup map for tags.
|
|
36549
|
-
const tags = tagIds.length > 0 ? (await BModels.EntityTag.GetListByIds({
|
|
37463
|
+
const tags = (!params.offline && tagIds.length > 0) ? (await BModels.EntityTag.GetListByIds({
|
|
36550
37464
|
api,
|
|
36551
37465
|
tagIds
|
|
36552
37466
|
})).tags : [];
|
|
@@ -36558,7 +37472,7 @@
|
|
|
36558
37472
|
for (let i = 0; i < params.entities.length; i++) {
|
|
36559
37473
|
const entity = params.entities[i];
|
|
36560
37474
|
const zoomItem = params.zoomItems[entity.Bruce.ID];
|
|
36561
|
-
const style = zoomItem.StyleID != -1 ? (_a = (await getStyle$3(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
37475
|
+
const style = (!params.offline && zoomItem.StyleID != -1) ? (_a = (await getStyle$3(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
36562
37476
|
// Pass through tags that may be needed for styling.
|
|
36563
37477
|
const tagIds = entity.Bruce["Layer.ID"];
|
|
36564
37478
|
const tags = [];
|
|
@@ -36581,7 +37495,7 @@
|
|
|
36581
37495
|
rendered: (_c = params.rendered) === null || _c === void 0 ? void 0 : _c.get(entity.Bruce.ID)
|
|
36582
37496
|
});
|
|
36583
37497
|
if (cEntity) {
|
|
36584
|
-
const name = await getName$2(api, entity);
|
|
37498
|
+
const name = await getName$2(api, entity, params.offline);
|
|
36585
37499
|
cEntity.name = name;
|
|
36586
37500
|
cEntity._renderGroup = exports.EntityRenderEngine.GetRenderGroupId(zoomItem);
|
|
36587
37501
|
cEntity.styleId = zoomItem.StyleID == -1 ? -1 : (+zoomItem.StyleID || null);
|
|
@@ -36592,7 +37506,16 @@
|
|
|
36592
37506
|
}
|
|
36593
37507
|
EntityRenderEnginePolyline.RenderGroup = RenderGroup;
|
|
36594
37508
|
})(exports.EntityRenderEnginePolyline || (exports.EntityRenderEnginePolyline = {}));
|
|
36595
|
-
async function getName$2(api, entity) {
|
|
37509
|
+
async function getName$2(api, entity, offline) {
|
|
37510
|
+
var _a;
|
|
37511
|
+
const ownName = GetUsableEntityName(entity);
|
|
37512
|
+
if (ownName) {
|
|
37513
|
+
return ownName;
|
|
37514
|
+
}
|
|
37515
|
+
if (offline) {
|
|
37516
|
+
// Anything further needs a request, so offline callers take what the entity carries, placeholder or not.
|
|
37517
|
+
return ((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.Name) || "Unnamed Entity";
|
|
37518
|
+
}
|
|
36596
37519
|
try {
|
|
36597
37520
|
const typeId = entity.Bruce["EntityType.ID"];
|
|
36598
37521
|
let type = null;
|
|
@@ -36834,6 +37757,13 @@
|
|
|
36834
37757
|
GetArchiveUrl() {
|
|
36835
37758
|
return this.archiveUrl;
|
|
36836
37759
|
}
|
|
37760
|
+
/**
|
|
37761
|
+
* The property this instance presents frames through, for a caller that needs to rebuild the entity's
|
|
37762
|
+
* material (eg: re-tinting for opacity/selection) without detaching the animation.
|
|
37763
|
+
*/
|
|
37764
|
+
GetImageProperty() {
|
|
37765
|
+
return this.imageProperty;
|
|
37766
|
+
}
|
|
36837
37767
|
onClockTick(currentTime) {
|
|
36838
37768
|
if (this.disposed) {
|
|
36839
37769
|
return;
|
|
@@ -37039,7 +37969,7 @@
|
|
|
37039
37969
|
let textureDataUri = null;
|
|
37040
37970
|
let textureTraceEffective = null;
|
|
37041
37971
|
let frameArchive = null;
|
|
37042
|
-
if (fillType === BModels.Style.EPolygonFillType.Texture) {
|
|
37972
|
+
if (fillType === BModels.Style.EPolygonFillType.Texture && !params.offline) {
|
|
37043
37973
|
try {
|
|
37044
37974
|
const resolved = await resolveTexturedFill({
|
|
37045
37975
|
api: params.api,
|
|
@@ -37120,8 +38050,8 @@
|
|
|
37120
38050
|
// We'll remove all that aren't in the allowed (direct) list.
|
|
37121
38051
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
37122
38052
|
const part = parts[i];
|
|
37123
|
-
if (part && part instanceof Cesium.Entity &&
|
|
37124
|
-
params.viewer
|
|
38053
|
+
if (part && part instanceof Cesium.Entity && !cEntity._siblingGraphics.includes(part)) {
|
|
38054
|
+
RemoveCEntityFromScene(params.viewer, part);
|
|
37125
38055
|
}
|
|
37126
38056
|
}
|
|
37127
38057
|
if (cEntity._parentEntity) {
|
|
@@ -37131,7 +38061,8 @@
|
|
|
37131
38061
|
};
|
|
37132
38062
|
const hasOutline = width > 0 && cLineColor;
|
|
37133
38063
|
let cEntity = null;
|
|
37134
|
-
|
|
38064
|
+
const isExistingGraphic = Boolean(params.rendered && params.rendered.polygon);
|
|
38065
|
+
if (!isExistingGraphic) {
|
|
37135
38066
|
cEntity = new Cesium.Entity({
|
|
37136
38067
|
id: BModels.ObjectUtils.UId(15),
|
|
37137
38068
|
polygon: {
|
|
@@ -37144,7 +38075,7 @@
|
|
|
37144
38075
|
classificationType: classification,
|
|
37145
38076
|
perPositionHeight: heightRef == Cesium.HeightReference.CLAMP_TO_GROUND ? false : true,
|
|
37146
38077
|
zIndex: zIndex,
|
|
37147
|
-
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width <= 0 || !cLineColor || units == "m" ? size : null, true)
|
|
38078
|
+
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width <= 0 || !cLineColor || units == "m" ? size : null, true, size)
|
|
37148
38079
|
},
|
|
37149
38080
|
position: exports.EntityUtils.GetPos({
|
|
37150
38081
|
viewer: params.viewer,
|
|
@@ -37198,9 +38129,38 @@
|
|
|
37198
38129
|
if (oldZIndex != zIndex) {
|
|
37199
38130
|
cEntity.polygon.zIndex = new Cesium.ConstantProperty(zIndex);
|
|
37200
38131
|
}
|
|
37201
|
-
|
|
37202
|
-
|
|
37203
|
-
|
|
38132
|
+
SetCPropIfChanged({
|
|
38133
|
+
viewer: params.viewer,
|
|
38134
|
+
graphic: cEntity.polygon,
|
|
38135
|
+
property: "distanceDisplayCondition",
|
|
38136
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width <= 0 || !cLineColor || units == "m" ? size : null, true, size)
|
|
38137
|
+
});
|
|
38138
|
+
SetCPropIfChanged({
|
|
38139
|
+
viewer: params.viewer,
|
|
38140
|
+
graphic: cEntity.polygon,
|
|
38141
|
+
property: "shadows",
|
|
38142
|
+
value: Cesium.ShadowMode.ENABLED
|
|
38143
|
+
});
|
|
38144
|
+
SetCPropIfChanged({
|
|
38145
|
+
viewer: params.viewer,
|
|
38146
|
+
graphic: cEntity.polygon,
|
|
38147
|
+
property: "classificationType",
|
|
38148
|
+
value: classification
|
|
38149
|
+
});
|
|
38150
|
+
cEntity.show = true;
|
|
38151
|
+
}
|
|
38152
|
+
// Must run before any material is baked below: the Animator takes over polygon.material, so a bake
|
|
38153
|
+
// has to know whether it is baking over a live animation or over a disposed one's restored material.
|
|
38154
|
+
const animator = syncTextureFrameArchive(cEntity, frameArchive, params.viewer, style.textureColorMask);
|
|
38155
|
+
if (animator) {
|
|
38156
|
+
exports.CesiumEntityStyler.SetDefaultTextureImage({
|
|
38157
|
+
entity: cEntity,
|
|
38158
|
+
image: animator.GetImageProperty(),
|
|
38159
|
+
viewer: params.viewer,
|
|
38160
|
+
requestRender: false
|
|
38161
|
+
});
|
|
38162
|
+
}
|
|
38163
|
+
else if (isExistingGraphic) {
|
|
37204
38164
|
// TODO: animate the texture!
|
|
37205
38165
|
if (textureDataUri) {
|
|
37206
38166
|
// Rebaking texture to ensure we don't revert to the wrong one later.
|
|
@@ -37227,12 +38187,12 @@
|
|
|
37227
38187
|
entity: cEntity,
|
|
37228
38188
|
viewer: params.viewer,
|
|
37229
38189
|
override: true,
|
|
38190
|
+
// Fill colour only. The outline sibling gets its own line colour baked below.
|
|
38191
|
+
includeSiblings: false,
|
|
37230
38192
|
requestRender: false
|
|
37231
38193
|
});
|
|
37232
38194
|
}
|
|
37233
|
-
cEntity.show = true;
|
|
37234
38195
|
}
|
|
37235
|
-
syncTextureFrameArchive(cEntity, frameArchive, params.viewer, style.textureColorMask);
|
|
37236
38196
|
if (frameArchive && params.onSeriesDiscovered) {
|
|
37237
38197
|
const segment = frameArchiveToSeriesSegment(frameArchive, params.entity);
|
|
37238
38198
|
if (segment) {
|
|
@@ -37265,7 +38225,7 @@
|
|
|
37265
38225
|
classificationType: Cesium.ClassificationType.TERRAIN,
|
|
37266
38226
|
arcType: Cesium.ArcType.GEODESIC,
|
|
37267
38227
|
zIndex: zIndex,
|
|
37268
|
-
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance)
|
|
38228
|
+
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, null, false, size)
|
|
37269
38229
|
}) : null,
|
|
37270
38230
|
corridor: units == "m" ? {
|
|
37271
38231
|
positions: borderPosses,
|
|
@@ -37277,7 +38237,7 @@
|
|
|
37277
38237
|
zIndex: zIndex + 1,
|
|
37278
38238
|
cornerType: Cesium.CornerType.MITERED,
|
|
37279
38239
|
classificationType: classification,
|
|
37280
|
-
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width),
|
|
38240
|
+
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width, false, size),
|
|
37281
38241
|
shadows: Cesium.ShadowMode.ENABLED
|
|
37282
38242
|
} : null,
|
|
37283
38243
|
show: true
|
|
@@ -37304,11 +38264,21 @@
|
|
|
37304
38264
|
}
|
|
37305
38265
|
const oldMaterial = GetCValue(params.viewer, cEntityBorder.polyline.material);
|
|
37306
38266
|
const newMaterial = new Cesium.ColorMaterialProperty(cLineColor);
|
|
37307
|
-
if (
|
|
38267
|
+
if (!areColorMaterialsEqual(params.viewer, oldMaterial, newMaterial)) {
|
|
37308
38268
|
cEntityBorder.polyline.material = newMaterial;
|
|
37309
38269
|
}
|
|
37310
|
-
|
|
37311
|
-
|
|
38270
|
+
SetCPropIfChanged({
|
|
38271
|
+
viewer: params.viewer,
|
|
38272
|
+
graphic: cEntityBorder.polyline,
|
|
38273
|
+
property: "classificationType",
|
|
38274
|
+
value: Cesium.ClassificationType.TERRAIN
|
|
38275
|
+
});
|
|
38276
|
+
SetCPropIfChanged({
|
|
38277
|
+
viewer: params.viewer,
|
|
38278
|
+
graphic: cEntityBorder.polyline,
|
|
38279
|
+
property: "distanceDisplayCondition",
|
|
38280
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, null, false, size)
|
|
38281
|
+
});
|
|
37312
38282
|
cEntityBorder.corridor = undefined;
|
|
37313
38283
|
}
|
|
37314
38284
|
else {
|
|
@@ -37334,15 +38304,35 @@
|
|
|
37334
38304
|
}
|
|
37335
38305
|
const oldMaterial = GetCValue(params.viewer, cEntityBorder.corridor.material);
|
|
37336
38306
|
const newMaterial = new Cesium.ColorMaterialProperty(cLineColor);
|
|
37337
|
-
if (
|
|
38307
|
+
if (!areColorMaterialsEqual(params.viewer, oldMaterial, newMaterial)) {
|
|
37338
38308
|
cEntityBorder.corridor.material = newMaterial;
|
|
37339
38309
|
}
|
|
37340
|
-
|
|
37341
|
-
|
|
38310
|
+
SetCPropIfChanged({
|
|
38311
|
+
viewer: params.viewer,
|
|
38312
|
+
graphic: cEntityBorder.corridor,
|
|
38313
|
+
property: "fill",
|
|
38314
|
+
value: true
|
|
38315
|
+
});
|
|
38316
|
+
SetCPropIfChanged({
|
|
38317
|
+
viewer: params.viewer,
|
|
38318
|
+
graphic: cEntityBorder.corridor,
|
|
38319
|
+
property: "distanceDisplayCondition",
|
|
38320
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width, false, size)
|
|
38321
|
+
});
|
|
37342
38322
|
cEntityBorder.polyline = undefined;
|
|
37343
38323
|
}
|
|
37344
38324
|
cEntityBorder.show = true;
|
|
37345
38325
|
}
|
|
38326
|
+
// Bake the outline's own colour as its default, so a deselect/opacity refresh restores the line
|
|
38327
|
+
// colour rather than falling back to the fill's.
|
|
38328
|
+
exports.CesiumEntityStyler.SetDefaultColor({
|
|
38329
|
+
color: cLineColor,
|
|
38330
|
+
entity: cEntityBorder,
|
|
38331
|
+
viewer: params.viewer,
|
|
38332
|
+
override: true,
|
|
38333
|
+
includeSiblings: false,
|
|
38334
|
+
requestRender: false
|
|
38335
|
+
});
|
|
37346
38336
|
cEntityBorder._parentEntity = cEntity;
|
|
37347
38337
|
cEntity._siblingGraphics.push(cEntityBorder);
|
|
37348
38338
|
for (let i = 0; i < holePosses.length; i++) {
|
|
@@ -37358,7 +38348,7 @@
|
|
|
37358
38348
|
classificationType: Cesium.ClassificationType.TERRAIN,
|
|
37359
38349
|
arcType: Cesium.ArcType.GEODESIC,
|
|
37360
38350
|
zIndex: zIndex,
|
|
37361
|
-
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance)
|
|
38351
|
+
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, null, false, size)
|
|
37362
38352
|
}) : null,
|
|
37363
38353
|
corridor: units == "m" ? {
|
|
37364
38354
|
positions: borderPosses,
|
|
@@ -37370,7 +38360,7 @@
|
|
|
37370
38360
|
zIndex: zIndex + 1,
|
|
37371
38361
|
cornerType: Cesium.CornerType.MITERED,
|
|
37372
38362
|
classificationType: classification,
|
|
37373
|
-
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width),
|
|
38363
|
+
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width, false, size),
|
|
37374
38364
|
shadows: Cesium.ShadowMode.ENABLED,
|
|
37375
38365
|
} : null,
|
|
37376
38366
|
show: true
|
|
@@ -37411,7 +38401,7 @@
|
|
|
37411
38401
|
// De-dupe the tag IDs.
|
|
37412
38402
|
tagIds = Array.from(new Set(tagIds));
|
|
37413
38403
|
// Request if at least one then create a quick lookup map for tags.
|
|
37414
|
-
const tags = tagIds.length > 0 ? (await BModels.EntityTag.GetListByIds({
|
|
38404
|
+
const tags = (!params.offline && tagIds.length > 0) ? (await BModels.EntityTag.GetListByIds({
|
|
37415
38405
|
api,
|
|
37416
38406
|
tagIds
|
|
37417
38407
|
})).tags : [];
|
|
@@ -37423,7 +38413,7 @@
|
|
|
37423
38413
|
for (let i = 0; i < params.entities.length; i++) {
|
|
37424
38414
|
const entity = params.entities[i];
|
|
37425
38415
|
const zoomItem = params.zoomItems[entity.Bruce.ID];
|
|
37426
|
-
const style = zoomItem.StyleID != -1 ? (_a = (await getStyle$4(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
38416
|
+
const style = (!params.offline && zoomItem.StyleID != -1) ? (_a = (await getStyle$4(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
37427
38417
|
// Pass through tags that may be needed for styling.
|
|
37428
38418
|
const tagIds = entity.Bruce["Layer.ID"];
|
|
37429
38419
|
const tags = [];
|
|
@@ -37458,7 +38448,7 @@
|
|
|
37458
38448
|
console.error(`Polygon.RenderGroup: failed to render entity ${((_d = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _d === void 0 ? void 0 : _d.ID) || "<NONE>"}:`, e);
|
|
37459
38449
|
}
|
|
37460
38450
|
if (cEntity) {
|
|
37461
|
-
const name = await getName$3(api, entity);
|
|
38451
|
+
const name = await getName$3(api, entity, params.offline);
|
|
37462
38452
|
cEntity.name = name;
|
|
37463
38453
|
cEntity._renderGroup = exports.EntityRenderEngine.GetRenderGroupId(zoomItem);
|
|
37464
38454
|
cEntity.styleId = zoomItem.StyleID == -1 ? -1 : (+zoomItem.StyleID || null);
|
|
@@ -37480,7 +38470,16 @@
|
|
|
37480
38470
|
}
|
|
37481
38471
|
EntityRenderEnginePolygon.DisposeTextureFrameSeriesAnimator = DisposeTextureFrameSeriesAnimator;
|
|
37482
38472
|
})(exports.EntityRenderEnginePolygon || (exports.EntityRenderEnginePolygon = {}));
|
|
37483
|
-
async function getName$3(api, entity) {
|
|
38473
|
+
async function getName$3(api, entity, offline) {
|
|
38474
|
+
var _a;
|
|
38475
|
+
const ownName = GetUsableEntityName(entity);
|
|
38476
|
+
if (ownName) {
|
|
38477
|
+
return ownName;
|
|
38478
|
+
}
|
|
38479
|
+
if (offline) {
|
|
38480
|
+
// Anything further needs a request, so offline callers take what the entity carries, placeholder or not.
|
|
38481
|
+
return ((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.Name) || "Unnamed Entity";
|
|
38482
|
+
}
|
|
37484
38483
|
try {
|
|
37485
38484
|
const typeId = entity.Bruce["EntityType.ID"];
|
|
37486
38485
|
let type = null;
|
|
@@ -37584,6 +38583,7 @@
|
|
|
37584
38583
|
/**
|
|
37585
38584
|
* Reconciles cEntity's TextureFrameSeriesAnimator.Animator (if any) against this render's resolved texture.
|
|
37586
38585
|
* Called once cEntity is fully created/updated and definitely has a `polygon` graphics.
|
|
38586
|
+
* Returns the animator now driving the entity, or null if this render has no frame series.
|
|
37587
38587
|
* @param cEntity
|
|
37588
38588
|
* @param frameArchive
|
|
37589
38589
|
* @param viewer
|
|
@@ -37592,22 +38592,24 @@
|
|
|
37592
38592
|
function syncTextureFrameArchive(cEntity, frameArchive, viewer, textureColorMask) {
|
|
37593
38593
|
const existing = cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY];
|
|
37594
38594
|
if (frameArchive && existing && !existing.IsDisposed() && existing.GetArchiveUrl() === frameArchive.url) {
|
|
37595
|
-
return;
|
|
38595
|
+
return existing;
|
|
37596
38596
|
}
|
|
37597
38597
|
if (existing && !existing.IsDisposed()) {
|
|
37598
38598
|
existing.Dispose();
|
|
37599
38599
|
cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY] = null;
|
|
37600
38600
|
}
|
|
37601
|
-
if (frameArchive) {
|
|
37602
|
-
|
|
37603
|
-
viewer,
|
|
37604
|
-
entity: cEntity,
|
|
37605
|
-
archiveUrl: frameArchive.url,
|
|
37606
|
-
frames: frameArchive.metadata.Frames,
|
|
37607
|
-
textureColorMask
|
|
37608
|
-
});
|
|
37609
|
-
cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY] = animator;
|
|
38601
|
+
if (!frameArchive) {
|
|
38602
|
+
return null;
|
|
37610
38603
|
}
|
|
38604
|
+
const animator = new TextureFrameSeriesAnimator.Animator({
|
|
38605
|
+
viewer,
|
|
38606
|
+
entity: cEntity,
|
|
38607
|
+
archiveUrl: frameArchive.url,
|
|
38608
|
+
frames: frameArchive.metadata.Frames,
|
|
38609
|
+
textureColorMask
|
|
38610
|
+
});
|
|
38611
|
+
cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY] = animator;
|
|
38612
|
+
return animator;
|
|
37611
38613
|
}
|
|
37612
38614
|
/**
|
|
37613
38615
|
* Derives a min/max/label time-range segment from a resolved frame archive's Frames metadata,
|
|
@@ -37774,7 +38776,7 @@
|
|
|
37774
38776
|
* @param b
|
|
37775
38777
|
* @returns
|
|
37776
38778
|
*/
|
|
37777
|
-
function
|
|
38779
|
+
function areColorMaterialsEqual(viewer, a, b) {
|
|
37778
38780
|
// Same reference.
|
|
37779
38781
|
if (a == b) {
|
|
37780
38782
|
return true;
|
|
@@ -38083,15 +39085,44 @@
|
|
|
38083
39085
|
}
|
|
38084
39086
|
})(exports.StyleEffective || (exports.StyleEffective = {}));
|
|
38085
39087
|
(function (EntityRenderEngine) {
|
|
39088
|
+
/**
|
|
39089
|
+
* Identifies the zoom band a graphic was last rendered for, covering everything in that band which
|
|
39090
|
+
* changes how the entity is drawn. Used to decide whether a re-render is needed at all.
|
|
39091
|
+
*
|
|
39092
|
+
* Deliberately NOT the reuse key: most of a band's identity is plain graphics properties that can be
|
|
39093
|
+
* patched onto the existing graphic, so see GetGraphicShapeId for that decision.
|
|
39094
|
+
*/
|
|
38086
39095
|
function GetRenderGroupId(zoomItem) {
|
|
38087
39096
|
if (!zoomItem) {
|
|
38088
39097
|
return null;
|
|
38089
39098
|
}
|
|
38090
|
-
return
|
|
39099
|
+
return exports.RenderManager.GetZoomControlSignature([zoomItem]);
|
|
38091
39100
|
}
|
|
38092
39101
|
EntityRenderEngine.GetRenderGroupId = GetRenderGroupId;
|
|
39102
|
+
/**
|
|
39103
|
+
* Identifies the kind of Cesium graphic a zoom item + entity resolves to, ignoring anything that is merely a property on it.
|
|
39104
|
+
*/
|
|
39105
|
+
function GetGraphicShapeId(zoomItem, entity) {
|
|
39106
|
+
var _a;
|
|
39107
|
+
let displayType = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.DisplayType;
|
|
39108
|
+
if (!displayType) {
|
|
39109
|
+
displayType = BModels.ZoomControl.EDisplayType.Hidden;
|
|
39110
|
+
}
|
|
39111
|
+
// Backwards compatibility, same mapping the render pass applies.
|
|
39112
|
+
else if (displayType == "polygon") {
|
|
39113
|
+
displayType = BModels.ZoomControl.EDisplayType.Geometry;
|
|
39114
|
+
}
|
|
39115
|
+
// Multi-geometry builds a container graphic holding sibling graphics rather than a flat one.
|
|
39116
|
+
const geometry = BModels.Entity.GetValue({
|
|
39117
|
+
entity: entity,
|
|
39118
|
+
path: ["Bruce", "VectorGeometry"]
|
|
39119
|
+
});
|
|
39120
|
+
const isMulti = ((_a = geometry === null || geometry === void 0 ? void 0 : geometry.MultiGeometry) === null || _a === void 0 ? void 0 : _a.length) > 1;
|
|
39121
|
+
return displayType + "|" + (isMulti ? "multi" : "single");
|
|
39122
|
+
}
|
|
39123
|
+
EntityRenderEngine.GetGraphicShapeId = GetGraphicShapeId;
|
|
38093
39124
|
async function Render(params) {
|
|
38094
|
-
var _a, _b, _c
|
|
39125
|
+
var _a, _b, _c;
|
|
38095
39126
|
const groupRenderParams = {
|
|
38096
39127
|
apiGetter: params.apiGetter,
|
|
38097
39128
|
viewer: params.viewer,
|
|
@@ -38099,10 +39130,15 @@
|
|
|
38099
39130
|
zoomItems: {},
|
|
38100
39131
|
menuItemId: params.menuItemId,
|
|
38101
39132
|
onSeriesDiscovered: params.onSeriesDiscovered,
|
|
38102
|
-
visualRegister: params.visualRegister
|
|
39133
|
+
visualRegister: params.visualRegister,
|
|
39134
|
+
offline: params.offline
|
|
38103
39135
|
};
|
|
38104
39136
|
const updated = new Map();
|
|
38105
39137
|
const cEntities = new Map();
|
|
39138
|
+
// Entity ID -> the graphic shape resolved for this pass, stamped onto the results at the end.
|
|
39139
|
+
const shapeIds = new Map();
|
|
39140
|
+
// Entity ID -> what its zoom band was resolved from, stamped alongside the shape.
|
|
39141
|
+
const bandChecks = new Map();
|
|
38106
39142
|
const models = [];
|
|
38107
39143
|
const multiGeometry = [];
|
|
38108
39144
|
const polygons = [];
|
|
@@ -38152,11 +39188,21 @@
|
|
|
38152
39188
|
for (let i = 0; i < params.entities.length; i++) {
|
|
38153
39189
|
let entity = params.entities[i];
|
|
38154
39190
|
const id = entity.Bruce.ID;
|
|
39191
|
+
const resolution = {};
|
|
38155
39192
|
const zoomItem = exports.RenderManager.DetermineZoomItem({
|
|
38156
39193
|
viewer: params.viewer,
|
|
38157
39194
|
entity,
|
|
38158
|
-
zoomControl: params.zoomControl
|
|
38159
|
-
|
|
39195
|
+
zoomControl: params.zoomControl,
|
|
39196
|
+
out: resolution
|
|
39197
|
+
});
|
|
39198
|
+
if (zoomItem && resolution.distance != null && resolution.cameraPos) {
|
|
39199
|
+
bandChecks.set(id, {
|
|
39200
|
+
distance: resolution.distance,
|
|
39201
|
+
cameraPos: resolution.cameraPos,
|
|
39202
|
+
min: zoomItem.MinZoom,
|
|
39203
|
+
max: zoomItem.MaxZoom
|
|
39204
|
+
});
|
|
39205
|
+
}
|
|
38160
39206
|
let displayType = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.DisplayType;
|
|
38161
39207
|
if (!displayType) {
|
|
38162
39208
|
displayType = BModels.ZoomControl.EDisplayType.Hidden;
|
|
@@ -38170,8 +39216,13 @@
|
|
|
38170
39216
|
entityId: id,
|
|
38171
39217
|
menuItemId: params.menuItemId
|
|
38172
39218
|
});
|
|
39219
|
+
const existingVisual = existingRego === null || existingRego === void 0 ? void 0 : existingRego.visual;
|
|
38173
39220
|
const newRenderId = GetRenderGroupId(zoomItem);
|
|
38174
|
-
const oldRenderId =
|
|
39221
|
+
const oldRenderId = existingVisual === null || existingVisual === void 0 ? void 0 : existingVisual._renderGroup;
|
|
39222
|
+
// Resolved before prepareGeometry() below, which flattens a single-item MultiGeometry and
|
|
39223
|
+
// would otherwise make the same entity resolve to a different shape than it was stamped with.
|
|
39224
|
+
const newShapeId = GetGraphicShapeId(zoomItem, entity);
|
|
39225
|
+
shapeIds.set(id, newShapeId);
|
|
38175
39226
|
if (!params.force &&
|
|
38176
39227
|
newRenderId == oldRenderId &&
|
|
38177
39228
|
!(existingRego === null || existingRego === void 0 ? void 0 : existingRego.stale) &&
|
|
@@ -38181,13 +39232,13 @@
|
|
|
38181
39232
|
cEntities.set(id, existingRego.visual);
|
|
38182
39233
|
}
|
|
38183
39234
|
else {
|
|
38184
|
-
|
|
38185
|
-
if (existingRego &&
|
|
39235
|
+
const oldShapeId = existingVisual === null || existingVisual === void 0 ? void 0 : existingVisual._graphicShape;
|
|
39236
|
+
if (existingRego && newShapeId == oldShapeId) {
|
|
38186
39237
|
cEntities.set(id, existingRego.visual);
|
|
38187
39238
|
// Flag as no longer stale as we're unlikely to recreate the rego if we're reusing the graphic.
|
|
38188
39239
|
existingRego.stale = false;
|
|
38189
39240
|
// Update metadata for the same reason.
|
|
38190
|
-
existingRego.outline = (
|
|
39241
|
+
existingRego.outline = (_a = entity.Bruce) === null || _a === void 0 ? void 0 : _a.Outline;
|
|
38191
39242
|
existingRego.entityTypeId = entity.Bruce["EntityType.ID"];
|
|
38192
39243
|
updated.set(id, true);
|
|
38193
39244
|
}
|
|
@@ -38201,7 +39252,7 @@
|
|
|
38201
39252
|
entity: entity,
|
|
38202
39253
|
path: ["Bruce", "VectorGeometry"]
|
|
38203
39254
|
});
|
|
38204
|
-
if ((
|
|
39255
|
+
if ((_b = geometry === null || geometry === void 0 ? void 0 : geometry.MultiGeometry) === null || _b === void 0 ? void 0 : _b.length) {
|
|
38205
39256
|
multiGeometry.push(entity);
|
|
38206
39257
|
}
|
|
38207
39258
|
else {
|
|
@@ -38244,7 +39295,7 @@
|
|
|
38244
39295
|
entity: entity,
|
|
38245
39296
|
path: ["Bruce", "VectorGeometry"]
|
|
38246
39297
|
});
|
|
38247
|
-
if (!((
|
|
39298
|
+
if (!((_c = geometry === null || geometry === void 0 ? void 0 : geometry.MultiGeometry) === null || _c === void 0 ? void 0 : _c.length)) {
|
|
38248
39299
|
polygons.push(entity);
|
|
38249
39300
|
continue;
|
|
38250
39301
|
}
|
|
@@ -38363,6 +39414,21 @@
|
|
|
38363
39414
|
}
|
|
38364
39415
|
}
|
|
38365
39416
|
}
|
|
39417
|
+
// Stamped centrally rather than per-engine so the value always matches what the gate above compared,
|
|
39418
|
+
// regardless of which engine (or fallback engine) ended up producing the graphic.
|
|
39419
|
+
cEntities.forEach((cEntity, id) => {
|
|
39420
|
+
if (!cEntity) {
|
|
39421
|
+
return;
|
|
39422
|
+
}
|
|
39423
|
+
const shapeId = shapeIds.get(id);
|
|
39424
|
+
if (shapeId) {
|
|
39425
|
+
cEntity._graphicShape = shapeId;
|
|
39426
|
+
}
|
|
39427
|
+
const bandCheck = bandChecks.get(id);
|
|
39428
|
+
if (bandCheck) {
|
|
39429
|
+
cEntity._bandCheck = bandCheck;
|
|
39430
|
+
}
|
|
39431
|
+
});
|
|
38366
39432
|
return {
|
|
38367
39433
|
entities: cEntities,
|
|
38368
39434
|
updated
|
|
@@ -38398,9 +39464,7 @@
|
|
|
38398
39464
|
});
|
|
38399
39465
|
}
|
|
38400
39466
|
}
|
|
38401
|
-
|
|
38402
|
-
viewer.entities.remove(entity);
|
|
38403
|
-
}
|
|
39467
|
+
RemoveCEntityFromScene(viewer, entity);
|
|
38404
39468
|
}
|
|
38405
39469
|
doRemove({
|
|
38406
39470
|
viewer: params.viewer,
|
|
@@ -38435,9 +39499,10 @@
|
|
|
38435
39499
|
* @param max
|
|
38436
39500
|
* @param meterSize size of "thing" in meters, eg polyline is 0.5 meters width. If size is provided we can potentially cull it earlier.
|
|
38437
39501
|
* @param isPolygon
|
|
39502
|
+
* @param fitMeterSize overall extent of the "thing" in meters, eg a parcel's bounding-box diagonal. If provided we keep it visible far enough out to actually fit on screen.
|
|
38438
39503
|
* @returns
|
|
38439
39504
|
*/
|
|
38440
|
-
function GetDisplayCondition(min, max, meterSize, isPolygon) {
|
|
39505
|
+
function GetDisplayCondition(min, max, meterSize, isPolygon, fitMeterSize) {
|
|
38441
39506
|
// Max is required.
|
|
38442
39507
|
if (isNaN(+max)) {
|
|
38443
39508
|
return undefined;
|
|
@@ -38467,6 +39532,15 @@
|
|
|
38467
39532
|
return undefined;
|
|
38468
39533
|
}
|
|
38469
39534
|
}
|
|
39535
|
+
// The configured max is a guess about viewing distance, and for a large thing that guess is often short:
|
|
39536
|
+
// it vanishes while still overflowing the screen, so you can never see all of it at once.
|
|
39537
|
+
// A thing of size S needs roughly S * 0.87 of camera distance to fit a 60deg vertical fov, so we
|
|
39538
|
+
// floor the max at a margin above that rather than culling something you haven't finished zooming out to.
|
|
39539
|
+
fitMeterSize = +fitMeterSize;
|
|
39540
|
+
if (!isNaN(fitMeterSize) && fitMeterSize > 0) {
|
|
39541
|
+
const FIT_DISTANCE_PER_METER = 1.4;
|
|
39542
|
+
max = Math.max(max, fitMeterSize * FIT_DISTANCE_PER_METER);
|
|
39543
|
+
}
|
|
38470
39544
|
return new Cesium.DistanceDisplayCondition(min, max);
|
|
38471
39545
|
}
|
|
38472
39546
|
EntityRenderEngine.GetDisplayCondition = GetDisplayCondition;
|
|
@@ -38489,7 +39563,71 @@
|
|
|
38489
39563
|
}
|
|
38490
39564
|
return value;
|
|
38491
39565
|
}
|
|
39566
|
+
const pendingRemovalsByViewer = new WeakMap();
|
|
39567
|
+
function scheduleEntityRemoval(viewer, entity) {
|
|
39568
|
+
let pending = pendingRemovalsByViewer.get(viewer);
|
|
39569
|
+
if (!pending) {
|
|
39570
|
+
pending = { entities: new Set(), hook: null };
|
|
39571
|
+
pendingRemovalsByViewer.set(viewer, pending);
|
|
39572
|
+
}
|
|
39573
|
+
pending.entities.add(entity);
|
|
39574
|
+
if (pending.hook) {
|
|
39575
|
+
return;
|
|
39576
|
+
}
|
|
39577
|
+
pending.hook = viewer.scene.postRender.addEventListener(() => {
|
|
39578
|
+
var _a;
|
|
39579
|
+
(_a = pending.hook) === null || _a === void 0 ? void 0 : _a.call(pending);
|
|
39580
|
+
pending.hook = null;
|
|
39581
|
+
const batch = Array.from(pending.entities);
|
|
39582
|
+
pending.entities.clear();
|
|
39583
|
+
if (!batch.length) {
|
|
39584
|
+
return;
|
|
39585
|
+
}
|
|
39586
|
+
WithSuspendedCCollections(batch.map(x => GetCEntityCollection(viewer, x)), () => {
|
|
39587
|
+
for (const item of batch) {
|
|
39588
|
+
try {
|
|
39589
|
+
exports.EntityRenderEngine.Remove({
|
|
39590
|
+
viewer,
|
|
39591
|
+
entity: item
|
|
39592
|
+
});
|
|
39593
|
+
}
|
|
39594
|
+
catch (e) {
|
|
39595
|
+
console.error(e);
|
|
39596
|
+
}
|
|
39597
|
+
}
|
|
39598
|
+
});
|
|
39599
|
+
});
|
|
39600
|
+
}
|
|
38492
39601
|
(function (CesiumAnimatedInOut) {
|
|
39602
|
+
/**
|
|
39603
|
+
* Runs any removals already queued for this viewer immediately, instead of waiting for the next render.
|
|
39604
|
+
* For teardown paths that need the scene emptied synchronously.
|
|
39605
|
+
*/
|
|
39606
|
+
function FlushPendingRemovals(viewer) {
|
|
39607
|
+
var _a;
|
|
39608
|
+
const pending = pendingRemovalsByViewer.get(viewer);
|
|
39609
|
+
if (!(pending === null || pending === void 0 ? void 0 : pending.entities.size)) {
|
|
39610
|
+
return;
|
|
39611
|
+
}
|
|
39612
|
+
const batch = Array.from(pending.entities);
|
|
39613
|
+
pending.entities.clear();
|
|
39614
|
+
(_a = pending.hook) === null || _a === void 0 ? void 0 : _a.call(pending);
|
|
39615
|
+
pending.hook = null;
|
|
39616
|
+
WithSuspendedCCollections(batch.map(x => GetCEntityCollection(viewer, x)), () => {
|
|
39617
|
+
for (const item of batch) {
|
|
39618
|
+
try {
|
|
39619
|
+
exports.EntityRenderEngine.Remove({
|
|
39620
|
+
viewer,
|
|
39621
|
+
entity: item
|
|
39622
|
+
});
|
|
39623
|
+
}
|
|
39624
|
+
catch (e) {
|
|
39625
|
+
console.error(e);
|
|
39626
|
+
}
|
|
39627
|
+
}
|
|
39628
|
+
});
|
|
39629
|
+
}
|
|
39630
|
+
CesiumAnimatedInOut.FlushPendingRemovals = FlushPendingRemovals;
|
|
38493
39631
|
/**
|
|
38494
39632
|
* Animates an Entity out of the scene.
|
|
38495
39633
|
* Removes it from the scene at the end of the animation.
|
|
@@ -38508,13 +39646,7 @@
|
|
|
38508
39646
|
return;
|
|
38509
39647
|
}
|
|
38510
39648
|
removed = true;
|
|
38511
|
-
|
|
38512
|
-
removal();
|
|
38513
|
-
exports.EntityRenderEngine.Remove({
|
|
38514
|
-
viewer,
|
|
38515
|
-
entity
|
|
38516
|
-
});
|
|
38517
|
-
});
|
|
39649
|
+
scheduleEntityRemoval(viewer, entity);
|
|
38518
39650
|
};
|
|
38519
39651
|
for (let i = 0; i < pieces.length; i++) {
|
|
38520
39652
|
const piece = pieces[i];
|
|
@@ -39062,7 +40194,7 @@
|
|
|
39062
40194
|
StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
|
|
39063
40195
|
})(exports.StyleUtils || (exports.StyleUtils = {}));
|
|
39064
40196
|
|
|
39065
|
-
const VERSION = "7.0.
|
|
40197
|
+
const VERSION = "7.0.4";
|
|
39066
40198
|
/**
|
|
39067
40199
|
* Updates the environment instance used by bruce-cesium to one specified.
|
|
39068
40200
|
* This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.
|