Files
road-compiler/.trellis/tasks/archive/2026-08/08-27-junction-dominated-roads/implement.md

3.2 KiB
Raw Blame History

实施计划

轻量任务,一个提交即可。门禁不过就停。

前置:无。客户端置灰渲染路径已由 08-26-direct-edit-map-editor 第 3 步交付并有单测覆盖, 本任务只补服务端输入。

关键决定:置灰只影响手柄,不影响求解

editable: false 只改变 handle manifest不改变 solveConstraints() 的行为。 落在被置灰 segment 上的既有约束仍然照常应用、照常参与几何编译。

理由:否则本次改动会让升级后的编译静默丢掉用户已保存的编辑——一个 UI 可编辑性的判断 不该回溯否决已持久化的意图。用户想撤销这类编辑,走 undo / 禁用约束的正常路径。

这也让「几何输出逐字节不变」这条验收标准成立,从而使本步骤可安全回滚。

1. 判据与置灰

  • 目标:可编辑带短于道路宽度的 segment其全部 road-* 手柄 editable: false
  • 位置:src/compile/direct-edit-solver.jsmakeRoadHandles()。 该函数已算出 start / end / length / width,判据是纯本地计算,不需要新数据。
  • 实现要点:
    • 带长米数 (end - start) * length,与 width(该 segment 双向宽度之和)比较。
    • 复用既有 baseDisabled 机制与既有文案「该道路全部位于路口保留区,请进入 JunctionTools 编辑。」, 不新增第二套提示语。
    • 保留原 unavailable 判断作为兜底,两者取或。
    • 被置灰的 segment 仍然产出手柄(位置照旧),只是 editable: false 且带 disabledReason
  • 不改:junctionReserves() 的 0.45 上限、cutback 推导、solveConstraints()、junction 手柄。

2. 测试

  • 位置:test/direct-edit-solver.js
  • 覆盖:
    • 短路段(带长 < 宽度)的全部 road-* 手柄 editable: falsedisabledReason 非空。
    • 正常路段 editable: true 且无 disabledReason
    • 判据边界:带长略小于 / 略大于宽度两侧各一例。
    • junction 手柄仍 editable: true
    • 置灰 segment 上的既有约束仍被求解(constraintStatesapplied: true 证明置灰没有回溯否决已保存编辑。

3. 验证

npm run test              # 含 test/direct-edit-solver.js
npm run test:client       # 客户端类型
npm run test:client:unit  # 客户端纯逻辑
npm run format:check
npm run build

几何不变的实测(本任务的核心安全性证明):对 test/fixtures/fengshu-er-road.osm 在改动前后各跑一次 compileGeometry,比较全部输出图层的 JSON必须完全一致。 npm run test 里的 fixture 基线测试已覆盖这条,若基线有 diff 即为回归。

手测(可选,directEdit 开关打开):选中 test/fixtures 里那 6 段短路之一, 应看到灰色手柄且 header 显示原因。这是父任务 prd 那条验收标准第一次真正可演示。

4. 门禁

  • 几何输出零变化fixture 基线无 diff
  • 正常路段行为与当前 main 完全一致。
  • 既有约束不因置灰而失效。

回滚点

单文件单函数改动,git revert 即可回到当前行为。 客户端不需要任何配合改动,回滚后灰色手柄自然消失,回到「空真」状态。