From d8aeade90c3df291ce70353e28ad50fb68480b93 Mon Sep 17 00:00:00 2001 From: zgw <13623675548@163.com> Date: Wed, 5 Aug 2026 16:33:42 +0800 Subject: [PATCH] docs(javaTest): design full-map route comparison --- ...vaTest-full-map-route-comparison-design.md | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-05-javaTest-full-map-route-comparison-design.md diff --git a/docs/superpowers/specs/2026-08-05-javaTest-full-map-route-comparison-design.md b/docs/superpowers/specs/2026-08-05-javaTest-full-map-route-comparison-design.md new file mode 100644 index 0000000..56e58c5 --- /dev/null +++ b/docs/superpowers/specs/2026-08-05-javaTest-full-map-route-comparison-design.md @@ -0,0 +1,138 @@ +# javaTest 完整地图与路径差异审计增量设计 + +## 1. 背景与目标 + +现有审计台虽然按真实坐标绘制路径,但画布边界只由选中任务涉及的站点决定,未显示完整地图 +拓扑。使用者只能看到一条孤立折线,无法判断路线位于实际地图的哪个通道,也难以识别历史 +`path_info` 与调度中心 `plannedPath` 的共同段和分叉段。 + +本增量设计替代原设计第 4.5 节中“只返回路径附近节点”的限制,并细化第 7 节的路径语义: + +- 默认显示当前楼层的完整可通行地图; +- 保留 1-8 楼切换,路径经过的楼层明确标记; +- 提供“完整地图”和“聚焦路径”两种视口; +- 对历史路径与新规划路径执行边级差异比较; +- 浏览器仍只展示 Java 返回的地图和结果,不实现路径规划算法。 + +## 2. 方案选择 + +### 2.1 采用:单画布完整楼层地图 + 差异叠加 + +当前楼层的全部站点和真实邻接边作为浅灰底图,新规划路径、历史路径和实际轨迹叠加在同一 +坐标系中。该方案最适合核对“新旧路线在哪个路口分开、在哪个路口重新汇合”,且无需在两张 +图之间依赖记忆比较。 + +### 2.2 不采用:历史/规划双画布并排 + +并排视图能分别看清两条路线,但每张图的可用宽度减半,移动端阅读困难;使用者仍需人工在 +两张图之间寻找同一个站点,不利于边级审计。 + +### 2.3 不采用:历史/规划交替切换 + +单选切换视觉最干净,但切换后上一条路线消失,无法直接定位分叉和汇合位置,不满足本次 +“看出区别”的核心要求。 + +## 3. 地图数据契约 + +`GET /api/bootstrap` 保留完整站点列表,并新增权威无向边列表 `edges`: + +```json +{ + "sites": [{ "siteId": "010701", "floor": 1, "x": 15, "y": 1 }], + "edges": [{ "fromSite": "010701", "toSite": "020701", "floor": 1 }] +} +``` + +边来源只能是 `HistoricalSimulationInput.getGridMap()`。后端遍历全部站点的 +`GridMap.getNeighbors(siteId)`,将端点按站点编号排序后去重,确保同一条无向边只返回一次。 +页面不得根据坐标猜测相邻关系。 + +每个任务继续返回原始 `historicalPath` 和调度结果 `plannedPath`,并增加 `pathComparison`: + +- `sharedEdges`:历史路径和新路径共同使用的真实边; +- `plannedOnlyEdges`:只有新规划使用的边; +- `historicalOnlyEdges`:只有历史路径使用的边; +- `invalidHistoricalSegments`:历史 `path_info` 中节点不存在或不相邻的段; +- `sharedEdgeCount/plannedOnlyEdgeCount/historicalOnlyEdgeCount`:检查器使用的计数。 + +边比较使用无向规范键,避免同一物理边因端点顺序不同被误判。`pathChanged` 原有的完整节点序列 +比较继续保留,用于兼容报告和既有测试;边差异用于可视化解释,不参与调度或规划。 + +## 4. 地图交互 + +### 4.1 默认视图 + +运行任务后默认选择任务起点所在楼层,并显示该楼层全部可通行站点和邻接边。楼层选择器列出 +1-8 楼;经过路径的楼层带有路径提示,当前车辆所在楼层带有车辆提示。 + +完整地图使用稳定坐标边界,不因选择任务、推进 tick 或切换历史路径而重新缩放。这样同一站点 +在同一楼层始终位于同一屏幕位置,便于重复核查。 + +### 4.2 视口工具 + +路径画布提供: + +- `完整地图`:适配当前楼层完整地图,为默认模式; +- `聚焦路径`:适配当前任务在该楼层涉及的路径范围; +- 放大、缩小、复位按钮; +- 鼠标滚轮缩放和拖动画布; +- 悬停站点显示站点编号、楼层和真实坐标。 + +切换 tick 只更新动态路径和车辆位置,不重置用户已经选择的缩放与平移状态。切换楼层或任务时 +重新执行当前视口模式的适配。 + +## 5. 视觉语义 + +绘制层级从底到顶固定为:完整地图、历史/规划对比、实际轨迹、节点状态、车辆。 + +- 完整地图边:浅灰 1px;完整地图节点:低对比度小圆点; +- 仅历史边:橙色点线; +- 仅新规划边:绿色实线; +- 共同边:绿色实线底层叠加较窄的橙色点线,使两份证据同时可见; +- 已实际通过边:蓝色高亮,位于比较路径上方; +- HOLD:琥珀色节点或边; +- A、B 和当前车辆:保留稳定的不同标记。 + +完整地图不常驻显示所有站点文字,避免 1,175 个站点形成文字遮挡。仅 A、B、车辆、HOLD、 +分叉点和鼠标悬停站点显示标签;完整站点编号仍可通过悬停和任务路径文本读取。 + +图例增加“共同路段、仅历史、仅新规划”,任务检查器增加边差异计数和无效历史段提示。 +历史参考开关关闭时只隐藏历史专属和共同边上的橙色证据,不隐藏新规划路径。 + +## 6. 性能与错误处理 + +完整地图按当前楼层绘制,而不是同时叠加 8 层。页面首次加载后缓存每层背景 SVG 分组;推进 +时间线时只重建路径、节点状态和车辆等动态层。约千级站点和邻接边不会在每个 tick 重复创建。 + +如果历史路径含未知站点或非邻接段,页面不把它伪造成地图连线:无效段显示在检查器中,已知且 +有效的历史段继续绘制。若某楼层没有任务路径,仍显示完整底图并提示该层无选中任务路径。 + +## 7. 测试策略 + +### 7.1 Java 测试 + +- bootstrap 边数与从 `GridMap.getNeighbors()` 导出的权威边集合完全一致; +- 所有边端点存在、端点顺序规范、没有正反向重复; +- 相同边、仅历史边、仅规划边的集合差计算正确; +- 空路径、单节点路径、反向边和未知历史节点不会产生伪造边; +- 原有 240/0/0、资源安全、归档和 WMS 幂等结果不变。 + +### 7.2 浏览器测试 + +- 未选择任务时也能显示当前楼层完整地图; +- 完整地图边数量明显大于选中任务路径边数量; +- “完整地图/聚焦路径”、楼层、缩放、拖拽和复位有效; +- 历史与规划不同的任务同时出现共同、仅历史和仅规划样式; +- 关闭历史参考后,新规划和完整底图仍存在; +- tick 推进不改变完整地图坐标和用户视口; +- 1440x900 和 390x844 无重叠、无横向页面溢出、控制台无错误。 + +## 8. 验收标准 + +- 使用者能明确看出路径位于当前楼层完整地图的哪个通道; +- 可以一键在全图上下文和路径细节之间切换; +- 历史路径和新规划路径的共同段、分叉段、汇合段无需手工阅读节点列表即可识别; +- 页面路径边全部来自后端权威地图拓扑,不由坐标推测; +- 历史无效段被明确报告且不绘制成真实地图边; +- 现有调度、交通裁决、PLC、车辆移动、归档和 WMS 结果不被改写; +- 自动测试与真实浏览器验收通过。