Status: resolved Labels: wayfinder:map
本 effort 只产出决策,不实现功能。实现票在本图收口后接进 .scratch/cockpit-shell-panel-layout/issues/ 的 34 之后(与 .scratch/cockpit-primary-area-guardrails 同一约定)。维护者指定的实现分支是 feat/anchor-panel-tracking(建图当日该工作树仍在 master,本地尚未看到该分支),本图先把它要发明的语义锁死。
把「点击监测点 → 镜头定位到该点位、能在三维场景里看清它 → 面板锚定跟随该点位、表明归属 → 展开该点位下所有设备点位(坐标图标/模型)→ 面板选设备与三维设备点互相对应 → 设备点位按状态(报警/预警/工单处置/正常/离线)产生特效」这五条交互,锁成 agent 可直接实现、不必再发明语义的契约。
目的地达成的判据:五条交互各有唯一答案且互相自洽 —— 镜头定位的 range 与主场景区限位(.scratch/cockpit-primary-area-guardrails 的 02 已 resolved)不打架;关联监测设备的位置与状态使用设备自身的后端数据,色值沿用 styles/tokens.css 的语义色,但设备状态视觉契约由 07/10 单独裁决,不能把 domain/pointStatus.js 的监测点聚合状态词表直接当作设备状态;且与三条既有已锁决策的冲突被显式裁决,不留两套说法:ADR 0008 的三键相机、决策地图票 04 的「选中只换中心、保持 heading/range」、实现票 10 的「关联设备不作为独立地图标记重复渲染」。
/cockpit。词汇以 CONTEXT.md 为准(监测点=承载一个或多个监测设备的空间业务对象;监测设备≠基础设施;点位状态=后端解析发布、前端只渲染不重算;两级详情;一张图)。CONTEXT.md、docs/adr/0001–0008、.scratch/cockpit-shell-panel-layout/spec.md;既有决策与票面 —— .scratch/web-cockpit-decision-map/issues/04-spring-arm-orbit-pivot.md、.scratch/cockpit-shell-panel-layout/issues/03-camera-control-contract.md、09-point-status-legend.md、10-monitoring-point-detail.md、22-cesium-pipeline-rendering.md、30-intro-gate-and-view-presets.md、34-lightweight-city-massing.md、.scratch/cockpit-primary-area-guardrails/issues/02-camera-limit-numeric-contract.md(已 resolved 的限位数值契约)与其 07(雾气规格,open);代码 —— src/modules/cockpit/domain/{pointStatus,detailFlow,pointDetail,mapSummary,camera,viewPresets}.js、services/{cameraControl,mapService,cesiumEngine,pointPick,cockpitConfig}.js、stores/{detailStore,mapStore}.js、components/{PointDetailCard,MapCanvas}.vue、styles/tokens.css。.scratch/cockpit-shell-panel-layout/issues/ 34 之后)。.scratch/cockpit-primary-area-guardrails 的限位数值契约(02 resolved)与其进出状态机(03 open)合成;② 设备状态特效与该图 07 的自建 depth 后处理级雾同处一个 PostProcessStageCollection,两者要在本图 07 里显式对齐顺序与开关。open/claimed/resolved,不套 triage 五标签。AGENTS.md,改代码后不自动跑 build/dev/走查。Blocked by: 字段行为准(verify/build-edges.ps1,并在同一次运行里校验子票数量=本 ## 任务清单 条目数);正文不写 Blocked by: #<n> 这类散文兜底,两者不得并存。domain/mapSummary.js 的摘要序列如此,票 08/09/10 的「关联设备从不进入标记计划」是结构性保证(domain/detailFlow.js 文件头写明)。services/pointPick.js(左键「点一下」与「拖着走」的位移判据)→ cesiumEngine.pickPointMarkerAt()(只认带 pointCode 的实体,回身份不回实体)→ mapService.onPointPick() → stores/detailStore.js 的两级详情(none → point → equipment)。cameraControl.setFocus() 正是这个语义(applyViewPreset() 才能连 hpr 一起换)。当前 range 是县域级(票 30 home pitch −55 / range 12000),所以「只换中心」到不了「能观察该监测点」。components/PointDetailCard.vue 在 CockpitShell.vue 里作为 main 的兄弟浮在左右两栏之间,不读屏幕坐标;左右两栏 z-index:2 压在满幅地图上(票 07 记录的定位约束)。SourceSmartDevice 上(CockpitMapSnapshot.java:105-107、CockpitMonitoringDistributionSnapshot.java:166-174),一旦按点位归集就换成无坐标的 CockpitMonitoringPointDeviceSnapshot(两条 SourceMonitoringPoint.devices 都是它:CockpitMapSnapshot.java:75、CockpitMonitoringDistributionSnapshot.java:107),CockpitMonitoringPointDeviceCard 只是继承了缺失。20 个 /api/cockpit/v1/ 端点无一能在「某点位下所有设备」这一粒度给全经纬度 + 校验 + 状态;/monitoring/situation 的 abnormalEquipment[] 有坐标但只含异常设备且无 monitoringPointCode;带完整坐标的只有 /equipments/{deviceCode}/archive(逐台=N+1)。缺的字段:设备级 longitude/latitude/coordinateValidation;要动的类:CockpitMonitoringPointDeviceSnapshot → CockpitMonitoringPointDeviceCard → CockpitMonitoringPointStatusResolver.cards();端点不必新增。Gogs #59 交付的是编码清单而非坐标 —— 「#59 已带坐标而前端漏读」这一设想可以排除。deviceCodes(后端 BT-1 / Gogs #59 已交付),所以「某个点位下有哪些设备」不必再靠逐点详情接口;另有 industry/typeCode/typeName/region(BT-2 / #60)。01 核实其语义:只在 map-snapshot 的 monitoringPoints[] 回传(distribution 的 marker 没有)、构造链无状态过滤所以含离线设备、在分页之前算完所以不受分页影响、空值是 [] 而非 null、源顺序去重未排序。前端全 src/ 对它 0 引用(尚未接线)。domain/pointStatus.js(监测点后端六态 + 「状态未发布」+「未关联设备」,各带色键/形状/文字);这不是设备自身状态词表。语义色只在 styles/tokens.css 声明,服务层从 .cockpit-shell 计算样式读出来烘焙进图片。设备视觉契约留给 07/10;引擎里目前零自定义 shader、零 post-process 级。src/plugins/zoneFreeScene/** 里以 oss.icegl.cn 远程 URL 存在(本地无副本);domain/pointStatus.js 的 SHAPES 8 个键全是几何原语,无任何设备形状;驾驶舱图标是内联 SVG data-URL(不是 canvas 光栅化,与 devicePixelRatio 无关)。3D Tiles 那条线是城市体块(票 34,示意体块、非实测建筑),与设备模型完全无关。research/device-position-data-and-rendering-primitives.md。research/device-status-effect-mechanisms.md。map.locate 配置可改)、applyViewPreset 连 hpr 一起换、中心取实测地形、不设限位例外(range_max = 12,000 m)、取消选中不回退、归位不改 home;ADR 0008 原位修订 + 决策地图票 04 同步。pickDeviceMarkerAt() 且设备点优先、可断言字段 data-map-device-picked / data-map-panel-selection / data-map-device-hovered;规格已固化为票 15。domain/deviceStatus.js 平行表并新增 effect 维度(不借用点位表,且须修掉 detailFlow.js 现有的借用);随票 05 图层常驻、选中设备强化、关详情随图层消失;超 30 台降级为静态异常标记 + 计数(降级后仍看得出有异常);沿用雾票已 resolved 的「随雾衰减、不开穿雾例外」,且本票特效走场景内 billboard 不占后处理集合故无排序冲突;新增 map.effects.*,缺省 null 跟随构建形态;验收=领域断言 + 场景图跨帧快照 + 真实帧差 + 人工走查。yarn dev @8000)后验收通过。已验证:贴点面板、四向落位、自动飞行、设备特效真在动(跨帧快照违规 0)、正常/离线静态、40 台/23 异常在上限 10 时正确降级且仍留异常标记;真跑另修掉 5 个静态断言抓不到的缺陷(BillboardCollection 未入场景就 add({heightReference}) 抛错致设备图标恒 0、computed 无响应式依赖致徽标永久缓存、控制台过大致四向 no-space、每帧重渲染、自动飞行与 goHome 阻尼竞态)。6 条实现约束已转交:①点击监测点/设备跳转定位(03/06/15 已锁契约)②锚定窗口复用既有两级「点位摘要」结构(12 的实现输入)③图标须可替换、临时图标不作最终验收(记入 10)④特效需更有科技感、参考图出现监测点级扩散环(记入 07,「监测点要不要有特效」是 07 未裁项)⑤初始地球视图不显示业务点位(记入 13 与 30)⑥遮挡规范改判(已原位修订 04/12)。snapshotAt 快照、详情/地图集合及分页对齐;现网坐标校核来源缺失,正式降级为清单-only;推送部署和真实联调仍待维护者执行。map.overlap.maxFan=10);结论已写回票 11 ## Answer,规格已固化为 17。ready-for-agent 规格子票,依赖 10;规格交付不表示设备位置符号、正式图片素材或真三维模型已实现。deviceStatus.js 词表),结论见票 13 ## Answer,CONTEXT.md 已补「设施点」「异常点」词条。ready-for-agent 规格子票,依赖 05;文档完成不代表设备图层已实现,现有票 03 的 spec.md 不覆盖。ready-for-agent 规格子票,依赖 06;把 hover/选中反应、定位联动、双向联动、弱化、拾取与可断言字段固化为实施输入,不覆盖票 03 的 spec.md。ready-for-agent 规格子票,依赖 11;把聚合符号/展开环、折叠态交互、面板接缝、K/N 计数、K>10 降级与可断言字段固化为实施输入,不覆盖票 03 的 spec.md。ready-for-agent 规格子票,依赖 13;把引导态 + 四模式的完整可见矩阵、异常点判定、设施点/管线语义、回联定位、图例随模式与选择态合成为实施输入,测试接缝=domain/modeLayerPlan.js 纯函数 + 外壳走查;不覆盖票 03 的 spec.md,不表示设施点/管线/异常点图层已实现。重叠设备持续聚合入口修订 / 对应规格修订 — 维护者将点子设备后隐藏规则改为:所选设备保持中心可见并接替聚合入口,hover/click 可再次展开切换;固定展开时原聚合符号变暗,名称与计数明确显示。
面板锚定规格:维护者复验修订 / 设备对应规格:复验修订 — 点位摘要锚向监测点,设备详情及连接短线锚向所选设备;中心图标保持清晰,状态动画移至外围。旧索引中的“锚点仍跟随监测点”已被本次直接裁定取代;上游票 04 的本地 Markdown 记录已同步。
research/device-position-data-and-rendering-primitives.md。一次拿不到设备坐标,且缺口在数据模型层而非响应包装:坐标只挂在 SourceSmartDevice 上,按点位归集时被换成无坐标的 CockpitMonitoringPointDeviceSnapshot(改动点 …DeviceSnapshot → …DeviceCard → StatusResolver.cards();端点不必新增);「#59 已带坐标而前端漏读」排除(#59 给的是编码清单)。deviceCodes 可直接用且不被分页污染(只在 map-snapshot 回传、含离线设备、空值 []、源顺序未排序、前端目前 0 引用)。设备与点位各存独立经纬度,关联表只有 equipment_id/point_id,后端无任何相对位置信息(同井/同杆/高度/朝向 grep 0 命中)也不保证两点相等 → 「同坐标重叠」是必须预先处置的可能形态(实际重叠比例未知,已毕业为 11)。呈现原语:三者 GPU 侧都批渲染、都能逐元素拾取,但 scene.pick 只回最上层一个(重叠必须 drillPick),且只有 PointPrimitive 不支持 heightReference(Entity 的 point 贴地是引擎内部拿无图 billboard 顶替)。仓库无设备级 glTF/GLB、SHAPES 8 键无任何设备形状、驾驶舱图标是内联 SVG data-URL。research/device-status-effect-mechanisms.md。特效首选 BillboardCollection 逐点 scale/color 动画(整集合一次 drawElements、逐点脏更新;官方 1 万个静态 266 FPS / 动画 138 FPS,故 200 点仍在安全区),升级路径是自定义 Primitive + N 个 GeometryInstance + 同一 Appearance(逐实例数据走 batch table,一次 draw call 画 N 个);Entity + CallbackProperty 非常量属性会每帧销毁并重建 Primitive(社区实测 25 个≈8 FPS、200 个≈0 FPS),只配 1–3 个聚焦设备;CustomDataSource 只是容器;PostProcessStage 全屏、无法只影响一个点;ParticleSystem 挂在 Scene.primitives、全局、无位置参数、无 pick 路径。与限距雾可同处一个 PostProcessStageCollection,但顺序必须显式定为「先特效、后雾」(execute 顺序=加入顺序、颜色链式而深度不链式),且两级 enabled 要一次原子对齐。色值在 WebGL 路径一律读不到 CSS 变量,必须经 services/mapService.js 的 toneColors() 烘焙(billboard.image、Billboard#color、Material uniform、ColorGeometryInstanceAttribute、BufferPointMaterial.color/outlineColor、PostProcessStage.uniforms、自建 GLSL 常量);形状仍只来自 domain/pointStatus.js 的 SHAPES。拾取只取决于有没有 pickId(与半透明无关),最易踩的坑是不透明特效即便无 pickId 也会用 depthOnly 派生命令挡住背后设备点的拾取 → 特效面片必须走半透明 pass。10/50/200 的量级是推断(产物里已标注),真数留实现票实测。applyViewPreset 连 hpr 一起换(缺省 heading 0 / pitch −55 / range 500 m,点位级;设备级 150 m;均 map.locate 配置可改);中心取实测地形(椭球 0 会埋进地形、破坏「点位居中」验收);不设限位例外(range_max = 12,000 m,guardrails 03 收口锚点,两档均不被夹);取消选中/关闭不回退、换点位直接飞下一个;归位不改 home、无历史栈;全球态点选不进区(已知边界)。ADR 0008 已原位修订(选中监测点→定位视角;非监测点对象与手动三键→只换中心),决策地图票 04 已同步;CONTEXT.md 已补「定位/归位」词条。## Answer 的 R-1~R-4 为准;派生规格见 12: 监测点详情面板锚定跟随规格。deviceCodes 是上图与总数前提,跨端点不同版显式提示;摘要与关联设备图例/计数分开。票 09/10 和 ADR 0005 已同步;设施、事件等全图模式矩阵移交13;规格已固化为14,完整取舍见子票 ## Answer。ready-for-agent 文档。测试接缝由维护者确认:外壳可观察行为为主、领域纯逻辑为辅;本票只交付规格,不宣称已上图。effect 维度。动效只给需处置的三态:报警=扩散脉冲、预警=闪烁、工单=旋转环;正常与离线无特效(五态全动会淹没画面、丢掉优先级语义;风险记录在案,「正常/离线是否够可辨」交 08 原型校准,不由实现票自行加回动效)。单一来源:新建 domain/deviceStatus.js 平行表,不 import pointStatus.js 的状态词表(只可共用 SHAPES 片段),色值仍只从 tokens.css 经 toneColors() 烘焙;须修掉既有越界——detailFlow.js:12/:99-107 现在正拿点位表给设备配色配形,即「把设备猜成点位状态」在代码里已经发生;状态未发布落 UNKNOWN 不猜 NORMAL;未关联设备十字标记保持原样。门控:随票 05 图层常驻、选中/定位设备额外强化、关详情随图层消失(无需单独消失逻辑);动态代价只落在异常设备上(CallbackProperty(isConstant=false) 会让按需渲染失效,故不扩展到全部设备)。并发:不静默截断(票 02 已核 200 点仍在安全区),超 30 台降级为静态异常标记 + 一行「N 台异常」计数,降级后仍看得出有异常(不能变成「什么都没画」而被读成没有报警);阈值交 08 现场定;计数沿用票 05 互斥口径,不混入票 09 八行摘要图例。与雾:沿用 .scratch/cockpit-primary-area-guardrails 雾票(已 resolved)Answer 第 6 条「随雾衰减、不开穿雾例外」;本票特效走场景内 billboard 而非后处理级,故「先特效、后雾」自动成立、不占 PostProcessStageCollection、无排序冲突,也不需要两级原子对齐开关。降噪:新增 map.effects,缺省 null = 跟随构建形态(与票 32 的 map.ui.debug 同构);关特效只关动效,静态色/形/文字仍在位(不破坏「颜色不是唯一线索」)。可断言(维护者选 A + 人工走查):领域纯逻辑断言(映射唯一、未知落 UNKNOWN、正常/离线 effect 空;不单独作为验收,避免恒真断言)+ 场景图快照(同一设备逐点 scale/color 跨帧确实变化,证明「真在跑」而非「已配置」)+ 真实帧差(两帧像素差,顺带补票 02 留下的实测空白)+ 人工走查观感。设备模型口径归 10、面板联动归 06、重叠设备归 11、其余图层矩阵归 13;本票只产决策不实现。detailStore.selectDevice)、选中=外环 + 放大 + 引线(连监测点标记中心,随锚点走;重叠时引线退化不画)、首次进设备级飞一次 150 m 且设备级内 A→B 只换中心、返回点位级回 500 m 定位视角(属层级回退,不是票 03 的「取消不回退」);全双向联动(三维点设备 → 面板滚动 + 进设备级第二级;返回点位还原为监测点选中态;锚点仍跟随监测点标记中心);其余设备压暗 + 缩小、阈值设备数 ≥ 3 台、hover 只作用于非选中设备(撤弱化 + 轻放大,不叠外环/引线);新建独立 pickDeviceMarkerAt()(认 deviceCode,票 05「不冒充监测点」结构性保证)、点选先设备点再监测点(设备点优先、监测点兜底);可断言字段 data-map-device-picked / data-map-panel-selection(none|point|equipment)/ data-map-device-hovered,不破坏既有 data-map-picked;重叠拾取归 11。本票只产决策不实现;规格已固化为15。yarn dev @8000)后验收通过、票已 resolved。已验证:贴点面板、四向落位、自动飞行、设备特效真在动(场景图跨帧快照违规 0)、正常/离线静态可辨、40 台/23 异常在上限 10 时正确降级且仍留异常标记。真跑修掉 5 个静态断言抓不到的缺陷:①BillboardCollection 未入场景就 add({heightReference}) → DeveloperError: Height reference is not supported without a scene,设备图标恒 0(Entity 路径不受影响,故「有点位没设备」)②computed 读普通 let 无响应式依赖 → 徽标永久缓存成「等待引擎」③控制台摊开约 940×180 从下方顶住面板 → 四向 no-space(原型自伤)④每帧无条件写 layout.value → 整组件每帧重渲染⑤引导遮罩消失 ≠ goHome 阻尼收敛完成(带约 10s 重试)→ 自动飞行被覆盖,改判 cameraControl.getState().settled。另记一笔探针教训:drawImage(canvas) 读 Cesium 得亮度 0 是 preserveDrawingBuffer:false 所致,不是画面黑,判断要用截图。走查产出 6 条实现约束并已转交:①点击监测点/设备跳转定位(03/06/15 已锁契约)②锚定窗口复用既有两级「点位摘要」结构(12 的实现输入,不得另造层级)③图标须可替换、临时图标不作最终验收(记入 10,接缝=SHAPES+markerSvg 单注入点)④特效需更有科技感(记入 07;参考图出现监测点级扩散环,而 07 只裁了设备级——「监测点要不要有自己的特效」是 07 未裁项,实现前须回 07 补裁)⑤初始地球视图不显示业务点位(记入 13 问题 5 与 30 遗留)⑥遮挡规范改判 → 已原位修订 04/12。ready-for-agent 规格子票,依赖 10;固化本期位置符号口径、统一可替换资产接缝、地形贴地、按类型渐进真模型、混合显示与透明降级,不表示功能或资产已实现。CONTEXT.md 人工坐标偏移禁令不动);不用 drillPick(靠反复改 show 会与票 07 独立开关打架),摊开后普通 pick 走票 06 pickDeviceMarkerAt() 设备优先链、双向不砍;折叠态交互=hover 瞬态预览 / click 粘性展开(点设备、点空白、返回点位三条件解除);面板 hover 设备卡片只给聚合符号弱指向不摊开,面板 click 选中卡片才摊开并高亮(摊开绑定持久选中);图例「已上图(聚合呈现)K 台」口径(K=当前可逐台绘制数,N=快照去重关联总数,K/N 两数语义固定,三处同源,被聚合不得虚报为逐台上图);K>10 降级(map.overlap.maxFan 缺省 10,与票 07 的 30 台特效降级互不影响),降级保持聚合符号 + 显式「K/N」、面板清单保留全部;新增可断言字段 data-map-overlap-state(collapsed|expanded|degraded)与 data-map-overlap-count(=K);与票 06/15 边界已写清(引线退化只约束地理重合的未摊开场景,展开态引线照 06 画),票 15 已补边界备注、CONTEXT.md 已加「重叠聚合符号」词条。本票只产决策不实现;规格已固化为 17。map.overlap.maxFan=10)与 data-map-overlap-state/data-map-overlap-count 断言字段固化为 ready-for-agent 文档;测试接缝沿用 14/15/16 已确认口径。本票只交付规格,不宣称重叠呈现已实现。/monitoring/situation 的 abnormalEquipment[] 回联为据,不借用监测点聚合词表)。管线折线四模式常驻,「地面/管线视图」为正交的全局呈现条件(只改相机预设与地形/瓦片半透明,不管管线层本身隐藏);CONTEXT.md「管线视图让地下管线可见」据此修订。引导态可预取但不显示(标记/图例/计数浮标/详情全部门控,进入后才挂载显示)。设施点=与监测点同级的独立空间对象(管网/泵站/水厂/水源地/用水户等,各类型后端独立成表),数据源=后端新契约;本票只锁「可见/可回联」,拾取/详情/视觉词表另开设施票。异常设备视觉跟票 07 deviceStatus.js 词表(与关联设备图层同表);图例只统计当前模式实际可见标记、行随模式变。回联定位不做模式过滤(目标在图上则飞、不在则不下发飞行);基础设施面板回联目标语义=设施点。选择态合成=票 05 规则的直接外推(概览↔分项保留身份暂停/恢复、分项↔分项清空;设施点无选择态;切模式不动相机不换快照)。风险:设施点/管线(票 22)/设备状态契约(票 09/#69)未交付 → 本期如实降级;pointStatus 临时视觉未承接(留给票 09/实现票)。CONTEXT.md 已补「设施点」「异常点」词条;规格已固化为 18。18: 一级模式图层可见性与选择态矩阵规格 — 已将 13 的完整矩阵、异常点判定(只认设备 WARNING/ALARM、abnormalEquipment[] 回联)、设施点/管线语义(设施点与监测点同级、管线四模式常驻、管线视图正交)、回联定位边界、图例随模式与选择态合成固化为 ready-for-agent 文档;测试接缝=domain/modeLayerPlan.js 纯函数(浏览器外可断言)+ 外壳人工走查。本票只交付规格,不宣称设施点/管线/异常点图层已实现;设施点拾取/详情/视觉词表另开设施票。
09: 向后端确认/补齐「点位下设备的坐标与状态」契约 — 后端远端已包含同 snapshotAt 的 Redis 共享快照与详情/地图分页集合对齐,最终 HEAD 77b4a34;现网无可信坐标校核源,设备位置清单-only;部署和真实联调待维护者完成。
无。运维自检已转交点位设备联动整体验收与质量收口的验收清单。
.scratch/cockpit-shell-panel-layout 实现票 09 的遗留,至今不在任何票范围内;本图只在 05/11 里处理「同一监测点下多台设备」这一点点,不接管跨点位聚合)。.scratch/cockpit-shell-panel-layout/issues/01–34 的既有实施历史;票 05 经维护者确认后只对票 09/10 补未来口径,并在 ADR 0005 记录模式选择态例外,不追认新图层已交付。已完成:目的地已锁;本图现有 18 张子票,其中 01–13 已 resolved,14–18 已发布为 ready-for-agent 规格。各票结论仍以本地图 Decisions so far 的链接为准;实施已转交 41–48。规格交付不表示设备图层、正式图片素材、设施点、管线或异常点已经上图。
下一步:本决策地图已收口并转交执行;实施入口为 .scratch/cockpit-shell-panel-layout/issues/41–48,按各票 Blocked by 顺序推进。当前最先可做的是监测点定位与面板锚定接入(仅依赖已完成的区域限位);后端 #69 已发布但现网设备坐标无可信校核,设备图层必须支持清单-only 降级。真实 Redis/Kingbase 联调和正式设备图片素材仍是后续执行/发布验收事项,不把规格发布当作功能已上图。