Skip to content

openlayer主要工具

前文我们总结了openlayer的总体封装思路,本文将介绍在这层封装中最主要的几项功能

地图初始化及切换底图功能

  • OpenlayerBaseMap/index.vue
vue
<template>
    <section class="ol_map_wrap">
        <!-- 地图 -->
        <section id="olMap" class="ol_map"></section>

        <!-- 这里将工具全部列出来,下文就不展示html的内容了 -->
        <!-- 图例 -->
`       <lend ref="refLend" :currentPageType="currentPageType" :isShowLend="isShowLend" />

        <!-- 切换底图控件 -->
        <switch-base-layer @switchBaseLayerType="switchBaseLayerType" />

        <!--  气泡窗 -->
        <popup-common ref="refPopupCommon" :currentPageType="currentPageType" />`

        <!-- 切换天地图token 弹窗 -->
        <set-token-dialog ref="refSetTokenDialog" />
    </section>
</template>

<script>
// vue - core
import { ref, onMounted, defineEmits, nextTick } from "vue";
// map - core
import * as mapUtils from "./mapUtils.js";
// 组件
import PopupCommon from "./components/popup/PopupCommon.vue"; // 气泡窗
import Lend from "./components/Lend.vue"; // 图例
import SwitchBaseLayer from "./components/SwitchBaseLayer.vue"; // 切换底图控件
import SetTokenDialog from "./components/SetTokenDialog.vue"; // 切换天地图token
// store
import { gisDataStore } from '@/store/modules/gis.js'

// 自定义事件
const emit = defineEmits([
  // 全局
  "getOlMapInstance",
  "getCurrentViewData",
  "reflashMap",
]);

// ref
const refPopupCommon = ref(null);
const refLend = ref(null);
const refSetTokenDialog = ref(null);

// 地图数据
let myOlMap = null;
const mapCommonData = {
  minRenderZoom: mapUtils.minRenderZoom, // 最小渲染层级
};

// 销毁地图
const destroyMap = (olMap) => {
  if (olMap) {
    mapUtils.destroyMap(olMap)
  }
}

// 初始化地图
const resetOlMap = () => {
  destroyMap(myOlMap)

  const olMap = mapUtils.initOlMap("olMap"); // 初始化地图

  mapInit(olMap); // 地图加载完初始化做的一些操作
  getMapInitInfo(olMap); // 地图加载完初始化后获取地图的一些信息
  setOlmap(olMap); // 设置地图
}

// 地图加载完初始化做的一些操作
const mapInit = (olMap) => {
  // console.log('地图加载完初始化做的一些操作', olMap)
  myOlMap = olMap; // 赋值全局变量,为后续业务操作做准备

  // 地图加载完初始化做的一些操作[业务相关]
  emit("getOlMapInstance", olMap, mapCommonData); // 向外供出olMap实例,以及一些公共数据

  mapUtils.resetControls(olMap); // 初始化所有控件

  // 设置鼠标右键属性
  // ......
};

// 地图加载完初始化后获取地图的一些信息
const getMapInitInfo = (olMap) => {
  // console.log("地图加载完初始化后获取地图的一些信息", olMap)

  // 获取可视区域数据 - 如果不需要自动加载
  if (!props.isAutoRenderData) {
    // console.log('刷新加载地图', props.isAutoRenderData)
    emit("getCurrentViewData", olMap); // 地图加载时会自动触发一次
  }
};

// 设置地图
const setOlmap = (olMap) => {
  mapEvent(olMap); // 地图事件
};

// 切换底图
const switchBaseLayerType = (val) => {
  // console.log('切换底图', val)

  mapUtils.switchBaseLayer(myOlMap, val)
}

/**
 * vue生命周期函数
 * 挂载后触发
 */
onMounted(() => {
  resetOlMap()  // 初始化地图

  switchBaseLayerType('t3imgPrivatization')  // 页面初始化时加载默认底图(有时候加载不出来)
});
</script>
<template>
    <section class="ol_map_wrap">
        <!-- 地图 -->
        <section id="olMap" class="ol_map"></section>

        <!-- 这里将工具全部列出来,下文就不展示html的内容了 -->
        <!-- 图例 -->
`       <lend ref="refLend" :currentPageType="currentPageType" :isShowLend="isShowLend" />

        <!-- 切换底图控件 -->
        <switch-base-layer @switchBaseLayerType="switchBaseLayerType" />

        <!--  气泡窗 -->
        <popup-common ref="refPopupCommon" :currentPageType="currentPageType" />`

        <!-- 切换天地图token 弹窗 -->
        <set-token-dialog ref="refSetTokenDialog" />
    </section>
</template>

<script>
// vue - core
import { ref, onMounted, defineEmits, nextTick } from "vue";
// map - core
import * as mapUtils from "./mapUtils.js";
// 组件
import PopupCommon from "./components/popup/PopupCommon.vue"; // 气泡窗
import Lend from "./components/Lend.vue"; // 图例
import SwitchBaseLayer from "./components/SwitchBaseLayer.vue"; // 切换底图控件
import SetTokenDialog from "./components/SetTokenDialog.vue"; // 切换天地图token
// store
import { gisDataStore } from '@/store/modules/gis.js'

// 自定义事件
const emit = defineEmits([
  // 全局
  "getOlMapInstance",
  "getCurrentViewData",
  "reflashMap",
]);

// ref
const refPopupCommon = ref(null);
const refLend = ref(null);
const refSetTokenDialog = ref(null);

// 地图数据
let myOlMap = null;
const mapCommonData = {
  minRenderZoom: mapUtils.minRenderZoom, // 最小渲染层级
};

// 销毁地图
const destroyMap = (olMap) => {
  if (olMap) {
    mapUtils.destroyMap(olMap)
  }
}

// 初始化地图
const resetOlMap = () => {
  destroyMap(myOlMap)

  const olMap = mapUtils.initOlMap("olMap"); // 初始化地图

  mapInit(olMap); // 地图加载完初始化做的一些操作
  getMapInitInfo(olMap); // 地图加载完初始化后获取地图的一些信息
  setOlmap(olMap); // 设置地图
}

// 地图加载完初始化做的一些操作
const mapInit = (olMap) => {
  // console.log('地图加载完初始化做的一些操作', olMap)
  myOlMap = olMap; // 赋值全局变量,为后续业务操作做准备

  // 地图加载完初始化做的一些操作[业务相关]
  emit("getOlMapInstance", olMap, mapCommonData); // 向外供出olMap实例,以及一些公共数据

  mapUtils.resetControls(olMap); // 初始化所有控件

  // 设置鼠标右键属性
  // ......
};

// 地图加载完初始化后获取地图的一些信息
const getMapInitInfo = (olMap) => {
  // console.log("地图加载完初始化后获取地图的一些信息", olMap)

  // 获取可视区域数据 - 如果不需要自动加载
  if (!props.isAutoRenderData) {
    // console.log('刷新加载地图', props.isAutoRenderData)
    emit("getCurrentViewData", olMap); // 地图加载时会自动触发一次
  }
};

// 设置地图
const setOlmap = (olMap) => {
  mapEvent(olMap); // 地图事件
};

// 切换底图
const switchBaseLayerType = (val) => {
  // console.log('切换底图', val)

  mapUtils.switchBaseLayer(myOlMap, val)
}

/**
 * vue生命周期函数
 * 挂载后触发
 */
onMounted(() => {
  resetOlMap()  // 初始化地图

  switchBaseLayerType('t3imgPrivatization')  // 页面初始化时加载默认底图(有时候加载不出来)
});
</script>
  • OpenlayerBaseMap/mapUtils.js
js
// 加载地图核心方法
let tdtTk = import.meta.env.VITE_APP_MapToken  // 全局配置 - 天地图密钥
const gisStoreData = gisDataStore()

/**
 * 天地图底图配置
    天地图图层类型
    vec: 矢量底图
    cva: 矢量注记图层
    eva: 矢量注记图层-英文注记
    img: 影像底图
    cia: 影像注记图层
    eia: 影像注记图层 -英文
    ter: 地形底图
    cta: 地形注记图层
 */
const baseLayerUrlConfig = {
  // 天地图底图
  getBaseMapLayer(item) {
    switch (item) {
      case 't3imgPrivatization':
        return setLayerUrl("/wtms/googlemaps/satellite/{z}/{y}/{x}.png", false)
      case 't0vec':
        return setLayerUrl("http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=")  // 街道底图
      case 't3img':
        return setLayerUrl("http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=")  // 卫星(影像)底图
      case 't4ter':
        return setLayerUrl("http://t4.tianditu.com/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=")  // 地形底图
      case 't07vec':
        return setLayerUrl("http://t{0-7}.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=")  // 街道底图2
      case 't07img':
        return setLayerUrl("http://t{0-7}.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=")  // 卫星底图2
    }
  },
  getBaseMapTxt(item) {
    switch (item) {
      case 'empty':
        return setLayerUrl('', false)  // 空注记
      case 't0cva': // 街道图注记
        return setLayerUrl("http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=")  // 街道图注记
      case 't4cva': // 地形图注记
        return setLayerUrl("http://t4.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=")  // 地形图注记
      case 't07cia': // 卫星图注记
        return setLayerUrl("http://t{0-7}.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=")  // 卫星图注记
      case 't07cva': // 卫星图注记
        return setLayerUrl("http://t{0-7}.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=")  // 卫星图注记
    }
  }
}

// 设置底图url
const setLayerUrl = (url, hasToken = true) => {
  if (gisStoreData.mapToken !== '') {
    tdtTk = gisStoreData.mapToken
  }
  if (hasToken) {
    return url + tdtTk
  }
  return url
}

