mars3d自定义图层管理器

243 阅读3分钟

mars3d的官网提供的例子中,图层都是作为一个变量导出的

// 创建矢量数据图层
export graphicLayer = new mars3d.layer.GraphicLayer()
map.addLayer(graphicLayer)

为什么我要自定义一个图层管理器呢,因为实际开发中,需要将不同的功能分为不同的模块,比如专门的生产矢量对象的模块,地图方法的模块,绑定地图事件的模块。

不同的模块,不同的部件,都需要调用不同的图层,使用export graphicLayer这种方式,我在别的页面还需要再导入一遍图层名字import { graphicLayer } from "./map",而且我英语很差,复杂点的单词都是复制粘贴,使用自定义图层管理器,可以对图层名字提示,就很方便

使用:

import { layerManager } from "../map/main"
const layer = layerManager.getLayer("global_heat_layer", true)
layer.clear()

完整代码:

// MapLayerManager.ts
import * as mars3d from "mars3d"
import { map } from "./main"
import { ref } from "vue"

export type BaseLayerType = mars3d.layer.GraphicLayer

// 定义图层类型映射
type LayerTypeMap = {
  // 全局热力图层
  global_heat_layer: mars3d.layer.GraphicLayer
  // 军事图层
  militaryLayer: mars3d.layer.GraphicLayer
  // 政治图层
  politicsLayer: mars3d.layer.GraphicLayer
  // 经济图层
  economyLayer: mars3d.layer.GraphicLayer
  // 经济-铁路图层
  railwayLayer: mars3d.layer.GraphicLayer
  // 安全图层
  secureLayer: mars3d.layer.GraphicLayer
  // 安全的预警图层
  secureWarningLayer: mars3d.layer.GraphicLayer
  // 国境线图层
  boundaryLayer: mars3d.layer.GraphicLayer
  light_points_Layer: mars3d.layer.GraphicLayer
}

// 定义所有支持的图层名称
export type LayerName = keyof LayerTypeMap

// 默认的图层
const DEFAULT_CLS = mars3d.layer.GraphicLayer

// 配置类型定义
interface LayerConfig<T extends BaseLayerType> {
  cls?: new (options: any) => T
  options?: any
}

// 默认图层配置
const DEFAULT_LAYER_CONFIG = {
  // 数字大的在上面。热力图全部是1,剩下最小也是2
  light_points_Layer: { options: { zIndex: 1, id: "light_points_Layer" } },
  militaryLayer: { options: { zIndex: 3, id: "militaryLayer" } },
  global_heat_layer: { options: { zIndex: 1, id: "global_heat_layer" } },
  politicsLayer: {
    options: { zIndex: 3, id: "politicsLayer" }
  },
  secureLayer: { options: { zIndex: 3, id: "secureLayer" } },
  secureWarningLayer: { options: { zIndex: 3, id: "secureWarningLayer" } },
  economyLayer: { options: { zIndex: 2, id: "economyLayer" } },
  railwayLayer: { options: { zIndex: 3, id: "railwayLayer" } },
  boundaryLayer: { options: { zIndex: 1, id: "boundaryLayer" } }
} as const satisfies Record<string, LayerConfig<BaseLayerType>>

// 可以切换显示隐藏的图层
const CAN_CHECK = ["militaryLayer", "politicsLayer", "economyLayer", "secureLayer"]

class MapLayerManager {
  private layers = new Map<LayerName, BaseLayerType>()
  private defaultConfig = DEFAULT_LAYER_CONFIG

  // 响应式状态
  public loadedLayers = ref<LayerName[]>([])

  // 更新响应式状态的方法
  updateLoadedLayers() {
    this.loadedLayers.value = Array.from(this.layers.entries())
      .filter(([_, layer]) => layer.isAdded && !layer.isDestroy)
      .map(([name]) => name)
  }

  /**
   * 初始化地图基础图层
   * @param layerNames 需要初始化的图层名称数组
   * @param customConfigs 自定义配置
   */
  initMap(layerNames: LayerName[], customConfigs: Partial<Record<LayerName, LayerConfig<BaseLayerType>>> = {}): void {
    layerNames.forEach((name) => {
      const config = {
        ...(this.defaultConfig[name] ?? {}),
        ...(customConfigs[name] ?? {})
      }
      if (!this.layers.has(name)) {
        const cls = config.cls || DEFAULT_CLS
        const layer = new cls(config.options)
        this.layers.set(name, layer)
        map.addLayer(layer)
      }
    })
    this.updateLoadedLayers()
  }

  /**
   * 获取图层实例
   * @param name 图层名称
   * @param autoCreate 如果没有图层是否自动创建(默认true)
   */
  getLayer<T extends LayerName>(name: LayerName, autoCreate = true): LayerTypeMap[T] {
    const layer = this.layers.get(name)
    // 完全被激活并且在地图上
    if (layer && !layer.isDestroy && layer.isAdded) {
      return layer as any
    }
    if (autoCreate && !layer && map) {
      return this.createLayer(name) as LayerTypeMap[T]
    }
    return layer as LayerTypeMap[T]
  }

  /**
   * 创建图层
   * @param name 图层名称
   * @param cls 图层类
   * @param options 配置选项
   */
  createLayer<T extends BaseLayerType>(name: LayerName, cls?: new (options: any) => T, options?: any): T {
    if (!map) {
      console.error("没有map,不能创建")
      return null
    }
    const defaultConfig: any = this.defaultConfig[name] || {}
    const finalOptions: any = { ...defaultConfig.options, ...options }
    const LayerClass = cls || DEFAULT_CLS
    const layer = new LayerClass(finalOptions) as T
    this.layers.set(name as LayerName, layer)
    map.addLayer(layer)
    this.updateLoadedLayers()
    return layer
  }

  /**
   * 移除图层
   * @param layerNames 图层名称 图层名称的数组
   * @param destroy 是否销毁实例 实例成员layers中删除
   */
  removeLayer(layerNames: LayerName | LayerName[], destroy = true): void {
    const namesArray = Array.isArray(layerNames) ? layerNames : [layerNames]
    const removeSingleLayer = (name: LayerName) => {
      const layer = this.layers.get(name)
      if (!layer) {
        return
      }
      layer.remove(destroy)
      if (destroy) {
        this.layers.delete(name)
      }
    }
    namesArray.forEach(removeSingleLayer)
    this.updateLoadedLayers()
  }

  /**
   * 飞行到图层位置
   * @param name 图层名称
   * @param options 参数
   */
  async flyTo(name: LayerName, options?: any, fun?: any) {
    const layer = this.layers.get(name)
    const isInMap = layer?.isAdded
    if (layer && isInMap) {
      const flyOver = await layer.flyTo(options || { radius: 1000 })
      if (flyOver && fun) {
        fun()
      }
    }
  }

  /**
   * 设置图层可见性
   */
  setVisibleLayers(): void {
    this.layers.forEach((layer, name) => {
      if (layer.isAdded && !layer.isDestroy) {
        if (CAN_CHECK.includes(name)) {
          layer.show = this.loadedLayers.value.includes(name)
        }
      }
    })
  }

  /**
   * 清除所有图层
   * @param whitelist 不被清除的图层
   */
  clearAll(whitelist = [] as LayerName[], destroy = false) {
    this.layers.forEach((layer, name) => {
      if (!whitelist.includes(name)) {
        if (destroy) {
          this.layers.delete(name)
        }
        if (layer.isAdded && !layer.isDestroy) {
          layer.clear()
          layer.closeTooltip()
        }
      }
    })
  }
}

// 单例实例导出
export const layerManager = new MapLayerManager()