Files
road-compiler/.trellis/tasks/archive/2026-08/08-28-junction-control-offsets/prd.md

92 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 路口控制标线偏移:斑马线与停止线可拖
父任务:`.trellis/tasks/08-26-direct-manipulation-road-editor`
这是「更多元素可直接操纵」方向的第一个元素类型。
## 为什么先做这一类
`08-26-direct-edit-map-editor` 交付了完整的直接操纵链路——
manifest → 命中 → 拖拽 → 投影 → 钳位 → ghost → 防抖 → 乱序仲裁 → 预览 → 保存 → 撤销。
这条链路**不认识具体元素**,只认 `kind + anchor + axis + value`。所以加一类元素
本应是「定义一个 kind + 一个写入器」,而不是造新子系统。
选斑马线/停止线打头因为可行性已实测确认2026-08-28
```js
611 model = modelWithDirectEditProfiles(model, options.directEdit);
613 const junctionPlans = compileJunctionPlans(model, options, diagnostics);
614 applyDirectJunctionPlans(junctionPlans, options.directEdit); // 直接编辑已合并
768 const controls = compileControlMarkings(model, lanes, diagnostics, junctionPlans);
1299 const plan = junctionPlans.get(junctionNodeId); // 已按路口取到 plan
```
junction 级约束**已经能流到控制标线的生成**,管线是通的。挡路的只是模块级常量:
```js
const STOP_LINE_OFFSET_METERS = 2.7;
const CROSSWALK_JUNCTION_INSET_METERS = 1.5;
```
它们全局一个值、不按进口区分。把常量换成「先查进口配置,没有再用默认」即可。
这与区间那件事性质不同:区间要求横断面**沿路变化**,是几何管线重构;这里只是
在已经拿到手的 `plan` 上多读一个字段。
## 强制顺序编译器优先UI 最后
`08-26-direct-edit-map-editor` 交付了一个拖了没有任何效果的区间手柄,因为
`compileGeometry()` 从不读 `profile.interval`——UI 先于消费者建成。
`research/interval-not-applied.md`
本任务反过来:**第 1 步不产出任何 UI**,只证明编译器真的消费这个参数。
第 1 步的门禁不过就停,不进入第 2、3 步。
## 范围
### 1. 服务端打通并证明(无 UI
- 新增两个约束 kind`junction-crosswalk-inset``junction-stop-line-offset`
锚点均为 `junction-approach`(求解器已建模该锚点)。
- `native-road-edits.js`schema 校验与取值范围。
- `direct-edit-solver.js``applyJunctionConstraint()` 把值写进该进口的 plan 条目。
- `native-road.js``compileControlMarkings()` 读进口配置,缺省时退回既有常量。
### 2. 手柄目标泛化
`EditHandle` 声明「一次手势写到哪里」,客户端在提交处分岔。
验收标准是:**加第 N+1 种元素时不需要修改任何已有<E5B7B2><E69C89>柄代码**。
### 3. 手柄与拖拽
选中路口后斑马线、停止线上出现手柄,沿进口方向拖动调整其距路口的距离。
复用既有链路,不新增预览或保存机制。
## 不做
- 不做红绿灯(属「有位姿的实体资产」,需要不同的写入器与相对锚点)
- 不做箭头(需先定交互语义:拖箭头应改行驶动作,而非移动图标)
- 不做区间生效,方块手柄继续隐藏
- 不改 `STOP_LINE_MAX_APPROACH_DISTANCE_METERS` 等与放置**是否成立**有关的判据,
只改放置**位置**
## 验收标准
### 第 1 步(门禁,不过则停)
- [ ]`junction-crosswalk-inset` 约束编译出的斑马线坐标,与不带时**不同**
- [ ]`junction-stop-line-offset` 约束编译出的停止线坐标,与不带时**不同**
- [ ] 无约束时输出与当前 main **逐字节相同**fixture 基线无 diff
- [ ] 越界取值产生阻塞诊断,不静默钳制
- [ ] 约束经保存与重新加载后状态为 `exact`
### 第 2、3 步
- [ ] 选中路口后斑马线与停止线出现手柄,拖动可改变其距路口距离
- [ ] 手柄位置由钳位值反算,拖到极限停在边界
- [ ] 新增元素类型未修改既有手柄代码(以 diff 佐证)
- [ ] `npm run format:check``npm run test``npm run test:client``npm run test:client:unit``npm run build` 全绿
## 顺序依赖
无前置。后继:红绿灯位姿与箭头语义,二者都依赖第 2 步的目标泛化。