// 初始化地图
export const initOlMap = (target) => {
  return new Map({
    target,
    layers: mapInitConfig.layers,
    view: mapInitConfig.view,
    interactions: defaults({ mouseWheelZoom: true })  // 禁止缩放
  });
}
// 地图初始化配置
const mapInitConfig = {
  // ol地图底图 - 默认街道底图
  layers: [
    // 天地图底图
    setBaseMapLayer(baseLayerUrlConfig.getBaseMapLayer('t3imgPrivatization')),  // 私有化底图
    // 天地图注记
    setBaseMapTxt(baseLayerUrlConfig.getBaseMapTxt('empty')),
  ],
  // ol地图基本配置 - View默认使用EPSG3857坐标系
  view: new View({
    center: fromLonLat([121.63, 29.88]),
    zoom: 16,
    maxZoom: 17,
    minZoom: 13,
    constrainResolution: true,  // 设置缩放级别为整数 
    smoothResolutionConstraint: false,  // 关闭无级缩放地图
  }),
}
// 创建底图基础配置
const createBaseLayerConfig = (url, layerSourceConfig = {}, layerConfig = {}) => {
  return new WebGLTile({
    source: new XYZ({
      url,
      ...layerSourceConfig
    }),
    type: 'baseLayer',
    url,
    ...layerConfig
  })
}

// 配置地图底图
const setBaseMapLayer = (url) => {
  return createBaseLayerConfig(url, {
    wrapX: false,
    crossOrigin: "anonymous",
  }, { layerType: 'baseMapLayer' })
}

// 配置地图注记
const setBaseMapTxt = (url) => {
  return createBaseLayerConfig(url, {}, { layerType: 'baseMapTxt' })
}

// 其他工具方法
// 销毁地图
export const destroyMap = (olMap) => {
  if (olMap) {
    // 销毁所有图层
    olMap.getLayers().forEach(function (layer) {
      layer.setMap(null);
    });

    // 销毁视图
    olMap.setView(null);

    // 销毁地图实例
    olMap.setTarget(null);
    olMap = null;
  }
}
// 初始化所有控件
export const resetControls = (olMap) => {
  olMap.getControls().clear()

  // 重新添加控件(如果需要)
  // olMap.addControl(new FullScreen());  // 全屏
  olMap.addControl(new Zoom());  // 缩放
  olMap.addControl(new ZoomSlider());  // 缩放
  olMap.addControl(new ScaleLine());  // 比例尺


  // olMap.addControl(new OverviewMap());  // 鹰眼
}

// 切换地图底图
export const switchBaseLayer = (olMap, type) => {
  let txtType = ''

  switch (type) {
    // 私有化底图
    case 't3imgPrivatization':
      txtType = 'empty'  // 卫星图注记
      break
    // 街道底图
    case 't0vec':
      txtType = 't0cva'  // 街道图注记
      break
    // 卫星(影像)底图
    case 't3img':
      txtType = 't07cia'  // 卫星图注记
      break
    // 地形底图
    case 't4ter':
      txtType = 't4cva'  // 地形图注记`
      break
  }

  // 天地图底图
  let newBaseMapLayer = setBaseMapLayer(baseLayerUrlConfig.getBaseMapLayer(type))
  // 天地图注记
  let newBaseMapTxt = setBaseMapTxt(baseLayerUrlConfig.getBaseMapTxt(txtType))

  console.log('当前天地图token:', tdtTk)
  console.log('当前天地图底图地址:', newBaseMapLayer.values_.url)
  console.log('当前天地图注记地址:', newBaseMapTxt.values_.url)

  // 获取当前地图中的所有图层
  const mapLayers = olMap.getLayers();

  olMap.getAllLayers().forEach((item, index) => {
    if (item.get('type') === 'baseLayer') {
      switch (item.get('layerType')) {
        case 'baseMapLayer':
          olMap.removeLayer(item)
          mapLayers.insertAt(index, newBaseMapLayer)
          break
        case 'baseMapTxt':
          if (newBaseMapTxt !== '') {
            olMap.removeLayer(item)
            mapLayers.insertAt(index, newBaseMapTxt)
          }

          if (newBaseMapTxt === '') {
            let newBaseMapTxtTmp = setBaseMapTxt('')
            olMap.removeLayer(item)
            mapLayers.insertAt(index, newBaseMapTxtTmp)
          }

          break
      }
    }
  })
}
// 加载地图核心方法
let tdtTk = import.meta.env.VITE_APP_MapToken  // 全局配置 - 天地图密钥
const gisStoreData = gisDataStore()

/**
 * 天地图底图配置
    天地图图层类型
    vec: 矢量底图
    cva: 矢量注记图层
    eva: 矢量注记图层-英文注记
    img: 影像底图
    cia: 影像注记图层
    eia: 影像注记图层 -英文
    ter: 地形底图
    cta: 地形注记图层
 */
const baseLayerUrlConfig = {
  // 天地图底图
  getBaseMapLayer(item) {
    switch (item) {
      case 't3imgPrivatization':
        return setLayerUrl("/wtms/googlemaps/satellite/{z}/{y}/{x}.png", false)
      case 't0vec':
        return setLayerUrl("http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=")  // 街道底图
      case 't3img':
        return setLayerUrl("http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=")  // 卫星(影像)底图
      case 't4ter':
        return setLayerUrl("http://t4.tianditu.com/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=")  // 地形底图
      case 't07vec':
        return setLayerUrl("http://t{0-7}.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=")  // 街道底图2
      case 't07img':
        return setLayerUrl("http://t{0-7}.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=")  // 卫星底图2
    }
  },
  getBaseMapTxt(item) {
    switch (item) {
      case 'empty':
        return setLayerUrl('', false)  // 空注记
      case 't0cva': // 街道图注记
        return setLayerUrl("http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=")  // 街道图注记
      case 't4cva': // 地形图注记
        return setLayerUrl("http://t4.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=")  // 地形图注记
      case 't07cia': // 卫星图注记
        return setLayerUrl("http://t{0-7}.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=")  // 卫星图注记
      case 't07cva': // 卫星图注记
        return setLayerUrl("http://t{0-7}.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=")  // 卫星图注记
    }
  }
}

// 设置底图url
const setLayerUrl = (url, hasToken = true) => {
  if (gisStoreData.mapToken !== '') {
    tdtTk = gisStoreData.mapToken
  }
  if (hasToken) {
    return url + tdtTk
  }
  return url
}

// 初始化地图
export const initOlMap = (target) => {
  return new Map({
    target,
    layers: mapInitConfig.layers,
    view: mapInitConfig.view,
    interactions: defaults({ mouseWheelZoom: true })  // 禁止缩放
  });
}
// 地图初始化配置
const mapInitConfig = {
  // ol地图底图 - 默认街道底图
  layers: [
    // 天地图底图
    setBaseMapLayer(baseLayerUrlConfig.getBaseMapLayer('t3imgPrivatization')),  // 私有化底图
    // 天地图注记
    setBaseMapTxt(baseLayerUrlConfig.getBaseMapTxt('empty')),
  ],
  // ol地图基本配置 - View默认使用EPSG3857坐标系
  view: new View({
    center: fromLonLat([121.63, 29.88]),
    zoom: 16,
    maxZoom: 17,
    minZoom: 13,
    constrainResolution: true,  // 设置缩放级别为整数 
    smoothResolutionConstraint: false,  // 关闭无级缩放地图
  }),
}
// 创建底图基础配置
const createBaseLayerConfig = (url, layerSourceConfig = {}, layerConfig = {}) => {
  return new WebGLTile({
    source: new XYZ({
      url,
      ...layerSourceConfig
    }),
    type: 'baseLayer',
    url,
    ...layerConfig
  })
}

// 配置地图底图
const setBaseMapLayer = (url) => {
  return createBaseLayerConfig(url, {
    wrapX: false,
    crossOrigin: "anonymous",
  }, { layerType: 'baseMapLayer' })
}

// 配置地图注记
const setBaseMapTxt = (url) => {
  return createBaseLayerConfig(url, {}, { layerType: 'baseMapTxt' })
}

// 其他工具方法
// 销毁地图
export const destroyMap = (olMap) => {
  if (olMap) {
    // 销毁所有图层
    olMap.getLayers().forEach(function (layer) {
      layer.setMap(null);
    });

    // 销毁视图
    olMap.setView(null);

    // 销毁地图实例
    olMap.setTarget(null);
    olMap = null;
  }
}
// 初始化所有控件
export const resetControls = (olMap) => {
  olMap.getControls().clear()

  // 重新添加控件(如果需要)
  // olMap.addControl(new FullScreen());  // 全屏
  olMap.addControl(new Zoom());  // 缩放
  olMap.addControl(new ZoomSlider());  // 缩放
  olMap.addControl(new ScaleLine());  // 比例尺


  // olMap.addControl(new OverviewMap());  // 鹰眼
}

