2026-04-27 12:48:37 +05:30
2026-04-27 12:48:37 +05:30
2026-04-27 12:48:37 +05:30
2026-04-27 12:48:37 +05:30
2026-04-27 12:48:37 +05:30
2026-04-27 12:48:37 +05:30
2026-04-27 12:48:37 +05:30
2026-04-27 12:48:37 +05:30
2026-04-27 12:48:37 +05:30
2026-04-27 12:48:37 +05:30
2026-04-27 12:48:37 +05:30
2026-04-27 12:48:37 +05:30

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

  1. Login — pick or create a user when the app opens. The username is stamped on every audit-log entry.
  2. 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.
  3. 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 from classes.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 side label; 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_name is Not available / NA.
  • Pair max slider (260 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.

  1. Filter the map to the affected slice (e.g., video=X, name=Streetlight).
  2. Click an asset → Mark as anchor (gold ring appears).
  3. Drag the gold-ringed asset to where it should be. Repeat for as many anchors as you like.
  4. 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 firstlast anchor span are not touched.
  5. 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 oneway between 0 / 1 / -1 when it's wrong.
  • Lane offset (m) — controls the parallel offset used by snap-to-road. Range 0.130 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_path URLs to disk (HTTPS URLs always pass through unchanged).

Export

The Export data… button writes every non-deleted asset in one of four formats:

  • .json Source JSON — round-trippable. Same shape import_fixed_assets and import_range_assets accept (separate fixed and range arrays). Includes image_path*, side, deleted, etc.
  • .geojson — FeatureCollection. Points for fixed assets, LineStrings for ranges. Properties include image_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: assets only 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 oneway direction.
  • Re-importing wipes my edits — re-import preserves rows where modified=1 (manual moves) and rows the user deleted; only modified=0 geometry is re-stamped from source. If you need a fresh start, use Reset DB in the Data section first.
Description
for kml verification and data modification
Readme 2.6 MiB
Languages
TypeScript 56.8%
Rust 41.6%
CSS 1.5%