fix: stabilize fengshu native road compilation
This commit is contained in:
@@ -154,7 +154,26 @@ function loadOverrides(file) {
|
||||
return validateOverrides(JSON.parse(fs.readFileSync(file, "utf8")));
|
||||
}
|
||||
|
||||
function validateOverrides(value, model) {
|
||||
// An override points at an id derived from OSM. Editing the source can retire
|
||||
// that id — a way deleted, or split differently so `segment/6` no longer
|
||||
// exists — which leaves the entry pointing at nothing. That is stale data, not
|
||||
// a malformed override, so callers that merely consume overrides can ask to
|
||||
// skip them and keep going. Callers that *save* overrides still use the default
|
||||
// strict mode: writing a reference that cannot resolve is a real error.
|
||||
function staleOverrideTarget(item, sets) {
|
||||
if (!sets.roadIds) return null;
|
||||
if (item.kind === "road" && typeof item.roadId === "string" && !sets.roadIds.has(item.roadId)) return item.roadId;
|
||||
if (item.kind === "lane-separator-style" && typeof item.roadId === "string" && !sets.roadIds.has(item.roadId)) return item.roadId;
|
||||
if (item.kind === "edge-line-style" && typeof item.roadId === "string" && !sets.directionalRoadIds.has(item.roadId)) return item.roadId;
|
||||
if (item.kind === "center-line-style" && typeof item.segmentId === "string" && !sets.segmentIds.has(item.segmentId)) return item.segmentId;
|
||||
if (item.kind === "junction-connection" && typeof item.fromEndpointId === "string" && typeof item.toEndpointId === "string"
|
||||
&& (!sets.endpointIds.has(item.fromEndpointId) || !sets.endpointIds.has(item.toEndpointId))) return `${item.fromEndpointId} → ${item.toEndpointId}`;
|
||||
if (item.kind === "lane-connection" && typeof item.fromLaneId === "string" && typeof item.toLaneId === "string"
|
||||
&& (!sets.laneIds.has(item.fromLaneId) || !sets.laneIds.has(item.toLaneId))) return `${item.fromLaneId} → ${item.toLaneId}`;
|
||||
return null;
|
||||
}
|
||||
|
||||
function validateOverrides(value, model, options = {}) {
|
||||
if (!value || value.schema !== OVERRIDE_SCHEMA || !Array.isArray(value.overrides)) throw new Error(`Overrides must use ${OVERRIDE_SCHEMA}.`);
|
||||
const ids = new Set();
|
||||
const roadIds = model ? new Set(model.roads.flatMap((road) => [road.id, road.sourceRoadId])) : null;
|
||||
@@ -162,9 +181,16 @@ function validateOverrides(value, model) {
|
||||
const endpointIds = model ? new Set(model.endpoints.map((endpoint) => endpoint.id)) : null;
|
||||
const laneIds = model ? new Set(model.roads.flatMap((road) => Array.from({ length: road.laneCount }, (_, index) => `lane:${road.id}:${index + 1}`))) : null;
|
||||
const segmentIds = model ? new Set(model.roads.map((road) => road.segmentId)) : null;
|
||||
const sets = { roadIds, directionalRoadIds, endpointIds, laneIds, segmentIds };
|
||||
const kept = [];
|
||||
const stale = [];
|
||||
for (const item of value.overrides) {
|
||||
if (!item || typeof item.id !== "string" || !item.id || ids.has(item.id)) throw new Error("Each override needs a unique id.");
|
||||
ids.add(item.id);
|
||||
if (options.skipStaleTargets) {
|
||||
const target = staleOverrideTarget(item, sets);
|
||||
if (target) { stale.push({ id: item.id, kind: item.kind, target }); continue; }
|
||||
}
|
||||
if (item.kind === "road") {
|
||||
if (typeof item.roadId !== "string" || roadIds && !roadIds.has(item.roadId)) throw new Error(`Unknown road override target: ${item.roadId}`);
|
||||
for (const key of ["widthMeters", "laneCount"]) if (item[key] !== undefined && (!Number.isFinite(item[key]) || item[key] <= 0 || (key === "laneCount" && !Number.isInteger(item[key])))) throw new Error(`Invalid road override ${key}.`);
|
||||
@@ -181,8 +207,9 @@ function validateOverrides(value, model) {
|
||||
} else if (item.kind === "edge-line-style") {
|
||||
if (typeof item.roadId !== "string" || (directionalRoadIds && !directionalRoadIds.has(item.roadId)) || !["left", "right"].includes(item.side) || !CENTER_LINE_COLORS.has(item.color) || !CENTER_LINE_PATTERNS.has(item.pattern)) throw new Error("Invalid edge line style override.");
|
||||
} else throw new Error(`Unsupported override kind: ${item.kind}`);
|
||||
kept.push(item);
|
||||
}
|
||||
return { schema: OVERRIDE_SCHEMA, overrides: value.overrides };
|
||||
return { schema: OVERRIDE_SCHEMA, overrides: kept, stale };
|
||||
}
|
||||
|
||||
function applyRoadOverrides(road, overrides, diagnostics) {
|
||||
|
||||
Reference in New Issue
Block a user