// 切换地图底图
export const switchBaseLayer = (olMap, type) => {
  let txtType = ''

  switch (type) {
    // 私有化底图
    case 't3imgPrivatization':
      txtType = 'empty'  // 卫星图注记
      break
    // 街道底图
    case 't0vec':
      txtType = 't0cva'  // 街道图注记
      break
    // 卫星(影像)底图
    case 't3img':
      txtType = 't07cia'  // 卫星图注记
      break
    // 地形底图
    case 't4ter':
      txtType = 't4cva'  // 地形图注记`
      break
  }

  // 天地图底图
  let newBaseMapLayer = setBaseMapLayer(baseLayerUrlConfig.getBaseMapLayer(type))
  // 天地图注记
  let newBaseMapTxt = setBaseMapTxt(baseLayerUrlConfig.getBaseMapTxt(txtType))

  console.log('当前天地图token:', tdtTk)
  console.log('当前天地图底图地址:', newBaseMapLayer.values_.url)
  console.log('当前天地图注记地址:', newBaseMapTxt.values_.url)

  // 获取当前地图中的所有图层
  const mapLayers = olMap.getLayers();

  olMap.getAllLayers().forEach((item, index) => {
    if (item.get('type') === 'baseLayer') {
      switch (item.get('layerType')) {
        case 'baseMapLayer':
          olMap.removeLayer(item)
          mapLayers.insertAt(index, newBaseMapLayer)
          break
        case 'baseMapTxt':
          if (newBaseMapTxt !== '') {
            olMap.removeLayer(item)
            mapLayers.insertAt(index, newBaseMapTxt)
          }

          if (newBaseMapTxt === '') {
            let newBaseMapTxtTmp = setBaseMapTxt('')
            olMap.removeLayer(item)
            mapLayers.insertAt(index, newBaseMapTxtTmp)
          }

          break
      }
    }
  })
}

右键菜单封装

js
// OpenlayerBaseMap/index.vue
// 地图加载完初始化做的一些操作
const mapInit = (olMap) => {
    // ......

  // 设置鼠标右键属性
  mapUtils.setContextmenu(
    olMap,
    (option) => {
      // console.log(option, mapUtils.menuMethods);
      setMenuMethods(option);
    },
    (next) => {
      // 根据具体页面配置菜单栏
      next(props.currentPageType);
    }
  );
};

// 设置鼠标右键菜单栏方法
const setMenuMethods = ({ option, feature, pixelPoint }) => {
  // console.log("设置鼠标右键菜单栏方法", option, feature, pixelPoint);

  // 点击地图隐藏气泡窗
  // ......

  menuUtils.setMenuMethods(myOlMap, option, feature, pixelPoint, proxy)
};

// OpenlayerBaseMap/mapUtils.js
// 重置右键属性菜单
export const resetContextMenu = (next) => {
  let mapWrap = document.querySelector('.ol_map_wrap')
  let menu = document.querySelector('.menu_wrap')

  // 判断是否存在menu
  if (menu) {
    mapWrap.removeChild(menu);
  }

  if (next) {
    next(mapWrap)
  }
}

// 获取所有图层
export const getAllLayer = (olMap, next) => {
  // 获取当前地图上的所有图层
  let layers = olMap.getLayers().getArray();

  // 获取所有图层(从地图中移除所有图层)
  for (let i = layers.length - 1; i >= 0; --i) {
    if (layers[i] instanceof VectorLayer) {
      next(layers[i])
    };
  }
}

// 公共动态选项判断
const setCommonMenuMethod = (condition, commonDynamicMenuMethod) => {
  if (condition) {
    if (condition instanceof Array) {
      if (condition.length !== 0) {
        // console.log(condition.get('tempType'))

        menuAddSingleMethod(commonDynamicMenuMethod)
      }

      if (condition.length === 0) {
        menuUtils.commonMenuMethodsArr = menuUtils.commonMenuMethodsArr.filter(item => item !== commonDynamicMenuMethod)
      }
    } else {
      if (condition instanceof Feature) {
        if (!condition.get('tempType')) {
          menuAddSingleMethod(commonDynamicMenuMethod)
        }
      } else {
        menuAddSingleMethod(commonDynamicMenuMethod)

        if (condition.length === 0) {
          menuUtils.commonMenuMethodsArr = menuUtils.commonMenuMethodsArr.filter(item => item !== commonDynamicMenuMethod)
        }
      }
    }
  }
  if (!condition && menuUtils.commonMenuMethodsArr.includes(commonDynamicMenuMethod)) {
    menuUtils.commonMenuMethodsArr = menuUtils.commonMenuMethodsArr.filter(item => item !== commonDynamicMenuMethod)
  }
}

// 设置鼠标右键属性
export const setContextmenu = (olMap, next, setMenuConfig) => {
  const { commonDynamicMenu, singleMenu } = menuUtils.menuMethodBtn  // 公共动态选项,每个页面有需要才显示

  // 添加右键菜单监听
  olMap.getViewport().addEventListener('contextmenu', e => {
    // console.log(transformToLonlat(olMap.getEventCoordinate(e)))  // 经纬度

    e.preventDefault(); // 阻止默认的右键菜单弹出

    /**
     * 子页动态选项
     */
    // 根据具体页面配置菜单栏
    if (setMenuConfig) {
      setMenuConfig(currentPageType => {
        // console.log('当前页面', currentPageType)

        // 根据具体页面配置菜单栏 - 子菜单在某些情况可能需要隐藏
        menuUtils.setMentBtnExtendByPage(currentPageType)
      })
    }

    // 屏幕坐标
    const pixelPoint = olMap.getEventCoordinate(e)
    const pixel = olMap.getPixelFromCoordinate(pixelPoint)
    const feature = olMap.forEachFeatureAtPixel(pixel, feature => {
      return feature
    })


    /**
     * 获取所有layer并做判断
     */
    let featureOnPage = []  // 页面所有的feature
    let myPointByMenuFeature = []  // 所有自定义定位点
    let POIPointByMenuFeature = []  // 所有POI定位点
    let drawTypeByMenuFeature = []  // 所有绘制内容
    getAllLayer(olMap, layerItem => {
      let currentFeature = layerItem.getSource().getFeatures()[0]

      if (!currentFeature) {
        return
      }

      featureOnPage.push(currentFeature)

      if (currentFeature.get('tempType') === 'myPointByMenu') {
        myPointByMenuFeature.push(currentFeature)
      }
      if (currentFeature.get('businessType') === 'POIMarker') {
        POIPointByMenuFeature.push(currentFeature)
      }
      if (currentFeature.get('drawType')) {
        drawTypeByMenuFeature.push(currentFeature)
      }
    })

    /**
     * 公共动态选项
     */
    // 判断是否显示清除所有要素
    setCommonMenuMethod(featureOnPage, commonDynamicMenu.commonDynamicMenuMethod1)

    // 判断是否显示当前要素
    setCommonMenuMethod(feature, commonDynamicMenu.commonDynamicMenuMethod2)

    // 判断是否需要显示停止绘制
    // 获取绘制的图形
    const drawInteraction = getDrawInteraction(olMap)
    setCommonMenuMethod(drawInteraction, commonDynamicMenu.commonDynamicMenuMethod3)

    // 自定义定位点
    setCommonMenuMethod(myPointByMenuFeature, '清空自定义标注点')

    // 自定义闪烁点
    let flickerPointDom = document.querySelectorAll('.flicker_point')
    setCommonMenuMethod(flickerPointDom, '清空自定义闪烁点')

    // 展示分析结果
    if (feature) {
      if (feature.get('pointData')?.isNeedAnalysis) {
        setCommonMenuMethod(feature, commonDynamicMenu.commonDynamicMenuMethod4)
      }
    }

    // 删除所有绘制内容  
    setCommonMenuMethod(drawTypeByMenuFeature, commonDynamicMenu.commonDynamicMenuMethod5)

    /**
     * 子页动态选项
     */
    // 清除POI点
    setCommonMenuMethod(POIPointByMenuFeature, singleMenu.singleMenuMethod2)


    // 重置右键属性菜单
    resetContextMenu(mapWrap => {
      let menu = null

      menu = document.createElement('div');
      menu.setAttribute("class", "menu_wrap");

      // 自定义菜单项
      let tempStr = ''
      menuUtils.commonMenuMethodsArr.forEach(item => {
        tempStr += `<li>${item}</li>`
      })

      menu.innerHTML = `
      <ul>
        ${tempStr}
      </ul>
    `;

      // 添加到页面上
      menu.style.position = 'fixed';
      menu.style.left = `${e.clientX}px`;
      menu.style.top = `${e.clientY}px`;
      mapWrap.appendChild(menu);

      // 监听菜单项的点击事件(可选)
      menu.addEventListener('click', (evt) => {
        const option = evt.target.textContent;
        next({ option, feature, pixelPoint })

        // 清理菜单
        mapWrap.removeChild(menu);
      });
    })
  });
}

// menuUtils.js
/**
 * 维护右键菜单栏
 */

import { ElMessage } from 'element-plus'
import * as mapUtils from "./mapUtils.js";
import mittBus from "@/utils/mittBus"; // mitt
import { copyTextToClipboard } from "@/utils/index.js";

// 菜单项
const menuMethodBtn = {
    // 公共选项,常驻菜单
    commonMenu: {
        // commonMenuMethod0: '地图功能测试',  // 公共选项0
        // commonMenuMethod01: '添加自定义标注点',  // 公共选项01
        // commonMenuMethod02: '添加自定义闪烁点',  // 公共选项02
        commonMenuMethod1: '拷贝当前经纬度',  // 公共选项1
        // commonMenuMethod2: '置顶要素',  // 公共选项2
        commonMenuMethod3: '切换天地图token',  // 公共选项3
    },
    // 公共动态选项,每个页面有需要才显示
    commonDynamicMenu: {
        commonDynamicMenuMethod1: '清除所有要素',  // 公共选项3
        commonDynamicMenuMethod2: '显示当前要素信息',  // 公共动态选项1
        commonDynamicMenuMethod3: '仅取消绘制状态',  // 公共动态选项3
        commonDynamicMenuMethod4: '展示分析结果',  // 公共动态选项4
        commonDynamicMenuMethod5: '删除所有绘制内容',  // 公共动态选项5
    },
    // 子页动态选项, 单页面显示或单页面有需要显示
    singleMenu: {
        singleMenuMethod1: '刷新地图',  // 子页动态选项1
        singleMenuMethod2: '清除POI点',  // 子页动态选项2
        // singleMenuMethod2: '展示分析结果'  // 子页动态选项2
    },
}

