Add OSM area preflight

This commit is contained in:
2026-08-04 11:58:12 +08:00
parent 34153a31ab
commit e1f5207e97
13 changed files with 434 additions and 5 deletions

99
scripts/preflight-area.js Normal file
View File

@@ -0,0 +1,99 @@
#!/usr/bin/env node
"use strict";
const fs = require("fs");
const path = require("path");
const { readAreaConfig } = require("./lib/area-config");
const {
analyzeOsmPreflight,
defaultConfigPath,
parseOsm,
} = require("./lib/area-diagnostics");
const { fileRecord, writeStageManifest } = require("./lib/stage-manifest");
const repoRoot = path.resolve(__dirname, "..");
function parseArgs(argv) {
const out = {};
for (let i = 0; i < argv.length; i += 1) {
const arg = argv[i];
if (!arg.startsWith("--")) continue;
const key = arg.slice(2).replace(/-([a-z])/g, (_, c) => c.toUpperCase());
const next = argv[i + 1];
if (!next || next.startsWith("--")) {
out[key] = "true";
} else {
out[key] = next;
i += 1;
}
}
return out;
}
function main() {
const startedAt = new Date().toISOString();
const args = parseArgs(process.argv.slice(2));
const configPath = path.resolve(args.config || defaultConfigPath(repoRoot));
const area = readAreaConfig(configPath, { repoRoot });
const osm = parseOsm(fs.readFileSync(area.input, "utf8"));
const preflight = analyzeOsmPreflight(osm);
printPreflightReport(area, configPath, preflight);
if (preflight.errors.length) {
process.exitCode = 1;
return;
}
const finishedAt = new Date().toISOString();
writeStageManifest(area, {
stage: "preflight",
status: "ok",
config: configPath,
startedAt,
finishedAt,
durationMs: Date.parse(finishedAt) - Date.parse(startedAt),
inputs: {
config: fileRecord(configPath),
osm: fileRecord(area.input),
},
outputs: {},
summary: preflight.summary,
errors: preflight.errors,
warnings: preflight.warnings,
});
}
function printPreflightReport(area, configPath, preflight) {
console.log("OSM area preflight");
console.log(`Area: ${area.id}`);
console.log(`Config: ${configPath}`);
console.log(`Input: ${area.input}`);
console.log("");
console.log(
`OSM: ${preflight.summary.nodes} nodes, ${preflight.summary.ways} ways, ` +
`${preflight.summary.relations} relations`,
);
console.log(
`Buildings: ${preflight.summary.buildingWays} way(s), ` +
`${preflight.summary.buildingMultipolygons} multipolygon relation(s)`,
);
console.log(`Bounds: ${preflight.summary.bounds ? "valid" : "invalid or missing"}`);
console.log("");
const status = preflight.errors.length ? "FAIL" : "PASS";
console.log(`${status}: ${preflight.errors.length} error(s), ${preflight.warnings.length} warning(s)`);
console.log("");
printLines("Errors", preflight.errors);
console.log("");
printLines("Warnings", preflight.warnings);
}
function printLines(label, lines) {
console.log(`${label} (${lines.length})`);
if (!lines.length) {
console.log(" none");
return;
}
for (const line of lines) console.log(` - ${line}`);
}
main();