# 18: 一级模式图层可见性与选择态矩阵规格(来自决策票 13) Type: spec Status: ready-for-agent Label: ready-for-agent Blocked by: 13 Category: spec 本规格固化[决策票 13](13-mode-layer-visibility-matrix.md)的维护者确认结果,作为[同一张 map](../map.md)的子规格单。它是「什么时候显示什么」的实施输入,不覆盖同目录现有的 `spec.md`;现有 `spec.md` 继续只描述票 03 的监测点/设备定位视角契约。 ## 进度:100% 规格文档已发布为 `ready-for-agent` 并挂到同一决策 map;100% 仅指规格交付,**不表示设施点、管线折线或异常点图层已实现**。下一步:设施点数据契约、管线折线数据源(实现图票 22)、设备级坐标/状态契约(票 09 / 后端 #69)到位后,后续实现按本规格接入;设施点的拾取/详情/视觉词表另开设施票。未经本对话明确要求,本次不运行 build 或浏览器走查。 ## Problem Statement 值班人员在四个一级模式(总体概览、基础设施、运行监测、预警处置)之间切换时,一张图上的业务对象范围应当随模式变化;当前实现对所有模式画出同一批地图摘要标记,没有任何按模式的可见性规则。问题集中在五个方面: 1. **可见矩阵缺失**:总体概览希望展示监测点、设施、预警报警等所有适用对象;基础设施只看设施;运行监测看监测点/设备;预警处置只看异常点。设施与监测设备是不同业务对象,监测点与未关联设备也不得合并为一类。 2. **数据来源缺口**:设施点(管网、泵站、水厂、水源地、用水户等,各类型独立成表)当前没有地图坐标数据源;管线折线数据源(票 22)未交付;设备级坐标/状态契约(票 09)未交付。不同图层缺数据时不得伪装成「该模式确实没有对象」。 3. **初始地球视图**:进入系统引导的最初地球视图只展示地球整体形态,不展示监测点、设备点位或点位详情;点击「点击进入系统」、镜头落到主场景后,业务点位才出现。 4. **选择态合成**:当前选中对象不属于目标模式时的详情暂停与恢复、镜头保持、图例计数和拾取对象优先级,需要与已确认的票 05 规则合成一张完整矩阵。 5. **回联定位边界**:事件不创建独立地图标记;设施点在基础设施模式可见并作为回联目标。需要明确各对象「在图上才能定位、不在则不下发飞行」的边界。 ## Solution 从值班人员视角,一张图在一级模式之间切换时中央地图保持常驻,显示的业务对象集合随模式变化。实现一个统一的「模式图层可见性计划」纯函数模块,作为「什么时候显示什么」的唯一权威;地图引擎和组件只消费该计划,不做第二次过滤判断。五种状态(引导态 + 四个一级模式)与各对象层的完整可见矩阵如下: | 状态\对象 | 监测点 | 未关联设备 | 关联设备图层(选中态) | 设施点 | 管线折线 | 事件 | |---|---|---|---|---|---|---| | **引导态**(进入前) | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | | **总体概览** | ✓ 全部 | ✓ | ✓ 全部有效(票 05) | ✓ | ✓ | 回联定位 | | **基础设施** | ✗ | ✗ | ✗(票 05) | ✓ | ✓ | 回联定位 | | **运行监测** | ✓ 全部 | ✓ | ✓ 全部有效(票 05) | ✗ | ✓ | 回联定位 | | **预警处置** | 仅异常点 | 仅预警/报警 | 仅 ALARM/WARNING(票 05) | ✗ | ✓ | 回联定位 | 异常点 = 至少一台关联监测设备处于预警或报警状态的监测点;判定以设备状态事实为准(`/monitoring/situation` 的 `abnormalEquipment[]` 回联到 `point.deviceCodes`),不借用监测点聚合状态词表。图例、计数与浮标只统计当前模式实际可见的标记,图例行随模式变化。回联定位不做模式过滤。总体概览与任一分项互切保留选择身份、目标模式不显示当前对象时暂停并恢复;分项之间互切清空选择。引导态可预取地图数据但不显示任何业务点位。 ## User Stories 1. 作为值班人员,我想在总体概览模式看到全部监测点、未关联设备和设施点,以便一览全貌。 2. 作为值班人员,我想切到基础设施模式后地图只显示设施点与管线,以便专注设施的空间范围。 3. 作为值班人员,我想切到运行监测模式后地图重新显示全部监测点与未关联设备、设施点隐藏,以便专注设备运行侧信息。 4. 作为值班人员,我想切到预警处置模式后地图只显示异常点与预警/报警的未关联设备,以便聚焦待处置对象。 5. 作为值班人员,我想在引导态只看到地球整体形态、没有业务点位,以便先建立空间直觉,不被数据淹没。 6. 作为值班人员,我想点击「进入系统」后业务点位才出现,以便把进入决策作为明确的呈现起点。 7. 作为值班人员,我想引导期可以预先加载地图摘要,以便进入后点位立即呈现而无需长等待。 8. 作为值班人员,我想引导态不显示业务标记、图例、点位计数浮标和详情,以便「没看到对象」不会被误读成「对象不存在」。 9. 作为值班人员,我想一级模式切换不重建地图实例、不换地图摘要快照,以便连续值守有稳定空间上下文。 10. 作为值班人员,我想任一模式的图例只出现该模式可见对象的状态行,以便图例与实际标记保持一致。 11. 作为值班人员,我想数据未就绪的图层如实显示「数据未就绪」,以便缺数据不会被误读成「该模式确实没有对象」。 12. 作为值班人员,我想预警处置模式画出异常点(含预警/报警设备的监测点),以便看清异常的空间分布。 13. 作为值班人员,我想预警/报警的未关联设备在预警处置模式也画出来,以便正在报警的设备不会因没有监测点归属而被漏掉。 14. 作为值班人员,我想正常/离线/工单处置设备不因监测点聚合状态被冒充成异常点,以便颜色语义不被误读。 15. 作为值班人员,我想异常点判定以设备状态事实为准(从 `/monitoring/situation` 的异常设备回联),以便不借用监测点聚合状态词表。 16. 作为值班人员,我想设备自身状态未知时预警处置模式不猜成正常或报警,以便不掩盖未知。 17. 作为值班人员,我想基础设施模式下已选中的监测点详情与关联设备图层暂停、切回总览且对象仍在当前范围时恢复,以便模式范围与选择归属不冲突。 18. 作为值班人员,我想总览与任一明细模式互切保留选择身份,以便切回总览不丢失正在看的对象。 19. 作为值班人员,我想三个分项模式之间切换清空选择,以便不会把上一分项的对象带到下一分项。 20. 作为值班人员,我想设施点在基础设施模式可见并作为回联目标,以便设施面板条目能定位到图上。 21. 作为值班人员,我想设施数据契约未到位时基础设施地图如实显示「无设施数据」,以便不把缺数据误读成「确实没有设施」。 22. 作为值班人员,我想设施点不进入监测点统计与图例,以便设施与监测点两类对象计数互不污染。 23. 作为值班人员,我想设施点的拾取/交互与视觉词表不在本规格承诺,以便不为不存在的设施详情发明选中态。 24. 作为值班人员,我想管线折线在进入后任何一个一级模式都可见(常驻),以便管线作为设施的一类空间对象持续有用。 25. 作为值班人员,我想地面/管线视图(正交的全局呈现条件)只改相机预设与地表/瓦片半透明、不影响管线层是否显示,以便视图开关不与模式隐藏打架。 26. 作为值班人员,我想事件不创建独立地图标记、而是按设备编码回联到地图位置,以便事件不与监测点标记重复。 27. 作为值班人员,我想事件行所在的设备/监测点可定位,以便从列表条目标到图上对象。 28. 作为值班人员,我想事件设备不在当前地图(未加载/无坐标)时如实提示且不下发飞行,以便不误导为地图上存在该点。 29. 作为值班人员,我想基础设施面板条目的回联目标是设施点,以便切到基础设施模式有图上归属。 30. 作为值班人员,我想设施契约到位前基础设施面板条目的定位如实说明不可定位,以便不把监测点坐标冒充设施位置。 31. 作为验收人员,我想通过外壳可观察行为验证模式切换、图例行变化、引导态门控和回联结果,以便验收外部行为而不依赖 Cesium 私有实体。 32. 作为实施人员,我想只有一个领域纯函数给出「模式 → 标记计划」,以便可见性决策不会在地图与组件两层各裁一遍。 ## Implementation Decisions ### 1. 统一「模式图层计划」纯函数矩阵 - 新建 `domain/modeLayerPlan.js`(建议名,实施时以契约为准)领域纯函数模块,不 import Cesium / Vue / 接口对象。 - 输入:`{ mode, objects(地图摘要对象集), abnormalDevices(异常设备集,`/monitoring/situation` 形状), facilities(设施点集), pipelines(管线折线计划), selection(当前选择), entered(是否已完成引导) }`。 - 输出:`{ markers, blocked, legend, locateTargets, degradedNotes }`——该模式应显示的标记、被坐标准入拦下的对象、图例行、可回联目标、以及「数据未就绪/无法定位」的如实说明。整个矩阵的裁决在这里收口。 - 该模块是「什么时候显示什么」的唯一事实源;引擎和组件只消费计划,不在 Cesium 层重新过滤。 - 纯函数可被浏览器外脚本直接调用断言(仿 `verify/t08-map-summary.mjs` / `t09-point-status.mjs` / `t21-view-modes.mjs` 先例)。 ### 2. 模式可见对象集 - 总体概览:监测点全部 + 未关联设备 + 关联设备图层(选中态,票 05:全部有效)+ 设施点 + 管线。 - 基础设施:设施点 + 管线;监测点、未关联设备、关联设备图层不可见。 - 运行监测:监测点全部 + 未关联设备 + 关联设备图层(全部有效)+ 管线;设施点不可见。 - 预警处置:仅异常点 + 预警/报警未关联设备 + 关联设备图层仅 ALARM/WARNING(票 05)+ 管线;设施点不可见。 - 引导态(`entered=false`):全部对象不可见;标记、图例、点位计数浮标、详情都不出现。数据可预取但不呈现。 - 管线折线在四个一级模式常驻;「地面/管线视图」是正交的全局呈现条件,不是本矩阵的显隐开关。 ### 3. 异常点判定 - 异常点 = 至少一台关联监测设备状态为 WARNING/ALARM 的监测点。 - 判定源:后端 `/monitoring/situation` 的 `abnormalEquipment[]`(设备状态事实)+ 地图摘要 `point.deviceCodes`(设备 → 监测点归属),把设备状态回联到监测点得到异常点集合。数据源未交付时模块如实降级:不猜、不画。 - `/monitoring/situation` 与 `map-snapshot` 是不同端点:沿用票 05「尽力展示并明确提示跨端点不同步」,不静默假设两份数据同一时刻。 ### 4. 设施点 - 设施点 = 与监测点同级的独立空间业务对象(管网、泵站、水厂、水源地、用水户等,各类型在后端独立成表);不计入监测点统计与图例。 - 本规格只锁「可见 / 可作为回联目标」;设施点的拾取、详情、视觉词表整体另开设施票,本规格不承诺。 - 设施数据契约未到位时,基础设施模式地图通过 `degradedNotes` 如实进入「无设施数据」降级态,不虚报设施行。 - 设施点的图例行待设施契约与视觉词表到位后由设施票定义。 ### 5. 管线视图正交 - 管线折线在进入后四个模式均常驻,模式矩阵不隐藏它。 - 「地面/管线视图」是正交的全局呈现条件:只改相机预设与地表/瓦片半透明(`domain/viewModes.js` 既有行为),不管管线层本身的显示。 - `CONTEXT.md`「管线视图让地下管线可见」已修订为本语义(「让管线呈现更清楚」,不是层显隐开关)。 ### 6. 事件回联 - 事件不创建独立地图标记,靠 `deviceCode` / `monitoringPointCode` 回联到地图对象位置。 - 回联定位不做模式过滤:目标在图上(坐标准入且已加载)则按既有定位契约飞行;不在图上则不下发飞行,`locateTargets` 由模式图层计划给出该模式允许的回联目标。 ### 7. 选择态合成 - 总体概览 ↔ 任一分项:保留选择身份;目标模式不显示所选项时暂停详情与关联设备图层,切回且对象仍在当前范围时恢复。 - 分项 ↔ 分项:清空选择。 - 设施点:本阶段不产生选择态。 - 切换模式不动镜头、不换地图快照,Viewer 常驻。 ### 8. 图例与计数 - 图例只统计「当前模式实际可见」的摘要标记;图例行随模式变化。 - 图例与标记必须一致(沿用票 09 的 `legendMatchesMarkers` 判据,指向同一计划层输出)。 - `MapCanvas.vue` 的图例列来源改为消费模式图层计划的输出,而不是全场对象视图。 ### 9. 引导态 - 引导态(进入前):不显示任何业务点位;点击「进入系统」后才挂载/显示,业务点位才出现。 - 允许预取:进入前可预取地图摘要,`entered=false` 时计划输出全部为空;显示层(标记/图例/浮标/详情)被门控。 - 实现侧进入态挂载归票 30 引导层生命周期;计划层以 `entered` 输入作门控。 ### 10. 领域词表 - `CONTEXT.md` 已补充「设施点」「异常点」词条并修订「地面/管线视图」(见决策票 13 的 Answer):设施点与监测点同级不混统计;异常点 = 任一关联设备 WARNING/ALARM 的监测点,以设备状态事实为准。 ## Testing Decisions - **主 seam(已由维护者确认)**:`domain/modeLayerPlan.js` 纯函数是最高接缝,浏览器外逻辑脚本可直接断言;引擎/组件只消费计划,不在 Cesium 层重判可见性。 - **补充 seam**:驾驶舱外壳人工走查,覆盖模式切换观感、图例行变化、引导态门控、管线常驻与回联定位手感。 - **纯逻辑断言覆盖**:五种状态 × 各对象的可见矩阵(含「不该显示的一定不在计划里」)、异常点判定只认 WARNING/ALARM、图例与标记一致、引导态全空、回联目标、降级注释;设施集用注入 mock 断言矩阵逻辑(语义锁死、数据待接线)。 - **测试先例**:沿用 `verify/t08-map-summary.mjs`(合并态纯逻辑)、`t09-point-status.mjs`(图例与标记一致)、`t21-view-modes.mjs`(视图条件纯函数)的断言风格;走查沿用 `verify/*-walkthrough.mjs` 的 `data-*` 可断言字段约定。 - 不把 Cesium 私有实体、组件私有变量或两份相同 JS 输入互比作为成功判据;不做引擎层可见性重判。 ## Out of Scope - 设施点坐标契约、设备级坐标/状态契约(票 09 / 后端 #69)、管线折线数据源(实现图票 22)的实际补齐;后端契约缺失只阻塞实现,不改变本规格的可见性规则。 - 设施点的拾取、详情、视觉词表与图例行定义(另开设施票)。 - 设备状态特效、设备模型、重叠拾取等已由票 06/07/10/11 裁决的视觉与交互细节;本规格在其输出范围内引用,不重裁。 - 位置筛选(如 `pointStatus` 状态筛选落图、行业/区域筛选)的既有契约与端点;本规格只定义模式可见性。 - 真实数据全面接线(后端 BT-5 / Gogs #63)。 - 登录、权限、工单写操作、移动端、竖屏和多屏拼接。 - 覆盖或改写现有票 03 的定位视角规格与票 05/06/07/10/11 的关联设备图层契约;本规格只在既有契约之上合成模式矩阵。 ## Further Notes - 本规格的唯一决策来源是票 13 的 `## Answer`;它把讨论结论转为后续实现可消费的行为契约。 - 「没有对象」与「数据未就绪」必须分开:`EMPTY`(后端确实没有)与「设施/设备数据契约未到位」是两种状态,界面与 `degradedNotes` 都要说得出区别,不能把缺数据伪装成空数据。 - 管线折线常驻四模式是 2026-09-28 维护者在票 13 的裁决(比「仅基础设施/概览可见」选项更宽);管线视图的正交语义已同步 `CONTEXT.md`。 - 异常点判定依赖设备级状态事实;`/monitoring/situation` 只含异常设备且与 `map-snapshot` 跨端点,跨端点不同步提示是强制行为,不得静默删除。 - 本规格新增为同一决策 map 的子规格单(编号续 14/15/16/17 之后),现有票 03 的 `spec.md` 保持不变。规格交付不表示设施点/管线/异常点图层已实现。 ## Comments ### 规格交付说明(2026-09-28) 本规格由票 13 的 `/to-spec` 产出,忠实固化维护者确认的完整矩阵与五要素结论。测试接缝(领域纯函数 + 外壳人工走查)已由维护者确认。`CONTEXT.md` 已同步「设施点」「异常点」「地面/管线视图」三个词条。本次只发布规格文档,没有修改票 03 的 `spec.md`,没有运行 build、dev 或浏览器调试(AGENTS.md 规则;规格票只写验收契约)。