if (import.meta.env.VITE_APP_ENV === 'development') {
    menuMethodBtn.commonMenu = {
        ...menuMethodBtn.commonMenu,
        commonMenuMethod0: '地图功能测试',  // 公共选项0
        commonMenuMethod01: '添加自定义标注点',  // 公共选项01
        commonMenuMethod02: '添加自定义闪烁点',  // 公共选项02
    }
}

// 主菜单项
const { commonMenu } = menuMethodBtn  // 公共选项,常驻菜单
let commonMenuMethodsArr = []  // 常驻菜单数组
// 将对象中的值传入数组
for (let i in commonMenu) {
    commonMenuMethodsArr.push(commonMenu[i])
}

export default {
    // 菜单项
    menuMethodBtn,

    // 常驻菜单数组
    commonMenuMethodsArr,

    // 设置鼠标右键菜单栏方法
    setMenuMethods(olMap, option, feature, pixelPoint, proxy) {
        // console.log(olMap, option, feature, pixelPoint, proxy)

        // 经纬度
        let currentLonlat = mapUtils.transformToLonlat(pixelPoint)

        /**
         * 菜单栏
         * commonMenu  // 公共选项,常驻菜单
         * commonDynamicMenu  // 公共动态选项,每个页面有需要才显示
         * singleMenu  // 子页动态选项, 单页面显示或单页面有需要显示
         */
        const { commonMenu, commonDynamicMenu, singleMenu } = this.menuMethodBtn;

        switch (option) {
            /**
             * ===========================
             *      公共选项,常驻菜单
             * ===========================
             */
            // 地图功能测试
            case commonMenu.commonMenuMethod0:
                // console.log("test", commonMenu.commonMenuMethod0);

                mapUtils.olMapTestCommon(olMap, feature, pixelPoint);
                break;
            // 添加标注点
            case commonMenu.commonMenuMethod01:
                // console.log("test", commonMenu.commonMenuMethod1);

                mapUtils.addMyPointByMenu(olMap, pixelPoint);
                break;
            // 清空自定义标注点
            case '清空自定义标注点':
                // console.log("test", '清空自定义标注点');

                // 根据条件移除要素
                mapUtils.removeByCondition(olMap, currentFeature => {
                    return currentFeature.get('tempType') === 'myPointByMenu'
                })
                break;
            // 添加闪烁点
            case commonMenu.commonMenuMethod02:
                // console.log("test", commonMenu.commonMenuMethod2);

                mapUtils.addFlickerPoint(olMap, pixelPoint);
                break;
            // 清空自定义闪烁点
            case '清空自定义闪烁点':
                // console.log("test", '清空自定义闪烁点');

                let flickerPointDom = document.querySelectorAll('.flicker_point')

                flickerPointDom.forEach(item => {
                    item.classList.remove('flicker_point')
                })

                break;
            // 拷贝当前经纬度
            case commonMenu.commonMenuMethod1:
                // console.log("拷贝当前经纬度");
                copyTextToClipboard(`[${currentLonlat}]`, () => {
                    ElMessage.success(`[${currentLonlat}] 拷贝成功`);
                });
                break;
            // 置顶图层
            case commonMenu.commonMenuMethod2:
                // console.log("置顶图层");
                mapUtils.featureToMaxTop(olMap, feature);
                break;
            // 切换天地图token
            case commonMenu.commonMenuMethod3:
                // console.log("切换天地图token");

                mittBus.emit("showSetTokenDialog");
                break;
            /**
             * =======================================
             *      公共动态选项,每个页面有需要才显示
             * =======================================
             */
            // 清除所有要素
            case commonDynamicMenu.commonDynamicMenuMethod1:
                // console.log("清除所有要素");

                mapUtils.removeAllLayer(olMap);
                break;
            // 显示当前要素信息
            case commonDynamicMenu.commonDynamicMenuMethod2:
                // console.log("显示当前要素信息");
                mittBus.emit("singleFeaturesClick", { feature, pixelPoint });
                break;
            // 仅取消绘制状态
            case commonDynamicMenu.commonDynamicMenuMethod3:
                // console.log("仅取消绘制状态");

                mapUtils.cancelDrawInteraction(olMap)
                break;
            // 展示分析结果
            case commonDynamicMenu.commonDynamicMenuMethod4:
                let currentData = feature.get('pointData')
                // console.log("展示分析结果", feature.get('pointData'));
                mittBus.emit("analysisPointData", currentData);
                break;
            // 删除所有绘制内容
            case commonDynamicMenu.commonDynamicMenuMethod5:
                console.log("删除所有绘制内容");

                // 根据条件移除要素
                mapUtils.removeByCondition(olMap, currentFeature => {
                    return currentFeature.get('drawType')
                })

                // let currentData = feature.get('pointData')

                // mittBus.emit("analysisPointData", currentData);
                break;
            /**
             * =============================================
             *      子页动态选项, 单页面显示或单页面有需要显示
             * =============================================
             */
            // 刷新地图
            case singleMenu.singleMenuMethod1:
                // console.log("刷新地图");
                mittBus.emit("reflashMap");
                break;
            // 清除POI点
            case singleMenu.singleMenuMethod2:
                // console.log("清除POI点");
                mapUtils.removeLayerByBusinessType(olMap, "POIMarker"); // 根据类型移除图层
                break;
        }
    },

    // 根据具体页面配置菜单栏
    setMentBtnExtendByPage(currentPageType) {
        const { singleMenu } = this.menuMethodBtn

        switch (currentPageType) {
            case 'gis':
                mapUtils.menuAddSingleMethod(singleMenu.singleMenuMethod1)
                mapUtils.menuAddSingleMethod(singleMenu.singleMenuMethod2)
                break;
        }
    }
}
// OpenlayerBaseMap/index.vue
// 地图加载完初始化做的一些操作
const mapInit = (olMap) => {
    // ......

  // 设置鼠标右键属性
  mapUtils.setContextmenu(
    olMap,
    (option) => {
      // console.log(option, mapUtils.menuMethods);
      setMenuMethods(option);
    },
    (next) => {
      // 根据具体页面配置菜单栏
      next(props.currentPageType);
    }
  );
};

// 设置鼠标右键菜单栏方法
const setMenuMethods = ({ option, feature, pixelPoint }) => {
  // console.log("设置鼠标右键菜单栏方法", option, feature, pixelPoint);

  // 点击地图隐藏气泡窗
  // ......

  menuUtils.setMenuMethods(myOlMap, option, feature, pixelPoint, proxy)
};

// OpenlayerBaseMap/mapUtils.js
// 重置右键属性菜单
export const resetContextMenu = (next) => {
  let mapWrap = document.querySelector('.ol_map_wrap')
  let menu = document.querySelector('.menu_wrap')

  // 判断是否存在menu
  if (menu) {
    mapWrap.removeChild(menu);
  }

  if (next) {
    next(mapWrap)
  }
}

// 获取所有图层
export const getAllLayer = (olMap, next) => {
  // 获取当前地图上的所有图层
  let layers = olMap.getLayers().getArray();

  // 获取所有图层(从地图中移除所有图层)
  for (let i = layers.length - 1; i >= 0; --i) {
    if (layers[i] instanceof VectorLayer) {
      next(layers[i])
    };
  }
}

// 公共动态选项判断
const setCommonMenuMethod = (condition, commonDynamicMenuMethod) => {
  if (condition) {
    if (condition instanceof Array) {
      if (condition.length !== 0) {
        // console.log(condition.get('tempType'))

        menuAddSingleMethod(commonDynamicMenuMethod)
      }

      if (condition.length === 0) {
        menuUtils.commonMenuMethodsArr = menuUtils.commonMenuMethodsArr.filter(item => item !== commonDynamicMenuMethod)
      }
    } else {
      if (condition instanceof Feature) {
        if (!condition.get('tempType')) {
          menuAddSingleMethod(commonDynamicMenuMethod)
        }
      } else {
        menuAddSingleMethod(commonDynamicMenuMethod)

        if (condition.length === 0) {
          menuUtils.commonMenuMethodsArr = menuUtils.commonMenuMethodsArr.filter(item => item !== commonDynamicMenuMethod)
        }
      }
    }
  }
  if (!condition && menuUtils.commonMenuMethodsArr.includes(commonDynamicMenuMethod)) {
    menuUtils.commonMenuMethodsArr = menuUtils.commonMenuMethodsArr.filter(item => item !== commonDynamicMenuMethod)
  }
}

