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

4.5 KiB
Raw Blame History

路口主导的短路段整条置灰

父任务:.trellis/tasks/08-26-direct-manipulation-road-editor。约束模型与编辑所有权的权威定义在父任务 design.md

问题

src/compile/direct-edit-solver.jseditable: false 的唯一来源是 unavailable

const start = Math.min(1, startReserve);
const end = Math.max(0, 1 - endReserve);
const unavailable = start >= end;

junctionReserves() 给每端保留区的比例有硬上限 Math.min(0.45, cutback / length) 于是 start ≤ 0.45end ≥ 0.55start >= end 结构上永远为假。 该分支是死代码,连带那句提示语「该道路全部位于路口保留区,请进入 JunctionTools 编辑。」永远不可能显示。

实测 test/fixtures/fengshu-er-road.osm126 个道路手柄0 个 editable: false

后果是短路段拿到了一条无意义的编辑带(test/fixtures/fengshu-er-road.osm20 个有保留区的段):

路长(米) 总宽(米) 窗口 可编辑带(米)
14.5 9.8 [0.45,0.55] 1.5
15.4 9.8 [0.45,0.55] 1.5
18.6 9.8 [0.45,0.55] 1.9
19.1 9.8 [0.45,0.55] 1.9
19.2 9.8 [0.45,0.55] 1.9
19.6 6.5 [0.45,0.55] 2.0
82.2 9.8 [0.17,0.83] 54.9
199.2 9.8 [0.00,0.93] 185.6

第一行那条路只有 14.5 米长、9.8 米宽cutback 是 max(宽度) × 1.4 ≈ 13.7 米—— 每一端的路口都要这条路的 94%,两端合计 188%,远超全长。上限把它压成各 45% 凭空造出中间 10%1.5 米)的「可编辑带」。

这违反两条已写明的约定:

  • 父任务不变量「相邻 profile 之间必须有可计算的过渡」。约束默认 transition: 'smoothstep' 作用于区间两端回归基线1.5 米的区间两侧紧贴保留区,没有任何余量做过渡。
  • 父任务「编辑所有权」:主地图只编辑两个 junction reserve 之间的道路内部 interval。 这种路的真实路口几何占满全长,根本不存在「之间」。

目标

让路口几何占满的短路段整条归 JunctionTools恢复那个分支的可达性 并使父任务 prd 的验收标准「落在 junction reserve 内的手柄不可拖动,并提示进入 JunctionTools」 从空真变成可演示。

判据

可编辑带长度(米)< 道路总宽度(米)→ 该 segment 的所有道路手柄 editable: false

用物理长度而非归一化 station理由是过渡段需要的是实际距离与道路长短无关。 一条比自身宽度还短的编辑带装不下横断面的平滑变化。

在上表数据上分界干净无边界模糊样本1.5 < 9.8 置灰54.9 > 9.8 保留。 恰好切出可编辑带 < 10 米的那 6 段。

判断必须在上限生效之后用实际窗口算,而不是拿未截断的 cutback / length 之和—— 后者与「过渡段放不下」这件事没有直接关系。

验收标准

  • 可编辑带短于道路宽度的 segment其全部 road-* 手柄 editable: false 且带 disabledReason
  • disabledReason 复用既有文案,引导进入 JunctionTools。
  • 可编辑带不短于道路宽度的 segment行为与当前 main 完全一致(手柄数量、位置、editable: true)。
  • 置灰不改变 reserves 本身,也不改变任何几何输出:compileGeometry 结果与置灰前逐字节一致。
  • 置灰的 segment 仍然出现在 manifest 中(不是被删除),否则客户端无法解释为什么不能编辑。
  • junction 手柄不受影响,仍然 editable: true
  • test/direct-edit-solver.js 覆盖:短路段全部置灰、正常路段不受影响、判据边界(带长 ≈ 宽度)。
  • npm run testnpm run test:clientnpm run test:client:unitnpm run format:checknpm run build 全绿。
  • 客户端无需改动即可显示灰色手柄与原因(08-26-direct-edit-map-editor 已实现该路径)。

不做

  • 不改 junctionReserves() 的 0.45 上限本身。上限保护的是 reserve 语义,改它会牵动 junction 侧几何。
  • 不改 cutback 的推导公式。
  • 不实现 JunctionTools 侧的编辑能力(属 08-26-direct-edit-junction-tools)。
  • 不做客户端改动。
  • 不把置灰的 segment 从 manifest 里移除。

顺序依赖

08-26-direct-edit-map-editor 的第 4、5 步无依赖,可并行或后置。 客户端置灰渲染路径已在该任务第 3 步交付并有单测覆盖,本任务只补上服务端的输入。