diff --git a/FORMATS.md b/FORMATS.md index 39bca87..669137d 100644 --- a/FORMATS.md +++ b/FORMATS.md @@ -104,7 +104,7 @@ Coordinates are `[lat, lng]`; the importer swaps to `[lng, lat]` internally. Gar - Non-finite or out-of-range lat/lng. - Jumps > 5 km between consecutive points. -Stored only in memory (cleared by the **Loaded data → Clear** button or app restart). +**Persisted in the SQLite database** (`video_metadata` table, keyed by `video_name`). Once imported, the polylines hydrate automatically on every app start — you don't have to re-pick the file each session. Cleared by the **Loaded data → Clear** button on the Per-video metadata row, or by **Reset DB** (which wipes the whole database). ### Metadata polyline (legacy single-track) Single-video legacy format used by the old FastAPI pipeline. diff --git a/README.md b/README.md index c33baad..cea0f79 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Tauri 2 desktop app for reviewing, correcting and exporting fixed-asset / range- - **Range assets (JSON)** — linear assets with start / mid / end (e.g., crash barriers). - **KML scope polygon** — defines which assets are "in scope". Points outside the polygon are hidden by default. - **OSM roads (GeoJSON)** — imported road network for snapping / direction lookups. - - **Metadata polyline (KML)** — vehicle GPS track from the source video; takes priority over OSM for direction inference. + - **Per-video metadata (JSON)** — vehicle GPS track per video; takes priority over OSM for direction inference. **Persists in the SQLite database**, so you only pick the file once — every subsequent app start hydrates it automatically. Cleared only by the **Clear** button on the Per-video metadata row, or by **Reset DB**. 3. The map auto-centers on the first imported asset. Pan / zoom triggers viewport-bounded fetches (debounced) to keep the deck.gl rendering snappy. --- @@ -51,6 +51,23 @@ Tauri 2 desktop app for reviewing, correcting and exporting fixed-asset / range- --- +## Single-video focus mode + +When you want to inspect / clean one video's worth of data in isolation: + +- **Tap that video's metadata polyline on the map**, or +- **Leave exactly one video checked in the Filters panel**. + +Either path triggers focus mode: + +- Other videos' metadata polylines are hidden — only the focused track renders. +- OSM roads are spatially filtered to those within ~75 m of the focused track (cheap spatial-hash buffer; recomputed on each switch). +- Clicking the metadata line again, or unchecking the lone video filter, restores the full view. + +Focus mode also unlocks the bulk OSM road tools (multi-select / hide / merge — see **OSM road editing**). Selection and hidden state are session-scoped: they reset whenever you exit OSM edit mode or change the focused video. + +--- + ## Cross-side / cross-video pair linking Common situation: one physical asset (e.g., a median streetlight) is captured in two videos (LHS and RHS) and shows up as two near-duplicate points. Pair linking marks them as the same physical thing without deleting either. @@ -97,45 +114,70 @@ Range assets (start / mid / end) translate as a rigid body — all three vertice ## OSM road editing ### Modes -- **OSM tools…** modal — generate roads for the visible bbox (Overpass), import existing GeoJSON, export current roads, prune small road classes. +- **OSM tools…** modal — generate roads for the visible bbox or for a buffer around imported assets (Overpass), import existing GeoJSON, export current roads, prune small road classes. - **Edit OSM roads** button — toggles OSM edit mode. While on, every other layer is dimmed and only OSM roads are interactive. +- **Magnifier** button — cursor-following circular lens that zooms +3 levels around the cursor; renders satellite + OSM cyan + dashed-green metadata + red asset dots. Toggle on, hover anywhere, then ESC or click again to exit. - **Lane offset (m)** — controls the parallel offset used by snap-to-road. Range 0.1–30 m. -### Picking a road to edit -1. Turn on **Edit OSM roads** (right panel → Data section). -2. Zoom in to **z ≥ 14** — vertex handles only render at that zoom or deeper, to keep the map responsive. -3. Click any road. Its yellow `•` vertex pins appear; other roads stay un-pinned. The selected road's id is shown in the OSM-edit panel. +### Two click models -### Modifying a road -- **Drag a yellow `•` pin** — moves that vertex to wherever you drop it. The change is saved immediately. -- **Click a yellow `+` ghost pin** between two vertices — inserts a new vertex at that midpoint. Useful when an OSM segment is too sparse for the curve. -- **Flip direction** — cycles `oneway` through forward (`1`) → reverse (`-1`) → undirected (`0`). Use when OSM has the heading wrong on a divided road. +OSM edit mode behaves differently depending on whether a single video is focused (see **Single-video focus mode**): + +- **Non-focus** — click a road to enter the legacy single-road vertex editor (the only road remains visible; vertex pins appear). One road at a time. +- **Focus mode** — click a road to **toggle multi-select** (yellow highlight). All roads stay visible. When the selection narrows to **exactly one** road, the vertex editor automatically engages on it (Flip / Simplify / Delete this road / Ignore for snap appear inline). Click the road again to drop back to multi-select. + +### Modifying a road's vertices (single road active) +- **Drag a yellow `•` pin** — moves that vertex. Saved immediately. +- **Click a yellow `+` ghost pin** between two vertices — inserts a new vertex at that midpoint. +- **Flip direction** — cycles `oneway` through forward (`1`) → reverse (`-1`) → undirected (`0`). +- Vertex handles render at z ≥ 14; zoom in if you don't see them. ### Deleting vertices -Two tools, depending on scope: - **A. Surgical — Shift-click + Del** -1. Hold **Shift** and click a vertex pin → it turns red with an `✕`. -2. Repeat to mark more. -3. Press **Del** (or Backspace) → all marked vertices are removed in one shot. -4. The "Currently marked: N" label in the panel shows how many you've flagged. **Clear marks** unselects without deleting. -5. Shift-click a marked vertex again to unmark it individually. -6. The road must keep ≥ 2 vertices; the backend rejects deletes that would break that. +1. **Shift-click** a vertex pin → turns red with `✕`. Repeat to mark more. +2. Press **Del** → all marked vertices removed in one shot. +3. **Clear marks** unselects without deleting. Shift-click a marked vertex to unmark. +4. The road must keep ≥ 2 vertices. **B. Sweeping — Simplify by tolerance** -1. Use the **Simplify (m)** slider in the panel (0.5–20 m, default 2 m). Higher = more aggressive. -2. Click **Simplify this road**. Runs Douglas-Peucker on the polyline: any vertex within tolerance of the simplified line is dropped. +1. **Simplify (m)** slider (0.5–20 m, default 2 m). Higher = more aggressive. +2. Click **Simplify this road** → Douglas-Peucker on the polyline. 3. Status bar reports `before → after` vertex counts. -4. Try 1–2 m for cleanup, 5+ m for heavy decimation. Re-running with the same tolerance is idempotent. -### Deleting / flipping the whole road -- **Delete this road** — removes the road outright (with confirmation). -- **Deselect road** — exits the per-road editing tool but keeps OSM edit mode on. +### Bulk road tools (focus mode only) -### Notes -- OSM road edits are **not** undoable via the Recent actions panel — they're treated like reference-data tweaks. Be deliberate, especially with delete and simplify. -- Dragging a vertex triggers a single `update_osm_road` write per drag. Bulk delete and simplify are also single writes. -- After a vertex change, the road line refreshes in real time but the surrounding draggable pins re-render — slight visual flicker is normal. +A "Bulk road tools — focus: