bruce-cesium 7.2.0 → 7.2.2

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.
Files changed (43) hide show
  1. package/dist/bruce-cesium.es5.js +2237 -336
  2. package/dist/bruce-cesium.es5.js.map +1 -1
  3. package/dist/bruce-cesium.umd.js +2230 -333
  4. package/dist/bruce-cesium.umd.js.map +1 -1
  5. package/dist/lib/bruce-cesium.js +2 -1
  6. package/dist/lib/bruce-cesium.js.map +1 -1
  7. package/dist/lib/internal/image-utils.js +106 -1
  8. package/dist/lib/internal/image-utils.js.map +1 -1
  9. package/dist/lib/rendering/displaced-surface-primitive.js +41 -8
  10. package/dist/lib/rendering/displaced-surface-primitive.js.map +1 -1
  11. package/dist/lib/rendering/entity-render-engine-polygon.js +211 -13
  12. package/dist/lib/rendering/entity-render-engine-polygon.js.map +1 -1
  13. package/dist/lib/rendering/render-managers/common/historic-utils.js +471 -0
  14. package/dist/lib/rendering/render-managers/common/historic-utils.js.map +1 -0
  15. package/dist/lib/rendering/render-managers/entities/entities-ids-render-manager.js +14 -124
  16. package/dist/lib/rendering/render-managers/entities/entities-ids-render-manager.js.map +1 -1
  17. package/dist/lib/rendering/render-managers/entities/entities-render-manager.js +16 -13
  18. package/dist/lib/rendering/render-managers/entities/entities-render-manager.js.map +1 -1
  19. package/dist/lib/rendering/render-managers/tilesets/tileset-cad-render-manager.js +31 -109
  20. package/dist/lib/rendering/render-managers/tilesets/tileset-cad-render-manager.js.map +1 -1
  21. package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js +23 -7
  22. package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js.map +1 -1
  23. package/dist/lib/rendering/texture-frame-series-animator.js +621 -28
  24. package/dist/lib/rendering/texture-frame-series-animator.js.map +1 -1
  25. package/dist/lib/rendering/texture-value-labels.js +687 -0
  26. package/dist/lib/rendering/texture-value-labels.js.map +1 -0
  27. package/dist/lib/rendering/tileset-styler.js +28 -24
  28. package/dist/lib/rendering/tileset-styler.js.map +1 -1
  29. package/dist/lib/rendering/visuals-register.js +8 -3
  30. package/dist/lib/rendering/visuals-register.js.map +1 -1
  31. package/dist/types/bruce-cesium.d.ts +2 -1
  32. package/dist/types/internal/image-utils.d.ts +25 -0
  33. package/dist/types/rendering/displaced-surface-primitive.d.ts +5 -2
  34. package/dist/types/rendering/render-managers/common/historic-utils.d.ts +159 -0
  35. package/dist/types/rendering/render-managers/entities/entities-ids-render-manager.d.ts +1 -0
  36. package/dist/types/rendering/render-managers/entities/entities-render-manager.d.ts +5 -0
  37. package/dist/types/rendering/render-managers/tilesets/tileset-cad-render-manager.d.ts +1 -0
  38. package/dist/types/rendering/render-managers/tilesets/tileset-entities-render-manager.d.ts +2 -0
  39. package/dist/types/rendering/texture-frame-series-animator.d.ts +172 -1
  40. package/dist/types/rendering/texture-value-labels.d.ts +139 -0
  41. package/dist/types/rendering/tileset-styler.d.ts +2 -0
  42. package/dist/types/rendering/visuals-register.d.ts +1 -0
  43. package/package.json +2 -2
