Tap-to-Mark Phase I prototype
Inspector closed-loop validation tool. Walk the downstream reach with the AR overlay running, and tap the screen wherever the predicted inundation shoreline disagrees with the real terrain you're observing. Each tap records a discrepancy: lat/lon (back-projected from the tap through the camera model and DSM intersection), elevation, predicted depth at that world point, an observed-terrain class (wet / dry / uncertain), and an optional note. Marks export as a GeoJSON FeatureCollection that feeds back into the Bayesian breach posterior for envelope refinement (Phase I scope).
Inherits the rendering pipeline of ar-prototype.html: same WGS84 → ENU → camera projection, same DSM occluder, same 3D water column. Adds a tap-capture canvas above the overlay and a marks drawer.
Two recording modes (toggle is in the AR overlay, top-center): Discrepancy — original closed-loop validation against the predicted envelope. High-Water Mark — geotag observed peak-flood evidence (debris line, mud staining, bent vegetation, water/silt stain) for FEMA HMGP/BRIC, insurance damage assessment, and academic post-event reconstruction. HWM marks accept a per-mark evidence photo (stored in IndexedDB) and export as a FEMA-style survey package (GeoJSON + CSV + photos + README, bundled as a ZIP). Both modes coexist in the same session and on the same overlay.
1 · Inundation polygon (GeoJSON)
Same parser as the inundation viewer — accepts FeatureCollection, Feature,
or bare Polygon/MultiPolygon. WGS84 (lon, lat). Optional
depth_ft / depth_m / wsel_ft per feature.
2 · Observer position
Mark elevations are read from the active DSM if loaded; otherwise the observer ground plane is used as a planar approximation (degrades with range and varied terrain).
3 · DSM (optional, but improves mark elevation accuracy)
Loading a DSM (drone survey, project lidar, or USGS 3DEP) lets the inverse projection intersect the actual terrain rather than the observer's ground plane. Without it, marks >~100 m from the observer drift in elevation.
4 · Camera intrinsics
5 · Start AR + tap-to-mark
Marks persist in browser localStorage (records) and IndexedDB (HWM evidence photos) —
survives reload, cleared by the explicit button or by clearing site data.
How tap-to-mark works (inverse projection & mark schema)
1 · Forward pipeline (inherited)
The renderer projects each polygon vertex through three transforms identical to
ar-prototype.html:
(a) WGS84 → ENU (planar small-area approximation),
(b) ENU → camera frame via the heading/pitch/roll rotation built in
buildCamRotFromHPR,
(c) camera frame → screen pixels via the standard pinhole projection.
2 · Inverse projection (this tool)
A tap at screen pixel $(u, v)$ is mapped to a camera-space ray
$\;\vec{r}_{\rm cam} = \big( (u - W/2) \tan(\text{HFOV}/2) / (W/2),\; (v - H/2) \tan(\text{VFOV}/2) / (H/2),\; 1 \big)$
This is the analytic inverse of the pinhole forward map at $z = 1$. The ray is rotated into ENU via $\vec{r}_{\rm ENU} = R^{T} \vec{r}_{\rm cam}$ — note that $R$ is orthonormal so $R^{-1} = R^{T}$. The world-space ray origin is the camera at $(0, 0, 0)$ in ENU (i.e., the observer GPS at eye-height).
3 · Ray–surface intersection
With a DSM loaded, the ray is marched outward in steps of $\sim 1$ m up to a 1.5 km cap. At each step the bilinearly-interpolated DSM elevation is compared against the ray's instantaneous elevation; the first sample where the ray drops below terrain is the intersection (refined by one bisection pass). Without a DSM, the ray is intersected with the planar ground at the observer's elevation — accurate near the observer, drifts with range over varied terrain. The intersection point $(\Delta E, \Delta N, z_{\rm ground})$ is converted back to lat/lon via the inverse of the planar-ENU equations.
4 · What gets recorded per mark
- lat, lon — back-projected WGS84 coordinate of the tap target. Not a real GPS reading at that point; it is computed from the camera model. Accuracy depends on compass calibration, FOV calibration, and DSM availability.
- elevation_navd88 — DSM elevation at (lat, lon) if available; else observer ground elevation as a planar fallback.
- screen_xy — original screen pixel of the tap (for traceability + replay).
- timestamp — ISO 8601 UTC.
- predicted_depth_at_mark — depth from the active feature whose ring contains the
back-projected (lat, lon), resolved by the same property fallback chain as the
reticle HUD (
depth_ft→depth_m→wsel_ft− ground).0if the back-projected point is outside every active feature. - observed_terrain_class — inspector judgment from the on-screen picker:
wet/dry/uncertain. - discrepancy_kind — derived: if predicted depth > 0 and observed = "dry" →
ar_wet_observed_dry; if predicted depth = 0 and observed = "wet" →ar_dry_observed_wet; if observed = "uncertain" →uncertain; otherwiseagree(mark still saved — useful for confirming hits). - note — free-text annotation, optional.
- observer — copy of observer lat/lon/elev/heading at tap time, for traceability.
- scenario — copy of active storm/offset selection, since marks are scenario-specific.
5 · High-Water Mark (HWM) recording mode
A second tap mode geotags observed peak-flood evidence rather than predicted-vs-observed discrepancies. The inverse projection, DSM intersection, and lat/lon/elevation back-projection are identical to Discrepancy mode — only the schema and visual style differ.
- Tap flow: tap → bottom sheet prompts for
evidence_type(debris_line / mud_staining / bent_vegetation / water_stain / silt_line / other) andconfidence(high / medium / low) → save. - Per-mark photo: "Capture evidence" button on each HWM opens a still-photo capture
overlay; the photo is stored as a JPEG blob in IndexedDB (object store
hwm_photos, key = mark id) — keepslocalStoragewell below its 5-10 MB quota. - Visual style: HWM marks render as inverted teardrops (point-down) to distinguish from discrepancy marks (point-up); both can coexist on the same overlay.
- Color palette: orange (debris), brown (mud), green (vegetation), grey (water stain), tan (silt), purple (other).
- Schema fields specific to HWM:
mark_type:'high_water_mark',evidence_type,confidence,observation_date_iso,photo_capture_filename,free_text_note,observer_pose(heading/pitch/roll snapshot at tap time). - Export — FEMA HWM survey package (ZIP): mirrors USGS STN / FEMA HWM survey
conventions —
hwm_points.geojson(all HWM features),hwm_summary.csv(one row per HWM with lat/lon/elev/evidence/confidence/date/note),photos/hwm_<idx>_<evidence_type>.jpg, andREADME.txtwith provenance + survey methodology. This is a defensible derivative format, not a verbatim FEMA template — see README in the ZIP.
6 · What this prototype does NOT do (Phase I scope)
- The actual Bayesian importance reweighting against breach-parameter posterior draws.
That sits in the backend per
closed_loop_workflow_spec.md §2.3; this prototype only produces the GeoJSON observation set that feeds it. - The QA loop UI showing pre/post envelope side-by-side. Phase I §2.4.
- Camera-frame snapshot per tap. Phase I §2.2 step 5 — the existing snapshot
button in
ar-prototype.htmlcovers the equivalent at higher level. - Server sync. Marks are local-only in this prototype.