mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
fix: cancel Nepal media preloads and respect drawing ownership
Retain active-flight preloading while canceling hidden frames and pending Facebook sessions on stop, disable, and replacement. Add lifecycle and pointer-ownership regression coverage. Apply the runtime formatting adopted on main and keep the existing source-shape check insensitive to that formatting.
This commit is contained in:
1 parent
1a936ebac1
commit
a9482f0a5b
15 files changed
+3584
-1803
No files matched your search
@@ -1,26 +1,40 @@
|
||||
import { BHOTE_KOSHI_FLOOD_PATH } from './bhoteKoshiFloodPath.js';
|
||||
|
||||
export const SOURCE_PATH_BEAT_IDS = Object.freeze([
|
||||
'debris-dammed-lake', 'second-landslide', 'dhunche',
|
||||
'mailung-upper-trishuli', 'mailung-bazzar', 'dandagaun',
|
||||
'dandagaun-viewpoint', 'betrawati-bazaar', 'bhainse', 'bidur-trishuli-bridge',
|
||||
'debris-dammed-lake',
|
||||
'second-landslide',
|
||||
'dhunche',
|
||||
'mailung-upper-trishuli',
|
||||
'mailung-bazzar',
|
||||
'dandagaun',
|
||||
'dandagaun-viewpoint',
|
||||
'betrawati-bazaar',
|
||||
'bhainse',
|
||||
'bidur-trishuli-bridge',
|
||||
]);
|
||||
|
||||
function nearestVertex(point, route) {
|
||||
if (!point || !Number.isFinite(point.lon) || !Number.isFinite(point.lat)) return -1;
|
||||
const longitudeScale = Math.cos(point.lat * Math.PI / 180);
|
||||
if (!point || !Number.isFinite(point.lon) || !Number.isFinite(point.lat))
|
||||
return -1;
|
||||
const longitudeScale = Math.cos((point.lat * Math.PI) / 180);
|
||||
let nearest = -1;
|
||||
let distance = 1000; // Witness viewpoints can sit beside the river, not on it.
|
||||
route.forEach(([lon, lat], index) => {
|
||||
const metres = Math.hypot((lon - point.lon) * longitudeScale, lat - point.lat) * 111195;
|
||||
if (metres < distance) { distance = metres; nearest = index; }
|
||||
const metres =
|
||||
Math.hypot((lon - point.lon) * longitudeScale, lat - point.lat) * 111195;
|
||||
if (metres < distance) {
|
||||
distance = metres;
|
||||
nearest = index;
|
||||
}
|
||||
});
|
||||
return nearest;
|
||||
}
|
||||
|
||||
/** Split the already-bundled GeoPera centreline; never connect witness pins. */
|
||||
export function buildSourceShotPaths(event, route = BHOTE_KOSHI_FLOOD_PATH) {
|
||||
const observations = new Map((event.evidenceSpine || []).map((point) => [point.id, point]));
|
||||
const observations = new Map(
|
||||
(event.evidenceSpine || []).map((point) => [point.id, point]),
|
||||
);
|
||||
const result = new Map();
|
||||
const add = (id, from, to, { joinComparison = false } = {}) => {
|
||||
let start = nearestVertex(from, route);
|
||||
@@ -36,24 +50,42 @@ export function buildSourceShotPaths(event, route = BHOTE_KOSHI_FLOOD_PATH) {
|
||||
// downstream of it, rather than replaying the upstream half-segment.
|
||||
const [lon, lat] = route[start];
|
||||
const [nextLon, nextLat] = route[start + 1];
|
||||
const scale = Math.cos(from.lat * Math.PI / 180);
|
||||
const along = (from.lon - lon) * (nextLon - lon) * scale * scale
|
||||
+ (from.lat - lat) * (nextLat - lat);
|
||||
const scale = Math.cos((from.lat * Math.PI) / 180);
|
||||
const along =
|
||||
(from.lon - lon) * (nextLon - lon) * scale * scale +
|
||||
(from.lat - lat) * (nextLat - lat);
|
||||
if (along > 0) start++;
|
||||
}
|
||||
const coordinates = route.slice(start, end + 1);
|
||||
if (joinComparison && (coordinates[0][0] !== from.lon || coordinates[0][1] !== from.lat)) {
|
||||
if (
|
||||
joinComparison &&
|
||||
(coordinates[0][0] !== from.lon || coordinates[0][1] !== from.lat)
|
||||
) {
|
||||
coordinates.unshift([from.lon, from.lat]);
|
||||
}
|
||||
result.set(id, coordinates.map(([lon, lat], index) => ({
|
||||
lon, lat,
|
||||
// Stable source profile for explicit source-elevation shots; otherwise a
|
||||
// fallback when neither rendered mesh nor elevation terrain can be sampled.
|
||||
fallbackElevationM: startHeight + (endHeight - startHeight) * index / (coordinates.length - 1),
|
||||
})));
|
||||
result.set(
|
||||
id,
|
||||
coordinates.map(([lon, lat], index) => ({
|
||||
lon,
|
||||
lat,
|
||||
// Stable source profile for explicit source-elevation shots; otherwise a
|
||||
// fallback when neither rendered mesh nor elevation terrain can be sampled.
|
||||
fallbackElevationM:
|
||||
startHeight +
|
||||
((endHeight - startHeight) * index) / (coordinates.length - 1),
|
||||
})),
|
||||
);
|
||||
};
|
||||
add('debris-dammed-lake', observations.get('debris-dammed-lake'), observations.get('second-landslide'));
|
||||
add('second-landslide', observations.get('second-landslide'), observations.get('gyirong-border-gate'));
|
||||
add(
|
||||
'debris-dammed-lake',
|
||||
observations.get('debris-dammed-lake'),
|
||||
observations.get('second-landslide'),
|
||||
);
|
||||
add(
|
||||
'second-landslide',
|
||||
observations.get('second-landslide'),
|
||||
observations.get('gyirong-border-gate'),
|
||||
);
|
||||
let previous = event.reconstruction?.corridor?.at(-1);
|
||||
for (const id of SOURCE_PATH_BEAT_IDS.slice(2)) {
|
||||
const point = observations.get(id);
|
||||
|
||||
Reference in new issue
Block a user