bruce-cesium 7.5.3 → 7.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17255,6 +17255,9 @@
17255
17255
  }
17256
17256
  };
17257
17257
  }
17258
+ HasEntityDataOverride(eId) {
17259
+ return this.entityDataOverrides.has(eId);
17260
+ }
17258
17261
  SetEntityDataOverride(eId, entity) {
17259
17262
  if (this.disposed) {
17260
17263
  return;
@@ -17951,6 +17954,24 @@
17951
17954
  }
17952
17955
  return style;
17953
17956
  }
17957
+ /**
17958
+ * Reads the baked attribute declaration from a loaded tileset, keyed by path.
17959
+ * @param cTileset
17960
+ */
17961
+ function getBakedAttributes(cTileset) {
17962
+ var _a, _b;
17963
+ const result = new Map();
17964
+ const declared = (_b = (_a = cTileset === null || cTileset === void 0 ? void 0 : cTileset.extras) === null || _a === void 0 ? void 0 : _a.bruce) === null || _b === void 0 ? void 0 : _b.bakedAttributes;
17965
+ if (!Array.isArray(declared)) {
17966
+ return result;
17967
+ }
17968
+ for (const baked of declared) {
17969
+ if (Array.isArray(baked === null || baked === void 0 ? void 0 : baked.path) && baked.path.length && typeof baked.property == "string") {
17970
+ result.set(JSON.stringify(baked.path), baked);
17971
+ }
17972
+ }
17973
+ return result;
17974
+ }
17954
17975
  function colorToCColor$3(color) {
17955
17976
  return new Cesium.Color(color.red ? color.red / 255 : 0, color.green ? color.green / 255 : 0, color.blue ? color.blue / 255 : 0, color.alpha);
17956
17977
  }
@@ -18021,6 +18042,10 @@
18021
18042
  // When false the Entity data is still gathered and the regos still updated, but no colour is
18022
18043
  // applied. A historic item that did not ask for styling needs the first without the second.
18023
18044
  this.applyStyles = true;
18045
+ // Attribute values the tiles carry per feature, keyed by JSON path. Empty for a tileset without them.
18046
+ this.bakedAttributes = new Map();
18047
+ // Entities changed since the tileset was generated, so their baked values can no longer be trusted.
18048
+ this.bakedStaleIds = new Set();
18024
18049
  this.reRenderState = new EntityReRenderMaintainState();
18025
18050
  // More expensive process.
18026
18051
  // When an Entity is styled, the rego is reviewed and updated if needed.
@@ -18062,6 +18087,7 @@
18062
18087
  this.viewer = viewer;
18063
18088
  this.api = api;
18064
18089
  this.cTileset = cTileset;
18090
+ this.bakedAttributes = getBakedAttributes(cTileset);
18065
18091
  this.register = register;
18066
18092
  this.menuItemId = menuItemId;
18067
18093
  this.historic = Boolean(historic);
@@ -18140,6 +18166,7 @@
18140
18166
  for (const [internalId, entityId] of this.styledByInternalId) {
18141
18167
  if (BModels.RecordChangeFeed.isEntityInternalIdInRangeString(rangeStr, internalId)) {
18142
18168
  this.feedPendingRestyleIds.add(entityId);
18169
+ this.bakedStaleIds.add(entityId);
18143
18170
  }
18144
18171
  }
18145
18172
  if (this.feedPendingRestyleIds.size && !this.feedRestyleThrottleTimer) {
@@ -18460,17 +18487,7 @@
18460
18487
  for (const key of pendingKeys) {
18461
18488
  const relatedIds = this.stylePendingEntityIds.get(key);
18462
18489
  if (relatedIds) {
18463
- if (this.getTilesetFeatureNeedsFullData(key)) {
18464
- this.entityGatherer.Queue(Array.from(relatedIds));
18465
- }
18466
- else {
18467
- relatedIds.forEach(id => {
18468
- const rego = this.getEntityRego(id);
18469
- if (rego) {
18470
- this.styleTilesetFeature(rego);
18471
- }
18472
- });
18473
- }
18490
+ this.styleOrGatherIds(key, relatedIds);
18474
18491
  }
18475
18492
  }
18476
18493
  this.stylePendingEntityIds.clear();
@@ -18485,17 +18502,7 @@
18485
18502
  if (!relatedIds) {
18486
18503
  return;
18487
18504
  }
18488
- if (this.getTilesetFeatureNeedsFullData(entityTypeId)) {
18489
- this.entityGatherer.Queue(Array.from(relatedIds));
18490
- }
18491
- else {
18492
- relatedIds.forEach(id => {
18493
- const rego = this.getEntityRego(id);
18494
- if (rego) {
18495
- this.styleTilesetFeature(rego);
18496
- }
18497
- });
18498
- }
18505
+ this.styleOrGatherIds(entityTypeId, relatedIds);
18499
18506
  this.stylePendingEntityIds.delete(entityTypeId);
18500
18507
  }
18501
18508
  hasMappingRow(entityTypeId) {
@@ -18580,20 +18587,10 @@
18580
18587
  this.loadEntityTypeDefaultStyle(typeId);
18581
18588
  }
18582
18589
  if (this.styleMappingsLoaded.get(typeId) || (this.styleMappingLoaded && !this.hasMappingRow(typeId))) {
18583
- if (this.getTilesetFeatureNeedsFullData(typeId)) {
18584
- needsDataIds.push(rego.entityId);
18585
- }
18586
- else {
18587
- this.styleTilesetFeature(rego);
18588
- }
18590
+ this.styleOrCollect(rego, typeId, needsDataIds);
18589
18591
  }
