fix bounding box in tracking mode

This commit is contained in:
Anatoly Antonov 2026-07-04 04:19:16 +09:00
parent 48140f0f77
commit a617d40777
13 changed files with 392 additions and 16 deletions

View file

@ -1,10 +1,10 @@
<script lang="ts">
import { onDestroy } from 'svelte';
import { getMap, plotPrediction, plotAnimatedMarker, plotEndMarker } from '$map';
import { getMap, plotPrediction, plotAnimatedMarker, plotEndMarker, plotBoundingBox } from '$map';
import { timelineStore } from '$features/timeline/store';
import { workspacesStore } from './store';
import type { Workspace } from './types';
import type { LatLngTuple } from '$domain';
import { computeBoundingBox, DEFAULT_BBOX_MARGIN_KM, type LatLngTuple } from '$domain';
/**
* Renders every workspace onto the shared map. Each workspace gets its own
@ -22,6 +22,7 @@
// belong to workspaces which were removed from the store since last tick.
const ownedPlotScenes = new Set<string>();
const ownedCursorScenes = new Set<string>();
const ownedBboxScenes = new Set<string>();
// Last-rendered state per workspace scene — skip re-plot when nothing changed.
const plotCache = new Map<string, { result: unknown; color: string; opacity: number }>();
// Cursor scenes that have reached their flight end and show a static end marker.
@ -29,6 +30,7 @@
const sceneName = (w: Workspace) => `ws/${w.id}`;
const cursorName = (w: Workspace) => `cursor/${w.id}`;
const bboxName = (w: Workspace) => `bbox/${w.id}`;
function updateGlobalRange(items: Workspace[]) {
let maxDuration = 0;
@ -85,6 +87,36 @@
}
}
function renderBboxes(items: Workspace[]) {
if (!map) return;
const live = new Set<string>();
for (const w of items) {
const name = bboxName(w);
live.add(name);
const box =
w.visible && w.result && w.bboxVisible
? computeBoundingBox(w.result.flight_path, w.bboxMargin ?? DEFAULT_BBOX_MARGIN_KM)
: null;
if (!box) {
if (ownedBboxScenes.has(name)) {
map.disposeScene(name);
ownedBboxScenes.delete(name);
}
continue;
}
plotBoundingBox(map.scene(name), box);
ownedBboxScenes.add(name);
}
for (const name of Array.from(ownedBboxScenes)) {
if (!live.has(name)) {
map.disposeScene(name);
ownedBboxScenes.delete(name);
}
}
}
function positionAt(path: LatLngTuple[], elapsed: number, durationMs: number): LatLngTuple | null {
if (path.length === 0) return null;
if (durationMs === 0) return path[0];
@ -150,6 +182,7 @@
$effect(() => {
const items = $workspacesStore.items;
renderAll(items);
renderBboxes(items);
updateGlobalRange(items);
});
@ -161,8 +194,10 @@
if (!map) return;
for (const name of ownedPlotScenes) map.disposeScene(name);
for (const name of ownedCursorScenes) map.disposeScene(name);
for (const name of ownedBboxScenes) map.disposeScene(name);
ownedPlotScenes.clear();
ownedCursorScenes.clear();
ownedBboxScenes.clear();
doneCursorScenes.clear();
});
</script>