chore(task): archive 08-08-cesium-lane-centered-route
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
# 自动匹配 Cesium 巡航车道中心:技术设计
|
||||
|
||||
## 设计目标
|
||||
|
||||
巡航路线以 osm2streets internal road topology 与已渲染的 Driving lane polygon 为几何事实源。道路区间直接使用 polygon 的中轴,不再对 OSM way 中心线施加固定米数偏移;OSM 只提供原始标签和转向语义,不再作为最终路口拓扑。
|
||||
|
||||
## 数据流
|
||||
|
||||
```text
|
||||
network.json ──▶ internal road/intersection directed graph
|
||||
OSM XML ──▶ turn:lanes semantics
|
||||
│
|
||||
lane_polygons.geojson ──▶ validated Driving lane centerlines
|
||||
│
|
||||
▼
|
||||
maneuver-aware lane selection
|
||||
│
|
||||
▼
|
||||
internal road lane sections + surface-constrained junction curves
|
||||
│
|
||||
▼
|
||||
vehicle-route.json + diagnostics
|
||||
```
|
||||
|
||||
`scripts/build-area.js` 在 preview stage 调用 `buildVehicleRoute(osmPath, lanePolygonsPath)`。`lane_polygons.geojson` 同时写入 preview manifest inputs,`scripts/lib/area-diagnostics.js` 使用既有 SHA-256 freshness 检查自动识别过期路线。
|
||||
|
||||
## 模块边界
|
||||
|
||||
### `scripts/lib/lane-geometry.js`
|
||||
|
||||
新增纯几何共享模块,承载:
|
||||
|
||||
- 校验 Driving `Polygon` ring;
|
||||
- 通过 polygon 两侧对应顶点中点提取 lane centerline;
|
||||
- 米制距离、方向对齐、端点排序和 polyline 拼接所需的无副作用 helper。
|
||||
|
||||
`scripts/lib/turn-lane-arrows.js` 改为导入共享 `laneCenterline()`,确保箭头和巡航对 osm2streets polygon 顺序使用同一契约。
|
||||
|
||||
### `scripts/lib/vehicle-route.js`
|
||||
|
||||
保留现有 OSM 路线拓扑搜索,替换 `LANE_OFFSET_METERS` / `offsetClosedRouteRight()` 路径:
|
||||
|
||||
1. 加载并严格校验 `lane_polygons.geojson` 为 FeatureCollection。
|
||||
2. 按 `road`、lane `index` 和 `direction=Fwd|Back` 建立 Driving lane 索引;`osm_way_ids` 仅用于追溯 OSM 标签。
|
||||
3. 对每条 directed edge,使用实际横向位置按行驶方向排列同向车道;renderer `index` 只作为稳定 tie-breaker,不单独决定车道顺序。
|
||||
4. 将 edge 末端的 maneuver 与 `turn:lanes:forward|backward` 对齐。左转/掉头选最左兼容车道,右转选最右兼容车道,直行选最右兼容车道;无显式 lane restriction 时按相同位置规则选择。
|
||||
5. 每个 edge 对应一个 osm2streets internal road;禁止把同一 OSM way 下多个 internal road 当作无语义 fragment 直接拼接。
|
||||
6. 车道中轴端点之间使用 tangent Bezier / U-turn 连接,并绑定共同的 internal intersection;全部采样点必须落在对应 `intersection_surface` 内或边界容差内。
|
||||
7. 任一 edge 无法可靠匹配时丢弃该候选 route;继续搜索其他候选,最多输出 5 条。
|
||||
|
||||
## 输出契约
|
||||
|
||||
保留顶层 `routes`、兼容别名 `segments`、`loop`、`speedMetersPerSecond`,以及每条路线的 `coordinates`、`centerlineCoordinates`、`edgeIds`、`maneuvers` 和 `lengthMeters`。
|
||||
|
||||
每条路线新增 `laneSegments`,每段至少记录:
|
||||
|
||||
- `edgeId`、`osmWayId`、`direction`;
|
||||
- `laneIndex`、`widthMeters`、`centerOffsetMeters`;
|
||||
- `maneuver`、`source="lane_polygon_centerline"`;
|
||||
- 参与拼接的 polygon/road 标识。
|
||||
|
||||
顶层新增 `diagnostics`,按稳定 reason code 汇总被拒绝的 edge/route,例如 `missing_lane_polygon`、`invalid_lane_polygon`、`ambiguous_lane_order`、`no_compatible_turn_lane` 和 `disconnected_lane_fragments`。固定 `laneOffsetMeters` 不再作为几何输入;为避免伪造单值,不以平均偏移替代逐段事实。
|
||||
|
||||
## 错误与降级语义
|
||||
|
||||
- 整个 lane polygon 文件缺失、JSON 无法解析或不是 FeatureCollection:preview stage 在写产物前失败。
|
||||
- 单个 polygon 无效:记录诊断,该 polygon 不参与匹配。
|
||||
- directed edge 缺少唯一可信车道:候选 route 被拒绝,生成器继续选择其他 route。
|
||||
- 所有候选都被拒绝:生成合法的空 `routes` 和完整诊断;Cesium 场景仍可加载,但不显示巡航车辆。
|
||||
- 禁止回退到固定 `1.3 m`、固定 `1.5 m` 或默认 lane width。
|
||||
|
||||
## 兼容性
|
||||
|
||||
- Blender scene 经纬度投影改为 WGS84 ECEF→ENU,与 Cesium
|
||||
`eastNorthUpToFixedFrame` 的锚点坐标系一致;这是 route 与最终 GLB 道路重合的必要
|
||||
跨层契约。
|
||||
- `segments` 继续与 `routes` 引用相同数组。
|
||||
- Cesium runtime 当前只消费 `coordinates` 等既有字段,无需理解 `laneSegments` 即可运行。
|
||||
- preview manifest 新增 lane polygon input 后,旧 manifest 会被诊断为缺少记录并要求重建,这是预期迁移行为。
|
||||
|
||||
## 验证策略
|
||||
|
||||
- 纯几何测试:四边形、曲线 polygon、反向 geometry、坏 ring。
|
||||
- 路线 fixture:不同宽度、双向/单向、多车道和转向车道选择。
|
||||
- 精度断言:路线道路区间采样点到 polygon 中轴距离不超过 `0.10 m`。
|
||||
- 连续性断言:车道变化和路口连接处没有由数据拼接产生的异常横跳。
|
||||
- 集成验证:目标区域重跑 preview,检查 route JSON diagnostics、manifest freshness、区域质量门和 Cesium 实际显示。
|
||||
- 端到端视觉验证:重跑 `blender,cesium,preview`,对最终画面做道路横截面检查;不能用
|
||||
route 与 lane polygon 的厘米级一致性代替 GLB/Entity 对齐验证。
|
||||
|
||||
## Bug Analysis:GLB 与巡航路线随距离漂移
|
||||
|
||||
### 1. Root Cause Category
|
||||
|
||||
- **Category**:B - Cross-Layer Contract;D - Test Coverage Gap。
|
||||
- **Specific Cause**:Blender 使用固定米/度的平面近似,Cesium 使用 WGS84 椭球 ENU;
|
||||
两层没有共享坐标转换契约。
|
||||
|
||||
### 2. Why Fixes Failed
|
||||
|
||||
1. 固定车道偏移:只处理症状,且假定所有车道宽度相同。
|
||||
2. 从 Driving polygon 重建中轴:解决了车道宽度与 lane 选择,但只证明 GeoJSON 内部正确。
|
||||
3. 路口切线连接:改善了 connector,却没有解释直线路段整套坐标同向平移。
|
||||
|
||||
### 3. Prevention Mechanisms
|
||||
|
||||
| Priority | Mechanism | Specific Action | Status |
|
||||
|---|---|---|---|
|
||||
| P0 | Architecture | `Projector` 使用 WGS84 ECEF→ENU,与 Cesium 锚点一致 | DONE |
|
||||
| P0 | Test Coverage | 测试 WGS84 局部经纬度比例与 ENU 方向 | DONE |
|
||||
| P1 | Documentation | 在 Blender、preview 与 cross-layer spec 固化契约 | DONE |
|
||||
| P1 | Integration | 坐标变更后强制重跑 `blender,cesium,preview` 并视觉核对 | DONE |
|
||||
|
||||
### 4. Systematic Expansion
|
||||
|
||||
- **Similar Issues**:交通信号、语义模型、route polyline 等所有叠加在 GLB 上的 Cesium
|
||||
Entity 都依赖同一契约。
|
||||
- **Design Improvement**:坐标转换只有 `Projector` 一个 Blender 事实源。
|
||||
- **Process Improvement**:跨运行时几何必须验证最终组合画面,不能停在单层数值测试。
|
||||
|
||||
### 5. Knowledge Capture
|
||||
|
||||
- [x] 更新 Blender asset generation spec。
|
||||
- [x] 更新 preview vehicle route spec。
|
||||
- [x] 更新 cross-layer thinking guide。
|
||||
- [x] 增加 `ProjectorTest` WGS84 断言。
|
||||
|
||||
## 回滚
|
||||
|
||||
代码回滚只涉及 preview 路线生成和共享 JS helper;重跑 preview 即可恢复旧路线产物,不需要重建 Blender/GLB。用户已有区域配置修改保持不动。
|
||||
Reference in New Issue
Block a user