Files
gig-line/Geo
zwitschi 5be6c84b37 docs(agents): tooling-improvement and architecture-upkeep rules; add tool tests
Researched the sibling project's tooling discipline (tools/README inventory,
tools/tests with stdlib unittest, check_docs gate, clean-worktree rule, paid-API
tools human-triggered) and encoded it for this repository:

AGENTS.md gains two sections.
- 'Python and shell tooling': fix the tool not the artefact; improve over fork;
  one script one job; fail loudly; result files for Unreal commandlets; absolute
  paths into sandboxes; clean worktree for generators (.blend/.umap are
  read-only on checkout); network/paid tools human-triggered with 429 back-off;
  measure don't assert; document every tool in the README inventory; test the
  pure parts.
- 'Architecture documentation': Docs/Architecture is arc42 in Markdown; a table
  mapping each kind of change to the section that must be updated; describe what
  exists, ADRs append-only, keep architecture.md in sync, prettier --check.

Made the referenced scaffolding real rather than aspirational:
- Tools/tests/ (README + __init__) with 12 passing unittest tests covering
  input_emulation's ioctl/key-code encoding and block_height_report's height
  classification.
- requirements-tools.txt (requests).
- Extracted classify_height() out of block_height_report.main() so the roof/
  shelter rule is testable — the rule itself came from the v0.1.2 finding.
- Tools/README: tests section, input-injection rows, and the removed TEMP-QA row
  replaced by the real cvar/self-test description.
- Docs/Architecture 05 + architecture.md: tools table extended (input injection,
  tests) and a link to the tool rules; kept in sync per the new rule.
2026-11-08 16:25:26 +01:00
..

Geo

Geographic sources, manifests, and the tools that turn them into Blender and Unreal content.

OSM is layout data only. It is not authoritative for façade detail, height, or pavement, and it is never sampled as a texture or panorama source.

Layout

Path Contents
Geo/raw/ Verbatim source responses and downloads, checksummed. Never edited by hand.
Geo/manifests/ One manifest per source: extract, DEM, and the local origin
Geo/verification/ Per-pass notes: address, footprints, bounds, street profile, cross-sections, elevation
Geo/tools/ Every geographic tool (Python, standard library only unless noted)

Tools that build 3D content from these sources live next to their output in Art/blender/*/ (terrain_from_dem.py, street_mesh.py, site_assembly.py, blosm_blockout.py) because they need Blender; their shared geo helpers and the unit conversion come from Geo/tools/osm_common.py.

Tools

Tool Purpose
osm_common.py Shared helpers: parse .osm, stitch and clip a street, project to UTM through PROJ, and the single metres→centimetres conversion (to_unreal_local)
block_report.py Streets, boundary intersections, and the building set for a block, split by side
block_height_report.py Every block building with its height source — tag, levels × 3.2 m, or a placeholder guess
street_profile.py Carriageway width from crossings, sidewalk offsets, per-building setbacks
street_section.py Cross-sections from the DEM: crown, gutters, kerb detection
elevation_probe.py Samples 3DEP for relief and records the baseline for the release checks
dem_stats.py Stdlib reader for the tiled GeoTIFF the 3DEP service returns; GDAL does not run on this host
asset_metadata.py Writes and audits <asset>.geo.json sidecars: position, provenance, conversion

Unit boundary

There is exactly one conversion in the repository:

WGS84 (lat, lon) → EPSG:26911 (E, N metres) → project-local metres → Unreal centimetres

Geo/tools/osm_common.py::to_unreal_local is the only place that multiplies by 100. Per-asset sidecars record the result, and asset_metadata.py audit checks each saved sidecar against that function, so a file that drifts is caught rather than trusted.

Current state

The extract, both El Capitan footprints, the demo bounds, the building sets, the street profile, cross-sections, and the 3DEP DEM window are recorded in Geo/verification/ and Geo/manifests/. The local CRS and origin are fixed in manifests/local-origin.md.

Open items live in TODO.md under Geographic data.