KML Map Tool — User Guide
Tauri 2 desktop app for reviewing, correcting and exporting fixed-asset / range-asset annotations produced by the dashcam labelling pipeline. Replaces the legacy FastAPI + Leaflet tools.
Quick start
- Login — pick or create a user when the app opens. The username is stamped on every audit-log entry.
- Import data — top-left Import… button:
- Fixed assets (JSON) — point assets like streetlights, signs.
- 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.
- The map auto-centers on the first imported asset. Pan / zoom triggers viewport-bounded fetches (debounced) to keep the deck.gl rendering snappy.
Map basics
- Basemaps — Basemap selector at the top. Default: Google Satellite (deep zoom) which uses Google Earth tiles and goes deeper than the regular Google Satellite layer (helpful at z≥22 to see streetlights / road surface).
- Compare mode — secondary basemap layered side-by-side via the Compare toggle.
- Layer toggles — Fixed / Range / OSM / Scope / Metadata visibility.
- Filters panel (left side) — narrow the visible set by Asset type, Side, Video, Asset name. Counts update live with the current viewport.
- Show out-of-scope / Show deleted — toggles to expose hidden assets for inspection or restore.
Selecting and editing one asset
- Click an asset to select. The right-side Selected panel shows type, name, row_id, video, side. By default an image popup opens (toggle in Settings).
- Drag the pin on the map to move the asset. Range assets show S / M / E (start / mid / end) draggable pins.
[/]keyboard shortcuts step through the visible filtered list.- Reset to original — restores the lat/lng captured at first import. Useful if a snap or drag went wrong.
- Snap to nearest road — shifts the asset to the OSM road centerline or its lane-offset side. Direction priority: metadata polyline → OSM
oneway→ position-based fallback. Idempotent above 0.5 m drift. - Side: Left / Right — toggle without moving the geometry.
- Rename class… — change
asset_name(e.g. fix a mis-classified label). Pulls suggestions fromclasses.txt. - Delete — soft-delete (recoverable via Restore or Undo).
- Mark as anchor — flag for the bulk Distribute correction flow (see below).
Lasso selection (for bulk operations)
- Start lasso then pick a shape: circle, rect, or polygon.
- Polygon mode: click to add vertices, click near the first vertex (gold ring) or double-click to close. Pan / zoom while drawing — vertices stay anchored to the map.
- ESC cancels at any time and clears the lingering polygon panel.
- Once selected, you get bulk actions: In-scope / Out-of-scope / Auto / Delete / Restore / Rename / Set Left / Set Right / Reset to original / Clear links.
- Polygon-only extras: Auto-link L↔R, Auto-link by video, Auto-link nearest (see Pair linking).
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.
- Auto-link — draw a polygon lasso over the area, then pick the matching strategy in the polygon panel:
- L↔R: requires assets to have a
sidelabel; pairs Left with Right. - By video: pairs across the two largest video buckets (use when both videos see the same poles from opposite sides).
- Nearest: pairs by proximity regardless of side or video. Use when
video_nameisNot available/ NA.
- L↔R: requires assets to have a
- Pair max slider (2–60 m, default 30 m) — the maximum allowed pair distance. Independent from the duplicate epsilon.
- Manual links override auto-links:
- Right-click an asset → right-click another — locks them as a pair (pink line). The "anchor" asset gets a status-bar prompt.
- Right-click two already-linked assets — unlinks them.
- Click a link line to select it; press Delete to clear that link.
- Link colors: pink = locked manual link (survives Auto-link re-runs); blue = auto link (replaceable on the next re-run).
- Unlink an asset directly via Unlink button on the selected panel.
- After fixing a few wrong pairs manually, click Auto-link again — locked links stay; orphaned partners get re-matched among the remaining unlocked candidates.
Duplicates
- Find duplicates — scans the currently visible viewport for clusters of points within the chosen ε (metres). Zoom out to widen the search; zoom out fully to scan everywhere.
- Cross-video only — restrict matches to pairs from different videos.
- For each cluster you can Delete losers (keep one, delete the rest) or Move losers out-of-scope.
Distribute correction (GPS bias fix)
When the GPS is uniformly off for a whole video / stretch, you don't want to drag every streetlight by hand.
- Filter the map to the affected slice (e.g.,
video=X,name=Streetlight). - Click an asset → Mark as anchor (gold ring appears).
- Drag the gold-ringed asset to where it should be. Repeat for as many anchors as you like.
- Click Distribute correction in the yellow panel that appears at the top of the actions sidebar.
- 1 anchor → all visible assets shift by the same Δlat/Δlng (uniform).
- 2+ anchors → row_id-sorted piecewise linear interpolation between consecutive anchors. Assets outside the first–last anchor span are not touched.
- Undo in Recent actions reverts the entire distribution in one step.
Range assets (start / mid / end) translate as a rigid body — all three vertices shift by the same Δ.
OSM road editing
- OSM tools… modal — generate roads for the visible bbox (Overpass), import existing GeoJSON, export current roads, prune small road classes.
- OSM edit mode — drag any road's vertex to refine the centerline. Markers are gated by zoom ≥ 14 and capped at 80 vertices / 40 ghost dots per viewport so the map stays responsive.
- Flip road direction — cycle a road's
onewaybetween 0 / 1 / -1 when it's wrong. - Lane offset (m) — controls the parallel offset used by snap-to-road. Range 0.1–30 m.
Snap-to-road
- Per-asset — Snap to nearest road on the selected panel.
- Bulk visible — snap every visible fixed asset to the nearest road (50 m max).
- Snap by video — snap every asset (fixed + range) for a given video.
- Range assets snap all three vertices independently (not just mid).
- Direction priority: metadata polyline > OSM
oneway> position-based.
Centerline override
Some asset classes (expansion joint, vms gantry) belong on the road centerline, not the LHS/RHS offset. Settings → Snap to centerline (instead of offset lane) lets you tick those class names.
Settings ⚙ modal
- Image popup
- On / off (when off, marker pins still appear but no image opens on click).
- Width: S / M / L / XL.
- Aspect ratio: 16:9 / 4:3 / 3:2 / 1:1.
- Snap to centerline names — list of asset_names that should snap to centerline.
- Image folder (offline) — a local folder used to resolve
image_pathURLs to disk (HTTPS URLs always pass through unchanged).
Export
The Export data… button writes every non-deleted asset in one of four formats:
.jsonSource JSON — round-trippable. Same shapeimport_fixed_assetsandimport_range_assetsaccept (separatefixedandrangearrays). Includesimage_path*,side,deleted, etc..geojson— FeatureCollection. Points for fixed assets, LineStrings for ranges. Properties includeimage_path*,link_pair_id,link_locked,in_scope,modified..kml— Placemarks for GIS tools. Includes name, description, geometry..csv— full row dump for spreadsheets / external pipelines.
OSM roads can be exported separately via OSM tools… → Export current roads (writes GeoJSON with name, highway, oneway preserved).
Keyboard shortcuts
| Key | Action |
|---|---|
[ / ] |
Step prev / next asset in the filtered list |
ESC |
Cancel: lasso / link-pick / draw-road / road-edit / image popup |
Delete / Backspace |
Unlink the currently-selected link line |
Undo / Redo
Every state-changing action writes an audit row. The Recent actions panel shows the last N. Click Undo on any row to revert; Redo on a previously undone row replays it. Multi-asset operations (bulk delete, distribute, auto-link) revert as a single atomic step. Road edits (OSM vertex drag, create / delete / flip) are not audited.
Performance notes
- Viewport-bounded fetch:
assetsonly contains rows inside the current map bbox, debounced ~400 ms after pan / zoom. - Bulk operations use 500-id chunks to stay safely under SQLite's 999-bind-param ceiling.
- Auto-link / Distribute over very large viewports may take several seconds at 50k+ rows; prefer narrowing with filters or zoom first.
- Image prefetching warms the previous / next two thumbnails so
[/]navigation feels instant.
Troubleshooting
- No assets visible after import — check Filters panel (especially Videos), Show out-of-scope toggle, and whether a stale KML scope from a previous import is filtering everything out.
- Streetlights not visible on satellite — switch to Google Satellite (deep zoom) basemap and zoom to z≥22.
- Snap moves assets to the wrong side — load the metadata polyline (gives true vehicle heading), or fix the OSM road's
onewaydirection. - Re-importing wipes my edits — re-import preserves rows where
modified=1(manual moves) and rows the user deleted; onlymodified=0geometry is re-stamped from source. If you need a fresh start, use Reset DB in the Data section first.