// 设置鼠标右键属性
export const setContextmenu = (olMap, next, setMenuConfig) => {
  const { commonDynamicMenu, singleMenu } = menuUtils.menuMethodBtn  // 公共动态选项,每个页面有需要才显示

  // 添加右键菜单监听
  olMap.getViewport().addEventListener('contextmenu', e => {
    // console.log(transformToLonlat(olMap.getEventCoordinate(e)))  // 经纬度

    e.preventDefault(); // 阻止默认的右键菜单弹出

    /**
     * 子页动态选项
     */
    // 根据具体页面配置菜单栏
    if (setMenuConfig) {
      setMenuConfig(currentPageType => {
        // console.log('当前页面', currentPageType)

        // 根据具体页面配置菜单栏 - 子菜单在某些情况可能需要隐藏
        menuUtils.setMentBtnExtendByPage(currentPageType)
      })
    }

    // 屏幕坐标
    const pixelPoint = olMap.getEventCoordinate(e)
    const pixel = olMap.getPixelFromCoordinate(pixelPoint)
    const feature = olMap.forEachFeatureAtPixel(pixel, feature => {
      return feature
    })


    /**
     * 获取所有layer并做判断
     */
    let featureOnPage = []  // 页面所有的feature
    let myPointByMenuFeature = []  // 所有自定义定位点
    let POIPointByMenuFeature = []  // 所有POI定位点
    let drawTypeByMenuFeature = []  // 所有绘制内容
    getAllLayer(olMap, layerItem => {
      let currentFeature = layerItem.getSource().getFeatures()[0]

      if (!currentFeature) {
        return
      }

      featureOnPage.push(currentFeature)

      if (currentFeature.get('tempType') === 'myPointByMenu') {
        myPointByMenuFeature.push(currentFeature)
      }
      if (currentFeature.get('businessType') === 'POIMarker') {
        POIPointByMenuFeature.push(currentFeature)
      }
      if (currentFeature.get('drawType')) {
        drawTypeByMenuFeature.push(currentFeature)
      }
    })

    /**
     * 公共动态选项
     */
    // 判断是否显示清除所有要素
    setCommonMenuMethod(featureOnPage, commonDynamicMenu.commonDynamicMenuMethod1)

    // 判断是否显示当前要素
    setCommonMenuMethod(feature, commonDynamicMenu.commonDynamicMenuMethod2)

    // 判断是否需要显示停止绘制
    // 获取绘制的图形
    const drawInteraction = getDrawInteraction(olMap)
    setCommonMenuMethod(drawInteraction, commonDynamicMenu.commonDynamicMenuMethod3)

    // 自定义定位点
    setCommonMenuMethod(myPointByMenuFeature, '清空自定义标注点')

    // 自定义闪烁点
    let flickerPointDom = document.querySelectorAll('.flicker_point')
    setCommonMenuMethod(flickerPointDom, '清空自定义闪烁点')

    // 展示分析结果
    if (feature) {
      if (feature.get('pointData')?.isNeedAnalysis) {
        setCommonMenuMethod(feature, commonDynamicMenu.commonDynamicMenuMethod4)
      }
    }

    // 删除所有绘制内容  
    setCommonMenuMethod(drawTypeByMenuFeature, commonDynamicMenu.commonDynamicMenuMethod5)

    /**
     * 子页动态选项
     */
    // 清除POI点
    setCommonMenuMethod(POIPointByMenuFeature, singleMenu.singleMenuMethod2)


    // 重置右键属性菜单
    resetContextMenu(mapWrap => {
      let menu = null

      menu = document.createElement('div');
      menu.setAttribute("class", "menu_wrap");

      // 自定义菜单项
      let tempStr = ''
      menuUtils.commonMenuMethodsArr.forEach(item => {
        tempStr += `<li>${item}</li>`
      })

      menu.innerHTML = `
      <ul>
        ${tempStr}
      </ul>
    `;

      // 添加到页面上
      menu.style.position = 'fixed';
      menu.style.left = `${e.clientX}px`;
      menu.style.top = `${e.clientY}px`;
      mapWrap.appendChild(menu);

      // 监听菜单项的点击事件(可选)
      menu.addEventListener('click', (evt) => {
        const option = evt.target.textContent;
        next({ option, feature, pixelPoint })

        // 清理菜单
        mapWrap.removeChild(menu);
      });
    })
  });
}

// menuUtils.js
/**
 * 维护右键菜单栏
 */

import { ElMessage } from 'element-plus'
import * as mapUtils from "./mapUtils.js";
import mittBus from "@/utils/mittBus"; // mitt
import { copyTextToClipboard } from "@/utils/index.js";

// 菜单项
const menuMethodBtn = {
    // 公共选项,常驻菜单
    commonMenu: {
        // commonMenuMethod0: '地图功能测试',  // 公共选项0
        // commonMenuMethod01: '添加自定义标注点',  // 公共选项01
        // commonMenuMethod02: '添加自定义闪烁点',  // 公共选项02
        commonMenuMethod1: '拷贝当前经纬度',  // 公共选项1
        // commonMenuMethod2: '置顶要素',  // 公共选项2
        commonMenuMethod3: '切换天地图token',  // 公共选项3
    },
    // 公共动态选项,每个页面有需要才显示
    commonDynamicMenu: {
        commonDynamicMenuMethod1: '清除所有要素',  // 公共选项3
        commonDynamicMenuMethod2: '显示当前要素信息',  // 公共动态选项1
        commonDynamicMenuMethod3: '仅取消绘制状态',  // 公共动态选项3
        commonDynamicMenuMethod4: '展示分析结果',  // 公共动态选项4
        commonDynamicMenuMethod5: '删除所有绘制内容',  // 公共动态选项5
    },
    // 子页动态选项, 单页面显示或单页面有需要显示
    singleMenu: {
        singleMenuMethod1: '刷新地图',  // 子页动态选项1
        singleMenuMethod2: '清除POI点',  // 子页动态选项2
        // singleMenuMethod2: '展示分析结果'  // 子页动态选项2
    },
}

if (import.meta.env.VITE_APP_ENV === 'development') {
    menuMethodBtn.commonMenu = {
        ...menuMethodBtn.commonMenu,
        commonMenuMethod0: '地图功能测试',  // 公共选项0
        commonMenuMethod01: '添加自定义标注点',  // 公共选项01
        commonMenuMethod02: '添加自定义闪烁点',  // 公共选项02
    }
}

// 主菜单项
const { commonMenu } = menuMethodBtn  // 公共选项,常驻菜单
let commonMenuMethodsArr = []  // 常驻菜单数组
// 将对象中的值传入数组
for (let i in commonMenu) {
    commonMenuMethodsArr.push(commonMenu[i])
}

export default {
    // 菜单项
    menuMethodBtn,

    // 常驻菜单数组
    commonMenuMethodsArr,

    // 设置鼠标右键菜单栏方法
    setMenuMethods(olMap, option, feature, pixelPoint, proxy) {
        // console.log(olMap, option, feature, pixelPoint, proxy)

        // 经纬度
        let currentLonlat = mapUtils.transformToLonlat(pixelPoint)

        /**
         * 菜单栏
         * commonMenu  // 公共选项,常驻菜单
         * commonDynamicMenu  // 公共动态选项,每个页面有需要才显示
         * singleMenu  // 子页动态选项, 单页面显示或单页面有需要显示
         */
        const { commonMenu, commonDynamicMenu, singleMenu } = this.menuMethodBtn;

        switch (option) {
            /**
             * ===========================
             *      公共选项,常驻菜单
             * ===========================
             */
            // 地图功能测试
            case commonMenu.commonMenuMethod0:
                // console.log("test", commonMenu.commonMenuMethod0);

                mapUtils.olMapTestCommon(olMap, feature, pixelPoint);
                break;
            // 添加标注点
            case commonMenu.commonMenuMethod01:
                // console.log("test", commonMenu.commonMenuMethod1);

                mapUtils.addMyPointByMenu(olMap, pixelPoint);
                break;
            // 清空自定义标注点
            case '清空自定义标注点':
                // console.log("test", '清空自定义标注点');

                // 根据条件移除要素
                mapUtils.removeByCondition(olMap, currentFeature => {
                    return currentFeature.get('tempType') === 'myPointByMenu'
                })
                break;
            // 添加闪烁点
            case commonMenu.commonMenuMethod02:
                // console.log("test", commonMenu.commonMenuMethod2);

                mapUtils.addFlickerPoint(olMap, pixelPoint);
                break;
            // 清空自定义闪烁点
            case '清空自定义闪烁点':
                // console.log("test", '清空自定义闪烁点');

                let flickerPointDom = document.querySelectorAll('.flicker_point')

                flickerPointDom.forEach(item => {
                    item.classList.remove('flicker_point')
                })

                break;
            // 拷贝当前经纬度
            case commonMenu.commonMenuMethod1:
                // console.log("拷贝当前经纬度");
                copyTextToClipboard(`[${currentLonlat}]`, () => {
                    ElMessage.success(`[${currentLonlat}] 拷贝成功`);
                });
                break;
            // 置顶图层
            case commonMenu.commonMenuMethod2:
                // console.log("置顶图层");
                mapUtils.featureToMaxTop(olMap, feature);
                break;
            // 切换天地图token
            case commonMenu.commonMenuMethod3:
                // console.log("切换天地图token");

                mittBus.emit("showSetTokenDialog");
                break;
            /**
             * =======================================
             *      公共动态选项,每个页面有需要才显示
             * =======================================
             */
            // 清除所有要素
            case commonDynamicMenu.commonDynamicMenuMethod1:
                // console.log("清除所有要素");

                mapUtils.removeAllLayer(olMap);
                break;
            // 显示当前要素信息
            case commonDynamicMenu.commonDynamicMenuMethod2:
                // console.log("显示当前要素信息");
                mittBus.emit("singleFeaturesClick", { feature, pixelPoint });
                break;
            // 仅取消绘制状态
            case commonDynamicMenu.commonDynamicMenuMethod3:
                // console.log("仅取消绘制状态");

                mapUtils.cancelDrawInteraction(olMap)
                break;
            // 展示分析结果
            case commonDynamicMenu.commonDynamicMenuMethod4:
                let currentData = feature.get('pointData')
                // console.log("展示分析结果", feature.get('pointData'));
                mittBus.emit("analysisPointData", currentData);
                break;
            // 删除所有绘制内容
            case commonDynamicMenu.commonDynamicMenuMethod5:
                console.log("删除所有绘制内容");

                // 根据条件移除要素
                mapUtils.removeByCondition(olMap, currentFeature => {
                    return currentFeature.get('drawType')
                })

                // let currentData = feature.get('pointData')

                // mittBus.emit("analysisPointData", currentData);
                break;
            /**
             * =============================================
             *      子页动态选项, 单页面显示或单页面有需要显示
             * =============================================
             */
            // 刷新地图
            case singleMenu.singleMenuMethod1:
                // console.log("刷新地图");
                mittBus.emit("reflashMap");
                break;
            // 清除POI点
            case singleMenu.singleMenuMethod2:
                // console.log("清除POI点");
                mapUtils.removeLayerByBusinessType(olMap, "POIMarker"); // 根据类型移除图层
                break;
        }
    },

    // 根据具体页面配置菜单栏
    setMentBtnExtendByPage(currentPageType) {
        const { singleMenu } = this.menuMethodBtn

        switch (currentPageType) {
            case 'gis':
                mapUtils.menuAddSingleMethod(singleMenu.singleMenuMethod1)
                mapUtils.menuAddSingleMethod(singleMenu.singleMenuMethod2)
                break;
        }
    }
}

