import { isRenderable } from './domain/coordinate.js' import { findMapObject } from './domain/mapLocate.js' import { MAP_OBJECT_KIND } from './domain/mapSummary.js' import { cancelPointLocate, locateMonitoringPoint } from './services/mapService.js' import { useDetailStore } from './stores/detailStore.js' import { useDeviceLayerStore } from './stores/deviceLayerStore.js' import { useMapStore } from './stores/mapStore.js' /** * 监测点选择的**唯一入口**(票 41;票 42 在此接上关联设备图层)。 * * 为什么单独成一个接线模块:票 41 的验收第 1 条要求「地图点击和监测点台账选择使用同一监测点 * 选择入口」,而这件事天然横跨几块 —— 详情两层(`detailStore`)、地图定位(`mapService`)、 * 关联设备图层(`deviceLayerStore`)。各侧都**不许**自己长出对方: * · `stores/detailStore.js` 不得依赖 `mapService`(票 10 的 F4 守卫:详情路径不碰地图); * · `services/mapService.js` 不依赖 Vue / pinia(票 02 的层次纪律)。 * 所以把「先判定可信坐标 → 触发点位级定位 → 打开两级详情 → 同步关联设备图层」这段接线放在这里, * 由地图点选(`MapCanvas`)与台账卡片(`monitoringStore`)共同调用。 * * 三条并行关系(都是规格硬要求): * · 定位与详情**并行**:详情取数是网络请求,镜头不该等它; * · 设备图层与定位**并行**:设备数据一到就渲染,**不等相机动画停稳**; * · 设备图层先按**当前快照**出一次计划(此时详情可能还没回来 → 该点位设备落「待确认」), * 详情到达后再由订阅方重算一次(`CockpitShell` 订阅详情分区变化调 `syncForSelection`)。 */ export function selectMonitoringPoint(pointCode, options = {}) { const mapStore = useMapStore() const detailStore = useDetailStore() const deviceLayerStore = useDeviceLayerStore() // 换点位先作废上一次尚未落位的地形采样(否则 A 的迟到采样会覆盖刚选的 B)。 cancelPointLocate() const object = findMapObject(mapStore.summary.objects, pointCode) if (object && object.kind === MAP_OBJECT_KIND.MONITORING_POINT && isRenderable(object)) { // 有意不 await:详情取数与镜头飞行各走各的,谁先到都不影响另一个。 void locateMonitoringPoint(object) } // 票 42:设备图层**立即**按当前快照出计划(不等详情、不等镜头)。 // `force` 是因为换点时旧图层的计划指纹必须作废 —— 否则 A 的设备会留在图上冒充 B 的。 deviceLayerStore.syncForSelection({ force: true, mode: options.mode }) return detailStore.openPoint(pointCode, options) }