bruce-cesium 7.0.1 → 7.0.3
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 +1475 -289
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +1473 -287
- 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 +146 -63
- 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 +58 -4
- 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 +46 -23
- 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 +70 -11
- package/dist/lib/rendering/render-managers/entities/entities-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entity-render-manager.js +13 -1
- package/dist/lib/rendering/render-managers/entities/entity-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 +191 -97
- 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 +13 -0
- package/dist/types/rendering/render-managers/entities/entities-loaded-render-manager.d.ts +2 -0
- package/dist/types/rendering/render-managers/entities/entities-render-manager.d.ts +14 -0
- package/dist/types/rendering/render-managers/entities/entity-render-manager.d.ts +2 -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
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
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 :)
|
|
6010
|
+
}
|
|
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);
|
|
5673
6020
|
}
|
|
5674
|
-
return offset;
|
|
6021
|
+
return recorded.offset;
|
|
5675
6022
|
};
|
|
5676
6023
|
/**
|
|
5677
6024
|
* Converts given pos3d into a an absolute position.
|
|
@@ -5855,6 +6202,10 @@
|
|
|
5855
6202
|
if (cEntity.model) {
|
|
5856
6203
|
const model = cEntity.model;
|
|
5857
6204
|
if (model._radius && !isNaN(model._radius)) {
|
|
6205
|
+
// _radius is already measured from the model's origin rather than its own centre: the model3d
|
|
6206
|
+
// engine folds the bounding sphere's centre offset into it (plus padding for badly-centred
|
|
6207
|
+
// models), and measures it at the entity's scale. So it can be used as-is against a sphere
|
|
6208
|
+
// centred on the entity position.
|
|
5858
6209
|
sphere.radius = Math.max(model._radius, MODEL_MIN_RADIUS);
|
|
5859
6210
|
}
|
|
5860
6211
|
else {
|
|
@@ -5868,12 +6219,10 @@
|
|
|
5868
6219
|
let radius = getValue$1(viewer, cEntity.ellipse.semiMajorAxis);
|
|
5869
6220
|
const extrusion = getValue$1(viewer, cEntity.ellipse.extrudedHeight);
|
|
5870
6221
|
if (extrusion && !isNaN(extrusion)) {
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
radius = extrusion;
|
|
5876
|
-
}
|
|
6222
|
+
// Expand rather than replace: measured from the base centre, the top rim of an extruded ellipse
|
|
6223
|
+
// sits at sqrt(radius^2 + height^2). Taking whichever of the two is larger leaves the rim outside
|
|
6224
|
+
// the sphere, and for something both wide and tall it would actually shrink it.
|
|
6225
|
+
radius = radius ? Math.sqrt((radius * radius) + (extrusion * extrusion)) : extrusion;
|
|
5877
6226
|
}
|
|
5878
6227
|
if (radius && !isNaN(radius)) {
|
|
5879
6228
|
sphere.radius = radius;
|
|
@@ -5883,12 +6232,11 @@
|
|
|
5883
6232
|
else if (cEntity.polygon) {
|
|
5884
6233
|
const extrusion = getValue$1(viewer, cEntity.polygon.extrudedHeight);
|
|
5885
6234
|
if (extrusion && !isNaN(extrusion)) {
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
}
|
|
6235
|
+
// Same as the ellipse above: the footprint sphere has to grow to reach the extruded top corners,
|
|
6236
|
+
// at sqrt(footprint^2 + height^2) from the footprint centre.
|
|
6237
|
+
sphere.radius = sphere.radius
|
|
6238
|
+
? Math.sqrt((sphere.radius * sphere.radius) + (extrusion * extrusion))
|
|
6239
|
+
: extrusion;
|
|
5892
6240
|
}
|
|
5893
6241
|
}
|
|
5894
6242
|
else if (cEntity.point || cEntity.billboard) {
|
|
@@ -5910,7 +6258,15 @@
|
|
|
5910
6258
|
return false;
|
|
5911
6259
|
}
|
|
5912
6260
|
const adjustedSphere = boundingSphere.sphere.clone();
|
|
5913
|
-
|
|
6261
|
+
// Terrain only matters here because it moves the sphere onto the ground.
|
|
6262
|
+
// Far enough away that a plausible ground height is a rounding error against the viewing distance, sampling it is wasted work.
|
|
6263
|
+
const cameraDistance = Cesium.Cartesian3.distance(camera.position, adjustedSphere.center);
|
|
6264
|
+
if (cameraDistance > TERRAIN_SKIP_DISTANCE) {
|
|
6265
|
+
adjustedSphere.radius += TERRAIN_SKIP_RADIUS_PAD;
|
|
6266
|
+
}
|
|
6267
|
+
else {
|
|
6268
|
+
adjustedSphere.center = adjustPos3d(viewer, boundingSphere.heightRef, adjustedSphere.center);
|
|
6269
|
+
}
|
|
5914
6270
|
const cullingVolume = camera.frustum.computeCullingVolume(camera.position, camera.direction, camera.up);
|
|
5915
6271
|
const visibility = cullingVolume.computeVisibility(adjustedSphere);
|
|
5916
6272
|
return visibility !== Cesium.Intersect.INSIDE && visibility !== Cesium.Intersect.INTERSECTING;
|
|
@@ -5983,38 +6339,67 @@
|
|
|
5983
6339
|
rego.relation != null ||
|
|
5984
6340
|
// Explicitly being either shown or hidden.
|
|
5985
6341
|
rego.overrideShow != null ||
|
|
5986
|
-
// Part of
|
|
5987
|
-
//
|
|
5988
|
-
rego.collection ||
|
|
6342
|
+
// Part of a collection we did not create, eg. a geojson data source, which may have its own rules for
|
|
6343
|
+
// what is in the scene. Our own per-menu-item data sources are fair game.
|
|
6344
|
+
(rego.collection && !IsCCollectionOwned(rego.collection)) ||
|
|
5989
6345
|
// We won't cull historic records as they may be interpolating their locations.
|
|
5990
6346
|
Boolean(rego.outline && rego.outline.some(x => !!x.DateTime))) {
|
|
5991
6347
|
return true;
|
|
5992
6348
|
}
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6349
|
+
return false;
|
|
6350
|
+
}
|
|
6351
|
+
// A tileset's bounds are padded by this fraction before testing, so panning does not immediately evict something
|
|
6352
|
+
// at the edge of view and pay to re-traverse it moments later.
|
|
6353
|
+
const TILESET_CULL_PADDING = 0.25;
|
|
6354
|
+
/**
|
|
6355
|
+
* Suppresses tilesets whose padded bounds are outside the view, and restores ones that come back.
|
|
6356
|
+
*
|
|
6357
|
+
* Worth doing separately from entity culling because Cesium gates a tileset's whole update on its show flag: a
|
|
6358
|
+
* hidden tileset skips traversal, tile selection and request scheduling entirely, where hiding its features still
|
|
6359
|
+
* does all of that and merely draws nothing. There are only ever a handful of tilesets, so this needs no batching.
|
|
6360
|
+
* @param register
|
|
6361
|
+
*/
|
|
6362
|
+
function cullTilesets(register) {
|
|
6363
|
+
var _a;
|
|
6364
|
+
const viewer = register.Viewer;
|
|
6365
|
+
const tilesets = register.GetTilesets();
|
|
6366
|
+
if (!tilesets.length || viewer.isDestroyed() || !viewer.scene) {
|
|
6367
|
+
return;
|
|
6010
6368
|
}
|
|
6011
|
-
|
|
6012
|
-
|
|
6369
|
+
const camera = viewer.scene.camera;
|
|
6370
|
+
const cullingVolume = camera.frustum.computeCullingVolume(camera.position, camera.direction, camera.up);
|
|
6371
|
+
let changed = false;
|
|
6372
|
+
for (const rego of tilesets) {
|
|
6373
|
+
const tileset = rego.tileset;
|
|
6374
|
+
if (!tileset || !rego.gate) {
|
|
6375
|
+
continue;
|
|
6376
|
+
}
|
|
6377
|
+
// A destroyed tileset should not be held onto, let alone culled.
|
|
6378
|
+
if ((_a = tileset.isDestroyed) === null || _a === void 0 ? void 0 : _a.call(tileset)) {
|
|
6379
|
+
register.RemoveTileset(tileset);
|
|
6380
|
+
continue;
|
|
6381
|
+
}
|
|
6382
|
+
let sphere;
|
|
6383
|
+
try {
|
|
6384
|
+
sphere = tileset.boundingSphere;
|
|
6385
|
+
}
|
|
6386
|
+
catch (e) {
|
|
6387
|
+
// Not ready yet. Leave it alone rather than guessing.
|
|
6388
|
+
continue;
|
|
6389
|
+
}
|
|
6390
|
+
if (!sphere || isNaN(sphere.radius) || sphere.radius <= 0) {
|
|
6391
|
+
continue;
|
|
6392
|
+
}
|
|
6393
|
+
const padded = sphere.clone();
|
|
6394
|
+
padded.radius = sphere.radius * (1 + TILESET_CULL_PADDING);
|
|
6395
|
+
const visible = cullingVolume.computeVisibility(padded) !== Cesium.Intersect.OUTSIDE;
|
|
6396
|
+
if (register.SetTilesetCulled(tileset, !visible)) {
|
|
6397
|
+
changed = true;
|
|
6398
|
+
}
|
|
6013
6399
|
}
|
|
6014
|
-
|
|
6015
|
-
|
|
6400
|
+
if (changed) {
|
|
6401
|
+
viewer.scene.requestRender();
|
|
6016
6402
|
}
|
|
6017
|
-
return heightRef != Cesium.HeightReference.CLAMP_TO_GROUND;
|
|
6018
6403
|
}
|
|
6019
6404
|
/**
|
|
6020
6405
|
* Runs through all entities in the register and culls them if they are out of the viewport.
|
|
@@ -6030,6 +6415,7 @@
|
|
|
6030
6415
|
const entityIds = register.GetEntityIds();
|
|
6031
6416
|
// We'll use the terrain cache per culler cycle.
|
|
6032
6417
|
_terrainCache.Clear();
|
|
6418
|
+
cullTilesets(register);
|
|
6033
6419
|
checkInterval = setInterval(() => {
|
|
6034
6420
|
var _a;
|
|
6035
6421
|
if (viewer.isDestroyed() || !viewer.scene) {
|
|
@@ -6082,7 +6468,7 @@
|
|
|
6082
6468
|
else {
|
|
6083
6469
|
delete part[VisualRegisterCuller.VISUAL_CULL_KEY];
|
|
6084
6470
|
if (rego.overrideShow != false &&
|
|
6085
|
-
!viewer
|
|
6471
|
+
!IsCEntityInScene(viewer, part) &&
|
|
6086
6472
|
!state.hidden &&
|
|
6087
6473
|
(!isIsolatedAny || state.isolated)) {
|
|
6088
6474
|
toAdd.push(part);
|
|
@@ -6122,16 +6508,17 @@
|
|
|
6122
6508
|
}
|
|
6123
6509
|
const removal = viewer.scene.postRender.addEventListener(() => {
|
|
6124
6510
|
removal();
|
|
6125
|
-
for
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6511
|
+
// Batched, so Cesium raises one collectionChanged for the whole cull pass instead of one per entity.
|
|
6512
|
+
WithSuspendedCCollections(entities.map(x => GetCEntityCollection(viewer, x)), () => {
|
|
6513
|
+
for (let i = 0; i < entities.length; i++) {
|
|
6514
|
+
const entity = entities[i];
|
|
6515
|
+
if (entityRemoveAddState.get(entity.id) != false) {
|
|
6516
|
+
continue;
|
|
6517
|
+
}
|
|
6518
|
+
entityRemoveAddState.delete(entity.id);
|
|
6519
|
+
RemoveCEntityFromScene(viewer, entity);
|
|
6133
6520
|
}
|
|
6134
|
-
}
|
|
6521
|
+
});
|
|
6135
6522
|
});
|
|
6136
6523
|
}
|
|
6137
6524
|
/**
|
|
@@ -6146,16 +6533,17 @@
|
|
|
6146
6533
|
}
|
|
6147
6534
|
const removal = viewer.scene.postRender.addEventListener(() => {
|
|
6148
6535
|
removal();
|
|
6149
|
-
for
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6536
|
+
// Batched, so Cesium raises one collectionChanged for the whole cull pass instead of one per entity.
|
|
6537
|
+
WithSuspendedCCollections(entities.map(x => GetCEntityCollection(viewer, x)), () => {
|
|
6538
|
+
for (let i = 0; i < entities.length; i++) {
|
|
6539
|
+
const entity = entities[i];
|
|
6540
|
+
if (entityRemoveAddState.get(entity.id) != true) {
|
|
6541
|
+
continue;
|
|
6542
|
+
}
|
|
6543
|
+
entityRemoveAddState.delete(entity.id);
|
|
6544
|
+
AddCEntityToScene(viewer, entity);
|
|
6157
6545
|
}
|
|
6158
|
-
}
|
|
6546
|
+
});
|
|
6159
6547
|
});
|
|
6160
6548
|
}
|
|
6161
6549
|
var VisualRegisterCuller;
|
|
@@ -6226,6 +6614,19 @@
|
|
|
6226
6614
|
};
|
|
6227
6615
|
}
|
|
6228
6616
|
VisualRegisterCuller.Monitor = Monitor;
|
|
6617
|
+
/**
|
|
6618
|
+
* Runs the tileset visibility pass immediately, rather than waiting for the next cull cycle.
|
|
6619
|
+
* Exposed so the behaviour is directly assertable, and for a caller that needs it applied now.
|
|
6620
|
+
* @param register
|
|
6621
|
+
*/
|
|
6622
|
+
function CullTilesets(register) {
|
|
6623
|
+
cullTilesets(register);
|
|
6624
|
+
}
|
|
6625
|
+
VisualRegisterCuller.CullTilesets = CullTilesets;
|
|
6626
|
+
function IsCullingIgnored(viewer, rego) {
|
|
6627
|
+
return isCullingIgnored(viewer, rego);
|
|
6628
|
+
}
|
|
6629
|
+
VisualRegisterCuller.IsCullingIgnored = IsCullingIgnored;
|
|
6229
6630
|
function IsCulled(viewer, rego, visual) {
|
|
6230
6631
|
if (isCullingIgnored(viewer, rego)) {
|
|
6231
6632
|
return false;
|
|
@@ -6273,7 +6674,7 @@
|
|
|
6273
6674
|
return false;
|
|
6274
6675
|
}
|
|
6275
6676
|
if (visual instanceof Cesium.Entity) {
|
|
6276
|
-
return viewer
|
|
6677
|
+
return IsCEntityInScene(viewer, visual);
|
|
6277
6678
|
}
|
|
6278
6679
|
else if (visual instanceof Cesium.Primitive) {
|
|
6279
6680
|
return viewer.scene.primitives.contains(visual);
|
|
@@ -6300,6 +6701,32 @@
|
|
|
6300
6701
|
viewer
|
|
6301
6702
|
});
|
|
6302
6703
|
}
|
|
6704
|
+
/**
|
|
6705
|
+
* Returns the highest zIndex across a graphic and its siblings, or null when none of them set one.
|
|
6706
|
+
* @param viewer
|
|
6707
|
+
* @param visual
|
|
6708
|
+
*/
|
|
6709
|
+
function getHighestZIndex(viewer, visual) {
|
|
6710
|
+
if (!(visual instanceof Cesium.Entity)) {
|
|
6711
|
+
return null;
|
|
6712
|
+
}
|
|
6713
|
+
let highest = null;
|
|
6714
|
+
const parts = exports.EntityUtils.GatherEntity({
|
|
6715
|
+
entity: visual
|
|
6716
|
+
});
|
|
6717
|
+
for (const part of parts) {
|
|
6718
|
+
if (!(part instanceof Cesium.Entity)) {
|
|
6719
|
+
continue;
|
|
6720
|
+
}
|
|
6721
|
+
for (const graphic of [part.polygon, part.polyline, part.corridor, part.ellipse, part.rectangle]) {
|
|
6722
|
+
const zIndex = graphic ? GetCValue(viewer, graphic.zIndex) : null;
|
|
6723
|
+
if (zIndex != null && !isNaN(zIndex) && (highest == null || zIndex > highest)) {
|
|
6724
|
+
highest = zIndex;
|
|
6725
|
+
}
|
|
6726
|
+
}
|
|
6727
|
+
}
|
|
6728
|
+
return highest;
|
|
6729
|
+
}
|
|
6303
6730
|
const MAX_SHOW_DEPTH = 10;
|
|
6304
6731
|
function updateCEntityShow(viewer, visual, rego, show, ignoreParent, depth = 0) {
|
|
6305
6732
|
if (depth > MAX_SHOW_DEPTH) {
|
|
@@ -6318,26 +6745,24 @@
|
|
|
6318
6745
|
updateCEntityShow(viewer, sibling, rego, show, true, depth + 1);
|
|
6319
6746
|
}
|
|
6320
6747
|
}
|
|
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);
|
|
6748
|
+
if (show) {
|
|
6749
|
+
// Always restore membership on the way back in. Something else may have evicted this graphic while it
|
|
6750
|
+
// was hidden (the culler removes outright), and `show` alone would leave it invisible.
|
|
6751
|
+
AddCEntityToScene(viewer, visual, rego.collection);
|
|
6752
|
+
if (visual.show !== true) {
|
|
6753
|
+
visual.show = true;
|
|
6331
6754
|
}
|
|
6755
|
+
return;
|
|
6332
6756
|
}
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
viewer.entities.add(visual);
|
|
6757
|
+
// Hiding via `show` only updates a per-instance attribute, where leaving the collection rebuilds the whole
|
|
6758
|
+
// geometry batch. But it is not safe for every graphic, see CanToggleShowSafely for exactly why.
|
|
6759
|
+
if (CanToggleShowSafely([visual])) {
|
|
6760
|
+
if (visual.show !== false) {
|
|
6761
|
+
visual.show = false;
|
|
6339
6762
|
}
|
|
6763
|
+
return;
|
|
6340
6764
|
}
|
|
6765
|
+
RemoveCEntityFromScene(viewer, visual);
|
|
6341
6766
|
}
|
|
6342
6767
|
function updateEntityShow(viewer, rego, show) {
|
|
6343
6768
|
const visual = rego.visual;
|
|
@@ -6646,12 +7071,128 @@
|
|
|
6646
7071
|
// This lets us modify the update without re-adding the item to the queue if it's already in it.
|
|
6647
7072
|
this.updateQueueSettings = {};
|
|
6648
7073
|
this.updateQueueInterval = null;
|
|
7074
|
+
// Per menu item collections so we can refresh sets of Entities without affecting others.
|
|
7075
|
+
this.menuItemSources = new Map();
|
|
7076
|
+
// Set when the data source order no longer matches the zIndexes seen, so it is re-applied once.
|
|
7077
|
+
this.sourceOrderDirty = false;
|
|
7078
|
+
/*
|
|
7079
|
+
* Tilesets in the scene, keyed by the tileset itself.
|
|
7080
|
+
*/
|
|
7081
|
+
this.tilesets = new Map();
|
|
6649
7082
|
this.viewer = params.viewer;
|
|
6650
7083
|
this.apiGetters = params.apiGetters;
|
|
6651
7084
|
this.cameraCullerDispose = VisualRegisterCuller.Monitor({
|
|
6652
7085
|
register: this
|
|
6653
7086
|
});
|
|
6654
7087
|
}
|
|
7088
|
+
/**
|
|
7089
|
+
* Returns the collection a menu item's visuals belong in, creating its data source on first use.
|
|
7090
|
+
* Returns null when there is nothing to key off, leaving the caller on the viewer's own collection.
|
|
7091
|
+
* @param menuItemId
|
|
7092
|
+
*/
|
|
7093
|
+
ensureMenuItemCollection(menuItemId) {
|
|
7094
|
+
var _a;
|
|
7095
|
+
if (!menuItemId || this.disposed || !((_a = this.viewer) === null || _a === void 0 ? void 0 : _a.dataSources)) {
|
|
7096
|
+
return null;
|
|
7097
|
+
}
|
|
7098
|
+
const existing = this.menuItemSources.get(menuItemId);
|
|
7099
|
+
if (existing) {
|
|
7100
|
+
return existing.source.entities;
|
|
7101
|
+
}
|
|
7102
|
+
const source = new Cesium.CustomDataSource(`menu-item-${menuItemId}`);
|
|
7103
|
+
const record = {
|
|
7104
|
+
source,
|
|
7105
|
+
maxZIndex: 0,
|
|
7106
|
+
added: false
|
|
7107
|
+
};
|
|
7108
|
+
MarkCCollectionOwned(source.entities);
|
|
7109
|
+
this.menuItemSources.set(menuItemId, record);
|
|
7110
|
+
// Adding is asynchronous, so ordering has to wait until it is actually in the collection.
|
|
7111
|
+
Promise.resolve(this.viewer.dataSources.add(source))
|
|
7112
|
+
.then(() => {
|
|
7113
|
+
record.added = true;
|
|
7114
|
+
this.applySourceOrder();
|
|
7115
|
+
})
|
|
7116
|
+
.catch((e) => {
|
|
7117
|
+
console.error(e);
|
|
7118
|
+
});
|
|
7119
|
+
return source.entities;
|
|
7120
|
+
}
|
|
7121
|
+
/**
|
|
7122
|
+
* Notes the highest zIndex seen for a menu item, since that is what its data source has to sort by.
|
|
7123
|
+
* zIndex orders geometry within a data source but not between them, so a whole layer stacks by the
|
|
7124
|
+
* highest value anything in it asked for.
|
|
7125
|
+
* @param menuItemId
|
|
7126
|
+
* @param visual
|
|
7127
|
+
*/
|
|
7128
|
+
trackSourceZIndex(menuItemId, visual) {
|
|
7129
|
+
const record = this.menuItemSources.get(menuItemId);
|
|
7130
|
+
if (!record) {
|
|
7131
|
+
return;
|
|
7132
|
+
}
|
|
7133
|
+
const zIndex = getHighestZIndex(this.viewer, visual);
|
|
7134
|
+
if (zIndex == null || zIndex <= record.maxZIndex) {
|
|
7135
|
+
return;
|
|
7136
|
+
}
|
|
7137
|
+
record.maxZIndex = zIndex;
|
|
7138
|
+
this.sourceOrderDirty = true;
|
|
7139
|
+
this.applySourceOrder();
|
|
7140
|
+
}
|
|
7141
|
+
/**
|
|
7142
|
+
* Re-stacks the menu item data sources so a higher zIndex sits above a lower one.
|
|
7143
|
+
*/
|
|
7144
|
+
applySourceOrder() {
|
|
7145
|
+
var _a;
|
|
7146
|
+
if (this.disposed || !this.sourceOrderDirty || !((_a = this.viewer) === null || _a === void 0 ? void 0 : _a.dataSources)) {
|
|
7147
|
+
return;
|
|
7148
|
+
}
|
|
7149
|
+
const records = Array.from(this.menuItemSources.values()).filter(x => x.added);
|
|
7150
|
+
if (records.length < 2) {
|
|
7151
|
+
// Nothing to order against yet, so leave the flag set for when there is.
|
|
7152
|
+
return;
|
|
7153
|
+
}
|
|
7154
|
+
this.sourceOrderDirty = false;
|
|
7155
|
+
// Raising each in ascending order leaves the highest on top.
|
|
7156
|
+
records.sort((a, b) => a.maxZIndex - b.maxZIndex);
|
|
7157
|
+
for (const record of records) {
|
|
7158
|
+
try {
|
|
7159
|
+
this.viewer.dataSources.raiseToTop(record.source);
|
|
7160
|
+
}
|
|
7161
|
+
catch (e) {
|
|
7162
|
+
console.error(e);
|
|
7163
|
+
}
|
|
7164
|
+
}
|
|
7165
|
+
}
|
|
7166
|
+
/**
|
|
7167
|
+
* Drops a menu item's data source once nothing is registered under it any more.
|
|
7168
|
+
* @param menuItemId
|
|
7169
|
+
*/
|
|
7170
|
+
releaseMenuItemCollection(menuItemId) {
|
|
7171
|
+
var _a, _b, _c;
|
|
7172
|
+
const record = this.menuItemSources.get(menuItemId);
|
|
7173
|
+
if (!record) {
|
|
7174
|
+
return;
|
|
7175
|
+
}
|
|
7176
|
+
if ((_a = this.entityIdsByMenuItem[menuItemId]) === null || _a === void 0 ? void 0 : _a.size) {
|
|
7177
|
+
return;
|
|
7178
|
+
}
|
|
7179
|
+
this.menuItemSources.delete(menuItemId);
|
|
7180
|
+
try {
|
|
7181
|
+
(_c = (_b = this.viewer) === null || _b === void 0 ? void 0 : _b.dataSources) === null || _c === void 0 ? void 0 : _c.remove(record.source, true);
|
|
7182
|
+
}
|
|
7183
|
+
catch (e) {
|
|
7184
|
+
console.error(e);
|
|
7185
|
+
}
|
|
7186
|
+
}
|
|
7187
|
+
/** Every collection a bulk pass over this register's visuals could mutate. */
|
|
7188
|
+
allSceneCollections() {
|
|
7189
|
+
var _a;
|
|
7190
|
+
const collections = [(_a = this.viewer) === null || _a === void 0 ? void 0 : _a.entities];
|
|
7191
|
+
for (const record of Array.from(this.menuItemSources.values())) {
|
|
7192
|
+
collections.push(record.source.entities);
|
|
7193
|
+
}
|
|
7194
|
+
return collections;
|
|
7195
|
+
}
|
|
6655
7196
|
indexMenuItemEntity(menuItemId, entityId) {
|
|
6656
7197
|
if (!menuItemId) {
|
|
6657
7198
|
return;
|
|
@@ -7241,9 +7782,11 @@
|
|
|
7241
7782
|
return;
|
|
7242
7783
|
}
|
|
7243
7784
|
const end = Math.min(index + BATCH_SIZE, items.length);
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7785
|
+
WithSuspendedCCollections(this.allSceneCollections(), () => {
|
|
7786
|
+
for (; index < end; index++) {
|
|
7787
|
+
perItem(items[index]);
|
|
7788
|
+
}
|
|
7789
|
+
});
|
|
7247
7790
|
this.viewer.scene.requestRender();
|
|
7248
7791
|
if (index >= items.length) {
|
|
7249
7792
|
clearInterval(interval);
|
|
@@ -7400,7 +7943,7 @@
|
|
|
7400
7943
|
markEntity(this, rego, rego.visual, false);
|
|
7401
7944
|
}
|
|
7402
7945
|
Dispose() {
|
|
7403
|
-
var _a;
|
|
7946
|
+
var _a, _b, _c, _d;
|
|
7404
7947
|
(_a = this.cameraCullerDispose) === null || _a === void 0 ? void 0 : _a.call(this, {
|
|
7405
7948
|
uncull: false
|
|
7406
7949
|
});
|
|
@@ -7415,6 +7958,20 @@
|
|
|
7415
7958
|
}
|
|
7416
7959
|
this.activeChunkedIntervals.clear();
|
|
7417
7960
|
this.disposed = true;
|
|
7961
|
+
for (const record of Array.from(this.menuItemSources.values())) {
|
|
7962
|
+
try {
|
|
7963
|
+
(_c = (_b = this.viewer) === null || _b === void 0 ? void 0 : _b.dataSources) === null || _c === void 0 ? void 0 : _c.remove(record.source, true);
|
|
7964
|
+
}
|
|
7965
|
+
catch (e) {
|
|
7966
|
+
console.error(e);
|
|
7967
|
+
}
|
|
7968
|
+
}
|
|
7969
|
+
this.menuItemSources.clear();
|
|
7970
|
+
// Hand every tileset's show flag back to its owner, holding whatever the owner last asked for.
|
|
7971
|
+
for (const rego of Array.from(this.tilesets.values())) {
|
|
7972
|
+
(_d = rego.gate) === null || _d === void 0 ? void 0 : _d.Release();
|
|
7973
|
+
}
|
|
7974
|
+
this.tilesets.clear();
|
|
7418
7975
|
}
|
|
7419
7976
|
ForceUpdate(params) {
|
|
7420
7977
|
var _a;
|
|
@@ -8010,6 +8567,14 @@
|
|
|
8010
8567
|
});
|
|
8011
8568
|
}
|
|
8012
8569
|
const entityId = rego.entityId;
|
|
8570
|
+
// Scope this visual to its menu item's own data source, so a rebuild of it cannot re-tessellate
|
|
8571
|
+
// other layers. A caller that already picked a collection (eg. geojson) keeps its own.
|
|
8572
|
+
if (!rego.collection && rego.menuItemId) {
|
|
8573
|
+
const collection = this.ensureMenuItemCollection(rego.menuItemId);
|
|
8574
|
+
if (collection) {
|
|
8575
|
+
rego.collection = collection;
|
|
8576
|
+
}
|
|
8577
|
+
}
|
|
8013
8578
|
// Add the new visual to the register.
|
|
8014
8579
|
const entityRegos = (_a = this.rego[entityId]) !== null && _a !== void 0 ? _a : [];
|
|
8015
8580
|
entityRegos.push(rego);
|
|
@@ -8017,6 +8582,7 @@
|
|
|
8017
8582
|
this.indexMenuItemEntity(rego.menuItemId, entityId);
|
|
8018
8583
|
// Mark the visual as part of this register so selection works.
|
|
8019
8584
|
markEntity(this, rego, rego.visual, false);
|
|
8585
|
+
this.trackSourceZIndex(rego.menuItemId, rego.visual);
|
|
8020
8586
|
// Run any updates on the visual based on the calculated state.
|
|
8021
8587
|
// Eg: visibility, opacity, selection, etc.
|
|
8022
8588
|
this.queueUpdate({
|
|
@@ -8321,9 +8887,13 @@
|
|
|
8321
8887
|
this.startLazyRemoval(entityIds, removeOne, onComplete);
|
|
8322
8888
|
return;
|
|
8323
8889
|
}
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8890
|
+
WithSuspendedCCollections(this.allSceneCollections(), () => {
|
|
8891
|
+
for (const entityId of entityIds) {
|
|
8892
|
+
removeOne(entityId);
|
|
8893
|
+
}
|
|
8894
|
+
});
|
|
8895
|
+
this.releaseMenuItemCollection(menuItemId);
|
|
8896
|
+
this.RemoveTilesetsByMenuItem(menuItemId);
|
|
8327
8897
|
}
|
|
8328
8898
|
else if (entityId) {
|
|
8329
8899
|
const entityRegos = this.rego[entityId];
|
|
@@ -8506,8 +9076,75 @@
|
|
|
8506
9076
|
};
|
|
8507
9077
|
}
|
|
8508
9078
|
/**
|
|
8509
|
-
*
|
|
9079
|
+
* Registers a tileset so the register can decide when it is worth drawing.
|
|
9080
|
+
* @param params
|
|
9081
|
+
*/
|
|
9082
|
+
AddTileset(params) {
|
|
9083
|
+
const { tileset, menuItemId } = params;
|
|
9084
|
+
if (!tileset || this.disposed) {
|
|
9085
|
+
return;
|
|
9086
|
+
}
|
|
9087
|
+
const existing = this.tilesets.get(tileset);
|
|
9088
|
+
if (existing) {
|
|
9089
|
+
existing.menuItemId = menuItemId !== null && menuItemId !== void 0 ? menuItemId : existing.menuItemId;
|
|
9090
|
+
return;
|
|
9091
|
+
}
|
|
9092
|
+
this.tilesets.set(tileset, {
|
|
9093
|
+
tileset,
|
|
9094
|
+
menuItemId,
|
|
9095
|
+
// Null when the property could not be intercepted, in which case this tileset simply never gets
|
|
9096
|
+
// culled rather than us fighting its owner over the same field.
|
|
9097
|
+
gate: InstallShowGate(tileset),
|
|
9098
|
+
culled: false
|
|
9099
|
+
});
|
|
9100
|
+
}
|
|
9101
|
+
/**
|
|
9102
|
+
* Stops tracking a tileset and hands its show flag back to its owner.
|
|
9103
|
+
* @param tileset
|
|
9104
|
+
*/
|
|
9105
|
+
RemoveTileset(tileset) {
|
|
9106
|
+
var _a;
|
|
9107
|
+
const rego = this.tilesets.get(tileset);
|
|
9108
|
+
if (!rego) {
|
|
9109
|
+
return;
|
|
9110
|
+
}
|
|
9111
|
+
this.tilesets.delete(tileset);
|
|
9112
|
+
(_a = rego.gate) === null || _a === void 0 ? void 0 : _a.Release();
|
|
9113
|
+
}
|
|
9114
|
+
/**
|
|
9115
|
+
* Stops tracking every tileset belonging to a menu item.
|
|
9116
|
+
* @param menuItemId
|
|
9117
|
+
*/
|
|
9118
|
+
RemoveTilesetsByMenuItem(menuItemId) {
|
|
9119
|
+
if (!menuItemId) {
|
|
9120
|
+
return;
|
|
9121
|
+
}
|
|
9122
|
+
for (const rego of Array.from(this.tilesets.values())) {
|
|
9123
|
+
if (rego.menuItemId === menuItemId) {
|
|
9124
|
+
this.RemoveTileset(rego.tileset);
|
|
9125
|
+
}
|
|
9126
|
+
}
|
|
9127
|
+
}
|
|
9128
|
+
/**
|
|
9129
|
+
* Every tileset currently tracked.
|
|
9130
|
+
*/
|
|
9131
|
+
GetTilesets() {
|
|
9132
|
+
return Array.from(this.tilesets.values());
|
|
9133
|
+
}
|
|
9134
|
+
/**
|
|
9135
|
+
* Suppresses or restores a tileset.
|
|
9136
|
+
* Returns whether its effective visibility changed, so a caller can skip requesting a render when nothing did.
|
|
9137
|
+
* @param tileset
|
|
9138
|
+
* @param culled
|
|
8510
9139
|
*/
|
|
9140
|
+
SetTilesetCulled(tileset, culled) {
|
|
9141
|
+
const rego = this.tilesets.get(tileset);
|
|
9142
|
+
if (!(rego === null || rego === void 0 ? void 0 : rego.gate)) {
|
|
9143
|
+
return false;
|
|
9144
|
+
}
|
|
9145
|
+
rego.culled = Boolean(culled);
|
|
9146
|
+
return rego.gate.SetSuppressed(rego.culled);
|
|
9147
|
+
}
|
|
8511
9148
|
GetEntityIds() {
|
|
8512
9149
|
const ids = [];
|
|
8513
9150
|
for (const entityId in this.rego) {
|
|
@@ -9661,6 +10298,14 @@
|
|
|
9661
10298
|
// Type IDs that we'll allow to be rendered when receiving Entities.
|
|
9662
10299
|
// This might be exactly the Menu Item Type ID because of local data sources.
|
|
9663
10300
|
this.allowedTypeIDs = [];
|
|
10301
|
+
/**
|
|
10302
|
+
* Our default path.
|
|
10303
|
+
* We render each entity individually.
|
|
10304
|
+
* @param entities
|
|
10305
|
+
* @param force
|
|
10306
|
+
* @returns
|
|
10307
|
+
*/
|
|
10308
|
+
this.renderAsIndividualsChain = Promise.resolve();
|
|
9664
10309
|
const { viewer, apiGetter, monitor, item, register: visualsManager, sharedGetters, onSeriesDiscovered } = params;
|
|
9665
10310
|
this.viewer = viewer;
|
|
9666
10311
|
this.sharedGetters = sharedGetters;
|
|
@@ -9868,7 +10513,11 @@
|
|
|
9868
10513
|
const displayItems = this.zoomControl ? (_d = this.zoomControl) === null || _d === void 0 ? void 0 : _d.filter(x => x.DisplayType != BModels.ZoomControl.EDisplayType.Hidden) : [];
|
|
9869
10514
|
const shouldCheck = displayItems.length > 1;
|
|
9870
10515
|
this.entityCheckQueue = new BModels.DelayQueue(() => {
|
|
9871
|
-
this.
|
|
10516
|
+
// 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.
|
|
10517
|
+
const ids = shouldCheck
|
|
10518
|
+
? this.filterPossibleBandChanges(Object.keys(this.renderedEntities))
|
|
10519
|
+
: Object.keys(this.renderedEntities);
|
|
10520
|
+
this.doEntityCheck(ids);
|
|
9872
10521
|
}, shouldCheck ? 3000 : 30000);
|
|
9873
10522
|
const feed = (_e = this.apiGetter.getApi()) === null || _e === void 0 ? void 0 : _e.RecordChangeFeed;
|
|
9874
10523
|
if (feed) {
|
|
@@ -10111,6 +10760,30 @@
|
|
|
10111
10760
|
this.doEntityCheck(entityIds);
|
|
10112
10761
|
}
|
|
10113
10762
|
}
|
|
10763
|
+
/**
|
|
10764
|
+
* Narrows a camera-driven check to the entities whose zoom band could actually have changed.
|
|
10765
|
+
* @param ids
|
|
10766
|
+
*/
|
|
10767
|
+
filterPossibleBandChanges(ids) {
|
|
10768
|
+
return ids.filter((id) => {
|
|
10769
|
+
const rego = this.visualsManager.GetRego({
|
|
10770
|
+
entityId: id,
|
|
10771
|
+
menuItemId: this.item.id
|
|
10772
|
+
});
|
|
10773
|
+
// Anything without a live graphic to measure against has to be checked.
|
|
10774
|
+
if (!(rego === null || rego === void 0 ? void 0 : rego.visual) || rego.stale) {
|
|
10775
|
+
return true;
|
|
10776
|
+
}
|
|
10777
|
+
const bandCheck = rego.visual._bandCheck;
|
|
10778
|
+
if (!bandCheck) {
|
|
10779
|
+
return true;
|
|
10780
|
+
}
|
|
10781
|
+
return exports.RenderManager.CouldBandHaveChanged({
|
|
10782
|
+
viewer: this.viewer,
|
|
10783
|
+
bandCheck
|
|
10784
|
+
});
|
|
10785
|
+
});
|
|
10786
|
+
}
|
|
10114
10787
|
async doEntityCheck(ids) {
|
|
10115
10788
|
var _a, _b;
|
|
10116
10789
|
if (this.isRunningCheck) {
|
|
@@ -10593,14 +11266,18 @@
|
|
|
10593
11266
|
}
|
|
10594
11267
|
this.viewer.scene.requestRender();
|
|
10595
11268
|
}
|
|
10596
|
-
|
|
10597
|
-
|
|
10598
|
-
|
|
10599
|
-
|
|
10600
|
-
|
|
10601
|
-
|
|
10602
|
-
|
|
10603
|
-
|
|
11269
|
+
renderAsIndividuals(entities, force = false) {
|
|
11270
|
+
// Waiting for prior call to finish resolving.
|
|
11271
|
+
// This avoids race conditions against two sets of overlapping Entities.
|
|
11272
|
+
const next = this.renderAsIndividualsChain
|
|
11273
|
+
.then(() => this.doRenderAsIndividuals(entities, force))
|
|
11274
|
+
.catch((e) => {
|
|
11275
|
+
console.error("EntitiesRenderManager.renderAsIndividuals failed:", e);
|
|
11276
|
+
});
|
|
11277
|
+
this.renderAsIndividualsChain = next;
|
|
11278
|
+
return next;
|
|
11279
|
+
}
|
|
11280
|
+
async doRenderAsIndividuals(entities, force = false) {
|
|
10604
11281
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
10605
11282
|
// When live we just want to show the latest pos.
|
|
10606
11283
|
// When not live, the user might scroll the timeline and want to see it a fluid animation between points in time.
|
|
@@ -10778,6 +11455,19 @@
|
|
|
10778
11455
|
optimizeTolerance: (_o = item.optimizeTolerance) !== null && _o !== void 0 ? _o : ""
|
|
10779
11456
|
});
|
|
10780
11457
|
}
|
|
11458
|
+
/**
|
|
11459
|
+
* Everything about a menu item that changes how its entities are drawn, as a comparable string.
|
|
11460
|
+
* Two items with the same signature produce identical graphics, so a hand-off between them needs no
|
|
11461
|
+
* re-render (and so no re-fetch of entity data the hand-off just avoided requesting).
|
|
11462
|
+
* A false mismatch only costs the optimization, so key ordering inside an inline Style is not normalized.
|
|
11463
|
+
*/
|
|
11464
|
+
static GetRenderSignature(item) {
|
|
11465
|
+
return JSON.stringify({
|
|
11466
|
+
zoomControl: exports.RenderManager.GetZoomControlSignature(item.CameraZoomSettings),
|
|
11467
|
+
historicDrawTrack: Boolean(item.historicDrawTrack),
|
|
11468
|
+
historicInterpolation: Boolean(item.historicInterpolation)
|
|
11469
|
+
});
|
|
11470
|
+
}
|
|
10781
11471
|
PrepareHandoff() {
|
|
10782
11472
|
var _a;
|
|
10783
11473
|
if (this.disposed || this.useGeojson || this.item.enableClustering) {
|
|
@@ -10789,7 +11479,8 @@
|
|
|
10789
11479
|
internalByEntityId: new Map(this.internalByEntityId),
|
|
10790
11480
|
allowedTypeIDs: [...this.allowedTypeIDs],
|
|
10791
11481
|
renderQueue: [...this.renderQueue],
|
|
10792
|
-
sourceMenuItemId: this.item.id
|
|
11482
|
+
sourceMenuItemId: this.item.id,
|
|
11483
|
+
renderSignature: Manager.GetRenderSignature(this.item)
|
|
10793
11484
|
};
|
|
10794
11485
|
this.unsetGetter();
|
|
10795
11486
|
(_a = this.viewMonitorRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
@@ -10829,7 +11520,12 @@
|
|
|
10829
11520
|
if ((_a = payload.renderQueue) === null || _a === void 0 ? void 0 : _a.length) {
|
|
10830
11521
|
this.distributeForRender(payload.renderQueue);
|
|
10831
11522
|
}
|
|
10832
|
-
this
|
|
11523
|
+
// Adopted graphics are already drawn the way this item wants them, so re-rendering would only
|
|
11524
|
+
// re-request every entity from the API, which is the cost the hand-off exists to avoid.
|
|
11525
|
+
const needsRestyle = payload.renderSignature !== Manager.GetRenderSignature(this.item);
|
|
11526
|
+
if (needsRestyle) {
|
|
11527
|
+
this.ReRender({ entityIds: Object.keys(this.renderedEntities), force: true });
|
|
11528
|
+
}
|
|
10833
11529
|
this.viewer.scene.requestRender();
|
|
10834
11530
|
}
|
|
10835
11531
|
}
|
|
@@ -10954,6 +11650,14 @@
|
|
|
10954
11650
|
// Many things are not supported when this is enabled.
|
|
10955
11651
|
this.useGeojson = false;
|
|
10956
11652
|
this.reRenderState = new EntityReRenderMaintainState();
|
|
11653
|
+
/**
|
|
11654
|
+
* Our default path.
|
|
11655
|
+
* We render each entity individually.
|
|
11656
|
+
* @param entities
|
|
11657
|
+
* @param force
|
|
11658
|
+
* @returns
|
|
11659
|
+
*/
|
|
11660
|
+
this.renderAsIndividualsChain = Promise.resolve();
|
|
10957
11661
|
const { viewer, apiGetter, monitor, item, register: visualsManager } = params;
|
|
10958
11662
|
this.viewer = viewer;
|
|
10959
11663
|
this.apiGetter = apiGetter;
|
|
@@ -11263,7 +11967,7 @@
|
|
|
11263
11967
|
* @param force TODO: This should re-render entities that are already rendered.
|
|
11264
11968
|
*/
|
|
11265
11969
|
async renderAsGeojson(entities, force) {
|
|
11266
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
11970
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
11267
11971
|
entities = entities.filter((entity) => {
|
|
11268
11972
|
var _a;
|
|
11269
11973
|
return !this.renderedEntities[(_a = entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID];
|
|
@@ -11314,38 +12018,42 @@
|
|
|
11314
12018
|
if (!entities.length) {
|
|
11315
12019
|
return;
|
|
11316
12020
|
}
|
|
12021
|
+
// A menu item can declare that nothing about its render may touch the API. Styling then has to come from
|
|
12022
|
+
// the zoom item's inline Style, and names from what the entities already carry.
|
|
12023
|
+
const offline = Boolean((_a = this.item) === null || _a === void 0 ? void 0 : _a.offline);
|
|
11317
12024
|
let style = null;
|
|
11318
|
-
if ((zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.StyleID) && zoomItem.StyleID != -1) {
|
|
12025
|
+
if (!offline && (zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.StyleID) && zoomItem.StyleID != -1) {
|
|
11319
12026
|
try {
|
|
11320
|
-
style = (
|
|
12027
|
+
style = (_b = (await BModels.Style.Get({
|
|
11321
12028
|
api: this.apiGetter.getApi(),
|
|
11322
12029
|
styleId: zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.StyleID
|
|
11323
|
-
})).style) === null ||
|
|
12030
|
+
})).style) === null || _b === void 0 ? void 0 : _b.Settings;
|
|
11324
12031
|
}
|
|
11325
12032
|
// Probably deleted.
|
|
11326
12033
|
catch (e) {
|
|
11327
12034
|
console.error(e);
|
|
11328
12035
|
}
|
|
11329
12036
|
}
|
|
11330
|
-
let entityTypeId = (
|
|
12037
|
+
let entityTypeId = (_c = this.item.BruceEntity) === null || _c === void 0 ? void 0 : _c["EntityType.ID"];
|
|
11331
12038
|
if (!entityTypeId) {
|
|
11332
|
-
entityTypeId = (
|
|
12039
|
+
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"];
|
|
11333
12040
|
}
|
|
11334
|
-
//
|
|
12041
|
+
// Normally fetched regardless, since name calculation needs it. Offline callers take the names the
|
|
12042
|
+
// entities already carry instead.
|
|
11335
12043
|
let entityType;
|
|
11336
|
-
if (entityTypeId) {
|
|
12044
|
+
if (entityTypeId && !offline) {
|
|
11337
12045
|
// Try using the Entity Type default if one is specified in the menu item.
|
|
11338
12046
|
try {
|
|
11339
|
-
entityType = (
|
|
12047
|
+
entityType = (_f = (await BModels.EntityType.Get({
|
|
11340
12048
|
entityTypeId: entityTypeId,
|
|
11341
12049
|
api: this.apiGetter.getApi()
|
|
11342
|
-
}))) === null ||
|
|
12050
|
+
}))) === null || _f === void 0 ? void 0 : _f.entityType;
|
|
11343
12051
|
if (!style && entityType) {
|
|
11344
12052
|
if (entityType["DisplaySetting.ID"] && entityType["DisplaySetting.ID"] > 0) {
|
|
11345
|
-
style = (
|
|
12053
|
+
style = (_g = (await BModels.Style.Get({
|
|
11346
12054
|
api: this.apiGetter.getApi(),
|
|
11347
12055
|
styleId: entityType["DisplaySetting.ID"]
|
|
11348
|
-
})).style) === null ||
|
|
12056
|
+
})).style) === null || _g === void 0 ? void 0 : _g.Settings;
|
|
11349
12057
|
}
|
|
11350
12058
|
}
|
|
11351
12059
|
}
|
|
@@ -11353,9 +12061,13 @@
|
|
|
11353
12061
|
console.error(e);
|
|
11354
12062
|
}
|
|
11355
12063
|
}
|
|
11356
|
-
|
|
11357
|
-
|
|
11358
|
-
|
|
12064
|
+
// Fall back to whatever the zoom item carried inline, which is the only source offline.
|
|
12065
|
+
if (!style) {
|
|
12066
|
+
style = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.Style;
|
|
12067
|
+
}
|
|
12068
|
+
const pStyle = (_h = style === null || style === void 0 ? void 0 : style.polygonStyle) !== null && _h !== void 0 ? _h : {};
|
|
12069
|
+
const lStyle = (_j = style === null || style === void 0 ? void 0 : style.polylineStyle) !== null && _j !== void 0 ? _j : {};
|
|
12070
|
+
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;
|
|
11359
12071
|
const bFillColor = BModels.Calculator.GetColor(pStyle.fillColor, {}, []);
|
|
11360
12072
|
const cFillColor = bFillColor ? colorToCColor$2(bFillColor) : Cesium.Color.fromCssColorString("rgba(139, 195, 74, 0.8)");
|
|
11361
12073
|
const bLineColor = BModels.Calculator.GetColor(pStyle.lineColor, {}, []);
|
|
@@ -11577,14 +12289,19 @@
|
|
|
11577
12289
|
}
|
|
11578
12290
|
this.viewer.scene.requestRender();
|
|
11579
12291
|
}
|
|
11580
|
-
|
|
11581
|
-
|
|
11582
|
-
|
|
11583
|
-
|
|
11584
|
-
|
|
11585
|
-
|
|
11586
|
-
|
|
11587
|
-
|
|
12292
|
+
renderAsIndividuals(entities, force = false) {
|
|
12293
|
+
// Waiting for prior call to finish resolving.
|
|
12294
|
+
// This avoids race conditions against two sets of overlapping Entities.
|
|
12295
|
+
const next = this.renderAsIndividualsChain
|
|
12296
|
+
.then(() => this.doRenderAsIndividuals(entities, force))
|
|
12297
|
+
.catch((e) => {
|
|
12298
|
+
console.error("EntitiesLoadedRenderManager.renderAsIndividuals failed:", e);
|
|
12299
|
+
});
|
|
12300
|
+
this.renderAsIndividualsChain = next;
|
|
12301
|
+
return next;
|
|
12302
|
+
}
|
|
12303
|
+
async doRenderAsIndividuals(entities, force = false) {
|
|
12304
|
+
var _a;
|
|
11588
12305
|
const { updated, entities: cEntities } = await exports.EntityRenderEngine.Render({
|
|
11589
12306
|
viewer: this.viewer,
|
|
11590
12307
|
apiGetter: this.apiGetter,
|
|
@@ -11592,6 +12309,8 @@
|
|
|
11592
12309
|
menuItemId: this.item.id,
|
|
11593
12310
|
visualRegister: this.visualsManager,
|
|
11594
12311
|
zoomControl: this.item.CameraZoomSettings,
|
|
12312
|
+
// Carries the promise through to the engines, which do the rest of the API avoidance.
|
|
12313
|
+
offline: Boolean((_a = this.item) === null || _a === void 0 ? void 0 : _a.offline),
|
|
11595
12314
|
force
|
|
11596
12315
|
});
|
|
11597
12316
|
if (this.disposed) {
|
|
@@ -12220,6 +12939,7 @@
|
|
|
12220
12939
|
this.getterSub = null;
|
|
12221
12940
|
this.disposed = false;
|
|
12222
12941
|
this.reRenderState = new EntityReRenderMaintainState();
|
|
12942
|
+
this.renderEntityChain = Promise.resolve();
|
|
12223
12943
|
const { viewer, apiGetter, monitor, item, register: visualsManager } = params;
|
|
12224
12944
|
this.viewer = viewer;
|
|
12225
12945
|
this.apiGetter = apiGetter;
|
|
@@ -12342,7 +13062,18 @@
|
|
|
12342
13062
|
this.onGetterUpdate(entityId, true);
|
|
12343
13063
|
}
|
|
12344
13064
|
}
|
|
12345
|
-
|
|
13065
|
+
renderEntity(entity, force = false) {
|
|
13066
|
+
// Waiting for prior call to finish resolving.
|
|
13067
|
+
// This avoids race conditions against two sets of overlapping Entities.
|
|
13068
|
+
const next = this.renderEntityChain
|
|
13069
|
+
.then(() => this.doRenderEntity(entity, force))
|
|
13070
|
+
.catch((e) => {
|
|
13071
|
+
console.error("EntityRenderManager.renderEntity failed:", e);
|
|
13072
|
+
});
|
|
13073
|
+
this.renderEntityChain = next;
|
|
13074
|
+
return next;
|
|
13075
|
+
}
|
|
13076
|
+
async doRenderEntity(entity, force = false) {
|
|
12346
13077
|
try {
|
|
12347
13078
|
if (this.disposed || this.viewer.isDestroyed()) {
|
|
12348
13079
|
return;
|
|
@@ -13800,6 +14531,7 @@
|
|
|
13800
14531
|
}
|
|
13801
14532
|
TilesetRenderEngine.ApplySettings = ApplySettings;
|
|
13802
14533
|
async function Render(params) {
|
|
14534
|
+
var _a, _b, _c;
|
|
13803
14535
|
const api = params.apiGetter.getApi(params.accountId);
|
|
13804
14536
|
// Ensure regional url is loaded.
|
|
13805
14537
|
await api.Loading;
|
|
@@ -13863,6 +14595,10 @@
|
|
|
13863
14595
|
console.error(e);
|
|
13864
14596
|
}
|
|
13865
14597
|
});
|
|
14598
|
+
(_a = params.register) === null || _a === void 0 ? void 0 : _a.AddTileset({
|
|
14599
|
+
tileset: cTileset,
|
|
14600
|
+
menuItemId: params.menuItemId
|
|
14601
|
+
});
|
|
13866
14602
|
return cTileset;
|
|
13867
14603
|
}
|
|
13868
14604
|
else if (params.tileset.type === BModels.Tileset.EType.EntitiesSet) {
|
|
@@ -13879,6 +14615,10 @@
|
|
|
13879
14615
|
const cTileset = await createTileset(loadUrl, null, params.noMemoryLimit);
|
|
13880
14616
|
params.viewer.scene.primitives.add(cTileset);
|
|
13881
14617
|
watchTilesetDateRange(params.viewer, cTileset, params.tileset);
|
|
14618
|
+
(_b = params.register) === null || _b === void 0 ? void 0 : _b.AddTileset({
|
|
14619
|
+
tileset: cTileset,
|
|
14620
|
+
menuItemId: params.menuItemId
|
|
14621
|
+
});
|
|
13882
14622
|
return cTileset;
|
|
13883
14623
|
}
|
|
13884
14624
|
else if (params.tileset.type == BModels.Tileset.EType.PointCloud) {
|
|
@@ -13924,6 +14664,10 @@
|
|
|
13924
14664
|
console.error(e);
|
|
13925
14665
|
}
|
|
13926
14666
|
});
|
|
14667
|
+
(_c = params.register) === null || _c === void 0 ? void 0 : _c.AddTileset({
|
|
14668
|
+
tileset: cTileset,
|
|
14669
|
+
menuItemId: params.menuItemId
|
|
14670
|
+
});
|
|
13927
14671
|
return cTileset;
|
|
13928
14672
|
}
|
|
13929
14673
|
else {
|
|
@@ -13932,6 +14676,7 @@
|
|
|
13932
14676
|
}
|
|
13933
14677
|
TilesetRenderEngine.Render = Render;
|
|
13934
14678
|
async function RenderLegacy(params) {
|
|
14679
|
+
var _a;
|
|
13935
14680
|
let { apiGetter, viewer, tileset, ionId, loadUrl, viaCdn, accountId, noMemoryLimit, backFaceCulling } = params;
|
|
13936
14681
|
let settings = tileset === null || tileset === void 0 ? void 0 : tileset.Settings;
|
|
13937
14682
|
settings = {
|
|
@@ -14054,6 +14799,10 @@
|
|
|
14054
14799
|
console.error(e);
|
|
14055
14800
|
}
|
|
14056
14801
|
});
|
|
14802
|
+
(_a = params.register) === null || _a === void 0 ? void 0 : _a.AddTileset({
|
|
14803
|
+
tileset: cTileset,
|
|
14804
|
+
menuItemId: params.menuItemId
|
|
14805
|
+
});
|
|
14057
14806
|
return cTileset;
|
|
14058
14807
|
}
|
|
14059
14808
|
TilesetRenderEngine.RenderLegacy = RenderLegacy;
|
|
@@ -14563,6 +15312,8 @@
|
|
|
14563
15312
|
}
|
|
14564
15313
|
// Render outside the shared process because we can't control file requests from Cesium.
|
|
14565
15314
|
const cTileset = this.cTileset = await exports.TilesetRenderEngine.Render({
|
|
15315
|
+
register: this.visualsManager,
|
|
15316
|
+
menuItemId: this.item.id,
|
|
14566
15317
|
loadUrl: loadUrl,
|
|
14567
15318
|
apiGetter: this.getters.GetBruceGetter(),
|
|
14568
15319
|
tileset: tileset,
|
|
@@ -16778,6 +17529,7 @@
|
|
|
16778
17529
|
this.reRenderState = new EntityReRenderMaintainState();
|
|
16779
17530
|
this.zoomControl = [];
|
|
16780
17531
|
this.queryLoadId = 0;
|
|
17532
|
+
this.renderDataLabEntitiesChain = Promise.resolve();
|
|
16781
17533
|
const { viewer, item, apiGetter, monitor, visualsRegister } = params;
|
|
16782
17534
|
this.viewer = viewer;
|
|
16783
17535
|
this.item = item;
|
|
@@ -16893,7 +17645,12 @@
|
|
|
16893
17645
|
const displayItems = this.zoomControl ? this.zoomControl.filter(x => x.DisplayType != BModels.ZoomControl.EDisplayType.Hidden) : [];
|
|
16894
17646
|
const shouldCheck = displayItems.length > 1;
|
|
16895
17647
|
this.entityCheckQueue = new BModels.DelayQueue(() => {
|
|
16896
|
-
this
|
|
17648
|
+
// With a single band this pass is not looking for band changes at all, so it always runs over
|
|
17649
|
+
// everything. With more than one, most entities can be ruled out without asking the server.
|
|
17650
|
+
const ids = shouldCheck
|
|
17651
|
+
? this.filterPossibleBandChanges(Object.keys(this.renderedEntities))
|
|
17652
|
+
: Object.keys(this.renderedEntities);
|
|
17653
|
+
this.doEntityCheck(ids);
|
|
16897
17654
|
}, shouldCheck ? 3000 : 30000);
|
|
16898
17655
|
(_b = this.viewMonitorRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
16899
17656
|
this.viewMonitorRemoval = this.monitor.Updated().Subscribe(() => {
|
|
@@ -16901,6 +17658,30 @@
|
|
|
16901
17658
|
(_a = this.entityCheckQueue) === null || _a === void 0 ? void 0 : _a.Call();
|
|
16902
17659
|
});
|
|
16903
17660
|
}
|
|
17661
|
+
/**
|
|
17662
|
+
* Narrows a camera-driven check to the entities whose zoom band could actually have changed, so a pan or
|
|
17663
|
+
* zoom stops re-requesting the whole rendered set. See RenderManager.CouldBandHaveChanged.
|
|
17664
|
+
* @param ids
|
|
17665
|
+
*/
|
|
17666
|
+
filterPossibleBandChanges(ids) {
|
|
17667
|
+
return ids.filter((id) => {
|
|
17668
|
+
const rego = this.visualsManager.GetRego({
|
|
17669
|
+
entityId: id,
|
|
17670
|
+
menuItemId: this.item.id
|
|
17671
|
+
});
|
|
17672
|
+
if (!(rego === null || rego === void 0 ? void 0 : rego.visual) || rego.stale) {
|
|
17673
|
+
return true;
|
|
17674
|
+
}
|
|
17675
|
+
const bandCheck = rego.visual._bandCheck;
|
|
17676
|
+
if (!bandCheck) {
|
|
17677
|
+
return true;
|
|
17678
|
+
}
|
|
17679
|
+
return exports.RenderManager.CouldBandHaveChanged({
|
|
17680
|
+
viewer: this.viewer,
|
|
17681
|
+
bandCheck
|
|
17682
|
+
});
|
|
17683
|
+
});
|
|
17684
|
+
}
|
|
16904
17685
|
preventCurrentCheckApiRefresh(entityIds) {
|
|
16905
17686
|
var _a;
|
|
16906
17687
|
this.reRenderState.markSkipForCurrentRun(entityIds, this.isRunningCheck);
|
|
@@ -17116,7 +17897,18 @@
|
|
|
17116
17897
|
}
|
|
17117
17898
|
return Array.from(entityMap.values());
|
|
17118
17899
|
}
|
|
17119
|
-
|
|
17900
|
+
renderDataLabEntities(entities, force = false) {
|
|
17901
|
+
// Waiting for prior call to finish resolving.
|
|
17902
|
+
// This avoids race conditions against two sets of overlapping Entities.
|
|
17903
|
+
const next = this.renderDataLabEntitiesChain
|
|
17904
|
+
.then(() => this.doRenderDataLabEntities(entities, force))
|
|
17905
|
+
.catch((e) => {
|
|
17906
|
+
console.error("EntitiesDatalabRenderManager.renderDataLabEntities failed:", e);
|
|
17907
|
+
});
|
|
17908
|
+
this.renderDataLabEntitiesChain = next;
|
|
17909
|
+
return next;
|
|
17910
|
+
}
|
|
17911
|
+
async doRenderDataLabEntities(entities, force = false) {
|
|
17120
17912
|
var _a, _b, _c;
|
|
17121
17913
|
if (this.disposed || this.viewer.isDestroyed() || !(entities === null || entities === void 0 ? void 0 : entities.length)) {
|
|
17122
17914
|
return;
|
|
@@ -17216,6 +18008,15 @@
|
|
|
17216
18008
|
}
|
|
17217
18009
|
return `datalab:${queryId}`;
|
|
17218
18010
|
}
|
|
18011
|
+
/**
|
|
18012
|
+
* Everything about this menu item that changes how its entities are drawn, as a comparable string.
|
|
18013
|
+
* The hand-off key is only the query id, so this is what catches a styling difference between two items sharing that query.
|
|
18014
|
+
*/
|
|
18015
|
+
static GetRenderSignature(item) {
|
|
18016
|
+
return JSON.stringify({
|
|
18017
|
+
zoomControl: exports.RenderManager.GetZoomControlSignature(item.CameraZoomSettings)
|
|
18018
|
+
});
|
|
18019
|
+
}
|
|
17219
18020
|
PrepareHandoff() {
|
|
17220
18021
|
var _a, _b, _c;
|
|
17221
18022
|
if (this.disposed || !this.getter) {
|
|
@@ -17236,7 +18037,8 @@
|
|
|
17236
18037
|
getter,
|
|
17237
18038
|
renderedEntities: this.renderedEntities,
|
|
17238
18039
|
renderQueue: [...this.renderQueue],
|
|
17239
|
-
sourceMenuItemId: this.item.id
|
|
18040
|
+
sourceMenuItemId: this.item.id,
|
|
18041
|
+
renderSignature: Manager.GetRenderSignature(this.item)
|
|
17240
18042
|
};
|
|
17241
18043
|
this.renderQueue = [];
|
|
17242
18044
|
this.queryLoadId += 1;
|
|
@@ -17259,7 +18061,10 @@
|
|
|
17259
18061
|
if ((_a = payload.renderQueue) === null || _a === void 0 ? void 0 : _a.length) {
|
|
17260
18062
|
this.distributeForRender(payload.renderQueue);
|
|
17261
18063
|
}
|
|
17262
|
-
|
|
18064
|
+
const needsRestyle = payload.renderSignature !== Manager.GetRenderSignature(this.item);
|
|
18065
|
+
if (needsRestyle) {
|
|
18066
|
+
this.ReRender({ entityIds: Object.keys(this.renderedEntities), force: true });
|
|
18067
|
+
}
|
|
17263
18068
|
this.viewer.scene.requestRender();
|
|
17264
18069
|
}
|
|
17265
18070
|
}
|
|
@@ -18240,6 +19045,8 @@
|
|
|
18240
19045
|
}
|
|
18241
19046
|
}
|
|
18242
19047
|
const cTileset = this.cTileset = await exports.TilesetRenderEngine.Render({
|
|
19048
|
+
register: this.visualsManager,
|
|
19049
|
+
menuItemId: this.item.id,
|
|
18243
19050
|
apiGetter: this.getters.GetBruceGetter(),
|
|
18244
19051
|
tileset: tileset,
|
|
18245
19052
|
viewer: this.viewer,
|
|
@@ -18730,11 +19537,12 @@
|
|
|
18730
19537
|
constructor(params) {
|
|
18731
19538
|
this.disposed = false;
|
|
18732
19539
|
this.cTileset = null;
|
|
18733
|
-
const { viewer, getters: apiGetter, item, initQueue } = params;
|
|
19540
|
+
const { viewer, getters: apiGetter, item, initQueue, register } = params;
|
|
18734
19541
|
this.viewer = viewer;
|
|
18735
19542
|
this.getters = apiGetter;
|
|
18736
19543
|
this.item = item;
|
|
18737
19544
|
this.initQueue = initQueue;
|
|
19545
|
+
this.visualsManager = register;
|
|
18738
19546
|
}
|
|
18739
19547
|
Init() {
|
|
18740
19548
|
var _a;
|
|
@@ -18785,6 +19593,8 @@
|
|
|
18785
19593
|
return;
|
|
18786
19594
|
}
|
|
18787
19595
|
this.cTileset = await exports.TilesetRenderEngine.Render({
|
|
19596
|
+
register: this.visualsManager,
|
|
19597
|
+
menuItemId: this.item.id,
|
|
18788
19598
|
apiGetter: this.getters.GetBruceGetter(),
|
|
18789
19599
|
tileset: tileset,
|
|
18790
19600
|
viewer: this.viewer,
|
|
@@ -19371,6 +20181,8 @@
|
|
|
19371
20181
|
if (!accountId) {
|
|
19372
20182
|
accountId = this.getters.GetAccountId();
|
|
19373
20183
|
}
|
|
20184
|
+
// Deliberately NOT registered with the visuals register, so it is never whole-tileset culled.
|
|
20185
|
+
// An arbitrary tileset can be produced outside our system and its declared bounds cannot be trusted.
|
|
19374
20186
|
this.cTileset = await exports.TilesetRenderEngine.RenderLegacy({
|
|
19375
20187
|
apiGetter: this.getters.GetBruceGetter(),
|
|
19376
20188
|
tileset: legacyTileset,
|
|
@@ -20038,8 +20850,8 @@
|
|
|
20038
20850
|
* @param cEntity
|
|
20039
20851
|
*/
|
|
20040
20852
|
const killCEntity = (cEntity) => {
|
|
20041
|
-
if (cEntity && !this.viewer.isDestroyed()
|
|
20042
|
-
this.viewer
|
|
20853
|
+
if (cEntity && !this.viewer.isDestroyed()) {
|
|
20854
|
+
RemoveCEntityFromScene(this.viewer, cEntity);
|
|
20043
20855
|
}
|
|
20044
20856
|
if (cEntity === null || cEntity === void 0 ? void 0 : cEntity._dispose) {
|
|
20045
20857
|
cEntity._dispose();
|
|
@@ -20517,8 +21329,8 @@
|
|
|
20517
21329
|
* @param cEntity
|
|
20518
21330
|
*/
|
|
20519
21331
|
const killCEntity = (cEntity) => {
|
|
20520
|
-
if (cEntity && !this.viewer.isDestroyed()
|
|
20521
|
-
this.viewer
|
|
21332
|
+
if (cEntity && !this.viewer.isDestroyed()) {
|
|
21333
|
+
RemoveCEntityFromScene(this.viewer, cEntity);
|
|
20522
21334
|
}
|
|
20523
21335
|
if (cEntity === null || cEntity === void 0 ? void 0 : cEntity._dispose) {
|
|
20524
21336
|
cEntity._dispose();
|
|
@@ -22537,6 +23349,7 @@
|
|
|
22537
23349
|
rItem.renderManager = new exports.TilesetPointcloudRenderManager.Manager({
|
|
22538
23350
|
viewer: this.viewer,
|
|
22539
23351
|
getters: this.getters,
|
|
23352
|
+
register: this.visualsRegister,
|
|
22540
23353
|
item: params.item,
|
|
22541
23354
|
initQueue: this.tilesetInitQueue
|
|
22542
23355
|
});
|
|
@@ -22691,6 +23504,8 @@
|
|
|
22691
23504
|
}
|
|
22692
23505
|
if (allowHandoff && this.isHandoffCapable(item.renderManager)) {
|
|
22693
23506
|
this.pendingHandoffPool.push(item);
|
|
23507
|
+
// Series segments stay recorded under the pooled id for now. A claimed hand-off
|
|
23508
|
+
// transfers them to the claiming item, and a flushed one clears them.
|
|
22694
23509
|
}
|
|
22695
23510
|
else {
|
|
22696
23511
|
try {
|
|
@@ -22699,9 +23514,9 @@
|
|
|
22699
23514
|
catch (e) {
|
|
22700
23515
|
console.error(e);
|
|
22701
23516
|
}
|
|
23517
|
+
this.ClearSeriesSegments(item.id);
|
|
22702
23518
|
}
|
|
22703
23519
|
this.items = this.items.filter(x => x.id !== id);
|
|
22704
|
-
this.ClearSeriesSegments(item.id);
|
|
22705
23520
|
(_b = this.onUpdate) === null || _b === void 0 ? void 0 : _b.Trigger({ isEnabling: false, itemId: item.id });
|
|
22706
23521
|
}
|
|
22707
23522
|
}
|
|
@@ -22749,14 +23564,38 @@
|
|
|
22749
23564
|
if (poolIndex < 0) {
|
|
22750
23565
|
return null;
|
|
22751
23566
|
}
|
|
22752
|
-
const
|
|
23567
|
+
const pooledItem = this.pendingHandoffPool[poolIndex];
|
|
23568
|
+
const pooled = pooledItem.renderManager;
|
|
22753
23569
|
const payload = pooled.PrepareHandoff();
|
|
22754
23570
|
if (!payload) {
|
|
22755
23571
|
return null;
|
|
22756
23572
|
}
|
|
22757
23573
|
this.pendingHandoffPool.splice(poolIndex, 1);
|
|
23574
|
+
this.transferSeriesSegments(pooledItem.id, item.id);
|
|
22758
23575
|
return payload;
|
|
22759
23576
|
}
|
|
23577
|
+
/**
|
|
23578
|
+
* Moves any series segments recorded for one menu item over to another, for a claimed hand-off.
|
|
23579
|
+
* The adopting manager may legitimately skip re-rendering (nothing to restyle), and segments are only
|
|
23580
|
+
* ever reported from inside a render, so without this the claiming item would end up with none.
|
|
23581
|
+
*/
|
|
23582
|
+
transferSeriesSegments(fromItemId, toItemId) {
|
|
23583
|
+
const segments = this.seriesSegments.get(fromItemId);
|
|
23584
|
+
if (!(segments === null || segments === void 0 ? void 0 : segments.length)) {
|
|
23585
|
+
this.ClearSeriesSegments(fromItemId);
|
|
23586
|
+
return;
|
|
23587
|
+
}
|
|
23588
|
+
this.seriesSegments.delete(fromItemId);
|
|
23589
|
+
this.OnSeriesUpdated.Trigger({ itemId: fromItemId, segments: [] });
|
|
23590
|
+
const existing = this.seriesSegments.get(toItemId) || [];
|
|
23591
|
+
for (const segment of segments) {
|
|
23592
|
+
if (!existing.some((s) => s.key === segment.key)) {
|
|
23593
|
+
existing.push(segment);
|
|
23594
|
+
}
|
|
23595
|
+
}
|
|
23596
|
+
this.seriesSegments.set(toItemId, existing);
|
|
23597
|
+
this.OnSeriesUpdated.Trigger({ itemId: toItemId, segments: existing });
|
|
23598
|
+
}
|
|
22760
23599
|
// Disposes everything left unclaimed in the pending-hand-off pool.
|
|
22761
23600
|
FlushPendingHandoffs() {
|
|
22762
23601
|
var _a;
|
|
@@ -22772,6 +23611,7 @@
|
|
|
22772
23611
|
catch (e) {
|
|
22773
23612
|
console.error(e);
|
|
22774
23613
|
}
|
|
23614
|
+
this.ClearSeriesSegments(item.id);
|
|
22775
23615
|
}
|
|
22776
23616
|
}
|
|
22777
23617
|
GetEnabledItemIds() {
|
|
@@ -34128,6 +34968,10 @@
|
|
|
34128
34968
|
}
|
|
34129
34969
|
return minDistance;
|
|
34130
34970
|
}
|
|
34971
|
+
// Slack added when proving a zoom band cannot have changed.
|
|
34972
|
+
// See CouldBandHaveChanged: an entity's measured distance can jump by its altitude spread as the camera crosses over its footprint,
|
|
34973
|
+
// so being this close to a band edge means re-checking rather than trusting the bound.
|
|
34974
|
+
const BAND_EDGE_MARGIN_METERS = 500;
|
|
34131
34975
|
// Cache for distance calculations.
|
|
34132
34976
|
// It will keep only the most recent 3000 entries.
|
|
34133
34977
|
const distanceCache = new BModels.LRUCache(3000);
|
|
@@ -34270,7 +35114,7 @@
|
|
|
34270
35114
|
}
|
|
34271
35115
|
(function (RenderManager) {
|
|
34272
35116
|
function DetermineZoomItem(params) {
|
|
34273
|
-
const { viewer, entity, zoomControl } = params;
|
|
35117
|
+
const { viewer, entity, zoomControl, out } = params;
|
|
34274
35118
|
const pos = exports.EntityUtils.GetPos({
|
|
34275
35119
|
viewer,
|
|
34276
35120
|
entity
|
|
@@ -34283,11 +35127,16 @@
|
|
|
34283
35127
|
if (!cameraPos || !cameraPos.latitude) {
|
|
34284
35128
|
return null;
|
|
34285
35129
|
}
|
|
34286
|
-
const
|
|
35130
|
+
const cameraCarto = {
|
|
34287
35131
|
altitude: cameraPos.height,
|
|
34288
35132
|
latitude: Cesium.Math.toDegrees(cameraPos.latitude),
|
|
34289
35133
|
longitude: Cesium.Math.toDegrees(cameraPos.longitude)
|
|
34290
|
-
}
|
|
35134
|
+
};
|
|
35135
|
+
const distance = calculateDistance(cameraCarto, entity);
|
|
35136
|
+
if (out) {
|
|
35137
|
+
out.distance = distance;
|
|
35138
|
+
out.cameraPos = Cesium.Cartesian3.fromDegrees(cameraCarto.longitude, cameraCarto.latitude, cameraCarto.altitude);
|
|
35139
|
+
}
|
|
34291
35140
|
let zoomItem = (!distance && distance != 0) ? null : GetZoomControlFromDistance({
|
|
34292
35141
|
zoomControl,
|
|
34293
35142
|
distance
|
|
@@ -34300,6 +35149,41 @@
|
|
|
34300
35149
|
return zoomItem;
|
|
34301
35150
|
}
|
|
34302
35151
|
RenderManager.DetermineZoomItem = DetermineZoomItem;
|
|
35152
|
+
/**
|
|
35153
|
+
* Returns whether an entity could have moved into a different zoom band since its graphic was rendered,
|
|
35154
|
+
* given where the camera is now.
|
|
35155
|
+
*
|
|
35156
|
+
* Answers true whenever it cannot prove otherwise, so a caller may safely skip only on a false.
|
|
35157
|
+
*/
|
|
35158
|
+
function CouldBandHaveChanged(params) {
|
|
35159
|
+
var _a;
|
|
35160
|
+
const { viewer, bandCheck } = params;
|
|
35161
|
+
if (!bandCheck || bandCheck.distance == null || !bandCheck.cameraPos) {
|
|
35162
|
+
return true;
|
|
35163
|
+
}
|
|
35164
|
+
// An absent range is not something to reason about. Values that ARE present go through EnsureNumber so
|
|
35165
|
+
// this agrees with how GetZoomControlFromDistance matched the band in the first place.
|
|
35166
|
+
if (bandCheck.min == null || bandCheck.max == null) {
|
|
35167
|
+
return true;
|
|
35168
|
+
}
|
|
35169
|
+
const min = EnsureNumber(bandCheck.min);
|
|
35170
|
+
const max = EnsureNumber(bandCheck.max);
|
|
35171
|
+
if (!(max > min)) {
|
|
35172
|
+
return true;
|
|
35173
|
+
}
|
|
35174
|
+
const cameraPos = (_a = viewer.camera) === null || _a === void 0 ? void 0 : _a.positionCartographic;
|
|
35175
|
+
if (!cameraPos || !cameraPos.latitude) {
|
|
35176
|
+
return true;
|
|
35177
|
+
}
|
|
35178
|
+
const nowPos = Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(cameraPos.longitude), Cesium.Math.toDegrees(cameraPos.latitude), cameraPos.height);
|
|
35179
|
+
const travelled = Cesium.Cartesian3.distance(nowPos, bandCheck.cameraPos);
|
|
35180
|
+
if (isNaN(travelled)) {
|
|
35181
|
+
return true;
|
|
35182
|
+
}
|
|
35183
|
+
const slack = travelled + BAND_EDGE_MARGIN_METERS;
|
|
35184
|
+
return (bandCheck.distance - slack) < min || (bandCheck.distance + slack) > max;
|
|
35185
|
+
}
|
|
35186
|
+
RenderManager.CouldBandHaveChanged = CouldBandHaveChanged;
|
|
34303
35187
|
function GetZoomControlFromDistance(params) {
|
|
34304
35188
|
const { zoomControl, distance } = params;
|
|
34305
35189
|
for (let i = 0; i < zoomControl.length; i++) {
|
|
@@ -34311,6 +35195,26 @@
|
|
|
34311
35195
|
return null;
|
|
34312
35196
|
}
|
|
34313
35197
|
RenderManager.GetZoomControlFromDistance = GetZoomControlFromDistance;
|
|
35198
|
+
/**
|
|
35199
|
+
* Everything in a zoom control that changes how an entity is drawn, as a comparable string.
|
|
35200
|
+
* Used to tell whether two menu items would produce identical graphics (see a manager's GetRenderSignature).
|
|
35201
|
+
* A false mismatch only costs an optimization, so key ordering inside an inline Style is not normalized.
|
|
35202
|
+
*/
|
|
35203
|
+
function GetZoomControlSignature(zoomControl) {
|
|
35204
|
+
return JSON.stringify([].concat(zoomControl !== null && zoomControl !== void 0 ? zoomControl : []).map((zoomItem) => {
|
|
35205
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
35206
|
+
return ({
|
|
35207
|
+
MinZoom: (_a = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.MinZoom) !== null && _a !== void 0 ? _a : null,
|
|
35208
|
+
MaxZoom: (_b = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.MaxZoom) !== null && _b !== void 0 ? _b : null,
|
|
35209
|
+
DisplayType: (_c = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.DisplayType) !== null && _c !== void 0 ? _c : null,
|
|
35210
|
+
StyleID: (_d = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.StyleID) !== null && _d !== void 0 ? _d : null,
|
|
35211
|
+
Style: (_e = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.Style) !== null && _e !== void 0 ? _e : null,
|
|
35212
|
+
LODCategoryID: (_f = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.LODCategoryID) !== null && _f !== void 0 ? _f : null,
|
|
35213
|
+
LODLevel: (_g = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.LODLevel) !== null && _g !== void 0 ? _g : null
|
|
35214
|
+
});
|
|
35215
|
+
}));
|
|
35216
|
+
}
|
|
35217
|
+
RenderManager.GetZoomControlSignature = GetZoomControlSignature;
|
|
34314
35218
|
function GetZoomMinMax(params) {
|
|
34315
35219
|
const { zoomControl } = params;
|
|
34316
35220
|
let min = 0;
|
|
@@ -34395,8 +35299,8 @@
|
|
|
34395
35299
|
// We'll remove all that aren't in the allowed (direct) list.
|
|
34396
35300
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
34397
35301
|
const part = parts[i];
|
|
34398
|
-
if (part && part instanceof Cesium.Entity &&
|
|
34399
|
-
params.viewer
|
|
35302
|
+
if (part && part instanceof Cesium.Entity && !cEntity._siblingGraphics.includes(part)) {
|
|
35303
|
+
RemoveCEntityFromScene(params.viewer, part);
|
|
34400
35304
|
}
|
|
34401
35305
|
}
|
|
34402
35306
|
if (cEntity._parentEntity) {
|
|
@@ -34740,7 +35644,6 @@
|
|
|
34740
35644
|
cEntity.ellipse.semiMajorAxis = new Cesium.ConstantProperty(radius);
|
|
34741
35645
|
cEntity.ellipse.semiMinorAxis = new Cesium.ConstantProperty(radius);
|
|
34742
35646
|
}
|
|
34743
|
-
cEntity.ellipse.outlineWidth = undefined;
|
|
34744
35647
|
{
|
|
34745
35648
|
const curHeightRef = GetCValue(params.viewer, cEntity.ellipse.heightReference);
|
|
34746
35649
|
if (curHeightRef != heightRef) {
|
|
@@ -34761,13 +35664,26 @@
|
|
|
34761
35664
|
cEntity.ellipse.extrudedHeight = new Cesium.ConstantProperty(extrusion.value);
|
|
34762
35665
|
}
|
|
34763
35666
|
}
|
|
34764
|
-
|
|
34765
|
-
|
|
35667
|
+
SetCPropIfChanged({
|
|
35668
|
+
viewer: params.viewer,
|
|
35669
|
+
graphic: cEntity.ellipse,
|
|
35670
|
+
property: "zIndex",
|
|
35671
|
+
value: 1
|
|
35672
|
+
});
|
|
35673
|
+
SetCPropIfChanged({
|
|
35674
|
+
viewer: params.viewer,
|
|
35675
|
+
graphic: cEntity.ellipse,
|
|
35676
|
+
property: "distanceDisplayCondition",
|
|
35677
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance)
|
|
35678
|
+
});
|
|
34766
35679
|
const curClassification = GetCValue(params.viewer, cEntity.ellipse.classificationType);
|
|
34767
35680
|
if (curClassification != classification) {
|
|
34768
35681
|
cEntity.ellipse.classificationType = new Cesium.ConstantProperty(classification);
|
|
34769
35682
|
}
|
|
34770
|
-
|
|
35683
|
+
const curPos = GetCValue(params.viewer, cEntity.position);
|
|
35684
|
+
if (!curPos || !pos3d || !Cesium.Cartesian3.equals(curPos, pos3d)) {
|
|
35685
|
+
cEntity.position = new Cesium.ConstantPositionProperty(pos3d === null || pos3d === void 0 ? void 0 : pos3d.clone());
|
|
35686
|
+
}
|
|
34771
35687
|
// We'll use "SetDefaultColor" to updating the internal reference and to allow for an animation.
|
|
34772
35688
|
// WARNING: ellipse does not support animation (yet?).
|
|
34773
35689
|
exports.CesiumEntityStyler.SetDefaultColor({
|
|
@@ -34775,6 +35691,8 @@
|
|
|
34775
35691
|
entity: cEntity,
|
|
34776
35692
|
viewer: params.viewer,
|
|
34777
35693
|
override: true,
|
|
35694
|
+
// Fill colour only. The outline sibling gets its own cOutline baked below.
|
|
35695
|
+
includeSiblings: false,
|
|
34778
35696
|
requestRender: false
|
|
34779
35697
|
});
|
|
34780
35698
|
cEntity.show = true;
|
|
@@ -34813,8 +35731,18 @@
|
|
|
34813
35731
|
outlineEntity.ellipse.extrudedHeight = new Cesium.ConstantProperty(outlineExtrusion.value);
|
|
34814
35732
|
}
|
|
34815
35733
|
}
|
|
34816
|
-
|
|
34817
|
-
|
|
35734
|
+
SetCPropIfChanged({
|
|
35735
|
+
viewer: params.viewer,
|
|
35736
|
+
graphic: outlineEntity.ellipse,
|
|
35737
|
+
property: "zIndex",
|
|
35738
|
+
value: 2
|
|
35739
|
+
});
|
|
35740
|
+
SetCPropIfChanged({
|
|
35741
|
+
viewer: params.viewer,
|
|
35742
|
+
graphic: outlineEntity.ellipse,
|
|
35743
|
+
property: "distanceDisplayCondition",
|
|
35744
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance)
|
|
35745
|
+
});
|
|
34818
35746
|
const curClassification = GetCValue(params.viewer, outlineEntity.ellipse.classificationType);
|
|
34819
35747
|
if (curClassification != classification) {
|
|
34820
35748
|
outlineEntity.ellipse.classificationType = new Cesium.ConstantProperty(classification);
|
|
@@ -34826,6 +35754,7 @@
|
|
|
34826
35754
|
entity: outlineEntity,
|
|
34827
35755
|
viewer: params.viewer,
|
|
34828
35756
|
override: true,
|
|
35757
|
+
includeSiblings: false,
|
|
34829
35758
|
requestRender: false
|
|
34830
35759
|
});
|
|
34831
35760
|
outlineEntity.show = true;
|
|
@@ -35090,7 +36019,7 @@
|
|
|
35090
36019
|
// De-dupe the tag IDs.
|
|
35091
36020
|
tagIds = Array.from(new Set(tagIds));
|
|
35092
36021
|
// Request if at least one then create a quick lookup map for tags.
|
|
35093
|
-
const tags = tagIds.length > 0 ? (await BModels.EntityTag.GetListByIds({
|
|
36022
|
+
const tags = (!params.offline && tagIds.length > 0) ? (await BModels.EntityTag.GetListByIds({
|
|
35094
36023
|
api,
|
|
35095
36024
|
tagIds
|
|
35096
36025
|
})).tags : [];
|
|
@@ -35102,7 +36031,7 @@
|
|
|
35102
36031
|
for (let i = 0; i < params.entities.length; i++) {
|
|
35103
36032
|
const entity = params.entities[i];
|
|
35104
36033
|
const zoomItem = params.zoomItems[entity.Bruce.ID];
|
|
35105
|
-
const style = zoomItem.StyleID != -1 ? (_a = (await getStyle$1(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
36034
|
+
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;
|
|
35106
36035
|
// Pass through tags that may be needed for styling.
|
|
35107
36036
|
const tagIds = entity.Bruce["Layer.ID"];
|
|
35108
36037
|
const tags = [];
|
|
@@ -35140,7 +36069,7 @@
|
|
|
35140
36069
|
rego: rego
|
|
35141
36070
|
});
|
|
35142
36071
|
if (cEntity) {
|
|
35143
|
-
const name = await getName(api, entity);
|
|
36072
|
+
const name = await getName(api, entity, params.offline);
|
|
35144
36073
|
cEntity.name = name;
|
|
35145
36074
|
cEntity._renderGroup = exports.EntityRenderEngine.GetRenderGroupId(zoomItem);
|
|
35146
36075
|
cEntity.styleId = zoomItem.StyleID == -1 ? -1 : (+zoomItem.StyleID || null);
|
|
@@ -35311,7 +36240,16 @@
|
|
|
35311
36240
|
}
|
|
35312
36241
|
return data;
|
|
35313
36242
|
}
|
|
35314
|
-
async function getName(api, entity) {
|
|
36243
|
+
async function getName(api, entity, offline) {
|
|
36244
|
+
var _a;
|
|
36245
|
+
const ownName = GetUsableEntityName(entity);
|
|
36246
|
+
if (ownName) {
|
|
36247
|
+
return ownName;
|
|
36248
|
+
}
|
|
36249
|
+
if (offline) {
|
|
36250
|
+
// Anything further needs a request, so offline callers take what the entity carries, placeholder or not.
|
|
36251
|
+
return ((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.Name) || "Unnamed Entity";
|
|
36252
|
+
}
|
|
35315
36253
|
try {
|
|
35316
36254
|
const typeId = entity.Bruce["EntityType.ID"];
|
|
35317
36255
|
let type = null;
|
|
@@ -35487,8 +36425,8 @@
|
|
|
35487
36425
|
// We'll remove all that aren't in the allowed (direct) list.
|
|
35488
36426
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
35489
36427
|
const part = parts[i];
|
|
35490
|
-
if (part && part instanceof Cesium.Entity &&
|
|
35491
|
-
params.viewer
|
|
36428
|
+
if (part && part instanceof Cesium.Entity && !cEntity._siblingGraphics.includes(part)) {
|
|
36429
|
+
RemoveCEntityFromScene(params.viewer, part);
|
|
35492
36430
|
}
|
|
35493
36431
|
}
|
|
35494
36432
|
if (cEntity._parentEntity) {
|
|
@@ -35981,7 +36919,7 @@
|
|
|
35981
36919
|
// De-dupe the tag IDs.
|
|
35982
36920
|
tagIds = Array.from(new Set(tagIds));
|
|
35983
36921
|
// Request if at least one then create a quick lookup map for tags.
|
|
35984
|
-
const tags = tagIds.length > 0 ? (await BModels.EntityTag.GetListByIds({
|
|
36922
|
+
const tags = (!params.offline && tagIds.length > 0) ? (await BModels.EntityTag.GetListByIds({
|
|
35985
36923
|
api,
|
|
35986
36924
|
tagIds
|
|
35987
36925
|
})).tags : [];
|
|
@@ -35993,7 +36931,7 @@
|
|
|
35993
36931
|
for (let i = 0; i < params.entities.length; i++) {
|
|
35994
36932
|
const entity = params.entities[i];
|
|
35995
36933
|
const zoomItem = params.zoomItems[entity.Bruce.ID];
|
|
35996
|
-
const style = zoomItem.StyleID != -1 ? (_a = (await getStyle$2(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
36934
|
+
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;
|
|
35997
36935
|
// Pass through tags that may be needed for styling.
|
|
35998
36936
|
const tagIds = entity.Bruce["Layer.ID"];
|
|
35999
36937
|
const tags = [];
|
|
@@ -36032,8 +36970,8 @@
|
|
|
36032
36970
|
for (let i = 0; i < params.entities.length; i++) {
|
|
36033
36971
|
const entity = params.entities[i];
|
|
36034
36972
|
const zoomItem = params.zoomItems[entity.Bruce.ID];
|
|
36035
|
-
const styleRecord = zoomItem.StyleID != -1 ? (await getStyle$2(api, entity, zoomItem.StyleID)) : null;
|
|
36036
|
-
const style = zoomItem.StyleID != -1 ? styleRecord === null || styleRecord === void 0 ? void 0 : styleRecord.Settings : zoomItem.Style;
|
|
36973
|
+
const styleRecord = (!params.offline && zoomItem.StyleID != -1) ? (await getStyle$2(api, entity, zoomItem.StyleID)) : null;
|
|
36974
|
+
const style = (!params.offline && zoomItem.StyleID != -1) ? styleRecord === null || styleRecord === void 0 ? void 0 : styleRecord.Settings : zoomItem.Style;
|
|
36037
36975
|
const lod = lodData.find(x => x.entityId == entity.Bruce.ID);
|
|
36038
36976
|
if (!(lod === null || lod === void 0 ? void 0 : lod.clientFileId)) {
|
|
36039
36977
|
continue;
|
|
@@ -36079,7 +37017,7 @@
|
|
|
36079
37017
|
rego: rego
|
|
36080
37018
|
});
|
|
36081
37019
|
if (cEntity) {
|
|
36082
|
-
const name = await getName$1(api, entity);
|
|
37020
|
+
const name = await getName$1(api, entity, params.offline);
|
|
36083
37021
|
cEntity.name = name;
|
|
36084
37022
|
cEntity._renderGroup = exports.EntityRenderEngine.GetRenderGroupId(zoomItem);
|
|
36085
37023
|
cEntity.styleId = zoomItem.StyleID == -1 ? -1 : styleRecord === null || styleRecord === void 0 ? void 0 : styleRecord.ID;
|
|
@@ -36105,7 +37043,16 @@
|
|
|
36105
37043
|
}
|
|
36106
37044
|
return heightRef;
|
|
36107
37045
|
}
|
|
36108
|
-
async function getName$1(api, entity) {
|
|
37046
|
+
async function getName$1(api, entity, offline) {
|
|
37047
|
+
var _a;
|
|
37048
|
+
const ownName = GetUsableEntityName(entity);
|
|
37049
|
+
if (ownName) {
|
|
37050
|
+
return ownName;
|
|
37051
|
+
}
|
|
37052
|
+
if (offline) {
|
|
37053
|
+
// Anything further needs a request, so offline callers take what the entity carries, placeholder or not.
|
|
37054
|
+
return ((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.Name) || "Unnamed Entity";
|
|
37055
|
+
}
|
|
36109
37056
|
try {
|
|
36110
37057
|
const typeId = entity.Bruce["EntityType.ID"];
|
|
36111
37058
|
let type = null;
|
|
@@ -36374,8 +37321,8 @@
|
|
|
36374
37321
|
// Kill all expect last part. Last one is the primary entity.
|
|
36375
37322
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
36376
37323
|
const part = parts[i];
|
|
36377
|
-
if (part && part instanceof Cesium.Entity
|
|
36378
|
-
params.viewer
|
|
37324
|
+
if (part && part instanceof Cesium.Entity) {
|
|
37325
|
+
RemoveCEntityFromScene(params.viewer, part);
|
|
36379
37326
|
}
|
|
36380
37327
|
}
|
|
36381
37328
|
cEntity._siblingGraphics = [];
|
|
@@ -36406,7 +37353,12 @@
|
|
|
36406
37353
|
if (oldClampToGround != newClampToGround) {
|
|
36407
37354
|
cEntity.polyline.clampToGround = new Cesium.ConstantProperty(newClampToGround);
|
|
36408
37355
|
}
|
|
36409
|
-
|
|
37356
|
+
SetCPropIfChanged({
|
|
37357
|
+
viewer: params.viewer,
|
|
37358
|
+
graphic: cEntity.polyline,
|
|
37359
|
+
property: "distanceDisplayCondition",
|
|
37360
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance)
|
|
37361
|
+
});
|
|
36410
37362
|
cEntity.corridor = undefined;
|
|
36411
37363
|
}
|
|
36412
37364
|
else {
|
|
@@ -36430,7 +37382,12 @@
|
|
|
36430
37382
|
if (oldZIndex != getZIndex(style, entity, params.tags)) {
|
|
36431
37383
|
cEntity.corridor.zIndex = new Cesium.ConstantProperty(getZIndex(style, entity, params.tags));
|
|
36432
37384
|
}
|
|
36433
|
-
|
|
37385
|
+
SetCPropIfChanged({
|
|
37386
|
+
viewer: params.viewer,
|
|
37387
|
+
graphic: cEntity.corridor,
|
|
37388
|
+
property: "distanceDisplayCondition",
|
|
37389
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width)
|
|
37390
|
+
});
|
|
36434
37391
|
cEntity.polyline = undefined;
|
|
36435
37392
|
}
|
|
36436
37393
|
// We'll use "SetDefaultColor" to updating the internal reference and to allow for an animation.
|
|
@@ -36498,7 +37455,7 @@
|
|
|
36498
37455
|
// De-dupe the tag IDs.
|
|
36499
37456
|
tagIds = Array.from(new Set(tagIds));
|
|
36500
37457
|
// Request if at least one then create a quick lookup map for tags.
|
|
36501
|
-
const tags = tagIds.length > 0 ? (await BModels.EntityTag.GetListByIds({
|
|
37458
|
+
const tags = (!params.offline && tagIds.length > 0) ? (await BModels.EntityTag.GetListByIds({
|
|
36502
37459
|
api,
|
|
36503
37460
|
tagIds
|
|
36504
37461
|
})).tags : [];
|
|
@@ -36510,7 +37467,7 @@
|
|
|
36510
37467
|
for (let i = 0; i < params.entities.length; i++) {
|
|
36511
37468
|
const entity = params.entities[i];
|
|
36512
37469
|
const zoomItem = params.zoomItems[entity.Bruce.ID];
|
|
36513
|
-
const style = zoomItem.StyleID != -1 ? (_a = (await getStyle$3(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
37470
|
+
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;
|
|
36514
37471
|
// Pass through tags that may be needed for styling.
|
|
36515
37472
|
const tagIds = entity.Bruce["Layer.ID"];
|
|
36516
37473
|
const tags = [];
|
|
@@ -36533,7 +37490,7 @@
|
|
|
36533
37490
|
rendered: (_c = params.rendered) === null || _c === void 0 ? void 0 : _c.get(entity.Bruce.ID)
|
|
36534
37491
|
});
|
|
36535
37492
|
if (cEntity) {
|
|
36536
|
-
const name = await getName$2(api, entity);
|
|
37493
|
+
const name = await getName$2(api, entity, params.offline);
|
|
36537
37494
|
cEntity.name = name;
|
|
36538
37495
|
cEntity._renderGroup = exports.EntityRenderEngine.GetRenderGroupId(zoomItem);
|
|
36539
37496
|
cEntity.styleId = zoomItem.StyleID == -1 ? -1 : (+zoomItem.StyleID || null);
|
|
@@ -36544,7 +37501,16 @@
|
|
|
36544
37501
|
}
|
|
36545
37502
|
EntityRenderEnginePolyline.RenderGroup = RenderGroup;
|
|
36546
37503
|
})(exports.EntityRenderEnginePolyline || (exports.EntityRenderEnginePolyline = {}));
|
|
36547
|
-
async function getName$2(api, entity) {
|
|
37504
|
+
async function getName$2(api, entity, offline) {
|
|
37505
|
+
var _a;
|
|
37506
|
+
const ownName = GetUsableEntityName(entity);
|
|
37507
|
+
if (ownName) {
|
|
37508
|
+
return ownName;
|
|
37509
|
+
}
|
|
37510
|
+
if (offline) {
|
|
37511
|
+
// Anything further needs a request, so offline callers take what the entity carries, placeholder or not.
|
|
37512
|
+
return ((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.Name) || "Unnamed Entity";
|
|
37513
|
+
}
|
|
36548
37514
|
try {
|
|
36549
37515
|
const typeId = entity.Bruce["EntityType.ID"];
|
|
36550
37516
|
let type = null;
|
|
@@ -36786,6 +37752,13 @@
|
|
|
36786
37752
|
GetArchiveUrl() {
|
|
36787
37753
|
return this.archiveUrl;
|
|
36788
37754
|
}
|
|
37755
|
+
/**
|
|
37756
|
+
* The property this instance presents frames through, for a caller that needs to rebuild the entity's
|
|
37757
|
+
* material (eg: re-tinting for opacity/selection) without detaching the animation.
|
|
37758
|
+
*/
|
|
37759
|
+
GetImageProperty() {
|
|
37760
|
+
return this.imageProperty;
|
|
37761
|
+
}
|
|
36789
37762
|
onClockTick(currentTime) {
|
|
36790
37763
|
if (this.disposed) {
|
|
36791
37764
|
return;
|
|
@@ -36974,8 +37947,9 @@
|
|
|
36974
37947
|
const TEXTURE_FRAME_SERIES_ANIMATOR_KEY = "TextureFrameSeriesAnimator.Animator";
|
|
36975
37948
|
(function (EntityRenderEnginePolygon) {
|
|
36976
37949
|
async function Render(params) {
|
|
36977
|
-
var _a, _b;
|
|
37950
|
+
var _a, _b, _c;
|
|
36978
37951
|
const entity = params.entity;
|
|
37952
|
+
const style = params.style;
|
|
36979
37953
|
const pRings = BModels.Entity.GetValue({
|
|
36980
37954
|
entity: entity,
|
|
36981
37955
|
path: ["Bruce", "VectorGeometry", "Polygon"]
|
|
@@ -36983,7 +37957,6 @@
|
|
|
36983
37957
|
if (pRings == null || !Array.isArray(pRings) || pRings.length <= 0) {
|
|
36984
37958
|
return null;
|
|
36985
37959
|
}
|
|
36986
|
-
const style = params.style;
|
|
36987
37960
|
const fillType = style.fillType || BModels.Style.EPolygonFillType.Color;
|
|
36988
37961
|
const fillColorTrace = style.fillColor ? BModels.Calculator.TraceGetColor(style.fillColor, entity, params.tags) : { value: null, effective: null };
|
|
36989
37962
|
const bFillColor = fillColorTrace.value;
|
|
@@ -36991,16 +37964,21 @@
|
|
|
36991
37964
|
let textureDataUri = null;
|
|
36992
37965
|
let textureTraceEffective = null;
|
|
36993
37966
|
let frameArchive = null;
|
|
36994
|
-
if (fillType === BModels.Style.EPolygonFillType.Texture) {
|
|
36995
|
-
|
|
36996
|
-
|
|
36997
|
-
|
|
36998
|
-
|
|
36999
|
-
|
|
37000
|
-
|
|
37001
|
-
|
|
37002
|
-
|
|
37003
|
-
|
|
37967
|
+
if (fillType === BModels.Style.EPolygonFillType.Texture && !params.offline) {
|
|
37968
|
+
try {
|
|
37969
|
+
const resolved = await resolveTexturedFill({
|
|
37970
|
+
api: params.api,
|
|
37971
|
+
style,
|
|
37972
|
+
entity,
|
|
37973
|
+
tags: params.tags
|
|
37974
|
+
});
|
|
37975
|
+
textureDataUri = resolved.dataUri;
|
|
37976
|
+
textureTraceEffective = resolved.effective;
|
|
37977
|
+
frameArchive = resolved.frameArchive || null;
|
|
37978
|
+
}
|
|
37979
|
+
catch (e) {
|
|
37980
|
+
console.error(`Polygon.Render: failed to resolve textured fill for entity ${((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID) || "<NONE>"}:`, e);
|
|
37981
|
+
}
|
|
37004
37982
|
}
|
|
37005
37983
|
const hasFill = fillType === BModels.Style.EPolygonFillType.Texture
|
|
37006
37984
|
? Boolean(textureDataUri || frameArchive || cFillColor.alpha > 0)
|
|
@@ -37067,8 +38045,8 @@
|
|
|
37067
38045
|
// We'll remove all that aren't in the allowed (direct) list.
|
|
37068
38046
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
37069
38047
|
const part = parts[i];
|
|
37070
|
-
if (part && part instanceof Cesium.Entity &&
|
|
37071
|
-
params.viewer
|
|
38048
|
+
if (part && part instanceof Cesium.Entity && !cEntity._siblingGraphics.includes(part)) {
|
|
38049
|
+
RemoveCEntityFromScene(params.viewer, part);
|
|
37072
38050
|
}
|
|
37073
38051
|
}
|
|
37074
38052
|
if (cEntity._parentEntity) {
|
|
@@ -37078,7 +38056,8 @@
|
|
|
37078
38056
|
};
|
|
37079
38057
|
const hasOutline = width > 0 && cLineColor;
|
|
37080
38058
|
let cEntity = null;
|
|
37081
|
-
|
|
38059
|
+
const isExistingGraphic = Boolean(params.rendered && params.rendered.polygon);
|
|
38060
|
+
if (!isExistingGraphic) {
|
|
37082
38061
|
cEntity = new Cesium.Entity({
|
|
37083
38062
|
id: BModels.ObjectUtils.UId(15),
|
|
37084
38063
|
polygon: {
|
|
@@ -37091,7 +38070,7 @@
|
|
|
37091
38070
|
classificationType: classification,
|
|
37092
38071
|
perPositionHeight: heightRef == Cesium.HeightReference.CLAMP_TO_GROUND ? false : true,
|
|
37093
38072
|
zIndex: zIndex,
|
|
37094
|
-
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width <= 0 || !cLineColor || units == "m" ? size : null, true)
|
|
38073
|
+
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width <= 0 || !cLineColor || units == "m" ? size : null, true, size)
|
|
37095
38074
|
},
|
|
37096
38075
|
position: exports.EntityUtils.GetPos({
|
|
37097
38076
|
viewer: params.viewer,
|
|
@@ -37145,9 +38124,38 @@
|
|
|
37145
38124
|
if (oldZIndex != zIndex) {
|
|
37146
38125
|
cEntity.polygon.zIndex = new Cesium.ConstantProperty(zIndex);
|
|
37147
38126
|
}
|
|
37148
|
-
|
|
37149
|
-
|
|
37150
|
-
|
|
38127
|
+
SetCPropIfChanged({
|
|
38128
|
+
viewer: params.viewer,
|
|
38129
|
+
graphic: cEntity.polygon,
|
|
38130
|
+
property: "distanceDisplayCondition",
|
|
38131
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width <= 0 || !cLineColor || units == "m" ? size : null, true, size)
|
|
38132
|
+
});
|
|
38133
|
+
SetCPropIfChanged({
|
|
38134
|
+
viewer: params.viewer,
|
|
38135
|
+
graphic: cEntity.polygon,
|
|
38136
|
+
property: "shadows",
|
|
38137
|
+
value: Cesium.ShadowMode.ENABLED
|
|
38138
|
+
});
|
|
38139
|
+
SetCPropIfChanged({
|
|
38140
|
+
viewer: params.viewer,
|
|
38141
|
+
graphic: cEntity.polygon,
|
|
38142
|
+
property: "classificationType",
|
|
38143
|
+
value: classification
|
|
38144
|
+
});
|
|
38145
|
+
cEntity.show = true;
|
|
38146
|
+
}
|
|
38147
|
+
// Must run before any material is baked below: the Animator takes over polygon.material, so a bake
|
|
38148
|
+
// has to know whether it is baking over a live animation or over a disposed one's restored material.
|
|
38149
|
+
const animator = syncTextureFrameArchive(cEntity, frameArchive, params.viewer, style.textureColorMask);
|
|
38150
|
+
if (animator) {
|
|
38151
|
+
exports.CesiumEntityStyler.SetDefaultTextureImage({
|
|
38152
|
+
entity: cEntity,
|
|
38153
|
+
image: animator.GetImageProperty(),
|
|
38154
|
+
viewer: params.viewer,
|
|
38155
|
+
requestRender: false
|
|
38156
|
+
});
|
|
38157
|
+
}
|
|
38158
|
+
else if (isExistingGraphic) {
|
|
37151
38159
|
// TODO: animate the texture!
|
|
37152
38160
|
if (textureDataUri) {
|
|
37153
38161
|
// Rebaking texture to ensure we don't revert to the wrong one later.
|
|
@@ -37174,12 +38182,12 @@
|
|
|
37174
38182
|
entity: cEntity,
|
|
37175
38183
|
viewer: params.viewer,
|
|
37176
38184
|
override: true,
|
|
38185
|
+
// Fill colour only. The outline sibling gets its own line colour baked below.
|
|
38186
|
+
includeSiblings: false,
|
|
37177
38187
|
requestRender: false
|
|
37178
38188
|
});
|
|
37179
38189
|
}
|
|
37180
|
-
cEntity.show = true;
|
|
37181
38190
|
}
|
|
37182
|
-
syncTextureFrameArchive(cEntity, frameArchive, params.viewer, style.textureColorMask);
|
|
37183
38191
|
if (frameArchive && params.onSeriesDiscovered) {
|
|
37184
38192
|
const segment = frameArchiveToSeriesSegment(frameArchive, params.entity);
|
|
37185
38193
|
if (segment) {
|
|
@@ -37198,7 +38206,7 @@
|
|
|
37198
38206
|
}
|
|
37199
38207
|
}
|
|
37200
38208
|
let borderPosses = posses.map(x => x.clone ? x.clone() : { ...x });
|
|
37201
|
-
let cEntityBorder = (
|
|
38209
|
+
let cEntityBorder = (_c = (_b = params.rendered) === null || _b === void 0 ? void 0 : _b._siblingGraphics) === null || _c === void 0 ? void 0 : _c[0];
|
|
37202
38210
|
cEntity._siblingGraphics = [];
|
|
37203
38211
|
if (!cEntityBorder || ((!cEntityBorder.polyline && units == "px") ||
|
|
37204
38212
|
(!cEntityBorder.corridor && units == "m"))) {
|
|
@@ -37212,7 +38220,7 @@
|
|
|
37212
38220
|
classificationType: Cesium.ClassificationType.TERRAIN,
|
|
37213
38221
|
arcType: Cesium.ArcType.GEODESIC,
|
|
37214
38222
|
zIndex: zIndex,
|
|
37215
|
-
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance)
|
|
38223
|
+
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, null, false, size)
|
|
37216
38224
|
}) : null,
|
|
37217
38225
|
corridor: units == "m" ? {
|
|
37218
38226
|
positions: borderPosses,
|
|
@@ -37224,7 +38232,7 @@
|
|
|
37224
38232
|
zIndex: zIndex + 1,
|
|
37225
38233
|
cornerType: Cesium.CornerType.MITERED,
|
|
37226
38234
|
classificationType: classification,
|
|
37227
|
-
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width),
|
|
38235
|
+
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width, false, size),
|
|
37228
38236
|
shadows: Cesium.ShadowMode.ENABLED
|
|
37229
38237
|
} : null,
|
|
37230
38238
|
show: true
|
|
@@ -37251,11 +38259,21 @@
|
|
|
37251
38259
|
}
|
|
37252
38260
|
const oldMaterial = GetCValue(params.viewer, cEntityBorder.polyline.material);
|
|
37253
38261
|
const newMaterial = new Cesium.ColorMaterialProperty(cLineColor);
|
|
37254
|
-
if (
|
|
38262
|
+
if (!areColorMaterialsEqual(params.viewer, oldMaterial, newMaterial)) {
|
|
37255
38263
|
cEntityBorder.polyline.material = newMaterial;
|
|
37256
38264
|
}
|
|
37257
|
-
|
|
37258
|
-
|
|
38265
|
+
SetCPropIfChanged({
|
|
38266
|
+
viewer: params.viewer,
|
|
38267
|
+
graphic: cEntityBorder.polyline,
|
|
38268
|
+
property: "classificationType",
|
|
38269
|
+
value: Cesium.ClassificationType.TERRAIN
|
|
38270
|
+
});
|
|
38271
|
+
SetCPropIfChanged({
|
|
38272
|
+
viewer: params.viewer,
|
|
38273
|
+
graphic: cEntityBorder.polyline,
|
|
38274
|
+
property: "distanceDisplayCondition",
|
|
38275
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, null, false, size)
|
|
38276
|
+
});
|
|
37259
38277
|
cEntityBorder.corridor = undefined;
|
|
37260
38278
|
}
|
|
37261
38279
|
else {
|
|
@@ -37281,15 +38299,35 @@
|
|
|
37281
38299
|
}
|
|
37282
38300
|
const oldMaterial = GetCValue(params.viewer, cEntityBorder.corridor.material);
|
|
37283
38301
|
const newMaterial = new Cesium.ColorMaterialProperty(cLineColor);
|
|
37284
|
-
if (
|
|
38302
|
+
if (!areColorMaterialsEqual(params.viewer, oldMaterial, newMaterial)) {
|
|
37285
38303
|
cEntityBorder.corridor.material = newMaterial;
|
|
37286
38304
|
}
|
|
37287
|
-
|
|
37288
|
-
|
|
38305
|
+
SetCPropIfChanged({
|
|
38306
|
+
viewer: params.viewer,
|
|
38307
|
+
graphic: cEntityBorder.corridor,
|
|
38308
|
+
property: "fill",
|
|
38309
|
+
value: true
|
|
38310
|
+
});
|
|
38311
|
+
SetCPropIfChanged({
|
|
38312
|
+
viewer: params.viewer,
|
|
38313
|
+
graphic: cEntityBorder.corridor,
|
|
38314
|
+
property: "distanceDisplayCondition",
|
|
38315
|
+
value: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width, false, size)
|
|
38316
|
+
});
|
|
37289
38317
|
cEntityBorder.polyline = undefined;
|
|
37290
38318
|
}
|
|
37291
38319
|
cEntityBorder.show = true;
|
|
37292
38320
|
}
|
|
38321
|
+
// Bake the outline's own colour as its default, so a deselect/opacity refresh restores the line
|
|
38322
|
+
// colour rather than falling back to the fill's.
|
|
38323
|
+
exports.CesiumEntityStyler.SetDefaultColor({
|
|
38324
|
+
color: cLineColor,
|
|
38325
|
+
entity: cEntityBorder,
|
|
38326
|
+
viewer: params.viewer,
|
|
38327
|
+
override: true,
|
|
38328
|
+
includeSiblings: false,
|
|
38329
|
+
requestRender: false
|
|
38330
|
+
});
|
|
37293
38331
|
cEntityBorder._parentEntity = cEntity;
|
|
37294
38332
|
cEntity._siblingGraphics.push(cEntityBorder);
|
|
37295
38333
|
for (let i = 0; i < holePosses.length; i++) {
|
|
@@ -37305,7 +38343,7 @@
|
|
|
37305
38343
|
classificationType: Cesium.ClassificationType.TERRAIN,
|
|
37306
38344
|
arcType: Cesium.ArcType.GEODESIC,
|
|
37307
38345
|
zIndex: zIndex,
|
|
37308
|
-
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance)
|
|
38346
|
+
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, null, false, size)
|
|
37309
38347
|
}) : null,
|
|
37310
38348
|
corridor: units == "m" ? {
|
|
37311
38349
|
positions: borderPosses,
|
|
@@ -37317,7 +38355,7 @@
|
|
|
37317
38355
|
zIndex: zIndex + 1,
|
|
37318
38356
|
cornerType: Cesium.CornerType.MITERED,
|
|
37319
38357
|
classificationType: classification,
|
|
37320
|
-
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width),
|
|
38358
|
+
distanceDisplayCondition: exports.EntityRenderEngine.GetDisplayCondition(params.minDistance, params.maxDistance, width, false, size),
|
|
37321
38359
|
shadows: Cesium.ShadowMode.ENABLED,
|
|
37322
38360
|
} : null,
|
|
37323
38361
|
show: true
|
|
@@ -37339,7 +38377,7 @@
|
|
|
37339
38377
|
}
|
|
37340
38378
|
EntityRenderEnginePolygon.Render = Render;
|
|
37341
38379
|
async function RenderGroup(params) {
|
|
37342
|
-
var _a, _b, _c;
|
|
38380
|
+
var _a, _b, _c, _d;
|
|
37343
38381
|
const api = params.apiGetter.getApi();
|
|
37344
38382
|
const cEntities = new Map();
|
|
37345
38383
|
// Gathering tags in case styling needs it.
|
|
@@ -37358,7 +38396,7 @@
|
|
|
37358
38396
|
// De-dupe the tag IDs.
|
|
37359
38397
|
tagIds = Array.from(new Set(tagIds));
|
|
37360
38398
|
// Request if at least one then create a quick lookup map for tags.
|
|
37361
|
-
const tags = tagIds.length > 0 ? (await BModels.EntityTag.GetListByIds({
|
|
38399
|
+
const tags = (!params.offline && tagIds.length > 0) ? (await BModels.EntityTag.GetListByIds({
|
|
37362
38400
|
api,
|
|
37363
38401
|
tagIds
|
|
37364
38402
|
})).tags : [];
|
|
@@ -37370,7 +38408,7 @@
|
|
|
37370
38408
|
for (let i = 0; i < params.entities.length; i++) {
|
|
37371
38409
|
const entity = params.entities[i];
|
|
37372
38410
|
const zoomItem = params.zoomItems[entity.Bruce.ID];
|
|
37373
|
-
const style = zoomItem.StyleID != -1 ? (_a = (await getStyle$4(api, entity, zoomItem.StyleID))) === null || _a === void 0 ? void 0 : _a.Settings : zoomItem.Style;
|
|
38411
|
+
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;
|
|
37374
38412
|
// Pass through tags that may be needed for styling.
|
|
37375
38413
|
const tagIds = entity.Bruce["Layer.ID"];
|
|
37376
38414
|
const tags = [];
|
|
@@ -37383,23 +38421,29 @@
|
|
|
37383
38421
|
}
|
|
37384
38422
|
}
|
|
37385
38423
|
const pStyle = (_b = style === null || style === void 0 ? void 0 : style.polygonStyle) !== null && _b !== void 0 ? _b : {};
|
|
37386
|
-
|
|
37387
|
-
|
|
37388
|
-
|
|
37389
|
-
|
|
37390
|
-
|
|
37391
|
-
|
|
37392
|
-
|
|
37393
|
-
|
|
37394
|
-
|
|
37395
|
-
|
|
37396
|
-
|
|
37397
|
-
|
|
37398
|
-
|
|
37399
|
-
|
|
37400
|
-
|
|
38424
|
+
let cEntity = null;
|
|
38425
|
+
try {
|
|
38426
|
+
cEntity = await Render({
|
|
38427
|
+
entity: entity,
|
|
38428
|
+
style: pStyle,
|
|
38429
|
+
tags: tags,
|
|
38430
|
+
viewer: params.viewer,
|
|
38431
|
+
api,
|
|
38432
|
+
maxDistance: zoomItem.MaxZoom,
|
|
38433
|
+
minDistance: zoomItem.MinZoom,
|
|
38434
|
+
// Temporarily disabling re-using graphics for polygons as they have some bugs, and
|
|
38435
|
+
// they don't support any animation yet.
|
|
38436
|
+
// rendered: null
|
|
38437
|
+
rendered: (_c = params.rendered) === null || _c === void 0 ? void 0 : _c.get(entity.Bruce.ID),
|
|
38438
|
+
menuItemId: params.menuItemId,
|
|
38439
|
+
onSeriesDiscovered: params.onSeriesDiscovered
|
|
38440
|
+
});
|
|
38441
|
+
}
|
|
38442
|
+
catch (e) {
|
|
38443
|
+
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);
|
|
38444
|
+
}
|
|
37401
38445
|
if (cEntity) {
|
|
37402
|
-
const name = await getName$3(api, entity);
|
|
38446
|
+
const name = await getName$3(api, entity, params.offline);
|
|
37403
38447
|
cEntity.name = name;
|
|
37404
38448
|
cEntity._renderGroup = exports.EntityRenderEngine.GetRenderGroupId(zoomItem);
|
|
37405
38449
|
cEntity.styleId = zoomItem.StyleID == -1 ? -1 : (+zoomItem.StyleID || null);
|
|
@@ -37421,7 +38465,16 @@
|
|
|
37421
38465
|
}
|
|
37422
38466
|
EntityRenderEnginePolygon.DisposeTextureFrameSeriesAnimator = DisposeTextureFrameSeriesAnimator;
|
|
37423
38467
|
})(exports.EntityRenderEnginePolygon || (exports.EntityRenderEnginePolygon = {}));
|
|
37424
|
-
async function getName$3(api, entity) {
|
|
38468
|
+
async function getName$3(api, entity, offline) {
|
|
38469
|
+
var _a;
|
|
38470
|
+
const ownName = GetUsableEntityName(entity);
|
|
38471
|
+
if (ownName) {
|
|
38472
|
+
return ownName;
|
|
38473
|
+
}
|
|
38474
|
+
if (offline) {
|
|
38475
|
+
// Anything further needs a request, so offline callers take what the entity carries, placeholder or not.
|
|
38476
|
+
return ((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.Name) || "Unnamed Entity";
|
|
38477
|
+
}
|
|
37425
38478
|
try {
|
|
37426
38479
|
const typeId = entity.Bruce["EntityType.ID"];
|
|
37427
38480
|
let type = null;
|
|
@@ -37525,6 +38578,7 @@
|
|
|
37525
38578
|
/**
|
|
37526
38579
|
* Reconciles cEntity's TextureFrameSeriesAnimator.Animator (if any) against this render's resolved texture.
|
|
37527
38580
|
* Called once cEntity is fully created/updated and definitely has a `polygon` graphics.
|
|
38581
|
+
* Returns the animator now driving the entity, or null if this render has no frame series.
|
|
37528
38582
|
* @param cEntity
|
|
37529
38583
|
* @param frameArchive
|
|
37530
38584
|
* @param viewer
|
|
@@ -37533,22 +38587,24 @@
|
|
|
37533
38587
|
function syncTextureFrameArchive(cEntity, frameArchive, viewer, textureColorMask) {
|
|
37534
38588
|
const existing = cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY];
|
|
37535
38589
|
if (frameArchive && existing && !existing.IsDisposed() && existing.GetArchiveUrl() === frameArchive.url) {
|
|
37536
|
-
return;
|
|
38590
|
+
return existing;
|
|
37537
38591
|
}
|
|
37538
38592
|
if (existing && !existing.IsDisposed()) {
|
|
37539
38593
|
existing.Dispose();
|
|
37540
38594
|
cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY] = null;
|
|
37541
38595
|
}
|
|
37542
|
-
if (frameArchive) {
|
|
37543
|
-
|
|
37544
|
-
viewer,
|
|
37545
|
-
entity: cEntity,
|
|
37546
|
-
archiveUrl: frameArchive.url,
|
|
37547
|
-
frames: frameArchive.metadata.Frames,
|
|
37548
|
-
textureColorMask
|
|
37549
|
-
});
|
|
37550
|
-
cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY] = animator;
|
|
38596
|
+
if (!frameArchive) {
|
|
38597
|
+
return null;
|
|
37551
38598
|
}
|
|
38599
|
+
const animator = new TextureFrameSeriesAnimator.Animator({
|
|
38600
|
+
viewer,
|
|
38601
|
+
entity: cEntity,
|
|
38602
|
+
archiveUrl: frameArchive.url,
|
|
38603
|
+
frames: frameArchive.metadata.Frames,
|
|
38604
|
+
textureColorMask
|
|
38605
|
+
});
|
|
38606
|
+
cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY] = animator;
|
|
38607
|
+
return animator;
|
|
37552
38608
|
}
|
|
37553
38609
|
/**
|
|
37554
38610
|
* Derives a min/max/label time-range segment from a resolved frame archive's Frames metadata,
|
|
@@ -37715,7 +38771,7 @@
|
|
|
37715
38771
|
* @param b
|
|
37716
38772
|
* @returns
|
|
37717
38773
|
*/
|
|
37718
|
-
function
|
|
38774
|
+
function areColorMaterialsEqual(viewer, a, b) {
|
|
37719
38775
|
// Same reference.
|
|
37720
38776
|
if (a == b) {
|
|
37721
38777
|
return true;
|
|
@@ -38024,15 +39080,44 @@
|
|
|
38024
39080
|
}
|
|
38025
39081
|
})(exports.StyleEffective || (exports.StyleEffective = {}));
|
|
38026
39082
|
(function (EntityRenderEngine) {
|
|
39083
|
+
/**
|
|
39084
|
+
* Identifies the zoom band a graphic was last rendered for, covering everything in that band which
|
|
39085
|
+
* changes how the entity is drawn. Used to decide whether a re-render is needed at all.
|
|
39086
|
+
*
|
|
39087
|
+
* Deliberately NOT the reuse key: most of a band's identity is plain graphics properties that can be
|
|
39088
|
+
* patched onto the existing graphic, so see GetGraphicShapeId for that decision.
|
|
39089
|
+
*/
|
|
38027
39090
|
function GetRenderGroupId(zoomItem) {
|
|
38028
39091
|
if (!zoomItem) {
|
|
38029
39092
|
return null;
|
|
38030
39093
|
}
|
|
38031
|
-
return
|
|
39094
|
+
return exports.RenderManager.GetZoomControlSignature([zoomItem]);
|
|
38032
39095
|
}
|
|
38033
39096
|
EntityRenderEngine.GetRenderGroupId = GetRenderGroupId;
|
|
39097
|
+
/**
|
|
39098
|
+
* Identifies the kind of Cesium graphic a zoom item + entity resolves to, ignoring anything that is merely a property on it.
|
|
39099
|
+
*/
|
|
39100
|
+
function GetGraphicShapeId(zoomItem, entity) {
|
|
39101
|
+
var _a;
|
|
39102
|
+
let displayType = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.DisplayType;
|
|
39103
|
+
if (!displayType) {
|
|
39104
|
+
displayType = BModels.ZoomControl.EDisplayType.Hidden;
|
|
39105
|
+
}
|
|
39106
|
+
// Backwards compatibility, same mapping the render pass applies.
|
|
39107
|
+
else if (displayType == "polygon") {
|
|
39108
|
+
displayType = BModels.ZoomControl.EDisplayType.Geometry;
|
|
39109
|
+
}
|
|
39110
|
+
// Multi-geometry builds a container graphic holding sibling graphics rather than a flat one.
|
|
39111
|
+
const geometry = BModels.Entity.GetValue({
|
|
39112
|
+
entity: entity,
|
|
39113
|
+
path: ["Bruce", "VectorGeometry"]
|
|
39114
|
+
});
|
|
39115
|
+
const isMulti = ((_a = geometry === null || geometry === void 0 ? void 0 : geometry.MultiGeometry) === null || _a === void 0 ? void 0 : _a.length) > 1;
|
|
39116
|
+
return displayType + "|" + (isMulti ? "multi" : "single");
|
|
39117
|
+
}
|
|
39118
|
+
EntityRenderEngine.GetGraphicShapeId = GetGraphicShapeId;
|
|
38034
39119
|
async function Render(params) {
|
|
38035
|
-
var _a, _b, _c
|
|
39120
|
+
var _a, _b, _c;
|
|
38036
39121
|
const groupRenderParams = {
|
|
38037
39122
|
apiGetter: params.apiGetter,
|
|
38038
39123
|
viewer: params.viewer,
|
|
@@ -38040,10 +39125,15 @@
|
|
|
38040
39125
|
zoomItems: {},
|
|
38041
39126
|
menuItemId: params.menuItemId,
|
|
38042
39127
|
onSeriesDiscovered: params.onSeriesDiscovered,
|
|
38043
|
-
visualRegister: params.visualRegister
|
|
39128
|
+
visualRegister: params.visualRegister,
|
|
39129
|
+
offline: params.offline
|
|
38044
39130
|
};
|
|
38045
39131
|
const updated = new Map();
|
|
38046
39132
|
const cEntities = new Map();
|
|
39133
|
+
// Entity ID -> the graphic shape resolved for this pass, stamped onto the results at the end.
|
|
39134
|
+
const shapeIds = new Map();
|
|
39135
|
+
// Entity ID -> what its zoom band was resolved from, stamped alongside the shape.
|
|
39136
|
+
const bandChecks = new Map();
|
|
38047
39137
|
const models = [];
|
|
38048
39138
|
const multiGeometry = [];
|
|
38049
39139
|
const polygons = [];
|
|
@@ -38093,11 +39183,21 @@
|
|
|
38093
39183
|
for (let i = 0; i < params.entities.length; i++) {
|
|
38094
39184
|
let entity = params.entities[i];
|
|
38095
39185
|
const id = entity.Bruce.ID;
|
|
39186
|
+
const resolution = {};
|
|
38096
39187
|
const zoomItem = exports.RenderManager.DetermineZoomItem({
|
|
38097
39188
|
viewer: params.viewer,
|
|
38098
39189
|
entity,
|
|
38099
|
-
zoomControl: params.zoomControl
|
|
38100
|
-
|
|
39190
|
+
zoomControl: params.zoomControl,
|
|
39191
|
+
out: resolution
|
|
39192
|
+
});
|
|
39193
|
+
if (zoomItem && resolution.distance != null && resolution.cameraPos) {
|
|
39194
|
+
bandChecks.set(id, {
|
|
39195
|
+
distance: resolution.distance,
|
|
39196
|
+
cameraPos: resolution.cameraPos,
|
|
39197
|
+
min: zoomItem.MinZoom,
|
|
39198
|
+
max: zoomItem.MaxZoom
|
|
39199
|
+
});
|
|
39200
|
+
}
|
|
38101
39201
|
let displayType = zoomItem === null || zoomItem === void 0 ? void 0 : zoomItem.DisplayType;
|
|
38102
39202
|
if (!displayType) {
|
|
38103
39203
|
displayType = BModels.ZoomControl.EDisplayType.Hidden;
|
|
@@ -38111,8 +39211,13 @@
|
|
|
38111
39211
|
entityId: id,
|
|
38112
39212
|
menuItemId: params.menuItemId
|
|
38113
39213
|
});
|
|
39214
|
+
const existingVisual = existingRego === null || existingRego === void 0 ? void 0 : existingRego.visual;
|
|
38114
39215
|
const newRenderId = GetRenderGroupId(zoomItem);
|
|
38115
|
-
const oldRenderId =
|
|
39216
|
+
const oldRenderId = existingVisual === null || existingVisual === void 0 ? void 0 : existingVisual._renderGroup;
|
|
39217
|
+
// Resolved before prepareGeometry() below, which flattens a single-item MultiGeometry and
|
|
39218
|
+
// would otherwise make the same entity resolve to a different shape than it was stamped with.
|
|
39219
|
+
const newShapeId = GetGraphicShapeId(zoomItem, entity);
|
|
39220
|
+
shapeIds.set(id, newShapeId);
|
|
38116
39221
|
if (!params.force &&
|
|
38117
39222
|
newRenderId == oldRenderId &&
|
|
38118
39223
|
!(existingRego === null || existingRego === void 0 ? void 0 : existingRego.stale) &&
|
|
@@ -38122,13 +39227,13 @@
|
|
|
38122
39227
|
cEntities.set(id, existingRego.visual);
|
|
38123
39228
|
}
|
|
38124
39229
|
else {
|
|
38125
|
-
|
|
38126
|
-
if (existingRego &&
|
|
39230
|
+
const oldShapeId = existingVisual === null || existingVisual === void 0 ? void 0 : existingVisual._graphicShape;
|
|
39231
|
+
if (existingRego && newShapeId == oldShapeId) {
|
|
38127
39232
|
cEntities.set(id, existingRego.visual);
|
|
38128
39233
|
// Flag as no longer stale as we're unlikely to recreate the rego if we're reusing the graphic.
|
|
38129
39234
|
existingRego.stale = false;
|
|
38130
39235
|
// Update metadata for the same reason.
|
|
38131
|
-
existingRego.outline = (
|
|
39236
|
+
existingRego.outline = (_a = entity.Bruce) === null || _a === void 0 ? void 0 : _a.Outline;
|
|
38132
39237
|
existingRego.entityTypeId = entity.Bruce["EntityType.ID"];
|
|
38133
39238
|
updated.set(id, true);
|
|
38134
39239
|
}
|
|
@@ -38142,7 +39247,7 @@
|
|
|
38142
39247
|
entity: entity,
|
|
38143
39248
|
path: ["Bruce", "VectorGeometry"]
|
|
38144
39249
|
});
|
|
38145
|
-
if ((
|
|
39250
|
+
if ((_b = geometry === null || geometry === void 0 ? void 0 : geometry.MultiGeometry) === null || _b === void 0 ? void 0 : _b.length) {
|
|
38146
39251
|
multiGeometry.push(entity);
|
|
38147
39252
|
}
|
|
38148
39253
|
else {
|
|
@@ -38185,7 +39290,7 @@
|
|
|
38185
39290
|
entity: entity,
|
|
38186
39291
|
path: ["Bruce", "VectorGeometry"]
|
|
38187
39292
|
});
|
|
38188
|
-
if (!((
|
|
39293
|
+
if (!((_c = geometry === null || geometry === void 0 ? void 0 : geometry.MultiGeometry) === null || _c === void 0 ? void 0 : _c.length)) {
|
|
38189
39294
|
polygons.push(entity);
|
|
38190
39295
|
continue;
|
|
38191
39296
|
}
|
|
@@ -38304,6 +39409,21 @@
|
|
|
38304
39409
|
}
|
|
38305
39410
|
}
|
|
38306
39411
|
}
|
|
39412
|
+
// Stamped centrally rather than per-engine so the value always matches what the gate above compared,
|
|
39413
|
+
// regardless of which engine (or fallback engine) ended up producing the graphic.
|
|
39414
|
+
cEntities.forEach((cEntity, id) => {
|
|
39415
|
+
if (!cEntity) {
|
|
39416
|
+
return;
|
|
39417
|
+
}
|
|
39418
|
+
const shapeId = shapeIds.get(id);
|
|
39419
|
+
if (shapeId) {
|
|
39420
|
+
cEntity._graphicShape = shapeId;
|
|
39421
|
+
}
|
|
39422
|
+
const bandCheck = bandChecks.get(id);
|
|
39423
|
+
if (bandCheck) {
|
|
39424
|
+
cEntity._bandCheck = bandCheck;
|
|
39425
|
+
}
|
|
39426
|
+
});
|
|
38307
39427
|
return {
|
|
38308
39428
|
entities: cEntities,
|
|
38309
39429
|
updated
|
|
@@ -38339,9 +39459,7 @@
|
|
|
38339
39459
|
});
|
|
38340
39460
|
}
|
|
38341
39461
|
}
|
|
38342
|
-
|
|
38343
|
-
viewer.entities.remove(entity);
|
|
38344
|
-
}
|
|
39462
|
+
RemoveCEntityFromScene(viewer, entity);
|
|
38345
39463
|
}
|
|
38346
39464
|
doRemove({
|
|
38347
39465
|
viewer: params.viewer,
|
|
@@ -38376,9 +39494,10 @@
|
|
|
38376
39494
|
* @param max
|
|
38377
39495
|
* @param meterSize size of "thing" in meters, eg polyline is 0.5 meters width. If size is provided we can potentially cull it earlier.
|
|
38378
39496
|
* @param isPolygon
|
|
39497
|
+
* @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.
|
|
38379
39498
|
* @returns
|
|
38380
39499
|
*/
|
|
38381
|
-
function GetDisplayCondition(min, max, meterSize, isPolygon) {
|
|
39500
|
+
function GetDisplayCondition(min, max, meterSize, isPolygon, fitMeterSize) {
|
|
38382
39501
|
// Max is required.
|
|
38383
39502
|
if (isNaN(+max)) {
|
|
38384
39503
|
return undefined;
|
|
@@ -38408,6 +39527,15 @@
|
|
|
38408
39527
|
return undefined;
|
|
38409
39528
|
}
|
|
38410
39529
|
}
|
|
39530
|
+
// The configured max is a guess about viewing distance, and for a large thing that guess is often short:
|
|
39531
|
+
// it vanishes while still overflowing the screen, so you can never see all of it at once.
|
|
39532
|
+
// A thing of size S needs roughly S * 0.87 of camera distance to fit a 60deg vertical fov, so we
|
|
39533
|
+
// floor the max at a margin above that rather than culling something you haven't finished zooming out to.
|
|
39534
|
+
fitMeterSize = +fitMeterSize;
|
|
39535
|
+
if (!isNaN(fitMeterSize) && fitMeterSize > 0) {
|
|
39536
|
+
const FIT_DISTANCE_PER_METER = 1.4;
|
|
39537
|
+
max = Math.max(max, fitMeterSize * FIT_DISTANCE_PER_METER);
|
|
39538
|
+
}
|
|
38411
39539
|
return new Cesium.DistanceDisplayCondition(min, max);
|
|
38412
39540
|
}
|
|
38413
39541
|
EntityRenderEngine.GetDisplayCondition = GetDisplayCondition;
|
|
@@ -38430,7 +39558,71 @@
|
|
|
38430
39558
|
}
|
|
38431
39559
|
return value;
|
|
38432
39560
|
}
|
|
39561
|
+
const pendingRemovalsByViewer = new WeakMap();
|
|
39562
|
+
function scheduleEntityRemoval(viewer, entity) {
|
|
39563
|
+
let pending = pendingRemovalsByViewer.get(viewer);
|
|
39564
|
+
if (!pending) {
|
|
39565
|
+
pending = { entities: new Set(), hook: null };
|
|
39566
|
+
pendingRemovalsByViewer.set(viewer, pending);
|
|
39567
|
+
}
|
|
39568
|
+
pending.entities.add(entity);
|
|
39569
|
+
if (pending.hook) {
|
|
39570
|
+
return;
|
|
39571
|
+
}
|
|
39572
|
+
pending.hook = viewer.scene.postRender.addEventListener(() => {
|
|
39573
|
+
var _a;
|
|
39574
|
+
(_a = pending.hook) === null || _a === void 0 ? void 0 : _a.call(pending);
|
|
39575
|
+
pending.hook = null;
|
|
39576
|
+
const batch = Array.from(pending.entities);
|
|
39577
|
+
pending.entities.clear();
|
|
39578
|
+
if (!batch.length) {
|
|
39579
|
+
return;
|
|
39580
|
+
}
|
|
39581
|
+
WithSuspendedCCollections(batch.map(x => GetCEntityCollection(viewer, x)), () => {
|
|
39582
|
+
for (const item of batch) {
|
|
39583
|
+
try {
|
|
39584
|
+
exports.EntityRenderEngine.Remove({
|
|
39585
|
+
viewer,
|
|
39586
|
+
entity: item
|
|
39587
|
+
});
|
|
39588
|
+
}
|
|
39589
|
+
catch (e) {
|
|
39590
|
+
console.error(e);
|
|
39591
|
+
}
|
|
39592
|
+
}
|
|
39593
|
+
});
|
|
39594
|
+
});
|
|
39595
|
+
}
|
|
38433
39596
|
(function (CesiumAnimatedInOut) {
|
|
39597
|
+
/**
|
|
39598
|
+
* Runs any removals already queued for this viewer immediately, instead of waiting for the next render.
|
|
39599
|
+
* For teardown paths that need the scene emptied synchronously.
|
|
39600
|
+
*/
|
|
39601
|
+
function FlushPendingRemovals(viewer) {
|
|
39602
|
+
var _a;
|
|
39603
|
+
const pending = pendingRemovalsByViewer.get(viewer);
|
|
39604
|
+
if (!(pending === null || pending === void 0 ? void 0 : pending.entities.size)) {
|
|
39605
|
+
return;
|
|
39606
|
+
}
|
|
39607
|
+
const batch = Array.from(pending.entities);
|
|
39608
|
+
pending.entities.clear();
|
|
39609
|
+
(_a = pending.hook) === null || _a === void 0 ? void 0 : _a.call(pending);
|
|
39610
|
+
pending.hook = null;
|
|
39611
|
+
WithSuspendedCCollections(batch.map(x => GetCEntityCollection(viewer, x)), () => {
|
|
39612
|
+
for (const item of batch) {
|
|
39613
|
+
try {
|
|
39614
|
+
exports.EntityRenderEngine.Remove({
|
|
39615
|
+
viewer,
|
|
39616
|
+
entity: item
|
|
39617
|
+
});
|
|
39618
|
+
}
|
|
39619
|
+
catch (e) {
|
|
39620
|
+
console.error(e);
|
|
39621
|
+
}
|
|
39622
|
+
}
|
|
39623
|
+
});
|
|
39624
|
+
}
|
|
39625
|
+
CesiumAnimatedInOut.FlushPendingRemovals = FlushPendingRemovals;
|
|
38434
39626
|
/**
|
|
38435
39627
|
* Animates an Entity out of the scene.
|
|
38436
39628
|
* Removes it from the scene at the end of the animation.
|
|
@@ -38449,13 +39641,7 @@
|
|
|
38449
39641
|
return;
|
|
38450
39642
|
}
|
|
38451
39643
|
removed = true;
|
|
38452
|
-
|
|
38453
|
-
removal();
|
|
38454
|
-
exports.EntityRenderEngine.Remove({
|
|
38455
|
-
viewer,
|
|
38456
|
-
entity
|
|
38457
|
-
});
|
|
38458
|
-
});
|
|
39644
|
+
scheduleEntityRemoval(viewer, entity);
|
|
38459
39645
|
};
|
|
38460
39646
|
for (let i = 0; i < pieces.length; i++) {
|
|
38461
39647
|
const piece = pieces[i];
|
|
@@ -39003,7 +40189,7 @@
|
|
|
39003
40189
|
StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
|
|
39004
40190
|
})(exports.StyleUtils || (exports.StyleUtils = {}));
|
|
39005
40191
|
|
|
39006
|
-
const VERSION = "7.0.
|
|
40192
|
+
const VERSION = "7.0.3";
|
|
39007
40193
|
/**
|
|
39008
40194
|
* Updates the environment instance used by bruce-cesium to one specified.
|
|
39009
40195
|
* This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.
|