@@ -0,0 +1,471 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HistoricGatherer = exports.HistoricRangeCache = exports.HistoricFetchPlan = exports.HistoricFetchOrder = void 0;
4
+ const Cesium = require("cesium");
5
+ const bruce_models_1 = require("bruce-models");
6
+ const entity_utils_1 = require("../../../utils/entity-utils");
7
+ const view_utils_1 = require("../../../utils/view-utils");
8
+ /**
9
+ * How often a historic refresh is worth running, and which Entities it should ask about first.
10
+ *
11
+ * A handful of tracked vehicles can afford to re-read on almost every clock tick. Thousands of
12
+ * parcels cannot, and refreshing them that often was never buying anything since the answer barely
13
+ * changes between ticks.
14
+ */
15
+ var HistoricFetchOrder;
16
+ (function (HistoricFetchOrder) {
17
+ // The cadence for a set small enough that latency is what the user notices.
18
+ HistoricFetchOrder.MIN_INTERVAL_MS = 250;
19
+ // The cadence for a set large enough that the request itself is what the user notices.
20
+ HistoricFetchOrder.MAX_INTERVAL_MS = 10000;
21
+ // Below this many Entities the cadence stays at its fastest.
22
+ HistoricFetchOrder.SMALL_SET = 30;
23
+ // At and above this many it stays at its slowest.
24
+ HistoricFetchOrder.LARGE_SET = 5000;
25
+ /**
26
+ * Returns how long to wait between historic refreshes for a set of this size.
27
+ */
28
+ function IntervalFor(entityCount, minMs = HistoricFetchOrder.MIN_INTERVAL_MS, maxMs = HistoricFetchOrder.MAX_INTERVAL_MS) {
29
+ if (!(entityCount > HistoricFetchOrder.SMALL_SET)) {
30
+ return minMs;
31
+ }
32
+ if (entityCount >= HistoricFetchOrder.LARGE_SET) {
33
+ return maxMs;
34
+ }
35
+ // Log scaled, so going from 30 to 300 Entities costs more than going from 3000 to 5000.
36
+ const progress = Math.log(entityCount / HistoricFetchOrder.SMALL_SET) / Math.log(HistoricFetchOrder.LARGE_SET / HistoricFetchOrder.SMALL_SET);
37
+ return Math.round(minMs + ((maxMs - minMs) * progress));
38
+ }
39
+ HistoricFetchOrder.IntervalFor = IntervalFor;
40
+ /**
41
+ * Returns the Entities grouped into bands by distance from the camera, nearest band first.
42
+ *
43
+ * Bands rather than a true sort, so a small camera move does not reshuffle the whole queue and
44
+ * restart it. What the user is looking at resolves first either way.
45
+ */
46
+ function ByCameraDistance(params) {
47
+ var _a;
48
+ const { viewer, entities } = params;
49
+ const bands = params.bands || [500, 2000, 10000, 50000];
50
+ if (!(entities === null || entities === void 0 ? void 0 : entities.length)) {
51
+ return [];
52
+ }
53
+ const cameraPos = (_a = viewer === null || viewer === void 0 ? void 0 : viewer.camera) === null || _a === void 0 ? void 0 : _a.position;
54
+ if (!cameraPos) {
55
+ return [entities];
56
+ }
57
+ // One band past the named bounds, for everything beyond the last of them.
58
+ const banded = bands.map(() => []).concat([[]]);
59
+ for (const entity of entities) {
60
+ const pos = SafePos(entity, viewer);
61
+ if (!pos) {
62
+ banded[banded.length - 1].push(entity);
63
+ continue;
64
+ }
65
+ const distance = Cesium.Cartesian3.distance(cameraPos, pos);
66
+ let index = bands.findIndex(bound => distance <= bound);
67
+ if (index < 0) {
68
+ index = banded.length - 1;
69
+ }
70
+ banded[index].push(entity);
71
+ }
72
+ return banded.filter(band => band.length > 0);
73
+ }
74
+ HistoricFetchOrder.ByCameraDistance = ByCameraDistance;
75
+ /*
76
+ * Returns an Entity's world position, or null when it has none to place it by.
77
+ */
78
+ function SafePos(entity, viewer) {
79
+ try {
80
+ const pos = entity_utils_1.EntityUtils.GetPos({
81
+ entity: entity,
82
+ viewer: viewer,
83
+ allowRendered: true
84
+ });
85
+ if (!pos || isNaN(pos.x) || isNaN(pos.y) || isNaN(pos.z)) {
86
+ return null;
87
+ }
88
+ return pos;
89
+ }
90
+ catch {
91
+ return null;
92
+ }
93
+ }
94
+ })(HistoricFetchOrder = exports.HistoricFetchOrder || (exports.HistoricFetchOrder = {}));
95
+ /**
96
+ * Decides what slice of history is worth fetching for the clock as it is currently moving.
97
+ */
98
+ var HistoricFetchPlan;
99
+ (function (HistoricFetchPlan) {
100
+ // How many seconds of playback the detail window tries to stay ahead by.
101
+ HistoricFetchPlan.DEFAULT_LEAD_SECONDS = 10;
102
+ // The detail window never shrinks below this, so a paused clock still has something around it.
103
+ HistoricFetchPlan.DEFAULT_MIN_DETAIL_MS = 60 * 1000;
104
+ // Nor grows past it, which is what stops a fast scrub asking for the whole archive.
105
+ HistoricFetchPlan.DEFAULT_MAX_DETAIL_MS = 6 * 60 * 60 * 1000;
106
+ // Records the coarse pass may spend describing the whole range.
107
+ HistoricFetchPlan.DEFAULT_SAMPLE = 200;
108
+ /*
109
+ * Returns how wide the detail window should be for the rate the clock is moving at.
110
+ */
111
+ function DetailSpanFor(trajectory, leadSeconds, minMs, maxMs) {
112
+ const rate = Math.abs((trajectory === null || trajectory === void 0 ? void 0 : trajectory.ratePerSecondMs) || 0);
113
+ const span = rate * leadSeconds;
114
+ if (!(span > minMs)) {
115
+ return minMs;
116
+ }
117
+ return Math.min(span, maxMs);
118
+ }
119
+ HistoricFetchPlan.DetailSpanFor = DetailSpanFor;
120
+ /**
121
+ * Returns the detail window and the coarse pass for the clock as it stands.
122
+ */
123
+ function Plan(params) {
124
+ var _a;
125
+ const { currentTime, windowStart, windowStop, trajectory, leadSeconds = HistoricFetchPlan.DEFAULT_LEAD_SECONDS, minDetailMs = HistoricFetchPlan.DEFAULT_MIN_DETAIL_MS, maxDetailMs = HistoricFetchPlan.DEFAULT_MAX_DETAIL_MS, sample = HistoricFetchPlan.DEFAULT_SAMPLE } = params;
126
+ if (!(windowStop > windowStart)) {
127
+ return { detail: null, coarse: null };
128
+ }
129
+ // A range that fits the detail budget has nothing worth sampling: reading it whole is both
130
+ // cheaper than two requests and better than an approximation of it.
131
+ if ((windowStop - windowStart) <= maxDetailMs) {
132
+ return { detail: { start: windowStart, stop: windowStop }, coarse: null };
133
+ }
134
+ const span = DetailSpanFor(trajectory, leadSeconds, minDetailMs, maxDetailMs);
135
+ const direction = (_a = trajectory === null || trajectory === void 0 ? void 0 : trajectory.direction) !== null && _a !== void 0 ? _a : 0;
136
+ // Time running forward only ever reveals what is ahead, so the window leads rather than centres.
137
+ // A little is still kept behind so a record just passed can still be interpolated from.
138
+ const behind = direction === 0 ? span / 2 : span * 0.2;
139
+ const ahead = direction === 0 ? span / 2 : span * 0.8;
140
+ let start = direction < 0 ? currentTime - ahead : currentTime - behind;
141
+ let stop = direction < 0 ? currentTime + behind : currentTime + ahead;
142
+ start = Math.max(windowStart, start);
143
+ stop = Math.min(windowStop, stop);
144
+ if (!(stop > start)) {
145
+ return { detail: null, coarse: { start: windowStart, stop: windowStop, sample } };
146
+ }
147
+ const detail = { start, stop };
148
+ // Nothing to be coarse about once the detail window is the whole range.
149
+ if (start <= windowStart && stop >= windowStop) {
150
+ return { detail, coarse: null };
151
+ }
152
+ return { detail, coarse: { start: windowStart, stop: windowStop, sample } };
153
+ }
154
+ HistoricFetchPlan.Plan = Plan;
155
+ /**
156
+ * Tracks which way the clock is moving and how fast, from the times it is observed at.
157
+ * Playback and a user dragging the timeline both look the same here, which is the point.
158
+ */
159
+ class TrajectoryTracker {
160
+ // Smooths the rate so one slow frame does not collapse the window.
161
+ constructor(smoothing = 0.4) {
162
+ this.smoothing = smoothing;
163
+ this.lastTime = null;
164
+ this.lastObservedAt = null;
165
+ this.direction = 0;
166
+ this.ratePerSecondMs = 0;
167
+ }
168
+ /**
169
+ * Records where the clock is now. observedAt is the wall clock, in milliseconds.
170
+ */
171
+ Observe(sceneTime, observedAt) {
172
+ if (this.lastTime == null) {
173
+ this.lastTime = sceneTime;
174
+ this.lastObservedAt = observedAt;
175
+ return;
176
+ }
177
+ const elapsed = observedAt - this.lastObservedAt;
178
+ const moved = sceneTime - this.lastTime;
179
+ this.lastTime = sceneTime;
180
+ this.lastObservedAt = observedAt;
181
+ if (!(elapsed > 0)) {
182
+ return;
183
+ }
184
+ if (moved === 0) {
185
+ this.direction = 0;
186
+ this.ratePerSecondMs = 0;
187
+ return;
188
+ }
189
+ this.direction = moved > 0 ? 1 : -1;
190
+ const rate = Math.abs(moved) / (elapsed / 1000);
191
+ this.ratePerSecondMs = this.ratePerSecondMs === 0
192
+ ? rate
193
+ : (this.ratePerSecondMs * (1 - this.smoothing)) + (rate * this.smoothing);
194
+ }
195
+ Get() {
196
+ return { direction: this.direction, ratePerSecondMs: this.ratePerSecondMs };
197
+ }
198
+ Reset() {
199
+ this.lastTime = null;
200
+ this.lastObservedAt = null;
201
+ this.direction = 0;
202
+ this.ratePerSecondMs = 0;
203
+ }
204
+ }
205
+ HistoricFetchPlan.TrajectoryTracker = TrajectoryTracker;
206
+ })(HistoricFetchPlan = exports.HistoricFetchPlan || (exports.HistoricFetchPlan = {}));
207
+ /**
208
+ * Tracks which time ranges of historic data have already been requested, and the records they
209
+ * returned, so moving the clock only fetches the part that is genuinely new.
210
+ *
211
+ * Coverage is tracked by the ranges that were asked for, not by the timestamps that came back. A
212
+ * window holding no records is still covered, otherwise an empty stretch is re-requested forever.
213
+ */
214
+ class HistoricRangeCache {
215
+ // Ranges this far apart are treated as one, so a scrub does not leave a trail of slivers.
216
+ constructor(mergeToleranceMs = 60000) {
217
+ this.mergeToleranceMs = mergeToleranceMs;
218
+ // Requested ranges, kept sorted and non-overlapping.
219
+ this.held = [];
220
+ // Ranges covered only by a sampled read, which describe their span without holding every record.
221
+ this.heldCoarse = [];
222
+ this.records = {};
223
+ }
224
+ /**
225
+ * Returns the parts of the window that have not been requested yet.
226
+ */
227
+ MissingRanges(start, stop) {
228
+ if (!(stop > start)) {
229
+ return [];
230
+ }
231
+ const missing = [];
232
+ let cursor = start;
233
+ for (const range of this.held) {
234
+ if (range.stop <= cursor) {
235
+ continue;
236
+ }
237
+ if (range.start >= stop) {
238
+ break;
239
+ }
240
+ if (range.start > cursor) {
241
+ missing.push({ start: cursor, stop: Math.min(range.start, stop) });
242
+ }
243
+ cursor = Math.max(cursor, range.stop);
244
+ if (cursor >= stop) {
245
+ break;
246
+ }
247
+ }
248
+ if (cursor < stop) {
249
+ missing.push({ start: cursor, stop: stop });
250
+ }
251
+ return this.mergeAdjacent(missing);
252
+ }
253
+ /**
254
+ * Marks a range as requested and merges the records it returned into what is already held.
255
+ */
256
+ Absorb(start, stop, recordsByIds, coarse = false) {
257
+ if (stop > start) {
258
+ if (coarse) {
259
+ this.heldCoarse = this.mergeAdjacent([...this.heldCoarse, { start, stop }].sort((a, b) => a.start - b.start));
260
+ }
261
+ else {
262
+ this.held = this.mergeAdjacent([...this.held, { start, stop }].sort((a, b) => a.start - b.start));
263
+ }
264
+ }
265
+ if (!recordsByIds) {
266
+ return;
267
+ }
268
+ for (const entityId of Object.keys(recordsByIds)) {
269
+ const incoming = recordsByIds[entityId] || [];
270
+ const current = this.records[entityId] || [];
271
+ // Keyed by instant so a range fetched twice cannot double up its records.
272
+ const byInstant = new Map();
273
+ for (const record of current) {
274
+ byInstant.set(new Date(record.dateTime).getTime(), record);
275
+ }
276
+ for (const record of incoming) {
277
+ byInstant.set(new Date(record.dateTime).getTime(), record);
278
+ }
279
+ this.records[entityId] = Array.from(byInstant.values())
280
+ .sort((a, b) => new Date(a.dateTime).getTime() - new Date(b.dateTime).getTime());
281
+ }
282
+ }
283
+ GetRecords() {
284
+ return this.records;
285
+ }
286
+ /**
287
+ * Returns whether the window is already covered in full.
288
+ */
289
+ Covers(start, stop) {
290
+ return this.MissingRanges(start, stop).length === 0;
291
+ }
292
+ /**
293
+ * Returns whether a sampled pass already describes the window.
294
+ */
295
+ CoversCoarse(start, stop) {
296
+ if (!(stop > start)) {
297
+ return true;
298
+ }
299
+ return this.heldCoarse.some(range => range.start <= start && range.stop >= stop);
300
+ }
301
+ Clear() {
302
+ this.held = [];
303
+ this.heldCoarse = [];
304
+ this.records = {};
305
+ }
306
+ mergeAdjacent(ranges) {
307
+ if (ranges.length <= 1) {
308
+ return ranges;
309
+ }
310
+ const sorted = [...ranges].sort((a, b) => a.start - b.start);
311
+ const merged = [];
312
+ let current = { ...sorted[0] };
313
+ for (let i = 1; i < sorted.length; i++) {
314
+ const next = sorted[i];
315
+ if (next.start - current.stop <= this.mergeToleranceMs) {
316
+ current.stop = Math.max(current.stop, next.stop);
317
+ }
318
+ else {
319
+ merged.push(current);
320
+ current = { ...next };
321
+ }
322
+ }
323
+ merged.push(current);
324
+ return merged;
325
+ }
326
+ }
327
+ exports.HistoricRangeCache = HistoricRangeCache;
328
+ /**
329
+ * Pulls historic records for the visible clock range: what to ask for, in what order, and what has
330
+ * already been asked for.
331
+ */
332
+ class HistoricGatherer {
333
+ constructor(params) {
334
+ this.params = params;
335
+ this.trajectory = new HistoricFetchPlan.TrajectoryTracker();
336
+ // Range key to the request in flight for it, so the same range is never asked for twice at once.
337
+ this.inFlight = new Map();
338
+ this.disposed = false;
339
+ this.cache = new HistoricRangeCache();
340
+ }
341
+ get Records() {
342
+ return this.cache.GetRecords();
343
+ }
344
+ Clear() {
345
+ this.cache.Clear();
346
+ this.trajectory.Reset();
347
+ this.inFlight.clear();
348
+ }
349
+ Dispose() {
350
+ this.disposed = true;
351
+ this.Clear();
352
+ }
353
+ /**
354
+ * Returns how long to wait between refreshes for a set of this size.
355
+ */
356
+ IntervalFor(entityCount) {
357
+ return HistoricFetchOrder.IntervalFor(entityCount);
358
+ }
359
+ /**
360
+ * Fetches whatever the current clock range needs that is not already held.
361
+ * Returns whether anything was requested, alongside every record held for these Entities.
362
+ */
363
+ async Gather(entities) {
364
+ var _a;
365
+ if (this.disposed || !(entities === null || entities === void 0 ? void 0 : entities.length)) {
366
+ return { fetched: false, recordsByIds: this.cache.GetRecords() };
367
+ }
368
+ const { viewer } = this.params;
369
+ const windowStart = new Date(viewer.clock.startTime.toString()).getTime();
370
+ const windowStop = new Date(viewer.clock.stopTime.toString()).getTime();
371
+ const currentTime = new Date(viewer.clock.currentTime.toString()).getTime();
372
+ this.trajectory.Observe(currentTime, Date.now());
373
+ const liveEdge = view_utils_1.ViewUtils.GetTimeDetails({ viewer }).isLive ? currentTime : null;
374
+ const liveTail = (_a = this.params.liveTailMs) !== null && _a !== void 0 ? _a : HistoricGatherer.LIVE_TAIL_MS;
375
+ const plan = HistoricFetchPlan.Plan({
376
+ currentTime,
377
+ windowStart,
378
+ windowStop,
379
+ trajectory: this.trajectory.Get(),
380
+ sample: this.params.sample
381
+ });
382
+ let fetched = false;
383
+ if (plan.coarse && !this.cache.CoversCoarse(plan.coarse.start, plan.coarse.stop)) {
384
+ const records = await this.request(plan.coarse.start, plan.coarse.stop, entities, plan.coarse.sample);
385
+ if (this.disposed) {
386
+ return { fetched, recordsByIds: this.cache.GetRecords() };
387
+ }
388
+ this.cache.Absorb(plan.coarse.start, this.holdTo(plan.coarse.stop, liveEdge, liveTail), records, true);
389
+ fetched = true;
390
+ }
391
+ if (plan.detail) {
392
+ const bands = entities.length > HistoricFetchOrder.SMALL_SET
393
+ ? HistoricFetchOrder.ByCameraDistance({ viewer, entities })
394
+ : [entities];
395
+ for (const range of this.cache.MissingRanges(plan.detail.start, plan.detail.stop)) {
396
+ if (this.disposed) {
397
+ break;
398
+ }
399
+ for (const band of bands) {
400
+ if (this.disposed) {
401
+ break;
402
+ }
403
+ const records = await this.request(range.start, range.stop, band, 0);
404
+ if (this.disposed) {
405
+ break;
406
+ }
407
+ // Records land as each band arrives, while the range is only marked held once
408
+ // every band has been asked for.
409
+ this.cache.Absorb(0, 0, records);
410
+ fetched = true;
411
+ }
412
+ if (this.disposed) {
413
+ break;
414
+ }
415
+ const heldTo = this.holdTo(range.stop, liveEdge, liveTail);
416
+ if (heldTo > range.start) {
417
+ this.cache.Absorb(range.start, heldTo, {});
418
+ }
419
+ }
420
+ }
421
+ return { fetched, recordsByIds: this.cache.GetRecords() };
422
+ }
423
+ /*
424
+ * Returns how much of a range that was just read may be marked as held.
425
+ */
426
+ holdTo(stop, liveEdge, liveTailMs) {
427
+ if (liveEdge == null) {
428
+ return stop;
429
+ }
430
+ return Math.min(stop, liveEdge - liveTailMs);
431
+ }
432
+ /*
433
+ * Reads one range, joining a request already in flight for it rather than repeating it.
434
+ */
435
+ request(start, stop, entities, sample) {
436
+ var _a;
437
+ const padding = (_a = this.params.paddingMs) !== null && _a !== void 0 ? _a : 0;
438
+ const dateTimeFrom = new Date(start - padding).toISOString();
439
+ const dateTimeTo = new Date(stop + padding).toISOString();
440
+ const entityIds = entities.map(x => { var _a; return (_a = x.Bruce) === null || _a === void 0 ? void 0 : _a.ID; }).filter(x => !!x);
441
+ const key = `${dateTimeFrom}|${dateTimeTo}|${sample}|${entityIds.join(",")}`;
442
+ const existing = this.inFlight.get(key);
443
+ if (existing) {
444
+ return existing;
445
+ }
446
+ const prom = bruce_models_1.EntityHistoricData.GetRecordsByEntity({
447
+ attrKey: this.params.getAttrKey(),
448
+ dateTimeFrom,
449
+ dateTimeTo,
450
+ entityIds,
451
+ sample: sample > 0 ? sample : undefined,
452
+ api: this.params.getApi()
453
+ }).then((res) => {
454
+ const records = res.recordsByIds || {};
455
+ if (!this.disposed && this.params.onRecords) {
456
+ this.params.onRecords(records);
457
+ }
458
+ return records;
459
+ }).finally(() => {
460
+ this.inFlight.delete(key);
461
+ });
462
+ this.inFlight.set(key, prom);
463
+ return prom;
464
+ }
465
+ }
466
+ // How far back from the live edge is left unheld, so a record written moments ago still falls in
467
+ // something that gets asked for again. It has to outlast a write, a commit and a refresh, plus
468
+ // whatever the writer's clock and this one disagree by.
469
+ HistoricGatherer.LIVE_TAIL_MS = 15000;
470
+ exports.HistoricGatherer = HistoricGatherer;
471
+ //# sourceMappingURL=historic-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"historic-utils.js","sourceRoot":"","sources":["../../../../../src/rendering/render-managers/common/historic-utils.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ const bruce_models_1 = require("bruce-models");
5
5
  const Cesium = require("cesium");
