Add area diagnostics command
This commit is contained in:
@@ -42,13 +42,14 @@ Blender 高度与线性颜色。两侧靠 `catalog.check_layers()` 对账集合
|
||||
|
||||
### 区域输出路径
|
||||
|
||||
输出路径只在 `scripts/build-area.js:74` 的 `normalizeAreaConfig()` 推导。
|
||||
低层脚本读取 `_pipeline/osm2streets-qgis.config.json`,不要重新读取
|
||||
输出路径只在 `scripts/lib/area-config.js` 的 `normalizeAreaConfig()` 推导。
|
||||
`scripts/build-area.js` 和 `scripts/diagnose-area.js` 都必须通过 `readAreaConfig()` 读取
|
||||
区域配置。低层脚本读取 `_pipeline/osm2streets-qgis.config.json`,不要重新读取
|
||||
`config/areas/*.json` 或在阶段函数里现场拼路径。
|
||||
|
||||
新增产物时,在 `normalizeAreaConfig` 的 `outputs` 里加一项,再按需写入
|
||||
`writeDerivedConfig()`(`build-area.js:189`)。这样 `intermediates`、`reimport`、
|
||||
`blender`、`cesium`、`preview` 仍然只通过磁盘产物耦合。
|
||||
新增产物时,在 `area-config.js` 的 `outputs` 里加一项,再按需写入
|
||||
`writeDerivedConfig()`。这样 `intermediates`、`reimport`、`blender`、`cesium`、
|
||||
`preview` 和读-only 诊断仍然只通过磁盘产物耦合。
|
||||
|
||||
### 材质声明
|
||||
|
||||
@@ -65,18 +66,20 @@ Cesium 导出调色也属于同一个材质声明:新场景把 `catalog.MATERI
|
||||
|
||||
## 可接受的重复
|
||||
|
||||
### 三份 `parseArgs`
|
||||
### 多份 `parseArgs`
|
||||
|
||||
`parseArgs` 现在重复在三个独立入口:
|
||||
`parseArgs` 现在重复在多个独立入口:
|
||||
|
||||
- `scripts/build-area.js:50`
|
||||
- `scripts/build-area.js:54`
|
||||
- `scripts/build-osm2streets-qgis.js:153`
|
||||
- `scripts/reimport-gpkg.js:93`
|
||||
- `scripts/compress-glb.js:16`
|
||||
- `scripts/diagnose-area.js:17`
|
||||
|
||||
语义一致:`--kebab-case value` 变 `kebabCase: "value"`,无值 flag 变字符串 `"true"`。
|
||||
|
||||
这份重复目前是可接受技术债,因为三个脚本都能独立运行。改其中一处解析语义时,不要顺手
|
||||
只改一份;要么保持三份一致,要么把"抽公共模块"作为独立重构并跑 parity。
|
||||
这份重复目前是可接受技术债,因为这些脚本都能独立运行。改其中一处解析语义时,不要顺手
|
||||
只改一份;要么保持全部入口一致,要么把"抽公共模块"作为独立重构并跑对应入口检查。
|
||||
|
||||
### JS 与 Python 的图层颜色
|
||||
|
||||
@@ -132,7 +135,7 @@ Cesium 导出调色也属于同一个材质声明:新场景把 `catalog.MATERI
|
||||
|
||||
不要因为代码相似就抽象:
|
||||
|
||||
- 三份 `parseArgs` 当前保持独立入口价值
|
||||
- 多份 `parseArgs` 当前保持独立入口价值
|
||||
- `ROAD_LAYERS` 与 `SCENE_LAYERS` 跨语言且承载不同字段
|
||||
- 每个要素模块各自调用 `clip_polygon` 是模块边界,不是可消除重复
|
||||
|
||||
@@ -156,6 +159,6 @@ Cesium 导出调色也属于同一个材质声明:新场景把 `catalog.MATERI
|
||||
| 新增一份图层名列表 | 回到旧的四份同步,漏改静默错栈 |
|
||||
| 把两套颜色表统一 | 破坏 QGIS 与 Blender 各自调过的视觉结果 |
|
||||
| 低层脚本直接读 `config/areas/*.json` | 两层配置边界失效 |
|
||||
| 只改一份 `parseArgs` 的语义 | 三个入口行为分裂 |
|
||||
| 只改一份 `parseArgs` 的语义 | 独立入口行为分裂 |
|
||||
| 把要素模块裁剪逻辑挪到调用方 | 不同要素的越界处理开始漂移 |
|
||||
| 只改 `export_cesium.py` 的旧回退表,不写 `MATERIALS[*]["cesium"]` | 新 `.blend` 不会携带 Cesium 导出契约 |
|
||||
|
||||
@@ -30,8 +30,9 @@
|
||||
### 读代码复用思考指南
|
||||
|
||||
- [ ] 准备新增第二份或第三份图层、材质、配置字段枚举
|
||||
- [ ] 修改三份重复的 `parseArgs` 之一:
|
||||
`build-area.js:50`、`build-osm2streets-qgis.js:153`、`reimport-gpkg.js:93`
|
||||
- [ ] 修改多份重复的 `parseArgs` 之一:
|
||||
`build-area.js:54`、`build-osm2streets-qgis.js:153`、`reimport-gpkg.js:93`、
|
||||
`compress-glb.js:16`、`diagnose-area.js:17`
|
||||
- [ ] 多个要素模块都要做同一件几何预处理,比如
|
||||
`water.py:9`、`grass.py:9`、`scrub.py:8` 都先 `clip_polygon`
|
||||
- [ ] 低层脚本想直接读取 `config/areas/*.json`,绕开派生配置
|
||||
@@ -66,7 +67,7 @@ grep -rn "要改的值" scripts blender config
|
||||
- 先看它有没有读到对应包的 index 和本目录指南
|
||||
- 对任何"行为没变"的结论,要求说明是否需要 parity;需要却没跑就是风险
|
||||
- 对任何"可以合并重复"的建议,先判断重复是不是刻意边界:
|
||||
三份 `parseArgs` 目前是可接受技术债,JS/Python 图层颜色则是刻意不同步
|
||||
多份 `parseArgs` 目前是可接受技术债,JS/Python 图层颜色则是刻意不同步
|
||||
- 对任何"加精度、加默认值、直接覆盖文件"的建议,回到真实代码注释验证;
|
||||
`reimport-gpkg.js:152-156` 和 `reimport-gpkg.js:11-13` 都是反直觉约束
|
||||
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
|
||||
---
|
||||
|
||||
## 三个入口脚本
|
||||
## 命令入口脚本
|
||||
|
||||
| 脚本 | 角色 | 入口方式 |
|
||||
|---|---|---|
|
||||
| `scripts/build-area.js` | **主入口**。读区域配置,按阶段调度 | `npm run build` / `build:area` |
|
||||
| `scripts/build-osm2streets-qgis.js` | intermediates 阶段的实现 | 由 build-area 调起;`npm run build:qgis` 可单跑 |
|
||||
| `scripts/reimport-gpkg.js` | reimport 阶段的实现 | 由 build-area 调起 |
|
||||
| `scripts/diagnose-area.js` | 快速区域诊断;只读配置、OSM 和已有产物 | `npm run diagnose:area` |
|
||||
|
||||
`scripts/parity.js` 和 `scripts/glb-digest.js` 是校验工具,不属于构建链,见
|
||||
[产物一致性指南](../guides/artifact-parity-guide.md)。
|
||||
@@ -119,10 +120,102 @@ npm run compress:glb -- --input outputs/a/a.glb --output outputs/a/a-compressed-
|
||||
|
||||
---
|
||||
|
||||
## 区域诊断命令
|
||||
|
||||
### 1. Scope / Trigger
|
||||
|
||||
`diagnose:area` 是手工编辑 OSM、排查 building relation、高度语义、植被数量和现有
|
||||
产物体量时的快速读-only 检查。它不属于构建阶段,不进入 `--stages`,也不调用 QGIS、
|
||||
Blender、Cesium 或 `gltf-transform`。
|
||||
|
||||
### 2. Signatures
|
||||
|
||||
```bash
|
||||
npm run diagnose:area
|
||||
npm run diagnose:area -- --config config/areas/<area>.json
|
||||
```
|
||||
|
||||
底层入口:
|
||||
|
||||
```bash
|
||||
node scripts/diagnose-area.js [--config config/areas/<area>.json]
|
||||
```
|
||||
|
||||
### 3. Contracts
|
||||
|
||||
- 不传 `--config` 时默认读取 `config/areas/nantaizi-lake-innovation-valley.json`。
|
||||
- 区域配置必须通过 `scripts/lib/area-config.js` 的 `readAreaConfig()` 归一化,和
|
||||
`build-area.js` 共用同一套输出路径、压缩文件名、默认阶段和配置字段语义。
|
||||
- 命令只读取:
|
||||
- 区域配置
|
||||
- 配置里的 OSM XML
|
||||
- 已存在的 `area.outputs.*` 产物
|
||||
- 已存在的默认 GLB(通过 `scripts/glb-digest.js` 导出的 `digest()`)
|
||||
- 输出为 text report,包含 OSM bounds、节点/way/relation 数量、building way、
|
||||
building multipolygon relation、显式 `height` / `building:levels`、植被数量、
|
||||
产物存在性、metadata 摘要、GLB size/counts/extensions 和 warnings。
|
||||
- warnings 不改变退出码;配置缺失、输入 OSM 缺失、GLB 文件损坏这类无法继续读取的错误才
|
||||
非零退出。
|
||||
|
||||
### 4. Validation & Error Matrix
|
||||
|
||||
| 条件 | 结果 |
|
||||
|---|---|
|
||||
| 配置文件不存在 | `Config file not found: <path>`,非零 |
|
||||
| `id` / `input` 缺失 | `Missing config key: <key>`,非零 |
|
||||
| OSM XML 不存在 | `Input OSM XML not found: <path>`,非零 |
|
||||
| OSM 缺 `<bounds>` | warning,不中断 |
|
||||
| building multipolygon 缺 outer / unresolved way / open ring | warning,不中断 |
|
||||
| baseline 产物缺失 | warning,不中断 |
|
||||
| metadata JSON 损坏 | warning,不中断 |
|
||||
| GLB 存在但不是合法 GLB | 抛出 `glb-digest` 错误,非零 |
|
||||
| GLB 超过保守预算 | warning,不中断 |
|
||||
|
||||
### 5. Good/Base/Bad Cases
|
||||
|
||||
- Good: 手工改完 OSM 后先跑 `npm run diagnose:area -- --config ...`,确认 building
|
||||
relation healthy,再跑 `--stages blender,cesium`。
|
||||
- Base: 只生成过部分阶段时运行诊断,缺失产物以 warning 暴露,用来判断下一步该补哪个阶段。
|
||||
- Bad: 把诊断做成 `build-area` 的新 stage;它是读-only 工具,不应参与构建调度或产物生成。
|
||||
|
||||
### 6. Tests Required
|
||||
|
||||
- `node --check scripts/diagnose-area.js`
|
||||
- `node --check scripts/lib/area-config.js`
|
||||
- `node --check scripts/build-area.js`
|
||||
- `node --check scripts/glb-digest.js`
|
||||
- `npm run diagnose:area -- --config config/areas/nantaizi-lake-innovation-valley.json`
|
||||
- 如果抽取了配置归一化,至少跑一个轻量 `build-area` 阶段确认主入口仍能调度:
|
||||
`npm run build:area -- --config config/areas/nantaizi-lake-innovation-valley.json --stages preview`
|
||||
|
||||
### 7. Wrong vs Correct
|
||||
|
||||
Wrong:
|
||||
|
||||
```js
|
||||
const config = JSON.parse(fs.readFileSync("config/areas/a.json", "utf8"));
|
||||
const glb = path.join(config.outputRoot, config.id, `${config.id}.glb`);
|
||||
```
|
||||
|
||||
Correct:
|
||||
|
||||
```js
|
||||
const { readAreaConfig } = require("./lib/area-config");
|
||||
const area = readAreaConfig(configPath, { repoRoot });
|
||||
const glb = area.outputs.glb;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CLI 参数解析
|
||||
|
||||
三个脚本各有一份**完全相同**的 `parseArgs`
|
||||
(`build-area.js:50`、`build-osm2streets-qgis.js:153`、`reimport-gpkg.js:93`):
|
||||
独立入口脚本各有一份同语义的 `parseArgs`:
|
||||
|
||||
- `build-area.js:54`
|
||||
- `build-osm2streets-qgis.js:153`
|
||||
- `reimport-gpkg.js:93`
|
||||
- `compress-glb.js:16`
|
||||
- `diagnose-area.js:17`
|
||||
|
||||
```js
|
||||
--kebab-case value → { kebabCase: "value" }
|
||||
@@ -136,9 +229,9 @@ npm run compress:glb -- --input outputs/a/a.glb --output outputs/a/a-compressed-
|
||||
- **不做校验**。未知参数被静默收集,缺失参数由下游的 `requireText` / `Number.isFinite`
|
||||
报错
|
||||
|
||||
> 这份重复是已知的、**当前被接受的**技术债:三个脚本要能各自独立运行,抽公共模块的
|
||||
> 收益还不抵引入一层依赖。改其中一份时**不要**顺手把另外两份重构掉——那是独立的决定,
|
||||
> 且会扩大 diff。真要抽取,三处一起改并跑 parity。
|
||||
> 这份重复是已知的、**当前被接受的**技术债:这些脚本要能各自独立运行,抽公共模块的
|
||||
> 收益还不抵引入一层依赖。改其中一份解析语义时**不要**只改一份;要么保持全部一致,
|
||||
> 要么把抽公共解析器作为独立重构并跑对应入口检查。
|
||||
|
||||
---
|
||||
|
||||
@@ -279,7 +372,7 @@ parity 校验依赖 stage 的 stdout 标记来判断阶段是否跑到(如 `SC
|
||||
| 让 `reimport` / `preview` 能从配置文件默认开启 | 恢复动作变成常规行为 |
|
||||
| 新阶段忘了 `ensureFile` 前置校验 | 单跑时报底层堆栈而非人话 |
|
||||
| 改 stage 的 stdout 标记 | 静默破坏 parity 契约 |
|
||||
| 顺手把三份 `parseArgs` 合并 | 扩大 diff,且三个脚本的独立性是刻意的 |
|
||||
| 顺手把多份 `parseArgs` 合并 | 扩大 diff,且独立入口的独立性是刻意的 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
| 改九个 osm2streets 图层(增/删/改顺序/改色) | [图层表](./layer-registry.md) ← **最容易出静默错误** |
|
||||
| 调 QGIS / GDAL / Blender 子进程 | [外部工具调用](./external-tools.md) |
|
||||
| 加阶段、加 CLI 参数、改配置字段 | [CLI 与阶段](./cli-and-stages.md) |
|
||||
| 改区域诊断命令或共享区域配置归一化 | [CLI 与阶段](./cli-and-stages.md#区域诊断命令) |
|
||||
| 改预览页生成 | [../preview/](../preview/index.md) |
|
||||
| 声称"纯重构,产物不变" | [产物一致性指南](../guides/artifact-parity-guide.md) |
|
||||
|
||||
@@ -23,7 +24,9 @@
|
||||
```
|
||||
config/areas/<id>.json
|
||||
│
|
||||
▼ build-area.js — normalizeAreaConfig() 推导全部输出路径
|
||||
▼ lib/area-config.js — normalizeAreaConfig() 推导全部输出路径
|
||||
│
|
||||
▼ build-area.js — 阶段调度
|
||||
_pipeline/osm2streets-qgis.config.json (派生配置)
|
||||
│
|
||||
├─[intermediates]─▶ build-osm2streets-qgis.js
|
||||
@@ -75,14 +78,16 @@ config/areas/<id>.json
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|---|---|---|
|
||||
| `build-area.js` | 774 | 主入口:配置归一化、阶段调度、Cesium 预览页与车辆巡航生成 |
|
||||
| `build-area.js` | 745 | 主入口:区域配置读取、阶段调度、Cesium 预览页与车辆巡航生成 |
|
||||
| `diagnose-area.js` | 438 | 快速诊断:OSM building relation、植被统计、现有产物和 GLB digest |
|
||||
| `lib/area-config.js` | 133 | 区域配置归一化与输出路径推导,供 build / diagnose 复用 |
|
||||
| `build-osm2streets-qgis.js` | 1468 | intermediates:osm2streets 解析、图层拆分、人行道转角合成、GeoPackage 与 QGIS 工程生成 |
|
||||
| `reimport-gpkg.js` | 179 | reimport:GeoPackage → GeoJSON 反向导出 |
|
||||
| `lib/scene-layers.js` | 164 | 九个图层的单一事实源 + 四个派生函数 |
|
||||
| `lib/cesium-preview.js` / `.css` | 672 / 230 | 预览页运行时,见 [../preview/](../preview/index.md) |
|
||||
| `normalize-lane-arrows.py` | 182 | 合并 osm2streets 的三角网箭头(跑在 QGIS Python 里) |
|
||||
| `parity.js` | 270 | 产物一致性校验驱动 |
|
||||
| `glb-digest.js` | 121 | GLB 结构摘要 |
|
||||
| `glb-digest.js` | 132 | GLB 结构摘要,CLI 和诊断脚本共用 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user