# 执行票:地图标记 DOM overlay 渲染(billboard 发糊与底板生硬的结构性解决) Label: ready-for-agent Status: resolved Category: frontend-execution > **本票已迁移** → `cockpit-real-data-wayfinding` effort 的[票 47](../../cockpit-real-data-wayfinding/issues/47-dom-overlay-billboard.md)(维护者裁定:DOM overlay 属真实数据接线的渲染层工作,立错了地图)。本文件保留为迁移留痕,内容以票 47 为准。 ## 来源 维护者在批次 3(票 16)第七轮走查后的裁定:**「尝试立票做 DOM」**。billboard 方案经七轮迭代仍有两项引擎级限制无法根除: ① 位图缩到屏显后发糊(Cesium billboard 纹理 LINEAR_MIPMAP_LINEAR,预下采样只能缓解); ② Cesium label 底板不支持圆角/装饰边框(底板位图方案又因 image/text 互斥导致文字消失,已回退)。 DOM overlay 把标记与标签迁到 UI 同层渲染(CSS 全能力),3D 场景只负责每帧提供窗口坐标——维护者原话「使用和 UI 同一层的渲染模式,使用 3D 算法进行定位」。 ## 要做什么 - 新增 **`services/markerOverlay.js`**:每帧(`scene.postRender` / `preRender`)把 `planPointMarkers` 产出的标记经 `SceneTransforms.wgs84ToWindowCoordinates` 投影到屏幕坐标,同步一组 **绝对定位 DOM 节点**(标记 SVG/位图 + 圆角底板标签)。 - 标记图形:SVG 内联(状态色母版 + 内层图标 + 白描边全部可用 CSS/SVG 原生绘制,**无位图缩放发糊问题**);标签:真 DOM(圆角、装饰边、text-overflow、hover title 全部原生)。 - **可见性裁剪**:屏外/被地球遮挡(`heightReference` 贴地点位用 `globe.isPointVisible` 或深度近似)时隐藏节点;缩放/平移由 postRender 驱动自然跟随。 - **拾取**:DOM 节点自身可点(pointer-events),与既有 `pickDeviceOrPointAt` 链路并存——DOM 节点命中直接派发选中,Canvas 拾取保留给 3D 对象(管线等)。 - **性能防护**:节点池复用(不每帧重建);标记数量沿用既有规模(real 数据 9 台 + 6 点);`postRender` 回调内只做 transform 更新。 - **特效**:报警扩散环用 CSS animation(替代 haloSvg billboard),受 `map.effects` 门控。 - **降级**:`markerOverlay` 初始化失败 → 自动回退既有 billboard 链路(`syncPointMarkersForPlan` 不动)。 ## 保持不变(契约面) - 合成计划层 `domain/markerPlan.js`(尺寸/锚点/归属/降饱和逻辑原样复用,overlay 只换渲染媒介); - `data-*` 断言面(`data-legend-key`、`data-map-picked`、`markerMaster/markerInner/...` 全部挂到 DOM 节点上); - 状态词表、拾取身份、面板联动、四模式可见性。 ## 验收 - 纯逻辑:投影坐标换算、可见性裁剪、节点池复用断言。 - 走查:标记锐利无糊(SVG 矢量渲染)、标签圆角底板 + 装饰边可见、hover title 读全、点选联动(监测点/设备/未关联设备三类都能飞镜头)、`map.effects` 开关生效、帧率无肉眼可感下降。 ## Out of Scope - 聚合符号的 DOM 化(K>1 重叠聚合沿用既有 billboard 降级链,另行评估)。 - 设备级特效的 DOM 化(blink/glow/spin 沿用既有 billboard 动效)。 按 `AGENTS.md`,实施时未经用户明确要求不运行 build/dev。 ## 实施记录(2026-10-15,本会话) **状态:已实施 + 走查通过;billboard 链路保留为降级路径。** - **新增 `services/markerOverlay.js`**:DOM overlay 渲染层——标记 SVG(矢量母版,`--tone` 变量注状态色,实心/镂空双形)+ 真 DOM 标签(圆角底板、青色装饰边、text-overflow、hover title 原生能力);节点池复用(标记消失隐藏不销毁);`data-marker-overlay-key/kind/code` + `markerMaster/markerInner/markerAnchor/markerDesaturate` 断言面全挂 DOM 节点。 - **每帧驱动**:`postRender` → `syncMarkerOverlay`(投影 + transform 更新 + 屏外隐藏);投影走 `createCameraEngine` 返回对象的 `projectPivot`(SceneTransforms 包装,含画布原点修正),overlay 相对画布容器取坐标(修正记录在实施中——首版误用 `instance.engine.projectPivot` 报 TypeError,修正为 cameraEngine)。 - **拾取**:DOM 节点 `pointer-events:auto`,`data-marker-overlay-code/kind` 供点选派发;Canvas 拾取保留给 3D 对象。 - **内层染色**:SVG `` 不能逐像素重染,用 CSS filter 链近似(`brightness → invert → sepia → saturate → hue-rotate` → 浅蓝色调)——与共识 §4.2「内层去色重染」同一规则的 SVG 媒介实现。 - **接入**:`mapService` 挂载时 `mountMarkerOverlay(record.host)` + `attachOverlayRenderer`(每帧从 `markerPlan.markers` 现算投影);失败自动回退 billboard 链路(未挂成功时 `syncPointMarkersForPlan` 照常)。 - **markerAssets 输出**:`renderMarker` 输出预下采样到屏显尺寸(绕开 billboard mipmap 发虚)——降级路径同样受益。 ### 走查结论(浏览器实测) - 标记**锐利无糊**(SVG 矢量)、标签**圆角底板 + 装饰边**清晰、hover title 读全;三类点选(监测点/关联设备/未关联设备)镜头联动保持有效;控制台无业务报错(首版 `projectPivot` 引用错误当场修正)。 - billboard → DOM overlay 的**迁移验证**:同一份 `markerPlan.markers` 输入,两种媒介渲染结果一致(归属/颜色/尺寸/标签文本)。 ### 遗留 - 聚合符号(K>1)与设备特效(blink/glow/spin)仍在 billboard 层(票面 Out of Scope)。 - overlay 内层 filter 链是近似(sepia+hue-rotate 到浅蓝),与 billboard 逐像素重染的色相有细微差异——维护者走查若不满意可换 SVG mask 精确染色。 ## 进度 Status: ready-for-agent Type: task Blocked by: Labels: ready-for-agent, wayfinder:task ## Comments ### local — 2026-10-15T02:44:48.923Z 票立错地图:维护者裁定 DOM overlay 属 cockpit-real-data-wayfinding(真实数据接线)的渲染层工作。已在新 effort 重建为票 47(含全部实施记录与走查结论),本票关闭留痕。 ## Answer