chore(task): archive 08-05-cesium-traffic-signals
This commit is contained in:
@@ -0,0 +1 @@
|
||||
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}
|
||||
@@ -0,0 +1,44 @@
|
||||
# 设计:Cesium 路口信号灯可视化
|
||||
|
||||
## 分层边界
|
||||
|
||||
信号锚点不是 QGIS 业务图层:它不进入 GeoPackage、场景九图层或 QGIS 工程。`intermediates`
|
||||
在 `osm2streets_web_out/traffic_signals.json` 写出它;Blender 和 preview 都消费同一份文件。
|
||||
|
||||
Blender 的 `05_Props` 负责所有静态设施:灯杆、横杆、灯头、熄灭灯珠和倒计时牌外壳。它们
|
||||
随 `.blend` 和主 GLB 导出,成为正式场景的一部分。Cesium 预览只负责动态覆盖层:当前相位的
|
||||
发光灯珠、七段倒计时数字、Signals 显示开关,以及车辆在红黄灯前的等待。这样静态造型只有
|
||||
一份,浏览器不再用临时 Entity 重复搭建设施。
|
||||
|
||||
## 锚点与几何
|
||||
|
||||
中间阶段已有 `vehicle_stop_lines` 和 `intersection_surface`。信号锚点生成器将停止线的
|
||||
中点作为进口横向基准,依据相交路口面和停止线两端的方向判定来车朝向;灯杆置于停止线的
|
||||
侧后方、道路外缘一侧,且朝向来车。没有可唯一关联的路口面、停止线过短或无法确定外侧时,
|
||||
不输出锚点。
|
||||
|
||||
输出保存灯杆坐标、对应停止线坐标、朝向、稳定 ID 和 `layout` 几何契约,避免 Blender 或
|
||||
浏览器重新解析 GeoJSON 或 OSM。`layout` 包含灯头、灯珠、横杆和倒计时牌的尺寸与偏移;
|
||||
其中横向偏移以车辆行驶方向为基准,正值表示驾驶员右侧;`mastHeightMeters` 与
|
||||
`headCenterHeightMeters` 是横杆和灯壳的共同中心高度。三颗灯珠相对灯壳中心排列,而倒计时牌
|
||||
的垂直偏移为零、固定在横杆上。
|
||||
Blender 使用
|
||||
`Projector.xy((longitude, latitude))` 转成本地米制坐标,并以 `headingDegrees` 旋转;Cesium
|
||||
以同一字段派生地理位置与灯面朝向。
|
||||
每个路口按相对进口方向分为两组对向相位;统一循环绿、黄、全红切换。
|
||||
|
||||
预览将每条路线按累计米数投影到信号停止线。只有距离阈值内且行驶方向与信号进口一致的
|
||||
匹配才形成停车点。车辆的累计里程由 `clock.onTick` 推进;下一停车点为红或黄时将里程夹在
|
||||
停止线前,绿灯后从同一位置继续。没有停车点的路线保留原速度循环。
|
||||
|
||||
## 预览交互
|
||||
|
||||
预览加载锚点 JSON 失败时记录 warning,场景、路线与车辆仍可用。加载成功时信号灯默认显示,
|
||||
并在现有 View 控件中提供独立 Signals 复选框。动态灯珠和数字以 emissive 材质区分点亮和
|
||||
熄灭状态,不依赖环境光;静态部分由 GLB 的低多边形 MeshBatch 几何承载。
|
||||
|
||||
## 风险与回退
|
||||
|
||||
信号灯是示意设施,不能视为 OSM 语义。复杂交叉口或人工修补后的不完整标线宁可跳过,也不
|
||||
摆放到行车道中央。回退时删除附属锚点输出、`05_Props` 信号构件和 Cesium 动态覆盖层即可;
|
||||
QGIS、道路/标线和既有路线 JSON 不受影响。
|
||||
@@ -0,0 +1 @@
|
||||
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}
|
||||
@@ -0,0 +1,42 @@
|
||||
# 实施计划:Cesium 路口信号灯可视化
|
||||
|
||||
1. 复用 `traffic-signals.js` 的锚点推导,在 `intermediates` 阶段把附属
|
||||
`traffic_signals.json` 写入 `geojsonDir`;不修改 `SCENE_LAYERS`、GeoPackage 或 QGIS。
|
||||
2. 在 `blender/osmassets/traffic_signals.py` 用共享低多边形 MeshBatch 几何装配静态信号设施,
|
||||
并在 `generate_scene.py` 读取锚点、投影坐标、置入 `05_Props` 和写入计数。
|
||||
3. 在 `catalog.MATERIALS` 末尾追加信号设施材质和 Cesium 导出补偿,保证新 GLB 在 Cesium
|
||||
中不会发黑或材质索引漂移。
|
||||
4. 让 preview 直接读取 intermediates 的锚点文件;删除 Cesium 对立杆、横杆、灯头、熄灭灯珠
|
||||
和外壳的构造,只保留精确对齐的动态灯珠、数字与既有相位/车辆等待。
|
||||
5. 更新 Node 与纯 Python 测试,构建目标区域并用 parity 检查 GLB 差异只包含预期新增设施;
|
||||
人工核对主 GLB 静态构件和 preview 动态覆盖层。
|
||||
|
||||
## 验证
|
||||
|
||||
```bash
|
||||
npm run test:preview-assets
|
||||
node --check scripts/lib/cesium-preview.js
|
||||
python3 -m unittest discover blender/tests
|
||||
npm run build:area -- --config config/areas/nantaizi-lake-innovation-valley.json --stages intermediates,blender,cesium,preview
|
||||
git diff --check
|
||||
```
|
||||
|
||||
## 已验证决策与故障记录
|
||||
|
||||
- `assets/fonts/7LED-1.ttf` 已纳入版本管理;该字体是反向 LED 轮廓。直接填充文字会得到
|
||||
绿色背景/黑色字,曲线描边会得到空心描边字;当前实现改为采样负轮廓并构造实心挤出
|
||||
棱柱,独立 Blender 渲染已确认数字形状正确。
|
||||
- 为支持相位字色且避免复制几何,动态导出拆为灯珠 GLB + countdown group 0/1 两个 GLB。
|
||||
预览三者共用同一 placement,倒计时模型使用 `colorBlendMode=REPLACE` 做模型级换色。
|
||||
- 失败方案:Cesium `Model.getMaterial().setValue()` 修改普通 glTF PBR uniforms,用户实测
|
||||
数字仍为绿色,不能恢复使用。
|
||||
- 失败陷阱:导出器的 `groups` 是完整材质名集合,不能检查精确字符串 `"Countdown Group 0"`;
|
||||
必须用 `"Countdown Group 0" in name` 的包含判断,否则导出阶段报
|
||||
`Traffic countdown collection 0 is empty`。
|
||||
- glTF 的 `Could not calculate tangents` 警告来自无 UV 的纯色倒计时 mesh;只要三个 GLB
|
||||
均成功生成,它不是阻断错误。
|
||||
|
||||
## 回退
|
||||
|
||||
删除静态信号 Blender 模块、附属锚点输出和浏览器动态覆盖层;QGIS、道路/标线和既有路线
|
||||
JSON 不受影响。
|
||||
@@ -0,0 +1,55 @@
|
||||
# Cesium 路口信号灯可视化
|
||||
|
||||
## Goal
|
||||
|
||||
在 Cesium 预览中加入可直接观察的路口交通信号灯,使已完成的道路、停止线、斑马线、
|
||||
转向箭头和车辆巡航有清晰的交通控制参照。车辆应在对应停止线前遵守同一套相位,并在
|
||||
绿灯放行后继续巡航。
|
||||
|
||||
## Confirmed Facts
|
||||
|
||||
- `scripts/lib/cesium-preview.js` 目前只加载场景资产、巡航路线与车辆;没有信号灯图层、
|
||||
模型或相位状态。
|
||||
- 路线 JSON 包含连续的左、右、直转向曲线,但没有路口 ID 或信号相位字段。
|
||||
- 现有停止线、斑马线和转向箭头已由区域构建确认,且用户要求暂不触及 QGIS 的人工修补
|
||||
边界、道路生成与既有连续路线逻辑。
|
||||
- Cesium 当前同时绘制灯杆、横杆、灯头、熄灭灯珠、倒计时外壳,以及随相位变化的灯珠和
|
||||
七段数字。这使静态设施只存在于验证层,难以随主场景维护。
|
||||
- `05_Props` 集合已经进入主 `.blend` 和 Cesium GLB;`traffic-signals.js` 已是停止线和
|
||||
路口面推导信号锚点的唯一事实源。
|
||||
|
||||
## Requirements
|
||||
|
||||
- 在道路进口侧、停止线附近呈现简洁而可辨识的交通信号灯,并在不遮挡车道标线的前提下
|
||||
面向来车方向。
|
||||
- 红、黄、绿灯应有明确的点亮状态和周期性相位切换,使静态截图与实时预览都能看出其作用。
|
||||
- 信号灯应能独立显示/隐藏,遵循现有 Cesium 控件的克制设计语言。
|
||||
- 车辆接近已匹配的停止线时,红灯和黄灯必须停车,绿灯继续通行;相位切换后应自然恢复
|
||||
移动,不得瞬移到路口另一侧。
|
||||
- 等待逻辑只模拟单车对信号的响应,不做车辆间跟车距离、排队或碰撞避让。
|
||||
- 首版以主要路口的程序化示意灯覆盖为准:从已生成的停止线和路口面推导进口,缺少可靠
|
||||
几何锚点时跳过。它不宣称复刻 OSM 中逐节点标注的真实信号设施。
|
||||
- 灯杆、横杆、灯壳、熄灭灯珠和倒计时牌外壳必须成为 `05_Props` 中的静态场景几何,随
|
||||
主 GLB 导出;Cesium 只保留与这些几何严格对齐的发光灯珠、七段倒计时数字、显示开关和
|
||||
车辆相位等待。
|
||||
- 信号锚点必须在 `intermediates` 阶段写入 `osm2streets_web_out/traffic_signals.json`,由
|
||||
Blender 与 preview 共用;不得纳入 `SCENE_LAYERS`、GeoPackage 或 QGIS 工程。
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] 仅运行 `intermediates,blender,cesium` 后,主 GLB 已包含位于路口进口侧的灯杆、横杆、
|
||||
灯头、熄灭灯珠和倒计时牌外壳;静态几何位置与停止线/
|
||||
斑马线关系清楚,且不会漂浮在道路中央或遮挡车道箭头。
|
||||
- [ ] 灯组以可见状态呈现红、黄、绿的相位切换;未点亮灯珠明显较暗。
|
||||
- [ ] 页面提供独立的 Signals 显示开关,关闭后不影响场景、路线与车辆。
|
||||
- [ ] 匹配到信号停止线的巡航车辆会在红/黄灯时停在线前,绿灯后连续通过;没有可靠匹配的
|
||||
路线保持原有循环巡航,不因信号锚点缺失而卡住。
|
||||
- [ ] 不修改 QGIS 工程、道路/标线生成或既有路线 JSON 的基本契约。
|
||||
- [ ] preview 重建后,动态灯珠和数字与 GLB 中相应灯头、倒计时外壳对齐,且无 Cesium
|
||||
重复的杆、横杆、灯壳或外壳实体。
|
||||
|
||||
## Notes
|
||||
|
||||
- Keep `prd.md` focused on requirements, constraints, and acceptance criteria.
|
||||
- Lightweight tasks can remain PRD-only.
|
||||
- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`.
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "cesium-traffic-signals",
|
||||
"name": "cesium-traffic-signals",
|
||||
"title": "Cesium 路口信号灯可视化",
|
||||
"description": "",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": null,
|
||||
"package": null,
|
||||
"priority": "P2",
|
||||
"creator": "dingkang",
|
||||
"assignee": "dingkang",
|
||||
"createdAt": "2026-08-05",
|
||||
"completedAt": "2026-08-06",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
"commit": null,
|
||||
"pr_url": null,
|
||||
"subtasks": [],
|
||||
"children": [],
|
||||
"parent": null,
|
||||
"relatedFiles": [],
|
||||
"notes": "",
|
||||
"meta": {}
|
||||
}
|
||||
Reference in New Issue
Block a user