# Geospatial export `dji-embed convert` turns a DJI SRT flight track into geospatial formats that open in mapping tools and feed the project's own map viewers. ## GeoJSON ```bash dji-embed convert geojson DJI_0001.SRT # -> DJI_0001.geojson dji-embed convert geojson DJI_0001.SRT -o track.geojson ``` A `FeatureCollection` with one `LineString` for the flight path and one `Point` per sample carrying `abs_alt` and `timestamp`. Coordinates are `[longitude, latitude, altitude]` (RFC 7946). Opens in QGIS, geojson.io, and most web maps; it is also the canonical format the HTML/web-UI viewers render. ## KML ```bash dji-embed convert kml DJI_0001.SRT # -> DJI_0001.kml ``` A `LineString` placemark with absolute altitude — double-click to open the flight path in Google Earth. ## Camera footprints Add `--footprint` to a `geojson` or `kml` conversion to include camera ground-footprint polygons in the output — one rectangle per sampled frame showing the area imaged by the lens at that moment. ```bash dji-embed convert geojson DJI_0001.SRT --footprint --model air3 dji-embed convert kml DJI_0001.SRT --footprint --footprint-interval 5 ``` ### Sampling interval `--footprint-interval SECONDS` (default `2.0`) controls how often a footprint is sampled. One polygon is emitted per interval, not per frame. Increase the interval to keep file sizes manageable on long flights. ### Model and field of view FOV is derived from the SRT's `focal_len` field (a 35mm-equivalent, present on Format 3/3b models) when available. When `focal_len` is absent, a per-model native focal length is used instead. Pass `--model ` to select the correct table entry: | `--model` value | Equiv. focal length | Typical drone | |-----------------|--------------------:|---------------| | `air3` | 24 mm | DJI Air 3 | | `mini4pro` | 24 mm | DJI Mini 4 Pro | | `avata360` | 24 mm | DJI Avata 360 | | `avata2` | 12.7 mm | DJI Avata 2 | Omitting `--model` (or using an unrecognised name) falls back to a generic wide lens (~84° HFOV). To add a new model, extend `FOV_TABLE` in `src/dji_metadata_embedder/geo/footprint.py`. ### Gimbal-aware rotation The footprint rectangle is oriented to the drone's course over ground by default. On the **Avata 360** format, which carries `gb_yaw` in the SRT, the real gimbal yaw is used instead, so the footprint follows where the lens actually points. ### Oblique frames are skipped If the SRT carries gimbal pitch (`gb_pitch`) and the camera is more than ~30° off nadir, no footprint is drawn for that frame. Full oblique projection is deferred future work. When gimbal pitch is absent (most formats), nadir is assumed for every frame. The bundled `samples/Avata360/clip.SRT` is a horizon-pointing (gimbal pitch ≈ 0°) 360 capture — the nadir model intentionally skips every frame and produces no footprints. Gimbal yaw is used for footprint rotation only when the camera is near-nadir (pitch below the ~30° threshold). ### Privacy — footprints suppressed under `--redact` Footprint polygons are only emitted when `--redact none` (the default). Under `--redact fuzz` or `--redact drop`, no footprints are written — a precise polygon would re-sharpen a deliberately coarsened position. ### Output format details **GeoJSON** — footprints are `Polygon` features alongside the existing track `LineString` and `Point` features. Each footprint feature carries: ```json { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[[lon, lat], ...]] }, "properties": { "kind": "footprint", "index": 12, "timestamp": "00:00:24,000", "agl": 28.5, "hfov": 73.7, "vfov": 58.0 } } ``` **KML** — footprints are collected in a `` named "Camera footprints", each as a `clampToGround` polygon. ### Limitations - **Flat-earth projection.** Footprint size is computed with a plane-earth approximation (equirectangular). Errors grow with altitude and latitude but are negligible at the scales typical drone flights cover. - **Nadir assumed when no gimbal data.** Most DJI formats do not carry gimbal attitude in the SRT. When `gb_pitch` is absent the camera is assumed to be pointing straight down. Strongly oblique or FPV flights will produce inaccurate footprints in that case. - **No terrain / DEM.** AGL is taken from `rel_alt` in the SRT when present, otherwise estimated as `abs_alt − first-fix abs_alt`. Neither accounts for terrain relief below the drone. ## Standalone HTML map ```bash dji-embed convert html DJI_0001.SRT # -> DJI_0001.html dji-embed convert html DJI_0001.SRT -o flight.html ``` Produces a single self-contained file that opens in any browser. The flight path is drawn as a Leaflet/OpenStreetMap map, colored by altitude (blue = low, red = high), with start/end markers and clickable points that show index, altitude, and timestamp. > **Network note:** Leaflet and the basemap tiles load from the internet; the > flight data itself is embedded, so the file is portable but needs a connection > to render the map. `--redact` works the same as for GeoJSON/KML: ```bash dji-embed convert html DJI_0001.SRT --redact drop # empty track, no coords dji-embed convert html DJI_0001.SRT --redact fuzz # ~100 m coarsened coords ``` ## Privacy All three geo formats honour `--redact`: ```bash dji-embed convert geojson DJI_0001.SRT --redact drop # empty track, no coords dji-embed convert kml DJI_0001.SRT --redact fuzz # ~100 m coarsened coords ``` Pre-GPS-lock `(0, 0)` frames are always excluded. ## Batch ```bash dji-embed convert geojson ./footage --batch # all *.SRT in the folder dji-embed convert html ./footage --batch # one .html map per *.SRT ```