mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 07:42:23 +00:00
Fix scrubs to live on long tracks, fire ages in a past window, and gaps between hourly cloud frames
- World timeline: a scrub counts as at now within a share of the track (0.5%), now held to at most two minutes. A layer whose source covers years made the window weeks wide, so most of the last month snapped to live. Short tracks keep their window. - Fires: card and detail ages count back from the end of the 24 hours the layer shows when its snapshot ends at a set time, and from now only when it runs to now. A window that ended months ago read "new 105d" on fires three hours old at the time shown. - Weather: a product's max gap and the delay after which its latest frame reads late are at least one and a half of its feed's median frame spacing (over its latest frames). A regional cloud feed with frames an hour apart drew nothing for the second half of every hour while scrubbing and read late after twenty minutes; feeds with frames minutes apart keep their gaps.
This commit is contained in:
1 parent
7451c9b372
commit
5d733eb07b
12 files changed
+327
-15
No files matched your search
@@ -4,6 +4,52 @@ export const RADAR_MAX_GAP_MS = 30 * 60_000;
|
||||
export const REGIONAL_INFRARED_MAX_GAP_MS = 30 * 60_000;
|
||||
export const GLOBAL_INFRARED_MAX_GAP_MS = 3 * 60 * 60_000;
|
||||
export const LIGHTNING_MAX_GAP_MS = 30 * 60_000;
|
||||
/** How many of a feed's latest frames say how far apart its frames come. */
|
||||
const SPACING_FRAMES = 12;
|
||||
/** A frame holds this many of its feed's frame spacings before it lapses. */
|
||||
const SPACING_SLACK = 1.5;
|
||||
|
||||
/**
|
||||
* How far apart a feed's frames come: the median spacing of its latest
|
||||
* frames, in ms, or null with fewer than two. Takes UTC times or epoch ms.
|
||||
* @param {Array<string|number>} times
|
||||
* @returns {number|null}
|
||||
*/
|
||||
export function frameSpacingMs(times) {
|
||||
const at = [
|
||||
...new Set(
|
||||
(times ?? [])
|
||||
.map((time) => (typeof time === 'number' ? time : Date.parse(time)))
|
||||
.filter(Number.isFinite),
|
||||
),
|
||||
]
|
||||
.sort((a, b) => a - b)
|
||||
.slice(-(SPACING_FRAMES + 1));
|
||||
if (at.length < 2) return null;
|
||||
const gaps = at
|
||||
.slice(1)
|
||||
.map((time, i) => time - at[i])
|
||||
.sort((a, b) => a - b);
|
||||
const middle = gaps.length >> 1;
|
||||
return gaps.length % 2 ? gaps[middle] : (gaps[middle - 1] + gaps[middle]) / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* A product's least time, `leastMs`, held to its feed's own frame spacing:
|
||||
* never less than one and a half spacings, so a feed whose frames come an
|
||||
* hour apart covers the whole hour between them, while one with frames
|
||||
* minutes apart keeps `leastMs`.
|
||||
* @param {number} leastMs
|
||||
* @param {Array<string|number>} times
|
||||
* @returns {number}
|
||||
*/
|
||||
export function atLeastFrameSpacing(leastMs, times) {
|
||||
const spacing = frameSpacingMs(times);
|
||||
return spacing === null
|
||||
? leastMs
|
||||
: Math.max(leastMs, spacing * SPACING_SLACK);
|
||||
}
|
||||
|
||||
/** The longest play waits on a frame before it goes on without it. */
|
||||
export const PLAY_WAIT_MS = 8_000;
|
||||
// Playing on its own, the world does not wait on the frame it is at: that
|
||||
|
||||
Reference in new issue
Block a user