feat: import native road packages from ZIP

This commit is contained in:
2026-08-26 12:51:58 +08:00
parent 009fe34f79
commit 113ea54535
15 changed files with 200 additions and 100 deletions

View File

@@ -4,7 +4,7 @@ const fs = require("fs");
const path = require("path");
const { spawnSync } = require("child_process");
const { readAreaConfig } = require("./lib/area-config");
const { compileArea: compileNativeRoads } = require("./lib/road-compiler-cli");
const { importNativeRoadPackage } = require("./lib/native-road-package");
const { resolveStages } = require("./lib/build-stages");
const { validateManifest, addIntegrity } = require("./lib/package-contract");
const { blenderExecutable: resolveBlenderExecutable } = require("./lib/tool-paths");
@@ -225,10 +225,7 @@ function buildBlenderScene(area, roadProvider) {
}
fs.mkdirSync(path.dirname(area.outputs.blend), { recursive: true });
fs.mkdirSync(path.dirname(area.outputs.render), { recursive: true });
if (roadProvider === "native") {
compileNativeRoads(area);
ensureNativeRoadLayers(area);
}
const nativePackage = roadProvider === "native" ? importNativeRoadPackage(area) : null;
const blenderArgs = [
"--background",
@@ -246,8 +243,8 @@ function buildBlenderScene(area, roadProvider) {
area.blender.treeStyle,
];
if (roadProvider === "native") {
blenderArgs.push("--native-road", area.outputs.nativeRoadDir);
blenderArgs.push("--traffic-signals", path.join(area.outputs.nativeRoadDir, "traffic-signals.json"));
blenderArgs.push("--native-road", nativePackage.rootDir);
blenderArgs.push("--traffic-signals", path.join(nativePackage.rootDir, "traffic-signals.json"));
} else {
blenderArgs.push("--geojson", area.outputs.geojsonDir);
}
@@ -270,7 +267,7 @@ function buildBlenderScene(area, roadProvider) {
inputs: {
config: fileRecord(configPath),
osm: fileRecord(area.input),
...(roadProvider === "native" ? nativeRoadRecords(area) : sceneGeojsonRecords(area)),
...(roadProvider === "native" ? nativeRoadRecords(nativePackage) : sceneGeojsonRecords(area)),
...(roadProvider === "osm2streets" ? {
geojsonDir: fileRecord(area.outputs.geojsonDir),
trafficSignalAssemblies: fileRecord(area.outputs.trafficSignalAssemblies),
@@ -282,7 +279,7 @@ function buildBlenderScene(area, roadProvider) {
render: fileRecord(area.outputs.render),
},
summary: {
...(roadProvider === "native" ? { nativeRoad: nativeRoadFeatureCounts(area) } : { geojson: geojsonFeatureCounts(area) }),
...(roadProvider === "native" ? { nativeRoad: nativeRoadFeatureCounts(nativePackage) } : { geojson: geojsonFeatureCounts(area) }),
roadProvider,
blendBytes: fileRecord(area.outputs.blend).bytes,
renderBytes: fileRecord(area.outputs.render).bytes,
@@ -291,17 +288,13 @@ function buildBlenderScene(area, roadProvider) {
});
}
function ensureNativeRoadLayers(area) {
ensureFile(path.join(area.outputs.nativeRoadDir, "compiled.json"), "Native road compilation");
for (const file of ["road_surface.geojson", "edge_lines.geojson", "intersection_surface.geojson", "sidewalk_surface.geojson", "lane_separators.geojson", "center_lines.geojson", "direction_arrows.geojson", "turn_arrows.geojson", "crosswalks.geojson", "vehicle_stop_lines.geojson"]) {
ensureFile(path.join(area.outputs.nativeRoadDir, "layers", file), `Native road layer ${file}`);
}
}
function nativeRoadRecords(area) {
const root = path.join(area.outputs.nativeRoadDir, "layers");
function nativeRoadRecords(nativePackage) {
const root = path.join(nativePackage.rootDir, "layers");
return {
nativeRoadCompiled: fileRecord(path.join(area.outputs.nativeRoadDir, "compiled.json")),
nativeRoadZip: nativePackage.zipRecord,
nativeRoadImport: fileRecord(nativePackage.rootDir),
nativeRoadCompiled: fileRecord(path.join(nativePackage.rootDir, "compiled.json")),
nativeRoadSignals: fileRecord(path.join(nativePackage.rootDir, "traffic-signals.json")),
nativeRoadSurface: fileRecord(path.join(root, "road_surface.geojson")),
nativeEdgeLines: fileRecord(path.join(root, "edge_lines.geojson")),
nativeIntersectionSurface: fileRecord(path.join(root, "intersection_surface.geojson")),
@@ -315,8 +308,8 @@ function nativeRoadRecords(area) {
};
}
function nativeRoadFeatureCounts(area) {
const root = path.join(area.outputs.nativeRoadDir, "layers");
function nativeRoadFeatureCounts(nativePackage) {
const root = path.join(nativePackage.rootDir, "layers");
return {
roadSurface: featureCount(path.join(root, "road_surface.geojson")),
edgeLines: featureCount(path.join(root, "edge_lines.geojson")),
@@ -487,8 +480,9 @@ function compressCesiumGlb(area) {
function publishPackage(area, roadProvider) {
ensureFile(area.outputs.packageStagingManifest, "Staged package manifest");
const trafficSignalsSource = roadProvider === "native"
? path.join(area.outputs.nativeRoadDir, "traffic-signals.json")
const nativePackage = roadProvider === "native" ? importNativeRoadPackage(area) : null;
const trafficSignalsSource = nativePackage
? path.join(nativePackage.rootDir, "traffic-signals.json")
: area.outputs.trafficSignals;
ensureFile(trafficSignalsSource, "Traffic signal anchors");
const started = Date.now();
@@ -574,7 +568,7 @@ function writeCesiumPreview(area, roadProvider) {
intersectionSurface: fileRecord(intersectionSurface),
});
} else {
Object.assign(previewInputs, nativeRoadRecords(area));
Object.assign(previewInputs, nativeRoadRecords(importNativeRoadPackage(area)));
// This operational preview intentionally has no synthetic vehicle source.
// A stale descriptor from an older build must not resurrect simulated routes.
fs.rmSync(area.outputs.trafficSimulation, { force: true });