101 lines
5.0 KiB
Markdown
101 lines
5.0 KiB
Markdown
# Design: QGIS Traffic Signal Overrides
|
|
|
|
## Architecture
|
|
|
|
Introduce a separate auxiliary-edit-layer registry rather than adding traffic signals to `SCENE_LAYERS`. The initial registry contains one layer:
|
|
|
|
```text
|
|
traffic_signal_assemblies.geojson
|
|
geometry: Point (pole ground position, EPSG:4326)
|
|
properties: stable identity, source identity, heading, phase, reach, stop point, enabled, z offset
|
|
```
|
|
|
|
The existing runtime file remains:
|
|
|
|
```text
|
|
traffic_signals.json
|
|
version/layout/signals[] with full pose.* data
|
|
```
|
|
|
|
The editable GeoJSON is the placement source; the runtime JSON is a derived consumer artifact.
|
|
|
|
## Data Flow
|
|
|
|
```text
|
|
OSM controls + topology + stop lines + intersections
|
|
|
|
|
intermediates only
|
|
v
|
|
traffic_signal_assemblies.geojson
|
|
|
|
|
import into GeoPackage
|
|
|
|
|
edit in QGIS
|
|
|
|
|
reimport
|
|
v
|
|
traffic_signal_assemblies.geojson
|
|
|
|
|
validate + derive pose
|
|
v
|
|
traffic_signals.json
|
|
/ \
|
|
Blender preview/Cesium
|
|
```
|
|
|
|
`blender` reruns the final validation/derivation arrow from the editable GeoJSON so derived JSON cannot be stale, but it never reruns the OSM initialization arrow.
|
|
|
|
## Editable Feature Contract
|
|
|
|
Recommended properties:
|
|
|
|
| Property | Type | Ownership |
|
|
|---|---|---|
|
|
| `signal_uid` | string | generated, immutable technical identity |
|
|
| `display_id` | string | user-editable unique label/number |
|
|
| `control_id` | string | generated OSM control id |
|
|
| `approach_id` | string | generated physical approach identity |
|
|
| `source_way_id` | string | generated matching/diagnostic field |
|
|
| `heading_deg` | number | user-editable assembly facing direction |
|
|
| `phase_group` | integer 0/1 | user-editable current two-phase group |
|
|
| `mast_reach_m` | positive number | user-editable arm reach |
|
|
| `stop_lon`, `stop_lat` | finite numbers | generated vehicle stop point, preserved when pole moves |
|
|
| `enabled` | boolean/integer | user-editable suppression flag |
|
|
| `z_offset_m` | finite number | user-editable vertical adjustment |
|
|
|
|
Point geometry is the pole longitude/latitude. The runtime `id` should be derived from `signal_uid`, not display numbering, so changing `display_id` does not rename GLB nodes or break preview control.
|
|
|
|
## Stable Identity
|
|
|
|
Extend parsed OSM arm data to retain enough deterministic source identity (control node, way, adjacent arm direction/node). Generate a technical key from those source values. Do not use sorted array index or rounded heading as the primary key.
|
|
|
|
If topology changes on a future `intermediates` run, the rebuilt GeoPackage may produce new identities. This is consistent with current road-edit lifecycle and is explicitly out of scope for MVP migration. Validation still reports duplicate identities and malformed source fields.
|
|
|
|
## QGIS Integration
|
|
|
|
- Add an auxiliary layer definition separate from the nine render layers.
|
|
- Import it into the same GeoPackage after render layers.
|
|
- Include it in the generated project but exclude it from the merged scene and 2D raster preview unless deliberately enabled for editing visibility.
|
|
- Use a point marker plus rotated direction indicator driven by `heading_deg` and label by `display_id`, falling back to `signal_uid`.
|
|
- Configure read-only/editor widgets where practical: technical/source ids read-only; phase group constrained to 0/1; numeric fields constrained to valid ranges; enabled as checkbox.
|
|
|
|
## Reimport and Atomicity
|
|
|
|
Extend the reimport layer manifest to include auxiliary editable layers while keeping render-scene merge derived only from `SCENE_LAYERS`. Export every layer into staging, parse and validate all editable features, then replace output files. Runtime JSON is written only after the staged auxiliary layer passes validation.
|
|
|
|
## Compatibility
|
|
|
|
- The next `intermediates` run bootstraps existing areas; no old JSON migration is required.
|
|
- Main `.blend`/GLB geometry changes intentionally when a QGIS edit changes a signal.
|
|
- Dynamic and countdown GLBs continue using runtime signal ids, now stable across ordinary reimport edits.
|
|
- Current two-phase simulation remains unchanged.
|
|
|
|
## Risks and Controls
|
|
|
|
- **OSM way splitting changes source ids:** accepted across a full intermediates rebuild; ordinary reimport is stable.
|
|
- **QGIS boolean/string coercion:** normalize known GDAL representations before strict validation and test the round-trip output.
|
|
- **Accidental source-field editing:** mark technical fields read-only in QGIS and validate identity format during reimport.
|
|
- **Partial overwrite on invalid auxiliary data:** retain the existing staging-before-replace discipline.
|
|
- **Old spec conflict:** update pipeline specs that currently forbid traffic-signal anchors in GeoPackage, clarifying the distinction between editable assembly points and derived runtime anchors.
|
|
|