136 lines
6.5 KiB
Markdown
136 lines
6.5 KiB
Markdown
# Asset Package Contract Design
|
|
|
|
## Product Boundary
|
|
|
|
`outputs/<area-id>/` remains the build workspace. Its `package/` child is the only
|
|
publishable subtree and may be copied unchanged to another project. The package has
|
|
no dependency on the parent directory, repository checkout, absolute local paths,
|
|
QGIS, Blender, or the Cesium preview.
|
|
|
|
```
|
|
outputs/<area-id>/
|
|
package/ # publishable boundary
|
|
manifest.json # asset-package/v1
|
|
models/
|
|
<area-id>.glb # compressed complete static scene
|
|
roads.glb
|
|
buildings.glb
|
|
vegetation.glb
|
|
water.glb
|
|
<area-id>-cesium-preview.html # local verification only
|
|
_preview/ # vehicles, routes, dynamic signal runtime
|
|
_pipeline/ # staging, manifests and build diagnostics
|
|
osm2streets_web_out/, *.gpkg, *.qgz, *.blend, *.png
|
|
```
|
|
|
|
The package does not duplicate the GLBs: Cesium export and compression target the
|
|
package model paths. Build staging lives under `_pipeline/` and is removed before a
|
|
successful package is published.
|
|
|
|
## Manifest v1
|
|
|
|
The JSON root uses `schema: "osm-asset-package/v1"`. Required top-level fields are:
|
|
|
|
| Field | Contract |
|
|
|---|---|
|
|
| `schema`, `packageVersion`, `areaId` | Stable identity and schema evolution point |
|
|
| `coordinateSystem` | Literal local ENU contract: X east, Y north, Z up, meters |
|
|
| `placement` | WGS84 anchor longitude/latitude/height plus heading correction degrees |
|
|
| `bounds` | WGS84 `minLon`, `minLat`, `maxLon`, `maxLat` |
|
|
| `assets` | Deterministic list of declared publishable assets |
|
|
| `sceneStats` | Optional descriptive OSM-derived counts, not loading-critical |
|
|
|
|
Each asset has `id`, `role`, `category`, `uri`, and `defaultLoad`. `uri` is a
|
|
forward-slash relative path inside `package/`; it must not be absolute, start with
|
|
`/`, contain `..`, or resolve outside the package. Roles are `scene` for the complete
|
|
static scene and `layer` for separately loadable semantic subsets. Categories are
|
|
fixed in v1: `scene`, `roads`, `buildings`, `vegetation`, `water`.
|
|
|
|
`models/<area-id>.glb` is the only `scene` entry and defaults to load. Layer GLBs are
|
|
optional alternatives for selective loading and default off; consumers must not load
|
|
both the complete scene and overlapping layers unless intentionally composing them.
|
|
|
|
The manifest deliberately excludes `source_osm`, `source_geojson`, arbitrary Cesium
|
|
JavaScript, vehicle routes, vehicle models, dynamic signal states, countdown models,
|
|
preview runtime paths, build timestamps and desktop paths. File digests and sizes may
|
|
be added under an optional `integrity` object only after they are computed from final
|
|
compressed files.
|
|
|
|
## Pipeline Design
|
|
|
|
### 1. Static export seed
|
|
|
|
`blender/export_cesium.py` continues to own static GLB generation, WGS84 bounds,
|
|
anchor and semantic collection selection. It must emit data suitable for a manifest
|
|
seed, not a preview metadata document. Static traffic-signal geometry already in the
|
|
main scene remains part of the static scene; animated traffic signal and countdown
|
|
collections are not package assets.
|
|
|
|
### 2. Package staging and compression
|
|
|
|
The build orchestrator owns output paths through `normalizeAreaConfig()`. It adds
|
|
explicit package paths and exports static GLBs to a package staging directory beneath
|
|
`_pipeline/`. Compression works only on staged package files and rewrites the staged
|
|
manifest's main GLB URI after successful compression. It never needs to copy or alter
|
|
preview HTML.
|
|
|
|
After path validation, file existence checks, and manifest validation, the package
|
|
stage promotes the whole staging directory to `outputs/<area-id>/package/`. Promotion
|
|
is directory-level and replaces a previous package only after the new one is valid.
|
|
On failure, the previous published package remains usable and staging is retained or
|
|
reported for diagnosis according to existing pipeline failure conventions.
|
|
|
|
### 3. Preview adapter
|
|
|
|
The existing Cesium preview remains a verification tool outside the package. It reads
|
|
the package manifest via its relative path, then loads preview-only route, vehicle and
|
|
dynamic-signal descriptors from `_preview/`. Dynamic traffic assets are declared in a
|
|
preview-specific descriptor, never appended to package `assets`. This preserves
|
|
existing high-precision cruise validation without making it a downstream requirement.
|
|
|
|
### 4. Stage and compatibility behavior
|
|
|
|
Canonical order becomes `intermediates/reimport -> blender -> cesium -> compress ->
|
|
package -> preview`. `package` is included in the full default build and is callable
|
|
explicitly to validate/publish existing staged static exports. `preview` stays an
|
|
optional/verification stage, not a package dependency.
|
|
|
|
Existing `npm run build:area -- --config ... --stages ...` remains supported. Root
|
|
level legacy GLB/JSON/HTML files are not deleted by the migration; they are not read
|
|
as a fallback by the new package contract. A clean full build produces the package as
|
|
the canonical downstream asset source.
|
|
|
|
## Consumer Examples
|
|
|
|
Examples live in repository source, outside individual packages:
|
|
|
|
- Cesium: fetch `manifest.json`, derive the ENU frame from `placement`, apply heading
|
|
correction, then load `assets` by `uri`.
|
|
- Three.js: load the selected model URL relative to the manifest URL; expose the same
|
|
ENU placement object to the host application's georeferencing adapter. It must not
|
|
imply that Three.js alone converts ENU to WGS84.
|
|
|
|
Both examples load the complete scene and demonstrate selecting a single `layer`.
|
|
They validate that URLs are resolved relative to the manifest rather than the current
|
|
page or repository root.
|
|
|
|
## Validation and Rollback
|
|
|
|
Unit tests validate schema fields, category/role legality, package-relative URI rules,
|
|
and rejection of omitted/extra files. An integration fixture constructs a minimal
|
|
package and verifies that Cesium and Three.js example resolvers choose identical
|
|
relative URLs and placement values. A target-area package test checks final compressed
|
|
GLB parsing and manifest references.
|
|
|
|
The package stage writes a stage manifest containing only final published records and
|
|
their integrity. Diagnostic checks distinguish missing package, invalid package, and
|
|
stale package. Rollback is to the prior `package/` directory; legacy preview outputs
|
|
remain untouched throughout rollout.
|
|
|
|
## Deferred Decisions
|
|
|
|
- Rich per-feature semantics, routing graph delivery and simulation inputs are not in
|
|
v1; they should be introduced through a later schema version only when a downstream
|
|
consumer requires them.
|
|
- Asset coverage improvements are downstream of this contract work.
|