# 地图图层、图例和锚点加载逻辑 ## 一、整体流程 ``` GisView.vue (onMounted) │ ├─> 1. 获取图层配置 (mapStore.setLayerData) │ ├─> 2. 收集初始选中的图层 keys (collectCheckedKeys) │ ├─> 3. 加载所有锚点数据 (mapStore.loadAllLayerData) │ │ │ ├─> 并行加载选中的图层数据 (优先) │ ├─> 后台加载未选中的图层数据 │ └─> 数据缓存到 pointDataCache │ └─> 4. 更新图例和图层显隐 (mapStore.updateLayerData) │ ├─> 更新图层 checked 状态 ├─> 获取并排序图例数据 (getlegendData) ├─> 处理环保设施图例 (fp_point/eq_point 联动) └─> 控制锚点显示/隐藏 (setLegendPointVisible) ``` ## 二、核心组件和 Store ### 2.1 组件 - **GisView.vue**: 主视图,负责初始化加载流程 - **LayerController.vue**: 图层树控制器,处理图层勾选交互 - **mapLegend/index.vue**: 图例显示组件 ### 2.2 Store (map.ts) - `layerData`: 图层树配置数据 - `legendData`: 过滤排序后的图例数据 - `legendDataOriginal`: 原始图例数据 - `legendDataSelected`: 选中的图例数据 - `legendDataMap`: 图例数据映射 (nameEn -> 图例项) - `pointDataCache`: 锚点数据缓存 - `checkedLayerKeys`: 选中的图层 key 列表 ## 三、初始化加载流程 (GisView.vue) ### 3.1 获取图层配置 ```typescript const layerRes = await mapStore.getLayerConfig(); mapStore.setLayerData(limitedLayers); // 设置图层数据 ``` ### 3.2 收集初始选中的 keys ```typescript const checkedKeys = collectCheckedKeys(limitedLayers); ``` ### 3.3 加载锚点数据 ```typescript await mapStore.loadAllLayerData(limitedLayers, checkedKeys); ``` ### 3.4 更新图例和图层显隐 ```typescript await mapStore.updateLayerData(checkedKeys, true); // isInit = true ``` ## 四、锚点数据加载 (loadAllLayerData) ### 4.1 处理逻辑 1. 递归遍历所有图层配置 2. 区分**选中的图层**和**未选中的图层** 3. 选中的图层**优先加载**,阻塞等待 4. 未选中的图层**后台加载**,不阻塞 UI ### 4.2 数据缓存 - 所有加载的数据都会缓存到 `pointDataCache` - 已缓存的数据不会重复加载 - 即使图层未选中,也会加载数据并缓存,只是隐藏不显示 ### 4.3 加载完成后 1. 调用 `setSelectedLegendData()` 设置选中图例 2. 未选中图层继续后台加载,完成后打印日志 ## 五、图层勾选流程 (LayerController.vue) ### 5.1 用户勾选图层 ``` onCheck(v, e) │ ├─> 处理互斥逻辑 │ ├─> 珍稀鱼类 vs 沿程鱼类 │ ├─> 视频监控 vs AI视频监控 │ └─> 环保设施 vs 环保设施在建 │ ├─> checkedKeys.value = checkKeys │ └─> broadcast(checkKeys) │ └─> mapStore.updateLayerData(v) ``` ### 5.2 互斥图层处理 - `rare_fish_point` 与 `fish_along_point` 互斥 - `stinfo_video_point` 与 `stinfo_ai_video_point` 互斥 - `facilities` 与 `facilities_built` 互斥 ## 六、图例数据更新 (updateLayerData) ### 6.1 处理流程 ```typescript updateLayerData(checkKeys, isInit = false) │ ├─> 处理互斥图层 (stinfo_video_point vs stinfo_ai_video_point) │ ├─> 更新图层 checked 状态 (递归遍历 layerData) │ 记录 newlyChecked 和 newlyUnchecked │ ├─> 获取有效 keys (过滤掉 '-', 'customBaseLayer', 'powerBaseStation') │ ├─> 获取图例数据 (getlegendData) │ 过滤掉 name === '地图' 的项 │ 递归匹配 layerCode │ 去重 (根据 parent name) │ ├─> 处理环保设施图例联动 │ 勾选 fp_point 或 eq_point → 自动添加环保设施图例 │ 取消勾选 → 自动移除环保设施图例 │ ├─> 按 orderIndex 排序 │ ├─> 更新 legendDataSelected │ └─> 控制锚点显示/隐藏 isInit = true: 处理所有图层 isInit = false: 只处理变化的图层 ``` ### 6.2 环保设施图例联动 ```typescript const triggerKeys = ['fp_point', 'eq_point']; const hasTriggerLayer = triggerKeys.some(key => checkKeys.includes(key)); if (hasTriggerLayer) { // 添加环保设施图例 } else { // 移除环保设施图例 } ``` ## 七、图例点击处理 (mapLegend) ### 7.1 单个图例项点击 ```typescript legendItemClick(item) │ ├─> 切换 item.checked (0 ↔ 1) │ ├─> 更新 legendDataMap │ └─> 控制锚点显示/隐藏 pointMap 图层 → setLegendPointVisible GISMap 图层 → controlBaseLayerTreeShowAndHidden ``` ### 7.2 groupTitle 点击 (全选/取消全选) ```typescript toggleGroup(group) │ ├─> 获取组内所有叶子节点 (getAllLeafItems) │ ├─> 判断是否有任何选中 → 决定目标是全选还是取消全选 │ └─> 遍历所有叶子节点,切换 checked 状态 跳过 parentName === '环保设施' 的项 跳过 canBeChecked === 0 的项 ``` ### 7.3 groupTitle 变灰判断 ```typescript isGroupAllUnchecked(group) │ └─> 所有叶子节点 checked === 0 → 返回 true (变灰) ``` ## 八、锚点显示/隐藏控制 ### 8.1 pointMap 图层 ```typescript setLegendPointVisible(layerKey, nameEn, visible) │ ├─> 隐藏所有锚点 (setLegendPointVisible(key, '', false)) │ └─> 显示选中的锚点 (遍历 legendData,checked === 1 的项) ``` ### 8.2 GISMap 图层 ```typescript controlBaseLayerTreeShowAndHidden(layerKey, configId, visible) ``` ## 九、关键数据结构 ### 9.1 图层配置 (mapLayerVos) ```typescript { key: 'eng_point', title: '水电站', type: 'pointMap', // 或 'GISMap' checked: 1, // 0: 未选中, 1: 选中 url: '/api/xxx', params: {}, children: [] // 子图层 } ``` ### 9.2 图例数据 ```typescript { name: '已建', nameEn: 'large_eng_built', layerCode: 'eng_point', icon: 'xxx.png', checked: 1, // 0: 未选中, 1: 选中 canBeChecked: 1, // 0: 不可勾选, 1: 可勾选 childrenList: [] // 子图例 } ``` ### 9.3 锚点数据 ```typescript { stcd: 'xxx', // 站点编码 stnm: '三峡电站', // 站点名称 sttpMap: 'ENG', // 类型编码 anchoPointState: 'large_eng_built', // 状态 iconCode: 'xxx.png', // 图标编码 lng: 111.11, // 经度 lat: 33.33, // 纬度 } ``` ## 十、加载时序图 ``` 时间轴 │ ├─1─┤ setLayerData() - 设置图层配置 │ ├─2─┤ loadAllLayerData() 开始 │ │ │ ├─3─┤ 选中图层数据请求 (阻塞) │ │ │ │ │ └─4─┤ 数据返回,添加到地图,缓存 │ │ │ ├─5─┤ setSelectedLegendData() - 设置图例 │ │ │ └─6─┤ 未选中图层数据请求 (后台,不阻塞) │ │ │ └─7─┤ 数据返回,添加到地图,缓存 │ └─8─┤ updateLayerData() - 更新图层显隐,控制锚点显示 ```