右键菜单修改token功能

js
// OpenLayerBaseMap/menuUtils.js
mittBus.emit("showSetTokenDialog");

// OpenLayerBaseMap/index.vue
// 切换天地图token
mittBus.on("showSetTokenDialog", () => {
  refSetTokenDialog.value?.show();
})
// 根据不同token初始化地图
mittBus.on("initOlMapByToken", () => {
  resetOlMap()  // 初始化地图
});

// OpenLayerBaseMap/components/setTokenDialog.vue
<div class="dialog_wrap">
    <p>当前token: {{ currentToken }}</p>
    <el-autocomplete v-model="selectedToken" style="width: 65%;" :fetch-suggestions="querySearch"
        popper-class="my-autocomplete" placeholder="请选择或者输入" @select="handleSelect" clearable>
        <template #suffix>
        </template>
        <template #default="{ item }">
            <div class="input_wrap" :class="{ current_selected: item.value === currentToken }">
                <h3>{{ item.name }} <span v-if="item.value === currentToken">- 当前token</span></h3>
                <span>{{ item.value }}</span>
            </div>
        </template>
    </el-autocomplete>
    <el-button type="primary" style="margin-left: 25px;" @click="setTokenData"
        :disabled="selectedToken === ''">
        确定
    </el-button>
</div>

import { gisDataStore } from '@/store/modules/gis.js'  // store

const { setMapToken } = gisDataStore()
const gisStoreData = gisDataStore()

let currentToken = ref(import.meta.env.VITE_APP_MapToken)

const selectedToken = ref('')
const links = ref([])

const querySearch = (queryString, cb) => {
    const results = queryString
        ? links.value.filter(createFilter(queryString))
        : links.value
    // call callback function to return suggestion objects
    cb(results)
}
const createFilter = (queryString) => {
    return (restaurant) => {
        return (
            restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
        )
    }
}

const handleSelect = (item) => {
    setMapToken(item.value)
}

const setTokenData = () => {
    if (selectedToken.value.length !== 32) {
        ElMessage.warning("请输入正确的token")
        return
    }

    // 初始化地图
    mittBus.emit('initOlMapByToken')
    mittBus.emit('resetSwitchLayer')
    refDialogInfo.value.hide()

    currentToken.value = selectedToken.value
}


onMounted(() => {
    links.value = loadAll()
})

const loadAll = () => {
    return [
        { name: 'token1', value: 'xxxxxx' },
        { name: 'token2', value: 'xxxxxx' },
        { name: 'token3', value: 'xxxxxx' },
        { name: 'token4', value: 'xxxxxx' },
        { name: 'token5', value: 'xxxxxx' },
    ]
}

// OpenlayerBaseMap/components/SwitchBaseLayer.vue
// 根据不同token初始化地图
mittBus.on("resetSwitchLayer", () => {
  ruleForm.value.layerType = 't3imgPrivatization'
});
// OpenLayerBaseMap/menuUtils.js
mittBus.emit("showSetTokenDialog");

// OpenLayerBaseMap/index.vue
// 切换天地图token
mittBus.on("showSetTokenDialog", () => {
  refSetTokenDialog.value?.show();
})
// 根据不同token初始化地图
mittBus.on("initOlMapByToken", () => {
  resetOlMap()  // 初始化地图
});

// OpenLayerBaseMap/components/setTokenDialog.vue
<div class="dialog_wrap">
    <p>当前token: {{ currentToken }}</p>
    <el-autocomplete v-model="selectedToken" style="width: 65%;" :fetch-suggestions="querySearch"
        popper-class="my-autocomplete" placeholder="请选择或者输入" @select="handleSelect" clearable>
        <template #suffix>
        </template>
        <template #default="{ item }">
            <div class="input_wrap" :class="{ current_selected: item.value === currentToken }">
                <h3>{{ item.name }} <span v-if="item.value === currentToken">- 当前token</span></h3>
                <span>{{ item.value }}</span>
            </div>
        </template>
    </el-autocomplete>
    <el-button type="primary" style="margin-left: 25px;" @click="setTokenData"
        :disabled="selectedToken === ''">
        确定
    </el-button>
</div>

import { gisDataStore } from '@/store/modules/gis.js'  // store

const { setMapToken } = gisDataStore()
const gisStoreData = gisDataStore()

let currentToken = ref(import.meta.env.VITE_APP_MapToken)

const selectedToken = ref('')
const links = ref([])

const querySearch = (queryString, cb) => {
    const results = queryString
        ? links.value.filter(createFilter(queryString))
        : links.value
    // call callback function to return suggestion objects
    cb(results)
}
const createFilter = (queryString) => {
    return (restaurant) => {
        return (
            restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
        )
    }
}

const handleSelect = (item) => {
    setMapToken(item.value)
}

const setTokenData = () => {
    if (selectedToken.value.length !== 32) {
        ElMessage.warning("请输入正确的token")
        return
    }

    // 初始化地图
    mittBus.emit('initOlMapByToken')
    mittBus.emit('resetSwitchLayer')
    refDialogInfo.value.hide()

    currentToken.value = selectedToken.value
}


onMounted(() => {
    links.value = loadAll()
})

const loadAll = () => {
    return [
        { name: 'token1', value: 'xxxxxx' },
        { name: 'token2', value: 'xxxxxx' },
        { name: 'token3', value: 'xxxxxx' },
        { name: 'token4', value: 'xxxxxx' },
        { name: 'token5', value: 'xxxxxx' },
    ]
}

// OpenlayerBaseMap/components/SwitchBaseLayer.vue
// 根据不同token初始化地图
mittBus.on("resetSwitchLayer", () => {
  ruleForm.value.layerType = 't3imgPrivatization'
});

气泡窗封装

点击标注弹出气泡窗,所以需要捕捉点击事件

js
// OpenLayerBaseMap/index.vue
// 设置地图
const setOlmap = (olMap) => {
  mapEvent(olMap); // 地图事件
};

const mapEvent = (olMap) => {
    // 监听鼠标单击事件
    olMap.on("singleclick", (e) => {
        // 这里需要判断点击的目标是否重叠,点击的是什么类型的图形
        let pixel = olMap.getEventPixel(e.originalEvent);
        let featureList = olMap.getFeaturesAtPixel(pixel); // 点击时获取所有features

        // 这里为举例,假定点击的目标非重叠,且只是一个marker类型的feature
        if(featureList.length === 1) {
            singleFeaturesClick(olMap, featureList[0], e.coordinate);
        }
    })
}

// 点击单个feature - map - click事件
const singleFeaturesClick = (olMap, featureItem, pixelPoint) => {
  // console.log("无重叠,单个feature", featureItem, featureItem.get("type"));

  if (featureItem && featureItem.get('drawType') && mapUtils.getDrawInteraction(olMap)) {
    return
  }

  let popupData = null;

  // 点击点标注
  if (featureItem && featureItem.get("type") === "Marker") {
    // console.log('Marker点标注', featureItem);

    popupData = featureItem.get("pointData");
    // console.log('获取点标注数据', popupData)

    refPopupCommon.value.setCommonPopup(olMap, pixelPoint, popupData, featureItem);
  }

  // 点击扇形区域
  if (featureItem && featureItem.get("type") === "Curve") {
    // console.log('点击扇形区域', featureItem);

    popupData = featureItem.get("curveData");
    // console.log('获取扇形区数据', popupData)

    refPopupCommon.value.setCommonPopup(olMap, pixelPoint, popupData);
  }

  // 点击圆形区域
  // ......

  // 点击多边形
  // ......
};

// OpenlayerBaseMap/components/popup/PopupCommon.vue
// 通用信息展示弹窗
const setCommonPopup = (olMap, pixelPoint, popupData, featureItem) => {
  // console.log("点击标注弹出气泡", olMap, popupData, featureItem);

  // 判断是否有返回图标,有则删除 - 不为业务气泡窗不删除
  let popupBackDom = document.querySelector(`#popupBack`)
  if (popupBackDom) {
    if (featureItem && !featureItem.get('businessType')) {
      popupBackDom.remove();
    }
  }

  // 经纬度
  let coordinate = mapUtils.transformToLonlat(pixelPoint);
  // 点击尺 (这里是尺(米),并不是经纬度);
  let hdms = mapUtils.getHdms(pixelPoint); // 转换为经纬度显示

  const popupObj = {
    name: "通用信息展示弹窗",
    hdms,
    coordinate,
    popupData, // 气泡窗业务数据
  };
  currentPopupObj = popupObj;

  // 修改通用展示窗数据 - 子组件使用
  mittBus.emit("fixCommonPopupData", popupObj);

  mapUtils.setPopup(
    olMap,
    pixelPoint,
    popupInner.commonPopupInner(popupObj, featureItem),
    (event) => {
      popupClickEvent(event);
    }
  );
};

