feat: improve native road diagnostics and review
This commit is contained in:
@@ -23,6 +23,7 @@ function compileArea(configPath) {
|
||||
const overrides = loadOverrides(area.outputs.nativeRoadOverrides);
|
||||
const model = compileRoadModel(fs.readFileSync(area.input, "utf8"), overrides);
|
||||
validateOverrides(overrides, model);
|
||||
fs.mkdirSync(area.outputs.pipelineDir, { recursive: true });
|
||||
const compiled = compileGeometry(model, overrides);
|
||||
const staging = fs.mkdtempSync(path.join(area.outputs.pipelineDir, "native-road-"));
|
||||
try {
|
||||
@@ -34,7 +35,7 @@ function compileArea(configPath) {
|
||||
diagnostics: compiled.diagnostics,
|
||||
layers: { roadSurface: "layers/road_surface.geojson", intersectionSurface: "layers/intersection_surface.geojson", laneCenterlines: "layers/lane_centerlines.geojson", connectors: "layers/connectors.geojson" },
|
||||
};
|
||||
const comparison = compareOsm2Streets(area, result.model.roads.length);
|
||||
const comparison = compareOsm2Streets(area, result.model, compiled);
|
||||
writeJsonAtomic(path.join(staging, "compiled.json"), result);
|
||||
writeJsonAtomic(path.join(staging, "diagnostics.json"), { schema: "native-road-diagnostics/v1", diagnostics: compiled.diagnostics });
|
||||
writeJsonAtomic(path.join(staging, "comparison.json"), comparison);
|
||||
@@ -51,14 +52,36 @@ function compileArea(configPath) {
|
||||
}
|
||||
}
|
||||
|
||||
function compareOsm2Streets(area, nativeRoadCount) {
|
||||
function compareOsm2Streets(area, model, compiled) {
|
||||
const source = path.join(area.outputs.geojsonDir, "road_surface.geojson");
|
||||
let featureCount = null;
|
||||
if (fs.existsSync(source)) {
|
||||
const collection = JSON.parse(fs.readFileSync(source, "utf8"));
|
||||
featureCount = Array.isArray(collection.features) ? collection.features.length : null;
|
||||
}
|
||||
return { schema: "native-road-comparison/v1", nativeRoadCount, osm2streetsRoadSurfaceFeatures: featureCount, osm2streetsAvailable: featureCount !== null, note: "Counts are coverage evidence only; geometry quality requires diagnostic and visual review." };
|
||||
const diagnosticsBySeverity = {};
|
||||
const diagnosticsByRule = {};
|
||||
for (const item of compiled.diagnostics) {
|
||||
diagnosticsBySeverity[item.severity] = (diagnosticsBySeverity[item.severity] || 0) + 1;
|
||||
diagnosticsByRule[item.rule] = (diagnosticsByRule[item.rule] || 0) + 1;
|
||||
}
|
||||
const dangling = compiled.diagnostics.filter((item) => item.rule === "unconnected-interior-road-end");
|
||||
return {
|
||||
schema: "native-road-comparison/v2",
|
||||
nativeRoadCount: model.roads.length,
|
||||
nativeRoadSurfaceFeatures: compiled.roadSurface.features.length,
|
||||
nativeJunctionSurfaceFeatures: compiled.intersectionSurface.features.length,
|
||||
nativeLaneCenterlineFeatures: compiled.laneCenterlines.features.length,
|
||||
nativeConnectorFeatures: compiled.connectors.features.length,
|
||||
nativeConnectionCount: model.connections.length,
|
||||
unconnectedInteriorRoadEnds: dangling.length,
|
||||
unconnectedEndsWithManualCandidates: dangling.filter((item) => item.manualCandidates?.length).length,
|
||||
diagnosticsBySeverity,
|
||||
diagnosticsByRule,
|
||||
osm2streetsRoadSurfaceFeatures: featureCount,
|
||||
osm2streetsAvailable: featureCount !== null,
|
||||
note: "Counts are coverage evidence only; geometry quality requires diagnostic and visual review.",
|
||||
};
|
||||
}
|
||||
|
||||
function main() {
|
||||
|
||||
Reference in New Issue
Block a user