# 地图模块-详细说明 ## 1. 文档目的 本文档用于梳理当前前端地图模块的整体结构、运行链路、核心文件职责、图层与点位渲染机制、图例与筛选联动方式,以及后台配置与前台运行时之间的关系。 本文档只描述当前地图模块整体实现,不包含抽吸和碰撞的专项分析。 抽吸与碰撞问题单独整理在: - `docs/地图模块-OpenLayers抽吸与碰撞分析.md` ## 2. 当前技术栈 当前地图模块涉及的核心技术如下: - 前端框架:Vue 3 + TypeScript + Ant Design Vue - 状态管理:Pinia - 2D 地图引擎:OpenLayers - 3D 地图引擎:Cesium - 地图服务:GeoServer - 数据来源: - 后端接口返回图层树配置 - 后端接口返回图例配置 - 后端接口返回各类锚点数据 项目依赖中当前地图引擎版本如下: - `ol@^10.8.0` - `cesium@^1.141.0` - `leaflet@^1.9.4` 说明: - 当前 2D 主链路已经切换到 OpenLayers; - Leaflet 依赖仍保留在项目中,但不是当前主运行路径。 ## 3. 地图整体架构 当前地图模块可以分成 6 层: 1. 页面入口层 2. 应用编排层 3. 地图能力门面层 4. 地图引擎实现层 5. 状态存储层 6. 交互组件层 对应文件如下: - 页面入口层 - `src/components/gis/GisView.vue` - 应用编排层 - `src/modules/map/application/map-orchestrator.ts` - 地图能力门面层 - `src/components/gis/map.class.ts` - 地图引擎实现层 - `src/components/gis/map.ol.ts` - `src/components/gis/map.cesium.ts` - 状态存储层 - `src/store/modules/map.ts` - `src/modules/map/stores/map-config.store.ts` - `src/modules/map/stores/map-data.store.ts` - `src/modules/map/stores/map-view.store.ts` - 交互组件层 - `src/components/mapLegend/index.vue` - `src/components/mapFilter/index.vue` - `src/components/mapController/index.vue` - `src/components/mapController/LayerController.vue` - `src/components/BaseLayerSwitcher/index.vue` ## 4. 页面入口层 ### 4.1 全局挂载位置 地图视图最终由主布局中的 `GisView` 常驻挂载,入口位置在: - [AppMain.vue](file:///d:/wordpack/WholeProcessPlatform/frontend/src/layout/components/AppMain.vue) 这意味着地图并不是某一个业务页单独创建,而是作为全局地图容器持续存在,然后随着菜单切换切换图层和页面配置。 ### 4.2 `GisView.vue` 职责 文件: - [GisView.vue](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/gis/GisView.vue) 当前职责主要有: - 提供地图 DOM 容器 `#mapContainer` - 挂载地图 popup 容器 - 挂载地图图例、筛选器、控制器、底图切换器 - 根据当前路由计算 `pageKey` - 在组件挂载时触发地图初始化 - 在页面切换时触发地图页面配置切换 - 分发少量地图控制命令,例如 2D/3D 切换、梯级流域显示 它已经不再承担大部分地图业务拼装逻辑,更多是地图页面入口和组件装配层。 ## 5. 应用编排层 文件: - [map-orchestrator.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/modules/map/application/map-orchestrator.ts) `map-orchestrator` 是当前地图运行时的调度中心,主要负责把页面、Store、地图实例串起来。 核心职责包括: - 初始化地图壳和 popup 容器 - 根据 `pageKey` 加载当前页面地图配置 - 拉取图层树和图例配置 - 初始化基础底图 - 触发点位数据加载 - 处理图层树勾选 - 处理图例显隐 - 处理基地切换 - 处理时间筛选和重新加载 - 处理搜索定位 - 处理某些菜单下的缩放联动图层 ### 5.1 初始化主链路 大致流程如下: 1. `GisView.vue` 调用 `mapOrchestrator.mountView()` 2. 编排器初始化地图实例 3. 挂载 popup 容器 4. 加载当前页面的图层树、图例和页面图例 5. 初始化基础底图 6. 加载点位图层数据 7. 建立缩放监听、基地监听和图例联动 ### 5.2 页面切换 当路由变化后: - `GisView.vue` 重新计算 `pageKey` - 调用 `mapOrchestrator.handlePageChange()` - 编排器重新加载该页面对应的地图配置和显示状态 这使得地图容器本身不销毁,只是页面配置和显示内容发生变化。 ## 6. 地图能力门面层 文件: - [map.class.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/gis/map.class.ts) `MapClass` 是地图能力统一门面,对外提供统一方法,屏蔽 2D 和 3D 的差异。 典型能力包括: - `init()` - `addBaseDataLayer()` - `addInitDataLayer()` - `mdLayerTreeShowOrHidden()` - `setLegendPointVisible()` - `baseLayerSwitcher()` - `flyTopanto()` - `zoomToggle()` - `lengthCalculate()` - `areCalculate()` - `mapOutPut()` - `destroy()` - `switchView()` 当前 2D 主实现是: - `this.service = new MapOl()` 说明当前前台主要还是 OpenLayers 在承担地图业务。 ## 7. 地图引擎实现层 ### 7.1 OpenLayers 主实现 文件: - [map.ol.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/gis/map.ol.ts) 这是当前地图模块最核心的执行层文件,承担了大量实际渲染与地图交互逻辑,包括: - OpenLayers 地图初始化 - 视图和底图管理 - 点图层管理 - 点位样式生成 - hover popup 与批量 popup - 区域裁切 - 基地过滤 - 梯级流域图层 - 测量、截图、定位 ### 7.2 Cesium 实现 文件: - [map.cesium.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/gis/map.cesium.ts) 当前 3D 能力存在,但相对 2D 来说并没有完全对齐。 目前更像是保留了切换入口和部分基础能力,例如: - viewer 初始化 - 底图加载 - 定位与飞行 - 部分截图能力 多数业务点位和复杂运行逻辑仍然主要围绕 OpenLayers 设计。 ## 8. 点图层管理 文件: - [point-layer-manager.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/gis/ol/point-layer-manager.ts) 这个文件负责 OpenLayers 点图层的生命周期管理。 核心职责包括: - 按图层 key 创建 `VectorLayer` - 给每个点图层维护独立的 `VectorSource` - 把后端点位数据转为 `Feature` - 建立图例字段索引 - 控制整层显隐 - 控制图例项对应点位显隐 - 删除点图层 - 获取当前可视范围内点位 ### 8.1 当前图层组织方式 当前点位图层的组织方式是: - 每个业务点图层对应一个 `VectorLayer` - 每条后端点位数据被转换为一个 `Feature` - Feature 上会额外挂载运行时字段,例如: - `_iconUrl` - `_labelText` - `_legendVisible` - `_regionVisible` - `_layerKey` ### 8.2 图层显隐 图层显隐主要分三类: - 图层树控制整层显隐 - 图例项控制某一类点位显隐 - 基地裁切控制某些点位在当前基地范围外隐藏 这些状态最终会体现在 Feature 属性和图层可见性上。 ## 9. 点位样式与渲染 点位样式主逻辑在: - [map.ol.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/gis/map.ol.ts) 当前点位样式包含以下内容: - 图标 - 文字标签 - 字号随缩放动态变化 - 图标大小随缩放动态变化 - 图例显隐状态 - 基地区域显隐状态 - 按 `distance` 字段做缩放级别抽稀 ### 9.1 当前样式生成逻辑 当前渲染时会综合判断: - 是否有图标 URL - 图例是否可见 - 区域是否可见 - 是否满足当前缩放级别下的距离阈值 满足后才会返回 `Style`。 ### 9.2 当前标签处理 当前标签会做以下处理: - 去掉括号 - 最多显示两行 - 每行长度受限 - 超长文本截断并加省略号 - 根据单行或多行情况设置不同偏移 这部分属于当前地图的统一标签显示策略。 ## 10. Popup 机制 文件: - [popup-manager.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/gis/ol/popup-manager.ts) Popup 分为两类: - hover 时显示的单点 popup - 高缩放下批量显示的 popup ### 10.1 Hover Popup 基础 hover popup 由地图鼠标移动事件驱动: - 检测当前 hover 的要素 - 更新悬停状态 - 在对应坐标显示 popup ### 10.2 批量 Popup 在较高缩放级别下,会进入批量 popup 模式: - 获取当前视口内所有可见点位 - 逐个测量 popup 尺寸 - 做边界框碰撞判断 - 只渲染不冲突的 popup 这个机制的主要目的是避免高缩放下 popup 过多时完全覆盖地图。 ## 11. 基础底图与 GIS 图层 基础底图和 GIS 叠加图层相关能力主要集中在: - `map.ol.ts` - `mapurlManage.ts` - `gisUtils.ts` ### 11.1 `mapurlManage.ts` 文件: - [mapurlManage.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/gis/mapurlManage.ts) 主要维护: - GeoServer 服务地址 - WMTS 配置 - XYZ 配置 - 矢量图层相关配置 - 某些专题图层和图例显示参数 ### 11.2 `gisUtils.ts` 文件: - [gisUtils.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/gis/gisUtils.ts) 主要负责: - 图层树拍平 - 地图配置补全 - 底图配置转换 - 部分标签/偏移相关工具逻辑 ## 12. 图层树与图例 ### 12.1 图层树 UI 文件: - [LayerController.vue](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/mapController/LayerController.vue) 主要职责: - 展示右侧图层树 - 响应勾选变化 - 把勾选结果转发给编排器和 Store 当前图层树里还包含若干业务互斥规则,例如: - 视频站和 AI 视频站互斥 - 环保设施和环保设施在建互斥 - 珍稀鱼类和沿程鱼类互斥 ### 12.2 图例 UI 文件: - [mapLegend/index.vue](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/mapLegend/index.vue) 主要职责: - 展示当前页面和当前已选图层对应的图例 - 维护图例项勾选状态 - 把图例点击行为分发给编排器 图例不是固定写死的,而是由后端返回配置和当前已选图层共同决定。 ## 13. 地图筛选与控制器 ### 13.1 `MapFilter` 文件: - [mapFilter/index.vue](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/mapFilter/index.vue) 当前承担的筛选功能包括: - 基地筛选 - 时间筛选 - 装机容量筛选 - 关键字搜索 - 个别专题下的额外筛选 ### 13.2 `MapController` 文件: - [mapController/index.vue](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/mapController/index.vue) 当前承担的地图操作包括: - 放大缩小 - 图层树显隐 - 2D / 3D 切换 - 量算 - 截图 - 梯级流域专题显示 ### 13.3 `BaseLayerSwitcher` 文件: - [BaseLayerSwitcher/index.vue](file:///d:/wordpack/WholeProcessPlatform/frontend/src/components/BaseLayerSwitcher/index.vue) 用于切换: - 矢量底图 - 地形底图 - 影像底图 ## 14. Store 分层 ### 14.1 旧主 Store 文件: - [map.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/store/modules/map.ts) 当前仍然承担大量地图运行态逻辑,例如: - 图层选中状态 - 图例选中状态 - 图层数据加载 - 图例联动 - 点位缓存 - 图层更新 ### 14.2 新拆分 Store 文件: - [map-config.store.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/modules/map/stores/map-config.store.ts) - [map-data.store.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/modules/map/stores/map-data.store.ts) - [map-view.store.ts](file:///d:/wordpack/WholeProcessPlatform/frontend/src/modules/map/stores/map-view.store.ts) 当前已经开始按职责拆分: - `map-config.store.ts` - 维护图层树和图例配置 - `map-data.store.ts` - 维护图层数据缓存和点位数据 - `map-view.store.ts` - 维护视图相关运行态,例如选中图层、图例勾选、缩放级别、基地状态 这说明地图模块已经在往“编排层 + Store 分层 + 引擎执行层”方向演进。 ## 15. 基地裁切与区域过滤 基地逻辑是当前地图模块里的关键能力之一。 入口主要在: - `GisView.vue` - `map-orchestrator.ts` - `map.ol.ts` 整体过程大致如下: 1. 选择基地 2. 编排器接收基地变化 3. 调用地图实例更新基地范围 4. 请求或读取基地边界 GeoJSON 5. 对点位执行区域内外判断 6. 更新 Feature 的 `_regionVisible` 7. 地图样式函数据此决定是否显示 除了点位控制外,基地切换还会影响底图裁切和专题图层显示。 ## 16. 后台配置与前台运行时关系 地图模块不仅依赖前台代码,也强依赖后台配置。 ### 16.1 后台管理入口 主要页面位于: - [views/system/map/index.vue](file:///d:/wordpack/WholeProcessPlatform/frontend/src/views/system/map/index.vue) - [views/system/map/components/LayerManagement/index.vue](file:///d:/wordpack/WholeProcessPlatform/frontend/src/views/system/map/components/LayerManagement/index.vue) ### 16.2 后台管理内容 后台可维护的内容主要包括: - 图层树结构 - 图层是否启用 - 图层接口地址 - 图层基础参数 - 图例元数据 ### 16.3 前后台关系 运行时不是前端把所有图层写死,而是: - 后台维护元数据 - 前端进入页面后加载配置 - 再根据配置请求对应图层数据 - 最后交给地图引擎渲染 因此地图模块本质上是“配置驱动 + 运行时渲染”的模式。 ## 17. 当前调用链总结 ### 17.1 页面初始化链路 整体调用链如下: 1. `AppMain` 挂载 `GisView` 2. `GisView` 调用 `mapOrchestrator.mountView` 3. `mapOrchestrator` 调用 `MapClass.init` 4. `MapClass` 实际调用 `MapOl.init` 5. 编排器加载图层树和图例配置 6. 编排器初始化底图 7. 编排器加载点位数据 8. `PointLayerManager` 创建点图层并写入 Feature 9. `MapOl` 通过样式函数完成渲染 ### 17.2 图层勾选链路 整体调用链如下: 1. 用户勾选 `LayerController` 2. 编排器接收图层选择结果 3. Store 更新图层选中状态 4. 地图实例更新图层显隐 5. 图例重新派生 ### 17.3 图例点击链路 整体调用链如下: 1. 用户点击 `MapLegend` 2. 编排器接收图例切换 3. Store 更新图例选中状态 4. 地图实例更新图例对应点位显隐 ### 17.4 筛选链路 整体调用链如下: 1. 用户操作 `MapFilter` 2. 编排器接收搜索、时间、基地或容量变化 3. Store 更新运行态 4. 必要时删图层、清缓存、重新请求数据 5. 地图引擎重新渲染 ## 18. 当前模块特点 从现有实现看,地图模块有以下几个明显特点: - 地图容器是全局常驻的 - 页面切换主要依赖 `pageKey` 重新编排 - OpenLayers 是当前 2D 主引擎 - 地图运行态是配置驱动的 - 点位图层按业务图层分层组织 - 图层树、图例、筛选、基地切换之间耦合较深 - 编排层已经出现,但部分旧逻辑仍在 Store 和引擎层混合存在 ## 19. 相关文件清单 地图模块当前重点文件如下: - `src/components/gis/GisView.vue` - `src/components/gis/map.class.ts` - `src/components/gis/map.ol.ts` - `src/components/gis/map.cesium.ts` - `src/components/gis/gisUtils.ts` - `src/components/gis/mapurlManage.ts` - `src/components/gis/ol/point-layer-manager.ts` - `src/components/gis/ol/popup-manager.ts` - `src/modules/map/application/map-orchestrator.ts` - `src/modules/map/stores/map-config.store.ts` - `src/modules/map/stores/map-data.store.ts` - `src/modules/map/stores/map-view.store.ts` - `src/store/modules/map.ts` - `src/components/mapLegend/index.vue` - `src/components/mapFilter/index.vue` - `src/components/mapController/index.vue` - `src/components/mapController/LayerController.vue` - `src/components/BaseLayerSwitcher/index.vue` - `src/views/system/map/index.vue` - `src/views/system/map/components/LayerManagement/index.vue` ## 20. 结论 当前地图模块已经形成了比较清晰的主干结构: - `GisView` 作为入口层 - `map-orchestrator` 作为编排层 - `MapClass` 作为统一门面 - `MapOl` 作为 2D 主执行层 - 多个 Store 共同维护配置、数据和视图状态 - 图层树、图例、筛选器、底图切换器作为前台交互入口 如果后续继续扩展专题图层、复杂筛选、点位布局和高缩放交互,建议都优先沿着这条主干扩展,而不是再回到页面组件里直接堆业务逻辑。