bluerobotics / bluerobotics/cockpit

GeoTIFF map overlays disappear when switching vehicles

Open
#2,886 1 comment 0 reactions 0 assignees View on GitHub
map settings
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.