8.0 KiB
8.0 KiB
道路编译器独立化(parent)
Goal
把 native road compiler 从本仓库拆成可独立维护的项目,与本项目通过版本化文件契约相辅相成; 同时把道路渲染与 OSM 建筑渲染分离,使二者可各自演进。
本任务是 parent:它拥有源需求、契约定义、子任务地图、跨子任务验收标准和最终集成评审。 它自身不承担实现工作,所有可交付物在子任务中完成。
背景:为什么现在拆
scripts/lib/native-road.js已 1695 行,compileGeometry()单函数编排 15+ 个 pass, 顺序依赖只由行号编码,每加一个特性就往既有函数尾部挂位置参数 (compileLaneMarkings已 7 个位置参数)。- 道路与建筑渲染纠缠在
blender/generate_scene.py一个脚本内, 道路图层表NATIVE_ROAD_LAYERS硬编码在blender/osmassets/catalog.py:53。 - 道路编译的迭代节奏(几何、路口、标线、V2X 语义)与建筑/植被/水体渲染完全不同, 放在一个仓库里互相牵制。
拆分的可行性前提(已核实):
native-road.js只 requirefs/path/ 两个同族道路模块,对宿主项目零耦合。- 对宿主的唯一耦合是三个 CLI 入口里的
readAreaConfig。 - 输出侧
native-road/已经是文件契约,blender/generate_scene.py:801按图层名读取。 - stdout 标记
NATIVE_ROAD_COMPILE_DONE已存在,与SCENE_DONE/CESIUM_EXPORT_DONE同一约定 —— 子进程边界事实上已预留。
Requirements
R1 契约先行
- R1.1 输入输出契约必须在任何代码移动之前写死并版本化为
native-road-package/v1, 命名对齐既有osm-asset-package/v1约定。 - R1.2 契约的权威定义见本任务
design.md;Phase 0 负责把它落成仓库内文档 + 校验脚本。
R2 可证明的等价性
- R2.1 拆分过程中每一步都必须对两个有效区域
(
fengshu-er-road/nantaizi-lake-innovation-valley) 验证产物与基线一致。 - R2.2 任何差异必须逐条书面解释后才可接受,禁止"看起来差不多"。
- R2.3 验证方法沿用既有
.trellis/spec/guides/artifact-parity-guide.md。
R3 独立可维护
- R3.1 拆出的项目必须能脱离宿主自测(自带 fixture,不读宿主
inputs/或outputs/)。 - R3.2 保留 git 历史(
git subtree split或git filter-repo)—— 1695 行几何逻辑的 blame 是踩坑记录,丢失后无人敢改。 - R3.3 编译器不得反向依赖宿主任何模块、配置或目录布局。
R4 相辅相成(防漂移)
四个机制缺一不可:
| 机制 | 作用 | 落地于 |
|---|---|---|
native-road-package/v1 版本号 |
破坏性变更必须升版本,宿主主动 opt-in | Phase 0 |
| 编译器自声明图层(layer manifest) | 加图层不需要改宿主代码 | Phase 3 |
| 两区域 parity 基线留在编译器仓库当测试语料 | 编译器无法静默弄坏宿主 | Phase 0 → Phase 2 |
宿主锁版本依赖,不用 latest |
升级是决定,不是意外 | Phase 2 |
R5 渲染分离
- R5.1 道路图层表必须从宿主
catalog.py的硬编码变为编译器输出的 manifest。 - R5.2
blender/generate_scene.py内道路渲染分支抽离为独立模块; 建筑 / 植被 / 水体保持原位。 - R5.3 分离后,编译器新增图层不需要修改宿主任何代码即可被渲染。
Constraints(硬约束)
C1 不得在拆分过程中重构 IR 🔴
lane graph 提为一等 IR 是正确方向,但必须在 Phase 2 完成之后作为独立任务。
理由:拆分的正确性完全依赖"产物逐字节不变"这一 oracle。 一旦同时改 IR,oracle 失效,且无法判断产物变化来自搬迁还是重设计。
未来若做,形式是新增输出而非替换 compiled.json,
靠"解锁 drawtonomy / OpenDRIVE / Lanelet2 导出"赚取存在理由。
C2 拆分期不引入构建步骤
编译器保持 CommonJS、无构建步骤,与宿主 pipeline 层运行时一致
(见 .trellis/spec/pipeline/index.md)。
TypeScript / ESM 是独立决策;若后续 drawtonomy PoC 需要 SDK 互操作,只能在其独立任务的扩展目录内处理。
C3 Phase 1 必须先于 Phase 2
"包边界"与"换仓库"分两步做。合并执行时若产物变化,无法区分成因。
子任务地图
| Phase | 子任务 | 交付物 | 阻塞后续 |
|---|---|---|---|
| 0 | 08-25-rc-p0-contract-baseline |
契约文档 + 两区域 checksum 基线 + 校验脚本 | 是 |
| 1 | 08-25-rc-p1-package-boundary |
本仓库内 packages/road-compiler/,窄输入契约 |
是 |
| 2 | 08-25-rc-p2-repo-split |
独立仓库 + 宿主锁版本消费 | 是 |
| 3 | 08-25-rc-p3-render-separation |
layer manifest + Blender 道路模块抽离 | 否 |
顺序约束:0 → 1 → 2 必须串行。3 依赖 2 完成。
跨子任务验收标准
- AC1 Phase 0 基线建立后,两区域每个输出文件的 checksum 已提交进版本控制
- AC2 Phase 1 结束时,
npm run build:area两区域产物对 AC1 基线逐字节一致 - AC3 Phase 2 结束时,宿主从打包依赖构建,两区域 parity 仍成立
- AC4 Phase 2 结束时,编译器仓库
npm test在不访问宿主仓库的情况下通过 - AC5 Phase 3 结束时,向编译器新增一个图层,宿主零代码改动即可渲染出来(实测验证)
- AC6 Phase 3 结束时,
.blend结构摘要对基线一致(走 artifact-parity-guide) - AC7 全程未修改
compiled.json的结构(C1 未被违反) - AC8 编译器仓库对宿主的反向依赖数为 0(grep 验证)
已识别风险(跨子任务,逐个必须有归属)
| # | 风险 | 归属 Phase | 处置 |
|---|---|---|---|
| K1 | lib/traffic-signals.js 是真共用模块:reimport-gpkg.js / build-osm2streets-qgis.js / build-area.js / test-preview-assets.js 都在用,而 native-traffic-signals.js 也依赖它 |
1 | 需细读后拆分:信号文档 schema + OSM 信号节点提取随编译器走(编译器生成它就该拥有契约),legacy QGIS/预览读取器留宿主。全案唯一需要细读再动的地方 |
| K2 | comparison.json 依赖宿主产物 —— compile-native-roads.js:87 读 area.outputs.geojsonDir 里 osm2streets 输出做对比,拆出后摸不到 |
0(决策)/ 1(执行) | osm2streets 已 legacy,倾向直接砍掉,用高德参考 + 规范校验取代。决策需在 Phase 0 定档 |
| K3 | config 内绝对路径指向宿主仓库:config/areas/fengshu-er-road.json 的 referenceFile: "/Users/que01/osm2streets-qgis-workflow/inputs/osm/珠山湖大道(枫树二路)口.geojson" |
1 | 需定参考文件解析约定(相对 config 目录 / 显式 basePath) |
| K4 | workbench 的 OpenLayers 来自宿主 node_modules(design.md 的 import map 方案) |
2 | 新仓库自带依赖 |
| K5 | 测试 fixture 依赖宿主:test-native-road.js:167 读 inputs/osm/枫树二路.osm,其余为内联合成 OSM |
1 | 该文件(或裁剪版)作为测试数据提交进编译器仓库 |
Out of Scope
- lane graph IR 重构(见 C1,未来独立任务)
- pass manager / 显式依赖声明重构(同上,属编译器内部演进,不属本次拆分)
- 替换编译器为 drawtonomy 或 osm2streets —— 已评估否决:
drawtonomy 开源部分只读 Lanelet2(显式车道边界),不做 OSM
highway=*推导, 与本编译器的核心能力方向垂直 - osm2streets / QGIS legacy 链路的任何改动
- 宿主侧建筑 / 植被 / 水体渲染逻辑的改动(Phase 3 只抽离道路部分)
Notes
- 评估结论与选型依据见
design.md的「决策记录」一节。 - 时间估计:Phase 0-2 约 3 天(搬家 + 证明没搬坏),Phase 3 约 1-2 天。 拿到"道路与建筑渲染分离、可独立维护"是在 Phase 3 结束。
- 父任务验收完成后,下一项候选任务是独立的
08-25-rc-p4-drawtonomy-ext(drawtonomy 扩展 PoC);它不属于本任务完成条件。