18590
18592
  else if (!this.styleMappingsLoaded.has(typeId) && this.styleFallbackLoaded) {
18591
- if (this.getTilesetFeatureNeedsFullData(typeId)) {
18592
- needsDataIds.push(rego.entityId);
18593
- }
18594
- else {
18595
- this.styleTilesetFeature(rego);
18596
- }
18593
+ this.styleOrCollect(rego, typeId, needsDataIds);
18597
18594
  }
18598
18595
  else {
18599
18596
  if (!this.stylePendingEntityIds.has(typeId)) {
@@ -18606,6 +18603,96 @@
18606
18603
  this.entityGatherer.Queue(needsDataIds, highPriority);
18607
18604
  }
18608
18605
  }
18606
+ /**
18607
+ * Styles each Entity waiting on a type's style, gathering the records of those that need one.
18608
+ * @param entityTypeId
18609
+ * @param entityIds
18610
+ */
18611
+ styleOrGatherIds(entityTypeId, entityIds) {
18612
+ const gatherIds = [];
18613
+ for (const id of entityIds) {
18614
+ const rego = this.getEntityRego(id);
18615
+ if (rego) {
18616
+ this.styleOrCollect(rego, entityTypeId, gatherIds);
18617
+ }
18618
+ }
18619
+ if (gatherIds.length) {
18620
+ this.entityGatherer.Queue(gatherIds);
18621
+ }
18622
+ }
18623
+ /**
18624
+ * Styles a feature now when its style reads no record, or reads only values its tile carries, and otherwise collects it for gathering.
18625
+ * @param rego
18626
+ * @param entityTypeId
18627
+ * @param gatherIds Receives the Entity ID when its record is needed.
18628
+ */
18629
+ styleOrCollect(rego, entityTypeId, gatherIds) {
18630
+ if (!this.getTilesetFeatureNeedsFullData(entityTypeId)) {
18631
+ this.styleTilesetFeature(rego);
18632
+ return;
18633
+ }
18634
+ const record = this.canStyleFromBaked(rego.entityId, entityTypeId) ? this.readBakedRecord(rego.visual) : null;
18635
+ if (!record) {
18636
+ gatherIds.push(rego.entityId);
18637
+ return;
18638
+ }
18639
+ this.styleTilesetFeatureFullData(rego, record, []);
18640
+ // A later edit has to reach the record path, and the change feed finds Entities by Internal ID.
18641
+ if (rego.internalId != null) {
18642
+ this.styledByInternalId.set(rego.internalId, rego.entityId);
18643
+ }
18644
+ }
18645
+ /**
18646
+ * Returns if the tile's baked values hold everything this Entity's style would read from its record.
18647
+ * @param entityId
18648
+ * @param entityTypeId
18649
+ */
18650
+ canStyleFromBaked(entityId, entityTypeId) {
18651
+ var _a, _b, _c;
18652
+ // Baked values are the base record at generation time, which a scenario, a point in time or merged sources all differ from.
18653
+ if (!this.bakedAttributes.size || this.historic || !!this.scenario || this.expandSources) {
18654
+ return false;
18655
+ }
18656
+ if (this.bakedStaleIds.has(entityId) || ((_a = this.entityGatherer) === null || _a === void 0 ? void 0 : _a.HasEntityDataOverride(entityId))) {
18657
+ return false;
18658
+ }
18659
+ const paths = BModels.Calculator.GetFieldPaths((_c = (_b = this.getTilesetFeatureStyle(entityTypeId)) === null || _b === void 0 ? void 0 : _b.modelStyle) === null || _c === void 0 ? void 0 : _c.fillColor);
18660
+ return paths != null && paths.every(path => this.bakedAttributes.has(JSON.stringify(path)));
18661
+ }
18662
+ /**
18663
+ * Builds a stand-in record from a feature's baked values, holding only the attributes that have one.
18664
+ * Returns null when the feature's tile lacks a declared column, so the record is gathered instead.
18665
+ * @param visual
18666
+ */
18667
+ readBakedRecord(visual) {
18668
+ if (!(visual instanceof Cesium.Cesium3DTileFeature)) {
18669
+ return null;
18670
+ }
18671
+ const record = {};
18672
+ for (const baked of this.bakedAttributes.values()) {
18673
+ if (!visual.hasProperty(baked.property)) {
18674
+ return null;
18675
+ }
18676
+ let value = visual.getProperty(baked.property);
18677
+ if (value == null) {
18678
+ continue;
18679
+ }
18680
+ // Booleans travel as 0/1 because a boolean column has no way to say "no value".
18681
+ if (baked.type == "BOOLEAN") {
18682
+ value = value != 0;
18683
+ }
18684
+ let target = record;
18685
+ for (let i = 0; i < baked.path.length - 1; i++) {
18686
+ const segment = baked.path[i];
18687
+ if (target[segment] == null || typeof target[segment] != "object") {
18688
+ target[segment] = {};
18689
+ }
18690
+ target = target[segment];
18691
+ }
18692
+ target[baked.path[baked.path.length - 1]] = value;
18693
+ }
18694
+ return record;
18695
+ }
18609
18696
  styleTilesetFeature(rego) {
18610
18697
  this.styleTilesetFeatureFullData(rego, null, []);
18611
18698
  }
@@ -51083,7 +51170,7 @@ void main() {
51083
51170
  StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
51084
51171
  })(exports.StyleUtils || (exports.StyleUtils = {}));
51085
51172
 
51086
- const VERSION = "7.5.3";
51173
+ const VERSION = "7.5.4";
51087
51174
  /**
51088
51175
  * Updates the environment instance used by bruce-cesium to one specified.
51089
51176
  * This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.