Files
KML-Verification/FORMATS.md
2026-05-02 16:44:03 +05:30

9.5 KiB

Import & Export Formats

What each Import button accepts, plus what every Export option produces. Sample snippets included so you can shape data outside the tool and feed it in.


Imports

Fixed assets (JSON)

Source-of-truth shape used by the labelling pipeline. Each row is one point asset.

[
  {
    "row_id": "406_473_0.04_1",
    "asset_name": "Double_Arm_Street_Light",
    "video_name": "20250802150330_000000",
    "image_path": "https://auditor-master-images.seekright.com/.../406_473_0.04_1.jpeg",
    "coord": ["17.39869", "78.34701"],
    "deleted": false,
    "side": "Left"
  }
]
Field Type Required Notes
row_id string yes Unique key. Re-import upserts on this.
asset_name string yes Class label, e.g. Double_Arm_Street_Light.
video_name string yes Video the asset was captured in. "Not available" is treated as NA.
image_path string | null no HTTPS URL or local path. Used by the popup.
coord [lat, lng] yes Strings or numbers. Order is lat first.
deleted bool no Default false. Re-import never resurrects rows the user deleted.
side "Left" | "Right" | "LHS" | "RHS" | null no If absent, derived from image_path (e.g. a /LHS/ or /RHS/ segment).

Re-import behaviour: rows the user has manually moved (modified=1) or deleted are not overwritten — only modified=0 geometry is re-stamped from source.

Range assets (JSON)

Same idea but with start / mid / end coordinates and three image paths.

[
  {
    "row_id": "406_473_0.50_2",
    "asset_name": "Crash_Barrier",
    "video_name": "20250802150330_000000",
    "coord_lat": 17.4002,
    "coord_lng": 78.3445,
    "start_coord_lat": 17.40015,
    "start_coord_lng": 78.34448,
    "end_coord_lat": 17.40025,
    "end_coord_lng": 78.34452,
    "image_path1": "https://.../start.jpg",
    "image_path2": "https://.../mid.jpg",
    "image_path3": "https://.../end.jpg",
    "deleted": false,
    "side": "Left"
  }
]

coord_* may be strings or numbers. Same upsert / preserve rules as fixed assets.

KML scope

Standard KML 2.2. Polygons and LineStrings inside Placemarks become scope features. Polygons gate by point-in-polygon; LineStrings are 30 m proximity buffers.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Document>
    <Placemark>
      <name>HYDTOT corridor</name>
      <Polygon><outerBoundaryIs><LinearRing><coordinates>
        78.34,17.39,0  78.36,17.40,0  78.35,17.41,0  78.34,17.39,0
      </coordinates></LinearRing></outerBoundaryIs></Polygon>
    </Placemark>
  </Document>
</kml>

Importing a new KML replaces the entire scope set.

Per-video metadata (JSON)

Multi-video GPS polylines keyed by video_name. Used for direction inference (snap-to-road priority: metadata → OSM oneway → position fallback) and on-map display.

{
  "2026_0330_094759_F": [[
    [17.398456, 78.347281],
    [17.398522, 78.347233],
    [17.398581, 78.347192]
  ]],
  "2026_0330_095259_F": [[
    [17.410322, 78.320736],
    [17.410367, 78.320547]
  ]]
}

Structure: { video_name: [[ [lat, lng], … ]] }. Each value is an array containing one polyline (the outer wrapper is for compatibility with multi-segment legacy formats — the importer reads only the first inner array).

Coordinates are [lat, lng]; the importer swaps to [lng, lat] internally. Garbage points are filtered out automatically:

  • Anything within ~100 m of (0, 0).
  • Non-finite or out-of-range lat/lng.
  • Jumps > 5 km between consecutive points.

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.

{
  "track": [
    [17.398, 78.347],
    [17.399, 78.346]
  ]
}

track array of [lat, lng]. Used as the single source-of-truth track when no per-video map is loaded. Per-video JSON supersedes this.

OSM roads (GeoJSON)

A FeatureCollection of LineString features. Each feature's properties are stored on the roads table.

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [78.347281, 17.398456],
          [78.347233, 17.398522]
        ]
      },
      "properties": {
        "id": 12345,
        "name": "ORR Service Road",
        "highway": "service",
        "oneway": 1
      }
    }
  ]
}
Property Type Required Notes
id integer no If absent the importer assigns a sequential id.
name string no Used by Merge-by-name and the popup.
highway string no OSM class — motorway, trunk, primary, service, etc. Used by Prune.
oneway int no 1 = forward, -1 = reverse, 0 (or absent) = undirected. motorway and roundabout default to 1 if oneway is missing.

