geo: measure the block street profile and fix the local CRS and origin

New Geo/scripts/street_profile.py measures the 279.4 m block centreline, the
three signalised crossings (20.9-25.9 m across), sidewalk centrelines at 12.6 m
and 13.6 m, and per-building setbacks of 13.0-15.8 m. Derived sidewalk widths
of ~4.0 m south and ~5.3 m north cross-check against the mapped centrelines.

Geo/manifests/local-origin.md fixes EPSG:26911 and the Highland intersection
node as origin, defines the axes and the x100 metre-to-centimetre rule, and
leaves the projected pair blank because PROJ is not installed here.

Records the lane-count discrepancy (4 tagged lanes over a 20.9 m carriageway).
This commit is contained in:
zwitschi committed 2026-11-06 22:23:44 +01:00
1 parent 74e64a374e
commit 255c1a9e86
6 files changed
+364 -7

No files matched your search

+54
View File
@@ -0,0 +1,54 @@
# Local origin and projected CRS
Defined 2026-11-06. This is the single place where geographic coordinates become local metres, and where local metres become Unreal units. Every asset, blockout, and manifest refers to it; nothing else may define its own origin.
## Projected CRS
**EPSG:26911 — NAD83 / UTM zone 11N**, metres, grid north.
NAD83 rather than WGS84 is deliberate: it is the CRS the US national elevation and parcel data are published in, and the difference against WGS84 at this latitude (roughly 1 m, varying) is far below what a walkable demo can show. The choice is recorded here so nobody has to re-derive it, and so an elevation source can be brought in without a second reprojection.
## Origin
| Field | Value |
| --- | --- |
| Definition | Hollywood Blvd × North Highland Avenue intersection node, on the boulevard centreline |
| WGS84 | lat 34.101545, lon −118.338718 |
| OSM node | the single shared node between the `Hollywood Boulevard` and `North Highland Avenue` ways in `Geo/raw/osm-api-map-2026-11-06.osm` |
| EPSG:26911 easting / northing | **to be computed** — see below |
| Rationale | a real, data-defined, reproducible point at the demo block's east boundary; no surveyed control point exists for this project |
The origin is not "the hero building" on purpose: a building may later move a metre or two as verification corrects it, while an intersection node is fixed by the source data.
### Pending value
The projected pair is not filled in yet because neither `pyproj` nor the PROJ command line tools are installed on this workstation (`Docs/environment.md`), and inventing a number that later disagrees with QGIS would be worse than leaving it blank. Fill it in the QGIS step:
```bash
python3 -c "from pyproj import Transformer; \
t=Transformer.from_crs('EPSG:4326','EPSG:26911',always_xy=True); \
print(t.transform(-118.338718, 34.101545))"
```
Record the printed easting/northing back into this table and note the PROJ version used.
## Axis convention
| Axis | Meaning |
| --- | --- |
| Local X | easting − origin easting, metres, east positive |
| Local Y | northing − origin northing, metres, north positive |
| Local Z | up, metres, elevation relative to the origin's ground height |
The block then spans roughly **X −279 m to 0 m**, Y a few tens of metres either side, which keeps float precision comfortable in Unreal.
## Conversion to Unreal
1 metre → **100 Unreal units**. The ×100 happens exactly once, in the export/import path, and is asserted by the scale test required in `ROADMAP.md`. Blender files are authored in metres; Unreal receives centimetres.
Unreal's own axes differ (X forward, Y right, Z up). If a level rotates the imported block so that "north" is not +X, that rotation is recorded once, in the level's documentation, and never baked into the export.
## Obligations
- Any OSM-derived output keeps "© OpenStreetMap contributors" and the licence link. See `THIRD_PARTY_NOTICES.md`.
- Elevation data, when chosen, must be reprojected into EPSG:26911 with the origin above, and its vertical datum recorded (NAVD88 is the expected one for US sources; ellipsoidal heights are not interchangeable).