// 气泡弹出窗点击事件
const popupClickEvent = async (e) => {
  // console.log("气泡弹出窗点击事件", e)

  const { target } = e; // 事件对象
  // console.log("点击气泡窗返回气泡窗中的dom对象", target);

  // 当前dom绑定的函数
  let dataFunction = target.getAttribute("data-function");

  // 点击气泡窗获取更多
  if (dataFunction === "getMore") {
    // console.log("点击气泡窗获取更多");
    getMore();
  }

  // 点击唯一标识显示具体气泡信息
  if (dataFunction === "getSingleByFeatures") {
    // console.log(target.getAttribute("data-unique"));

    getSingleByFeatures(target.getAttribute("data-unique"));
  }

  // 点击popupDom返回
  if (dataFunction === "popupBack") {
    popupBack();
  }
};

// 点击气泡窗获取更多
const getMore = () => {
  // console.log("点击气泡窗获取更多"); 
  // 气泡窗点击更多 - 子组件使用
  // console.log('气泡窗点击更多 - 子组件使用', currentPopupObj)

  mittBus.emit("popupDataGetMore", {
    currentPopupObj,
    callback: (popupData) => {
      // console.log("fwdsdfsw", popupData);

      // 获取完数据后进行弹窗
      showPopupDialog(popupData, props.currentPageType); // 显示气泡弹出窗
    },
  });
};

// OpenlayerBaseMap/mapUtils.js
/**
 * 设置气泡窗
 * @param {*} olMap 地图对象
 * @param {*} pixelPoint 屏幕坐标
 * @param {*} popupData 气泡窗数据
 * @param {*} next 事件处理方法
 */
export const setPopup = (olMap, pixelPoint, popupInner, next) => {
  // const pixelPoint = e.coordinate  // 屏幕坐标
  popupCommonConfig(olMap, pixelPoint, popupInner, next, {
    autoPan: true, // 定义弹出窗口在边缘点击时候可能不完整 设置自动平移效果
    /* autoPanAnimation: {
        duration: 250, // 自动平移效果的动画时间 9毫秒)
    }, */
  })
}

/**
 * 气泡窗通用方法
 * @param {*} olMap 地图对象
 * @param {*} pixelPoint 屏幕坐标
 * @param {*} popupData 气泡窗数据
 * @param {*} next 事件方法
 * @param {*} overlayConfig 气泡窗配置 
 */
export const popupCommonConfig = (olMap, pixelPoint, popupInner, next, overlayConfig = null,) => {
  let container = document.getElementById('popup');
  // console.log('container', container)
  let closer = document.getElementById('popup-closer');
  // let content = document.getElementById('popup-content');
  container.style.display = 'block'

  let overlay = new Overlay({
    element: container, //绑定 Overlay 对象和 DOM 对象的
    ...overlayConfig,
    zIndex: 9999,
  });
  olMap.addOverlay(overlay);

  closer.onclick = () => {
    overlay.setPosition(undefined);
    closer.blur();
    overlay = null;
    return false;
  };

  // console.log(popupInner)
  // content.innerHTML = popupData;  // 使用jsx,不直接进行inner
  overlay.setPosition(pixelPoint); //把 overlay 显示到指定的 x,y坐标

  // 使用addEventListener会无限叠加事件,且不好使用removeEventListener移除(匿名函数)
  overlay.getElement().onclick = e => {
    next(e)
  }
}

// OpenlayerBaseMap/components/popup/popupInner.js
// 通用气泡窗
export const commonPopupInner = (popupObj, featureItem) => {
    mittBus.emit('setCommonPopupInner', {
        popupObj, featureItem, callback: (popupInnerDom) => {
            // 使用jsx,不需要return,直接将jsx结构render到dom即可
            render(popupInnerDom, innerDom())
        }
    })
}

// 业务代码gis
import { getPopupInnerDom, getPOIPopupInnerDom } from "./components/popup/gisPopup.jsx"; // 气泡窗dom
//  气泡窗点击更多 - 子组件使用
mittBus.on("popupDataGetMore", async ({ currentPopupObj, callback }) => {
  // console.log("气泡窗点击更多111", currentPopupObj);

  if (!currentPopupObj.currentPopupData && currentPopupObj.popupData) {
    currentPopupObj.currentPopupData = currentPopupObj.popupData
  }

  // 或者走接口,根据cgi获取详情
  const currentPopupAsyncObj = await apiCommon(gisApi.queryCellByCgi, {
    cgi: currentPopupObj.currentPopupData ? currentPopupObj.currentPopupData.cgi : currentPopupObj.cgi,
  });
  // console.log(currentPopupAsyncObj)

  if (!currentPopupAsyncObj.data) {
    proxy.$modal.msgWarning(currentPopupAsyncObj.msg);
    return
  }

  switch (currentPopupAsyncObj.data.networkType) {
    case "4g":
      currentPopupObj.currentPopupData = currentPopupAsyncObj.data.cell4g;
      currentPopupObj.currentPopupData.networkType = "4g";
      currentPopupObj.currentPopupData.newCellName = currentPopupObj.currentPopupData.cellName;
      break;
    case "5g":
      currentPopupObj.currentPopupData = currentPopupAsyncObj.data.cell5g;
      currentPopupObj.currentPopupData.networkType = "5g";
      currentPopupObj.currentPopupData.newCellName = currentPopupObj.currentPopupData.nrCellName;
      break;
  }

  // 获取完数据后进行弹窗
  callback(currentPopupObj.currentPopupData);
});
// 设置通用气泡窗html
mittBus.on("setCommonPopupInner", ({ popupObj, featureItem, callback }) => {
  // console.log("设置通用气泡窗html", popupObj, featureItem);

  if (!featureItem) {
    let currentPopupData = popupObj.currentPopupData
    if (!currentPopupData) {
      currentPopupData = popupObj.popupData
    }
    if (currentPopupData.searchType === 'POI') {
      callback(getPOIPopupInnerDom(popupObj));
      return
    }
    callback(getPopupInnerDom(popupObj));
    return
  }

  if (featureItem.get('businessType') === 'POIMarker') {
    callback(getPOIPopupInnerDom(popupObj));
    return
  }
  callback(getPopupInnerDom(popupObj));
});

// components/popup/gisPopup.jsx
import { ElDescriptions, ElDescriptionsItem } from "element-plus";

export const getPopupInnerDom = (popupObj) => {
    let popupData = null;

    if (popupObj.currentPopupData) {
        popupData = popupObj.currentPopupData;
    } else {
        popupData = popupObj.popupData;
    }

    return (
        <>
            <div class="common_popup_item">
                <ElDescriptions title={popupData.newCellName} border class="margin-top" column={2} size="small">
                    <ElDescriptionsItem label="xxx">{popupData.county}</ElDescriptionsItem>
                    <ElDescriptionsItem label="xxx">{popupData.cgi}</ElDescriptionsItem>
                    {popupData.antDirectionAngle && (
                        <ElDescriptionsItem label="xxx">{popupData.antDirectionAngle}°</ElDescriptionsItem>
                    )}
                    <ElDescriptionsItem label="经纬度">[{popupData.longitude}, {popupData.latitude}]</ElDescriptionsItem>
                </ElDescriptions >

                <span class='get_more' data-function="getMore">查看更多</span>
            </div>
        </>
    );
};

export const getPOIPopupInnerDom = (popupObj) => {
    let popupData = null;

    if (popupObj.currentPopupData) {
        popupData = popupObj.currentPopupData;
    } else {
        popupData = popupObj.popupData;
    }

    return (
        <>
            <div class="common_popup_item">
                <h3>POI搜索结果</h3>
                <ul>
                    <li>
                        <dl>
                            <dt>地址:</dt>
                            <dd>{popupData.address}</dd>
                        </dl>
                    </li>
                    <li>
                        <dl>
                            <dt>名称:</dt>
                            <dd>{popupData.name}</dd>
                        </dl>
                    </li>
                    <li>
                        <dl>
                            <dt>经纬度:</dt>
                            <dd>[{popupData.lonlat}]</dd>
                        </dl>
                    </li>
                </ul>
            </div>
        </>
    );
};
// OpenLayerBaseMap/index.vue
// 设置地图
const setOlmap = (olMap) => {
  mapEvent(olMap); // 地图事件
};

const mapEvent = (olMap) => {
    // 监听鼠标单击事件
    olMap.on("singleclick", (e) => {
        // 这里需要判断点击的目标是否重叠,点击的是什么类型的图形
        let pixel = olMap.getEventPixel(e.originalEvent);
        let featureList = olMap.getFeaturesAtPixel(pixel); // 点击时获取所有features

        // 这里为举例,假定点击的目标非重叠,且只是一个marker类型的feature
        if(featureList.length === 1) {
            singleFeaturesClick(olMap, featureList[0], e.coordinate);
        }
    })
}

// 点击单个feature - map - click事件
const singleFeaturesClick = (olMap, featureItem, pixelPoint) => {
  // console.log("无重叠,单个feature", featureItem, featureItem.get("type"));

  if (featureItem && featureItem.get('drawType') && mapUtils.getDrawInteraction(olMap)) {
    return
  }

  let popupData = null;

  // 点击点标注
  if (featureItem && featureItem.get("type") === "Marker") {
    // console.log('Marker点标注', featureItem);

    popupData = featureItem.get("pointData");
    // console.log('获取点标注数据', popupData)

    refPopupCommon.value.setCommonPopup(olMap, pixelPoint, popupData, featureItem);
  }

  // 点击扇形区域
  if (featureItem && featureItem.get("type") === "Curve") {
    // console.log('点击扇形区域', featureItem);

    popupData = featureItem.get("curveData");
    // console.log('获取扇形区数据', popupData)

    refPopupCommon.value.setCommonPopup(olMap, pixelPoint, popupData);
  }

  // 点击圆形区域
  // ......

  // 点击多边形
  // ......
};