GeoJSON convention: coordinates is [lng, lat] (the opposite of every JSON above). The importer expects the standard order.

You can also generate this file in-app via OSM tools… → Generate visible bbox (uses the Overpass API).


Exports

The Export data… button writes every non-deleted asset in one of four formats. The Save dialog filters by extension.

.json — Source JSON (round-trippable)

Same shape import_fixed_assets and import_range_assets accept, split into two arrays so each can be fed back through its matching importer.

{
  "fixed": [
    {
      "row_id": "406_473_0.04_1",
      "asset_name": "Double_Arm_Street_Light",
      "video_name": "20250802150330_000000",
      "image_path": "https://.../406_473_0.04_1.jpeg",
      "coord": [17.39869, 78.34701],
      "deleted": false,
      "side": "Left"
    }
  ],
  "range": [
    {
      "row_id": "406_473_0.50_2",
      "asset_name": "Crash_Barrier",
      "video_name": "20250802150330_000000",
      "coord_lat": 17.4002,
      "coord_lng": 78.3445,
      "start_coord_lat": 17.40015,
      "start_coord_lng": 78.34448,
      "end_coord_lat": 17.40025,
      "end_coord_lng": 78.34452,
      "image_path1": "https://.../start.jpg",
      "image_path2": "https://.../mid.jpg",
      "image_path3": "https://.../end.jpg",
      "deleted": false,
      "side": "Left"
    }
  ]
}

Use this for round-trip backup / sharing edits with a colleague.

.geojson — FeatureCollection

Standard GeoJSON for any GIS tool. Fixed → Point, range → LineString over [start, mid, end].

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": { "type": "Point", "coordinates": [78.34701, 17.39869] },
      "properties": {
        "row_id": "406_473_0.04_1",
        "asset_type": "fixed",
        "asset_name": "Double_Arm_Street_Light",
        "video_name": "20250802150330_000000",
        "side": "Left",
        "in_scope": 1,
        "modified": 1,
        "image_path": "https://.../...jpeg",
        "image_path1": null,
        "image_path2": null,
        "image_path3": null,
        "link_pair_id": 882,
        "link_locked": 1
      }
    }
  ]
}

Use for QGIS / Mapbox / shipping data downstream.

.kml — KML Placemarks

Each asset is a Placemark with name, description, and geometry. Useful for Google Earth and any KML-aware GIS.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"><Document>
  <Placemark>
    <name>Double_Arm_Street_Light · 406_473_0.04_1</name>
    <description>type: fixed
video: 20250802150330_000000
side: Left
modified: 1</description>
    <Point><coordinates>78.34701,17.39869,0</coordinates></Point>
  </Placemark>
</Document></kml>

.csv — flat row dump

Spreadsheet-friendly. Header row first.

id,row_id,asset_type,asset_name,video_name,side,in_scope,deleted,modified,lat,lng,start_lat,start_lng,end_lat,end_lng,link_pair_id,link_locked,image_path,image_path1,image_path2,image_path3
123,406_473_0.04_1,fixed,Double_Arm_Street_Light,20250802150330_000000,Left,1,0,1,17.39869,78.34701,,,,,,,,https://.../406_473_0.04_1.jpeg,,,

.geojson — OSM roads (separate export)

OSM tools… → Export current roads writes the entire roads table as a GeoJSON FeatureCollection. Same shape as the OSM import — feeds straight back into any GIS tool or back into this app on another machine.

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [[78.347281, 17.398456], [78.347233, 17.398522]]
      },
      "properties": {
        "id": 12345,
        "name": "ORR Service Road",
        "oneway": 1,
        "highway": "service"
      }
    }
  ]
}

Coordinate-order cheat sheet

Source Order
Fixed asset JSON coord [lat, lng]
Range asset JSON coord_* scalar lat / lng
Per-video metadata JSON [lat, lng]
Legacy single-track metadata [lat, lng]
KML <coordinates> lng,lat,alt (KML standard)
GeoJSON anywhere [lng, lat] (GeoJSON standard)
App / DB internals [lng, lat] (deck.gl convention)

When in doubt: JSON coords here are lat-first, GeoJSON / KML are lng-first. The importers swap as needed; the exports always emit the format's native order.