6
6
  const entity_render_engine_1 = require("../../entity-render-engine");
7
7
  const visuals_register_1 = require("../../visuals-register");
8
+ const historic_utils_1 = require("../common/historic-utils");
8
9
  const point_clustering_1 = require("../common/point-clustering");
9
10
  const entity_rerender_maintain_state_1 = require("../common/entity-rerender-maintain-state");
10
11
  const batched_data_getter_1 = require("../../getters/batched-data-getter");
@@ -50,6 +51,13 @@ var EntitiesIdsRenderManager;
50
51
  this.monitor = monitor;
51
52
  this.item = item;
52
53
  this.visualsManager = visualsManager;
54
+ this.historicGatherer = new historic_utils_1.HistoricGatherer({
55
+ viewer: this.viewer,
56
+ getApi: () => this.apiGetter.getApi(),
57
+ getAttrKey: () => { var _a; return (_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historicAttrKey; },
58
+ // Padding either side of a requested range, for clock desync between us and the server.
59
+ paddingMs: 15000
60
+ });
53
61
  if (this.item.enableClustering) {
54
62
  this.clustering = new point_clustering_1.PointClustering(visualsManager, this.item.id, (_a = this.item) === null || _a === void 0 ? void 0 : _a.clustering);
55
63
  }
@@ -399,140 +407,22 @@ var EntitiesIdsRenderManager;
399
407
  * @param entities
400
408
  */
401
409
  async getHistoricInfo(entities) {
402
- // Time padding in milliseconds (15 seconds).
403
- // Helps account for desync between client and server.
404
- const TIME_PADDING_MS = 15000;
405
- const minDateTimeStr = this.viewer.clock.startTime.toString();
406
- const maxDateTimeStr = this.viewer.clock.stopTime.toString();
407
- const minDateTime = new Date(minDateTimeStr).getTime();
408
- const maxDateTime = new Date(maxDateTimeStr).getTime();
409
- const tDetails = view_utils_1.ViewUtils.GetTimeDetails({
410
- viewer: this.viewer,
411
- });
412
- const isLive = tDetails.isLive;
413
- let rangesToRequest = [{
414
- start: minDateTime,
415
- stop: maxDateTime
416
- }];
417
- // If we already have cached data, determine what ranges we're missing.
418
- if (Object.keys(this.entitiesHistoric).length >= entities.length) {
419
- let foundMinDateTime = null;
420
- let foundMaxDateTime = null;
421
- // Find the min/max based on cached data.
422
- // Since we set the values sorted, we only have to check the first and last records for each entity.
423
- for (const entityId of Object.keys(this.entitiesHistoric)) {
424
- const records = this.entitiesHistoric[entityId] || [];
425
- if (records.length) {
426
- const dateTime = new Date(records[0].dateTime).getTime();
427
- if (foundMinDateTime == null || dateTime < foundMinDateTime) {
428
- foundMinDateTime = dateTime;
429
- }
430
- const dateTime2 = new Date(records[records.length - 1].dateTime).getTime();
431
- if (foundMaxDateTime == null || dateTime2 > foundMaxDateTime) {
432
- foundMaxDateTime = dateTime2;
433
- }
434
- }
435
- }
436
- // Complete overlap - we already have all the data.
437
- if (foundMinDateTime != null && foundMaxDateTime != null && foundMinDateTime <= minDateTime && foundMaxDateTime >= maxDateTime) {
438
- return [false, this.entitiesHistoric];
439
- }
440
- // Calculate missing ranges.
441
- rangesToRequest = [];
442
- // Check if we need data before our cached range.
443
- if (foundMinDateTime != null && foundMinDateTime > minDateTime) {
444
- // When live we focus on getting the next range rather than old data.
445
- // Ends up being one less request to perform every second.
446
- if (!isLive || foundMinDateTime == null) {
447
- rangesToRequest.push({
448
- start: minDateTime,
449
- stop: new Date(foundMinDateTime).getTime()
450
- });
451
- }
452
- }
453
- // Check if we need data after our cached range.
454
- if (foundMaxDateTime != null && foundMaxDateTime < maxDateTime) {
455
- rangesToRequest.push({
456
- start: new Date(foundMaxDateTime).getTime(),
457
- stop: maxDateTime
458
- });
459
- }
460
- // If the ranges to request are within a tolerance, combine them.
461
- if (rangesToRequest.length > 1) {
462
- const TOLERANCE_MS = 60000; // 1 minute.
463
- const mergedRanges = [];
464
- let currentRange = rangesToRequest[0];
465
- for (let i = 1; i < rangesToRequest.length; i++) {
466
- const nextRange = rangesToRequest[i];
467
- if (nextRange.start - currentRange.stop <= TOLERANCE_MS) {
468
- currentRange.stop = nextRange.stop;
469
- }
470
- else {
471
- mergedRanges.push(currentRange);
472
- currentRange = nextRange;
473
- }
474
- }
475
- }
476
- }
477
- const entityIds = entities.map(x => x.Bruce.ID);
478
- const combined = { ...this.entitiesHistoric };
479
- // Make requests for each missing range
480
- for (const range of rangesToRequest) {
481
- if (this.disposed) {
482
- break;
483
- }
484
- const start = new Date(range.start - TIME_PADDING_MS);
485
- const stop = new Date(range.stop + TIME_PADDING_MS);
486
- const historicData = await bruce_models_1.EntityHistoricData.GetList({
487
- attrKey: this.item.BruceEntity.historicAttrKey,
488
- dateTimeFrom: start.toISOString(),
489
- dateTimeTo: stop.toISOString(),
490
- entityIds: entityIds,
491
- api: this.apiGetter.getApi()
492
- });
493
- if (this.disposed) {
494
- break;
495
- }
496
- // Merge the new data with existing data
497
- const records = historicData.recordsByIds;
498
- const recordsIds = Object.keys(records);
499
- for (let i = 0; i < recordsIds.length; i++) {
500
- const entityId = recordsIds[i];
501
- const latest = records[entityId] || [];
502
- const current = combined[entityId] || [];
503
- // Use a Map to de-duplicate by timestamp.
504
- const tmp = new Map();
505
- for (let j = 0; j < current.length; j++) {
506
- const record = current[j];
507
- const dateTime = new Date(record.dateTime).getTime();
508
- tmp.set(dateTime, record);
509
- }
510
- for (let j = 0; j < latest.length; j++) {
511
- const record = latest[j];
512
- const dateTime = new Date(record.dateTime).getTime();
513
- tmp.set(dateTime, record);
514
- }
515
- // Convert to array and sort by date.
516
- const sorted = Array.from(tmp.values()).sort((a, b) => {
517
- return new Date(a.dateTime).getTime() - new Date(b.dateTime).getTime();
518
- });
519
- combined[entityId] = sorted;
520
- }
521
- }
410
+ const { fetched, recordsByIds } = await this.historicGatherer.Gather(entities);
522
411
  if (!this.disposed) {
523
- this.entitiesHistoric = combined;
412
+ this.entitiesHistoric = recordsByIds;
524
413
  }
525
- return [rangesToRequest.length > 0, combined];
414
+ return [fetched, recordsByIds];
526
415
  }
527
416
  viewerDateTimeSub() {
528
417
  var _a, _b;
529
418
  if ((!((_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historic) && !((_b = this.item.BruceEntity) === null || _b === void 0 ? void 0 : _b.historicAttrKey)) || this.viewerDateTimeChangeRemoval) {
530
419
  return;
531
420
  }
532
- const THROTTLE_INTERVAL = 2000;
421
+ // Scaled by how many Entities are on screen rather than fixed, since the cost of a refresh
422
+ // is the set size and a large set barely changes between ticks anyway.
533
423
  let queue = new bruce_models_1.DelayQueue(() => {
534
424
  this.onGetterUpdate(Object.keys(this.renderedEntities));
535
- }, THROTTLE_INTERVAL, true);
425
+ }, this.historicGatherer.IntervalFor(Object.keys(this.renderedEntities).length), true);
536
426
  let clockTickRemoval;
537
427
  let prevTick = this.viewer.clock.currentTime.toString();
538
428
  clockTickRemoval = this.viewer.clock.onTick.addEventListener(() => {