// OpenlayerBaseMap/components/popup/PopupCommon.vue
// 通用信息展示弹窗
const setCommonPopup = (olMap, pixelPoint, popupData, featureItem) => {
  // console.log("点击标注弹出气泡", olMap, popupData, featureItem);

  // 判断是否有返回图标,有则删除 - 不为业务气泡窗不删除
  let popupBackDom = document.querySelector(`#popupBack`)
  if (popupBackDom) {
    if (featureItem && !featureItem.get('businessType')) {
      popupBackDom.remove();
    }
  }

  // 经纬度
  let coordinate = mapUtils.transformToLonlat(pixelPoint);
  // 点击尺 (这里是尺(米),并不是经纬度);
  let hdms = mapUtils.getHdms(pixelPoint); // 转换为经纬度显示

  const popupObj = {
    name: "通用信息展示弹窗",
    hdms,
    coordinate,
    popupData, // 气泡窗业务数据
  };
  currentPopupObj = popupObj;

  // 修改通用展示窗数据 - 子组件使用
  mittBus.emit("fixCommonPopupData", popupObj);

  mapUtils.setPopup(
    olMap,
    pixelPoint,
    popupInner.commonPopupInner(popupObj, featureItem),
    (event) => {
      popupClickEvent(event);
    }
  );
};

// 气泡弹出窗点击事件
const popupClickEvent = async (e) => {
  // console.log("气泡弹出窗点击事件", e)

  const { target } = e; // 事件对象
  // console.log("点击气泡窗返回气泡窗中的dom对象", target);

  // 当前dom绑定的函数
  let dataFunction = target.getAttribute("data-function");

  // 点击气泡窗获取更多
  if (dataFunction === "getMore") {
    // console.log("点击气泡窗获取更多");
    getMore();
  }

  // 点击唯一标识显示具体气泡信息
  if (dataFunction === "getSingleByFeatures") {
    // console.log(target.getAttribute("data-unique"));

    getSingleByFeatures(target.getAttribute("data-unique"));
  }

  // 点击popupDom返回
  if (dataFunction === "popupBack") {
    popupBack();
  }
};

// 点击气泡窗获取更多
const getMore = () => {
  // console.log("点击气泡窗获取更多"); 
  // 气泡窗点击更多 - 子组件使用
  // console.log('气泡窗点击更多 - 子组件使用', currentPopupObj)

  mittBus.emit("popupDataGetMore", {
    currentPopupObj,
    callback: (popupData) => {
      // console.log("fwdsdfsw", popupData);

      // 获取完数据后进行弹窗
      showPopupDialog(popupData, props.currentPageType); // 显示气泡弹出窗
    },
  });
};

// OpenlayerBaseMap/mapUtils.js
/**
 * 设置气泡窗
 * @param {*} olMap 地图对象
 * @param {*} pixelPoint 屏幕坐标
 * @param {*} popupData 气泡窗数据
 * @param {*} next 事件处理方法
 */
export const setPopup = (olMap, pixelPoint, popupInner, next) => {
  // const pixelPoint = e.coordinate  // 屏幕坐标
  popupCommonConfig(olMap, pixelPoint, popupInner, next, {
    autoPan: true, // 定义弹出窗口在边缘点击时候可能不完整 设置自动平移效果
    /* autoPanAnimation: {
        duration: 250, // 自动平移效果的动画时间 9毫秒)
    }, */
  })
}

/**
 * 气泡窗通用方法
 * @param {*} olMap 地图对象
 * @param {*} pixelPoint 屏幕坐标
 * @param {*} popupData 气泡窗数据
 * @param {*} next 事件方法
 * @param {*} overlayConfig 气泡窗配置 
 */
export const popupCommonConfig = (olMap, pixelPoint, popupInner, next, overlayConfig = null,) => {
  let container = document.getElementById('popup');
  // console.log('container', container)
  let closer = document.getElementById('popup-closer');
  // let content = document.getElementById('popup-content');
  container.style.display = 'block'

  let overlay = new Overlay({
    element: container, //绑定 Overlay 对象和 DOM 对象的
    ...overlayConfig,
    zIndex: 9999,
  });
  olMap.addOverlay(overlay);

  closer.onclick = () => {
    overlay.setPosition(undefined);
    closer.blur();
    overlay = null;
    return false;
  };

  // console.log(popupInner)
  // content.innerHTML = popupData;  // 使用jsx,不直接进行inner
  overlay.setPosition(pixelPoint); //把 overlay 显示到指定的 x,y坐标

  // 使用addEventListener会无限叠加事件,且不好使用removeEventListener移除(匿名函数)
  overlay.getElement().onclick = e => {
    next(e)
  }
}

// OpenlayerBaseMap/components/popup/popupInner.js
// 通用气泡窗
export const commonPopupInner = (popupObj, featureItem) => {
    mittBus.emit('setCommonPopupInner', {
        popupObj, featureItem, callback: (popupInnerDom) => {
            // 使用jsx,不需要return,直接将jsx结构render到dom即可
            render(popupInnerDom, innerDom())
        }
    })
}

// 业务代码gis
import { getPopupInnerDom, getPOIPopupInnerDom } from "./components/popup/gisPopup.jsx"; // 气泡窗dom
//  气泡窗点击更多 - 子组件使用
mittBus.on("popupDataGetMore", async ({ currentPopupObj, callback }) => {
  // console.log("气泡窗点击更多111", currentPopupObj);

  if (!currentPopupObj.currentPopupData && currentPopupObj.popupData) {
    currentPopupObj.currentPopupData = currentPopupObj.popupData
  }

  // 或者走接口,根据cgi获取详情
  const currentPopupAsyncObj = await apiCommon(gisApi.queryCellByCgi, {
    cgi: currentPopupObj.currentPopupData ? currentPopupObj.currentPopupData.cgi : currentPopupObj.cgi,
  });
  // console.log(currentPopupAsyncObj)

  if (!currentPopupAsyncObj.data) {
    proxy.$modal.msgWarning(currentPopupAsyncObj.msg);
    return
  }

  switch (currentPopupAsyncObj.data.networkType) {
    case "4g":
      currentPopupObj.currentPopupData = currentPopupAsyncObj.data.cell4g;
      currentPopupObj.currentPopupData.networkType = "4g";
      currentPopupObj.currentPopupData.newCellName = currentPopupObj.currentPopupData.cellName;
      break;
    case "5g":
      currentPopupObj.currentPopupData = currentPopupAsyncObj.data.cell5g;
      currentPopupObj.currentPopupData.networkType = "5g";
      currentPopupObj.currentPopupData.newCellName = currentPopupObj.currentPopupData.nrCellName;
      break;
  }

  // 获取完数据后进行弹窗
  callback(currentPopupObj.currentPopupData);
});
// 设置通用气泡窗html
mittBus.on("setCommonPopupInner", ({ popupObj, featureItem, callback }) => {
  // console.log("设置通用气泡窗html", popupObj, featureItem);

  if (!featureItem) {
    let currentPopupData = popupObj.currentPopupData
    if (!currentPopupData) {
      currentPopupData = popupObj.popupData
    }
    if (currentPopupData.searchType === 'POI') {
      callback(getPOIPopupInnerDom(popupObj));
      return
    }
    callback(getPopupInnerDom(popupObj));
    return
  }

  if (featureItem.get('businessType') === 'POIMarker') {
    callback(getPOIPopupInnerDom(popupObj));
    return
  }
  callback(getPopupInnerDom(popupObj));
});

// components/popup/gisPopup.jsx
import { ElDescriptions, ElDescriptionsItem } from "element-plus";

export const getPopupInnerDom = (popupObj) => {
    let popupData = null;

    if (popupObj.currentPopupData) {
        popupData = popupObj.currentPopupData;
    } else {
        popupData = popupObj.popupData;
    }

    return (
        <>
            <div class="common_popup_item">
                <ElDescriptions title={popupData.newCellName} border class="margin-top" column={2} size="small">
                    <ElDescriptionsItem label="xxx">{popupData.county}</ElDescriptionsItem>
                    <ElDescriptionsItem label="xxx">{popupData.cgi}</ElDescriptionsItem>
                    {popupData.antDirectionAngle && (
                        <ElDescriptionsItem label="xxx">{popupData.antDirectionAngle}°</ElDescriptionsItem>
                    )}
                    <ElDescriptionsItem label="经纬度">[{popupData.longitude}, {popupData.latitude}]</ElDescriptionsItem>
                </ElDescriptions >

                <span class='get_more' data-function="getMore">查看更多</span>
            </div>
        </>
    );
};

export const getPOIPopupInnerDom = (popupObj) => {
    let popupData = null;

    if (popupObj.currentPopupData) {
        popupData = popupObj.currentPopupData;
    } else {
        popupData = popupObj.popupData;
    }

    return (
        <>
            <div class="common_popup_item">
                <h3>POI搜索结果</h3>
                <ul>
                    <li>
                        <dl>
                            <dt>地址:</dt>
                            <dd>{popupData.address}</dd>
                        </dl>
                    </li>
                    <li>
                        <dl>
                            <dt>名称:</dt>
                            <dd>{popupData.name}</dd>
                        </dl>
                    </li>
                    <li>
                        <dl>
                            <dt>经纬度:</dt>
                            <dd>[{popupData.lonlat}]</dd>
                        </dl>
                    </li>
                </ul>
            </div>
        </>
    );
};