Planning: parent design.md becomes the single authoritative contract (constraint model with 6 kinds, handle manifest, coordinate/unit layering, preview sequencing, storage layout and lazy migration, area config snapshot, API contract). Work is split into four independently verifiable child tasks with per-step gates and rollback points. Test infra: pin vitest 4.1.11, add test:client:unit for client pure logic, extend prettier globs to root *.ts so vitest.config.ts is checked. Add .gitignore: the repo had none, so inputs/, outputs/, workbench-data/ and the client build output were untracked rather than ignored. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3.3 KiB
3.3 KiB
道路与路口的联合求解边界
当前依赖已经存在
compileGeometry() 目前以同一 model 和 junctionPlans 依次生成道路面、车道中心线、边缘线、控制设施、中心线/车道标线、步行带、connector 与路口面。它们不是孤立图层:
道路横断面 / 进口尺寸
-> 道路面、步行带、车道偏移
-> 车道线与 connector
-> 路口边界、cutback、转弯圆角
-> 停止线、斑马线、箭头与诊断
普通路口目前由 compileJunctionPlans() 的 approach、cutbackMeters 和 boundary 驱动;复合路口则由 junctionTemplates.clusters 和 complex-junction.js 的 core radius、进口包络和角部岛生成。直接操纵不能在最终 roadSurface / intersectionSurface 上独立移动顶点,否则会破坏这条依赖链。
提议的新增阶段
OSM -> compileRoadModel -> 现有 v1 参数覆盖
-> resolveDirectEditConstraints
-> editableRoadModel + editableJunctionPlans
-> 既有图层编译器(逐步接收扩展参数) -> GeoJSON
resolveDirectEditConstraints 的职责是:
- 将
road-station/road-interval约束整理为道路横断面 profile; - 将道路末端 profile 与
junction-approach约束合并,构建一致的进口截面; - 以
junction-corner/junction-cutback约束生成可验证的 junction plan; - 在违反最小车道宽、相邻道路相交、交叉口连接线包络等不变量时,返回明确冲突而非偷偷修复;
- 输出一个 handle manifest,使地图手柄能从同一语义模型读取位置、可拖动方向、受影响对象和可见的值。
道路 interval 的默认范围由求解器决定,而不是 UI 预设像素:避开两端的 junction cutback,优先取拖拽站点两侧可用长度的有限比例;若道路过短或与另一个约束重叠,预览返回可调整范围或冲突信息。
交互预览
拖动不触发文件写入或完整工作台重建。地图维护 EditSession:
pointer down: 读取 handle 的 semantic anchor,创建 draft command
pointer move: 投影鼠标位置 -> 立即更新 ghost 与 draft constraint -> 防抖服务端预览求解
pointer up: 验证成功则压入本地命令栈;失败保留提示并回退到上一个有效预览
save: 批量持久化 constraints + operations
compile: 用已保存文档运行权威全量编译
浏览器 ghost 仅包含控制柄、辅助线与半透明预估轮廓,不承担权威道路几何。服务端复用正式编译的约束求解逻辑,返回受影响的少数 OpenLayers source(道路面、步行带、路口、标线、connector 和 handles);客户端替换它们,而非卸载 MapCanvas 或重新创建 Map。这与现有图层可见性和选择修复一致。
约束不变量
- 单车道最小宽度,例如 2.4m;道路横断面总宽度等于车道、边缘和步行带之和。
- 一个站点的左右外缘不得交叉;相邻 profile 之间必须有可计算的过渡。
- 进口截面必须在路口 cutback 处与路口边界连续。
- connector、停止线和人行横道必须保持在所属道路/路口可用面内,否则产生阻塞性诊断。
- 普通路口与复杂 cluster 不共用相同低层约束:前者锚定 node,后者锚定 cluster 和 arm,避免将 cluster 缩减为多个互相冲突的普通路口编辑。