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()