5.0 KiB
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:
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:
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
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_degand label bydisplay_id, falling back tosignal_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
intermediatesrun 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.