Files
osmWorkflow/docs/native-road-package-v1.md

4.0 KiB

Native Road Package v1.1

native-road-package/v1.1 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

{
  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)

manifest.json is required. It declares the same twelve sources in published order using { source, role, materialLayer?, splitBy? }. surface and marking layers declare a host material slot; semantic layers are published but Blender must not read or render them. A splitBy entry has one exact-match case or more plus exactly one default case, so the legacy white center-line and yellow lane-separator material routing remains declarative. Consumers reject a missing/invalid manifest, a source/file mismatch, and unknown material slots.

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:

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.