feat: make road compiler standalone

This commit is contained in:
2026-08-25 17:53:49 +08:00
parent aadd45bcad
commit 8e79790261
8 changed files with 588 additions and 2 deletions

View File

@@ -0,0 +1,98 @@
# Native Road Package v1
`native-road-package/v1` defines the boundary between the host area pipeline
and the native road compiler. The compiler accepts only the input below; it
does not read `config/areas/*.json` or derive host paths.
## Input
```js
{
areaId: string,
osmFile: string,
outDir: string,
stagingDir: string,
overridesFile: string,
trafficSignalsFile: string,
comparisonDir?: string,
options: {
edgeLines: boolean,
junctionTemplates: {
enabled: boolean,
references: [],
clusters: []
}
}
}
```
All paths are absolute at the process boundary. `stagingDir` is the parent for
the compiler's temporary output and `outDir` is promoted atomically only after
all files are written. The host maps normalized area configuration to this
shape and owns all path derivation.
## Output
`outDir` contains these JSON documents:
- `compiled.json`: top-level keys are `schema`, `areaId`, `source`, `model`,
`movements`, `trafficSignals`, `diagnostics`, and `layers`. `source` has
`osm`, `overrides`, and `trafficSignals` paths.
- `diagnostics.json`: `{ schema: "native-road-diagnostics/v1", diagnostics: [] }`.
Each diagnostic has `id`, `severity`, `subjectId`, `sourceIds`, `rule`,
`message`, and `geometry` (a GeoJSON geometry or `null`).
- `comparison.json`: coverage counts for the road workbench.
- `traffic-signal-assemblies.json` and `traffic-signals.json`: compiler-owned
signal assembly and runtime views.
`layers/` always contains these twelve GeoJSON FeatureCollections:
1. `road_surface.geojson`
2. `intersection_surface.geojson`
3. `sidewalk_surface.geojson`
4. `edge_lines.geojson`
5. `lane_separators.geojson`
6. `center_lines.geojson`
7. `crosswalks.geojson`
8. `vehicle_stop_lines.geojson`
9. `direction_arrows.geojson`
10. `turn_arrows.geojson`
11. `lane_centerlines.geojson` (semantic, not rendered)
12. `connectors.geojson` (semantic, not rendered)
The editable signal source at `trafficSignalsFile` is a sibling of `outDir`.
It is included in the parity baseline because regeneration must be stable.
Successful CLI execution prints exactly one completion marker:
```text
NATIVE_ROAD_COMPILE_DONE {"areaId":...,"roads":N,"endpoints":N,"diagnostics":N,"output":...,"comparison":...}
```
Consumers use the CLI process plus files in `outDir` and parse this marker.
An in-process import may be an optimization, never the sole contract.
## Comparison Input Decision
`comparison.json` remains part of v1. The road workbench currently reads it,
so removing it would break a real consumer. `comparisonDir` is therefore an
optional compiler input for a future standalone package: when absent, the
compiler emits native-only counts and marks osm2streets coverage unavailable.
## Parity Rules
`scripts/road-parity.js` snapshots every file below `outDir` plus the sibling
editable signal document. JSON object keys are recursively sorted before
hashing. GeoJSON records both a sorted-feature `contentHash` and original-order
`orderHash`; either difference is reported.
The only normalization is intentional volatility removal:
- absolute paths below this repository become `<repo>/...`;
- other absolute paths become `<external>/<basename>`;
- `native-road-*` temporary directory names become `<staging>`.
No coordinates are rounded and no feature order changes are ignored. Control
experiments on 2026-08-25 compiled `fengshu-er-road` and
`nantaizi-lake-innovation-valley` twice, then regenerated their editable
signal documents. All 18 tracked files per area matched.