# 监测点 / 设备镜头定位视角契约 spec Status: ready-for-agent Labels: cockpit-locate-view Category: spec 本规格固化决策地图「监测点定位、面板锚定与设备点位联动」的票 03(镜头「定位到监测点」的视角契约)的结论。上游决策记录:票面 `issues/03-locate-camera-view-contract.md`(`## Answer`);关联契约:ADR 0008(已原位修订)、ADR 0009(主场景区限位)、决策地图票 04(已同步)、`CONTEXT.md`(已补「定位 / 归位」词条)。 ## Problem Statement 值班人员点击地图上的一个监测点后,镜头只把旋转中心挪过去、仍停在县域全景(range 12 km),看不清这个监测点及其周边,也看不到该点位下的设备点位 ——「点击后首先将镜头移动定位到该监测点位置,能够在三维场景下观察该监测点的状况」这条需求拿不到。同时,点选监测点与手动三键(轨道 / 滚轮 / 平移)的相机语义在既有契约(ADR 0008 / 决策地图票 04)里是同一套「只换中心」,需要为「定位」单独立一条语义,否则实现无从下手。 ## Solution 从用户视角:点击地图上的监测点 → 镜头平滑飞向该点位的**定位视角**(中心对准点位地表、heading/pitch/range 一起换成点位级预设,缺省 `heading 0 / pitch −55 / range 500 m`),点位居中、周边街区级可辨、该点位下所有设备点位都可见;在监测面板里点一台设备 → 镜头飞向**设备级**定位视角(缺省 `range 150 m`)。取消选中或关闭面板后镜头**不回退**,用户自己滚轮 / 平移 / 归位离开;换一个点位直接从当前视角飞向下一个定位视角。「归位」永远是回「家」视角(县域级),定位不改变它。 ## User Stories 1. 作为值班人员,我想点击地图上的监测点后镜头自动飞到该点位并看清它,以便立刻知道这个点在哪、周围是什么。 2. 作为值班人员,我想点位级定位后该点位下的所有设备点位都出现在画面里,以便为接下来查看设备做准备。 3. 作为值班人员,我想点位始终落在画面中心附近,以便我知道当前镜头对准的是哪一个点。 4. 作为值班人员,我想定位后能看清点位周边一小片区域(街区级),以便判断它的空间上下文。 5. 作为值班人员,我想在监测面板里点一台设备后镜头飞到该设备,以便近距离观察这台设备。 6. 作为值班人员,我想设备级定位的视角比点位级更近,以便看清单台设备与其紧邻(特效也有空间表现)。 7. 作为值班人员,我想定位不会跳到随机的朝向,以便画面稳定、可预期(heading 由预设给,缺省正北)。 8. 作为值班人员,我想关闭详情面板或取消选中后镜头停留在定位视角,以便我继续观察而不是被弹回。 9. 作为值班人员,我想连续点选不同点位时镜头平滑地从上一个点位飞到下一个,以便快速巡检多个点位。 10. 作为值班人员,我想点「归位」任何时候都回到县城默认视角,以便在点乱之后一键回到全局。 11. 作为值班人员,我想定位视角的数值可以由部署配置调整,以便不同部署(不同点位密度)能各自适配。 12. 作为值班人员,我想定位不受主场景区限位的额外限制(定位 range 远小于限位上限),以便任何画布尺寸下行为一致。 ## Implementation Decisions 1. **机制**:定位走「中心 + heading/pitch/range 一起换」的完整视角预设路径(现有视角预设通道,即归位所用的那条),**不是** `setFocus` 的只换中心。定位飞行复用既有阻尼 / 动画路径,不新增时长开关。 2. **两档预设**: - 点位级:缺省 `heading 0 / pitch −55 / range 500 m`; - 设备级:缺省 `heading 0 / pitch −55 / range 150 m`; - 数值由部署配置给(建议 `map.locate` 一节,含 `point` / `device` 两组),组件不硬编码,后续可在配置中修改。设备级数值供「面板选设备 → 定位到设备」的联动票引用,不另发明第二套。 3. **中心**:定位中心=点位地表**实测地形**高程(沿用票 30 的地形采样口径),**不取椭球 0**。椭球 0 会把旋转中心埋进沅陵约 111.6 m 的地形里:贴地标记偏离画面中心(破坏「点位标记清晰落在画面中心」验收),且设备级 150 m 时相机离地仅剩约 11 m、120 m 档会入地。 4. **与主场景区限位的合成**:定位**不设例外**,定位 hpr 必须落在限位内(`range ∈ [120, range_max]`、相机离地高度 `≥ 正下方地形 + 10 m`),被夹就如实呈现。`range_max` 按并行图收口为 `home.range = 12,000 m`(ADR 0009)—— 两档预设均远低于上限,任何画布比例下都不会被夹。 5. **取消选中 / 关闭面板**:**完全不回退**(中心与视角都保留);换点位直接从当前视角飞向下一个定位视角,不先回退再定位。 6. **与「归位」的关系**:定位不改 home;归位永远回 home;**不新增**「回到定位前 / 上一视角历史栈」。 7. **非监测点对象与手动三键**:选中**非监测点对象**(未关联设备、事件等)或**手动三键操作**(右键轨道 / 滚轮 / 左键平移)时,维持既有「只换中心、保持当前 heading 与 range」的语义 —— 定位只作用于监测点(及其设备)。 8. **ADR 0008 原位修订**:旋转中心一节改为「选中监测点 → 定位视角(中心 + hpr 一起换);非监测点对象与手动三键 → 只换中心;取消选中不立即回退中心或视角」。**不新开 ADR**。决策地图票 04 已同步同一句。 9. **断言口径**:定位完成 = 相机状态 `settled`(经纬容差 1e-7° 已含 pivot 对齐)且 hpr 匹配对应档位预设,另断言相机离地高度 ≥ 点位地表高程 + 10 m(防入地由限位兜底,走查补一道)。走查读宿主 `dataset.camera` 或相机状态只读接口。 10. **已知边界(不裁决)**:主场景区状态机只认「进入系统 / 归位」两条进区锁 —— 全球态下点选监测点得到定位视角但**不进区**,5 秒闲置会回引导页(既定行为)。若实现后体验不佳,另开票评估。 ## Testing Decisions - 好的测试只断言**外部可观察行为**,不碰实现细节:点选一个点位后,最终相机状态 = 点位中心 + 对应档位预设 hpr + `settled`;关闭面板后状态不变;点「归位」后回到 home。 - 测试层级沿用仓库既有两条:**纯逻辑断言**(视角预设与夹取是纯函数,可脱离浏览器直接断言;参考既有相机契约的纯逻辑闸门)+**真机走查**(真实鼠标点标记、读宿主 dataset 断言;参考既有定位/点位详情的走查脚本,含「先等镜头停稳再断言」的既有坑位记录)。 - 需要覆盖的模块:相机/视角预设域逻辑、地图服务的定位入口、组件侧的点选 → 定位接线。回归面:既有三键相机契约走查与「进入引导 / 归位」走查不得回退。 - 数值校验口:点位级 500 m 的「该点位下所有设备点位可见」依赖设备点位图层(票 05/11)—— 数据落地时验证设备分布是否超出 ±200 m(= 500 m / −55° / 16:9 的屏幕竖直地面跨度一半),超了回来重议 500 m。 ## Out of Scope - 设备点位图层的渲染、触发与「关联设备不上图」裁决(票 05、11)。 - 设备状态特效的视觉语言与实现(票 07、02 调研)。 - 面板锚定跟随的形态(票 04)。 - 面板选设备与三维设备点的对应反应(票 06)。 - 后端「点位下设备的坐标与状态」契约补齐(票 09,HITL)。 - 设备「模型」的口径与资产来源(票 10)。 - 事件、管线、设施等其他对象的定位(事件定位归实现票 14/19,管线交互优先级归票 22)。 - 竖屏、移动端、多屏拼接。 ## Further Notes - 上游引用:本规格是决策地图的产物,不是新决策源;细节以票 03 的 `## Answer` 与 ADR 0008 / ADR 0009 为准。 - 数值都是**缺省**,部署配置可覆盖;写死任何一处都要回到本规格重审。 - 交叉引用:并行图「主场景区限位、视距与过渡」的 `range_max = 12,000 m`(ADR 0009)是本规格限位合成的前提;若该图后续再改锚点,本规格第 4 条要同步复核。