# lwir_map — LWIR Scene Map Tools

Utilities for building a navigable satellite-image atlas from imagej-elphel
LWIR scene output.  Useful after any aerial/drone LWIR acquisition to quickly
locate thousands of captured frames on a map without opening individual files.

---

## Purpose

imagej-elphel produces per-scene directories under a linked root such as:

```
/home/elphel/lwir16-proc/NC/linked/linked_1763232117-1763234145-v88/
```

These scripts read that output and produce:

1. A spreadsheet-friendly **TSV summary** — one row per scene, with GPS
   corners, AGL, heading, forestation estimate, ground-plane data, and
   status flags.
2. **Map overlay files** (GeoJSON, KML, SVG, bounds TSV) ready for the
   foliage-internal atlas rendering pipeline.

---

## Pipeline

```
imagej-elphel linked output
        │
        ▼  lwir_scene_summary.py
  summaries/<dataset>-summary.tsv
        │
        ▼  lwir_map_overlay.py
  summaries/<dataset>-overlay.geojson   (+ .kml  .svg  .bounds.tsv)
        │
        ▼  foliage-internal/scripts/download_basemap.py
  atlas/<dataset>/basemap.mbtiles  +  metadata.json
        │
        ▼  foliage-internal/scripts/render_overlay_atlas_pdf.py
  atlas/<dataset>/atlas-4x4.pdf         ← final product
```

Suggested output root: `/home/elphel/lwir16-proc/<site>/`

---

## Scripts

### `lwir_scene_summary.py`

Reads a linked scene root and writes a TSV with ~65 columns per scene.

Key columns: `status`, `scene_id`, `scene_timestamp_s`, `center_lat/long`,
`corner{1-4}_lat/long`, `rect_x_axis_heading_deg`, `agl_m`,
`forestation_percent`, `gp_*` (ground plane), `hfov_deg`, `footprint_x/y_m`.

```bash
scripts/lwir_map/lwir_scene_summary.py \
  /home/elphel/lwir16-proc/NC/linked/linked_1763232117-1763234145-v88 \
  -o /home/elphel/lwir16-proc/NC/summaries/linked_1763232117-1763234145-v88-summary.tsv
```

### `lwir_map_overlay.py`

Reads the TSV and generates map overlay files.

```bash
scripts/lwir_map/lwir_map_overlay.py \
  /home/elphel/lwir16-proc/NC/summaries/linked_1763232117-1763234145-v88-summary.tsv \
  --out-prefix /home/elphel/lwir16-proc/NC/summaries/linked_1763232117-1763234145-v88-overlay \
  --svg-fill none \
  --svg-color-by agl_m \
  --svg-label-mode first-per-group \
  --svg-direction-cue broken-right
```

Key options:

| Option | Values | Default |
|---|---|---|
| `--svg-fill` | `color`, `none` | `color` |
| `--svg-color-by` | `forestation_percent`, `agl_m`, `status` | `forestation_percent` |
| `--svg-label-mode` | `every`, `none`, `first-per-group`, `last-per-group` | `every` |
| `--svg-direction-cue` | `none`, `broken-right`, `open-right` | `broken-right` |
| `--ok-only` | flag | off |

The `broken-right` direction cue omits the middle third of the image-right
edge (corner1→corner2 side) as a flight-direction indicator.

---

## Generated outputs (NC dataset, 2026-05-14)

Summary TSV: 2193 scenes, 169 index groups, 2067 ok / 126 missing.

| File | Description |
|---|---|
| `*-summary.tsv` | Per-scene metadata table |
| `*-overlay.geojson` | GeoJSON polygon footprints |
| `*-overlay.kml` | KML for Google Earth |
| `*-overlay.svg` | Standalone SVG (equirectangular, A0) |
| `*-overlay.bounds.tsv` | Coverage bbox (~6.5 km × 4.0 km, NC site) |
| `*-overlay-agl-nofill-sparse.*` | Sparse variant: AGL color, no fill, first-per-group labels |

---

## Known limitations / future improvements

### Tilt during turns (high priority)
Rectangles are plotted centred on the aircraft GPS position with no attitude
correction.  During turns the aircraft banks, shifting the actual footprint
laterally from the nadir point.  For straight-and-level flight this error is
small; in tight turns it can be significant.

**Fix**: read roll/pitch from egomotion (or IMU) and project the four corners
through the actual camera-to-ground ray using the known AGL and sensor FoV.
`lwir_scene_summary.py` already reads egomotion CSV; roll/pitch columns would
need to be extracted and the footprint geometry updated in `_compute_corners()`.

### Other known gaps
- Forestation fraction uses a fixed elevation threshold; making it
  configurable per-dataset would improve accuracy.
- The SVG equirectangular projection is separate from the Web Mercator
  projection used by the foliage-internal rendering scripts; unifying them
  would simplify the pipeline.
- No support yet for multi-sensor rigs with per-sensor pointing offsets.
