bluerobotics / bluerobotics/cockpit
GeoTIFF map overlays disappear when switching vehicles
- Dominant language
- TypeScript
- Stars
- 198
- Forks
- 63
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 57
Description
## Problem
GeoTIFF overlays vanish when the user connects to a different vehicle, even with the same user. Reported by a user who imported overlays, switched vehicles, and found a different (empty) overlay list.
The raster bytes are still on disk — only the record of them is gone — so the data is invisible and unreclaimable through the UI.
## Cause
The two halves of an overlay are stored with different scopes:
- **Raster bytes**: localforage IndexedDB instance `Cockpit - Map Overlays` / `cockpit-map-overlays-db` (`src/libs/map/overlay-storage.ts:13-18`), keyed by a uuid. Origin-global, machine-local.
- **Metadata (including that uuid)**: a settings key (`src/stores/mission.ts:130`):
```ts
const mapOverlays = useBlueOsStorage('cockpit-map-overlays-v1', [])
```
`useBlueOsStorage` stores under `cockpit-settings-v2[user][vehicle]` and syncs to BlueOS under `settings/{userId}/`. So the only pointer to a machine-local blob is scoped per user × vehicle.
A first-time vehicle usually looks fine, because `runVehicleGettingOnlinePipeline` falls back to the last connected vehicle's package (`src/libs/settings-management.ts:1126-1164`). The breakage appears once both vehicles already have their own settings package: the current combo hits, and overlays imported under vehicle A are simply not in vehicle B's list.
## Consequences
1. **Orphaned rasters.** Overlays imported under one profile are unreachable from another. Their bytes stay in IndexedDB consuming quota, referenced by nothing, with no UI to reclaim them.
2. **Silent dangling references.** Because the key syncs through BlueOS, a second ground station connecting to the same vehicle pulls down metadata whose uuids only exist in the first machine's IndexedDB. The overlay is listed and ticked visible, and never draws — the only signal is a console warning (`src/composables/map/useMapOverlays.ts:150-154`):
```ts
const blob = await mapOverlayStorage.getItem(meta.id)
if (!blob) {
console.warn(`Map overlay "${meta.name}" has no stored raster; skipping render.`)
return
}
```
3. **Cross-profile deletion.** The fallback copy duplicates metadata including the uuids, so two vehicle slices can reference the same raster. Removing the overlay under one calls `deleteStoredOverlay` (`src/components/map/MapOverlaysDialog.vue:213-216`), which deletes the shared bytes globally, leaving the other profile with an entry that can never render.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by tracing the overlay metadata in src/stores/mission.ts:130, raster storage in src/libs/map/overlay-storage.ts:13-18, and vehicle settings fallback in src/libs/settings-management.ts:1126-1164. Reproduce switching between vehicles and inspect rendering in src/composables/map/useMapOverlays.ts:150-154 and deletion in src/components/map/MapOverlaysDialog.vue:213-216. Done should prevent overlays from becoming inaccessible or dangling across vehicle profiles.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100