Hwf 8 месяцев назад
Родитель
Сommit
ecf5d76580

+ 1 - 0
.env.development

@@ -31,3 +31,4 @@ VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
 
 # websocket 开关
 VITE_APP_WEBSOCKET = true
+VITE_APP_BASE_WEBSOCKET= 'ws://http://10.181.7.236:9988'

+ 24 - 18
src/components/Map/index.vue

@@ -44,8 +44,9 @@ import {
   getMiningOperationsDetails,
   getEmergencyTransportResourcesDetails,
   getEmergencyDisasterInfoOfficerDetails,
-  getMidmapDzzhDetails, getVehicleDetails
-} from "@/api/globalMap/spatialAnalysis";
+  getMidmapDzzhDetails,
+  getVehicleDetails
+} from '@/api/globalMap/spatialAnalysis';
 import { pointDetailTemplate } from '@/views/globalMap/data/mapData';
 import ElementResizeDetectorMaker from 'element-resize-detector';
 import useAppStore from '@/store/modules/app';
@@ -89,21 +90,7 @@ let AMap, map, scale;
 // 鼠标绘制工具
 const drawTool = useDrawTool();
 // 初始化地图
-const {
-  getAMap,
-  getMap,
-  switchMap,
-  addMarker,
-  addSearchMarker,
-  clearMarker,
-  getMarkers,
-  getScale,
-  showInfo,
-  hideInfo,
-  handleHover,
-  creatMask,
-  trackPlayback
-} = useAMap({
+const mapUtils = useAMap({
   key: '30d3d8448efd68cb0b284549fd41adcf', // 申请好的Web端开发者Key,首次调用 load 时必填
   version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
   pitch: mapState.isThreeDimensional ? 45 : 0,
@@ -184,6 +171,21 @@ const {
     }
   }
 });
+const {
+  getAMap,
+  getMap,
+  switchMap,
+  addMarker,
+  addSearchMarker,
+  clearMarker,
+  getMarkers,
+  getScale,
+  showInfo,
+  hideInfo,
+  handleHover,
+  creatMask,
+  trackPlayback
+} = { ...mapUtils };
 const handlePointDetails = (data) => {
   let methodList = {
     '1': getEmergencyExpertDetails,
@@ -430,7 +432,11 @@ const setCenter = (item) => {
   map.setCenter([item.longitude, item.latitude]);
 };
 
-defineExpose({ addMarker, addSearchMarker, setCenter, getMarkers, clearMarker, getMap, drawTool, handleHover, trackPlayback });
+const getMapUtils = () => {
+  return mapUtils;
+};
+
+defineExpose({ addMarker, addSearchMarker, setCenter, getMarkers, clearMarker, getMap, drawTool, handleHover, trackPlayback, getMapUtils });
 const handleResize = () => {
   const containerWidth = containerRef.value.clientWidth * containerScale().scaleX;
   const containerHeight = containerRef.value.clientHeight * containerScale().scaleY;

+ 100 - 4
src/hooks/AMap/useAMap.ts

@@ -1,4 +1,6 @@
 import AMapLoader from '@amap/amap-jsapi-loader';
+import { nanoid } from 'nanoid';
+import { deepClone } from '@/utils';
 
 export function useAMap(options) {
   let AMap, map, nowLayer, labelsLayer, scale, cluster;
@@ -69,9 +71,11 @@ export function useAMap(options) {
     addMarker([item], true);
     options.onMarkerClick(item);
   };
-
-  const addMarker = (points, isSearchItem?: boolean) => {
-    clearMarker('point');
+  // 添加多个点
+  const addMarker = (points, notClean?: boolean) => {
+    if (!notClean) {
+      clearMarker('point');
+    }
     addPoints = points;
     const count = points.length;
     const _renderClusterMarker = function (context) {
@@ -315,6 +319,97 @@ export function useAMap(options) {
       autoRotation: true
     });
   };
+
+  const drawData = (data) => {
+    data.forEach((item) => {
+      let graphic;
+      // debugger
+      if (['rectangle', 'polygon'].includes(item.type)) {
+        graphic = new AMap.Polygon({
+          path: item.path,
+          strokeColor: item.strokeColor,
+          strokeOpacity: item.strokeOpacity,
+          strokeWeight: item.strokeWeight,
+          fillColor: item.fillColor,
+          fillOpacity: item.fillOpacity
+        });
+        map.add(graphic);
+      } else if (item.type === 'circle') {
+        graphic = new AMap.Circle({
+          center: item.center,
+          radius: item.radius,
+          strokeColor: item.strokeColor,
+          strokeOpacity: item.strokeOpacity,
+          strokeWeight: item.strokeWeight,
+          fillColor: item.fillColor,
+          fillOpacity: item.fillOpacity
+        });
+        map.add(graphic);
+      } else if (item.type === 'straightLine') {
+        graphic = new AMap.Polyline({
+          path: item.path,
+          strokeColor: item.strokeColor,
+          strokeOpacity: item.strokeOpacity,
+          strokeWeight: item.strokeWeight,
+          strokeStyle: item.strokeStyle
+        });
+        map.add(graphic);
+      } else if (item.type === 'text') {
+        addText(item);
+      } else if (item.type === 'measureArea') {
+        graphic = new AMap.Polygon({
+          path: item.path,
+          strokeColor: item.strokeColor,
+          strokeOpacity: item.strokeOpacity,
+          strokeWeight: item.strokeWeight,
+          fillColor: item.fillColor,
+          fillOpacity: item.fillOpacity
+        });
+        map.add(graphic);
+        // 计算区域面积
+        const area = Math.round(AMap.GeometryUtil.ringArea(item.path));
+
+        const text = new AMap.Text({
+          position: item.path[item.path.length - 1],
+          text: '区域面积' + area + '平方米',
+          offset: new AMap.Pixel(-20, -20)
+        });
+        data.area = area;
+        map.add(text);
+      } else if (item.type === 'marker') {
+        addMarker([item], true);
+      }
+    });
+  };
+  const addText = (options) => {
+    // 文本覆盖物的样式
+    const textStyle = {
+      fontSize: options.fontSize,
+      color: options.fontColor,
+      borderColor: 'transparent',
+      backgroundColor: 'transparent',
+      borderWidth: 0,
+      cursor: 'pointer' // 鼠标悬停时显示指针
+    };
+
+    // 创建文本覆盖物
+    const text = new AMap.Text({
+      text: options.text, // 文本内容,可以根据需要自定义
+      position: options.lnglat, // 文本位置(经纬度)
+      style: textStyle, // 文本样式
+      zIndex: 100, // 文本层级
+      draggable: false // 是否可拖动(可选)
+    });
+    // 将文本覆盖物添加到地图
+    map.add(text);
+    const id = nanoid();
+    text._opts.extData = {
+      id: id
+    };
+    const data: any = deepClone(options);
+    data.id = id;
+    return { text, data };
+  };
   onMounted(() => {
     initMap(options);
   });
@@ -331,6 +426,7 @@ export function useAMap(options) {
     hideInfo,
     handleHover,
     creatMask,
-    trackPlayback
+    trackPlayback,
+    drawData
   };
 }

+ 1 - 1
src/layout/index.vue

@@ -26,7 +26,7 @@ import SideBar from './components/Sidebar/index.vue';
 import { AppMain, Navbar, Settings, TagsView } from './components';
 import useAppStore from '@/store/modules/app';
 import useSettingsStore from '@/store/modules/settings';
-import { initWebSocket } from '@/utils/websocket';
+import { initWebSocket } from '@/utils/websocket2';
 
 const settingsStore = useSettingsStore();
 const theme = computed(() => settingsStore.theme);

+ 27 - 0
src/store/modules/websocketStore.ts

@@ -0,0 +1,27 @@
+import { sendSock, createWebSocket, closeSock } from '@/utils/websocket.js';
+
+const websocketStore = defineStore('websocket', {
+  state: () => ({
+    webSocketList: {
+      bizType: null,
+      content: '',
+      id: '',
+      remindLevel: 0,
+      senderId: null,
+      type: 1,
+      userId: null
+    }
+  }),
+  actions: {
+    init() {
+      console.log('websocket init');
+      createWebSocket(this.handleData);
+    },
+    handleData(res) {
+      console.log('websocket handleData', res);
+      Object.assign(this.webSocketList, res);
+    }
+  }
+});
+
+export default websocketStore;

+ 122 - 121
src/utils/websocket.ts

@@ -1,139 +1,140 @@
-/**
- * @module initWebSocket 初始化
- * @module websocketonopen 连接成功
- * @module websocketonerror 连接失败
- * @module websocketclose 断开连接
- * @module resetHeart 重置心跳
- * @module sendSocketHeart 心跳发送
- * @module reconnect 重连
- * @module sendMsg 发送数据
- * @module websocketonmessage 接收数据
- * @module test 测试收到消息传递
- * @description socket 通信
- * @param {any} url socket地址
- * @param {any} websocket websocket 实例
- * @param {any} heartTime 心跳定时器实例
- * @param {number} socketHeart 心跳次数
- * @param {number} HeartTimeOut 心跳超时时间
- * @param {number} socketError 错误次数
- */
-
-import { getToken } from '@/utils/auth';
-import { ElNotification } from 'element-plus';
-import useNoticeStore from '@/store/modules/notice';
-
-let socketUrl: any = ''; // socket地址
-let websocket: any = null; // websocket 实例
-let heartTime: any = null; // 心跳定时器实例
-let socketHeart = 0 as number; // 心跳次数
-const HeartTimeOut = 10000; // 心跳超时时间 10000 = 10s
-let socketError = 0 as number; // 错误次数
-
-// 初始化socket
-export const initWebSocket = (url: any) => {
-  if (import.meta.env.VITE_APP_WEBSOCKET === 'false') {
+import useUserStore from '@/store/modules/user';
+
+let webSock = null;
+let connectState = false; // 标记 WebSocket 连接状态
+let rec; //断线重连后,延迟5秒重新创建WebSocket连接  rec用来存储延迟请求的代码
+let closeFlag = false; // 是否关闭socket
+let global_callback = null;
+
+const port = '8080'; // webSocket连接端口
+const useUser = useUserStore();
+const wsUrl = `${import.meta.env.VITE_APP_BASE_WEBSOCKET}?userId=${useUser.userId}`;
+
+function createWebSocket(callback) {
+  if (webSock != null) {
     return;
   }
-  socketUrl = url;
-  // 初始化 websocket
-  websocket = new WebSocket(url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID);
-  websocketonopen();
-  websocketonmessage();
-  websocketonerror();
-  websocketclose();
-  sendSocketHeart();
-  return websocket;
-};
-
-// socket 连接成功
-export const websocketonopen = () => {
-  websocket.onopen = function () {
-    console.log('连接 websocket 成功');
-    resetHeart();
+  webSock = new WebSocket(wsUrl);
+  global_callback = callback;
+  webSock.onopen = function () {
+    // 连接打开时的处理
+    websocketOpen();
   };
-};
 
-// socket 连接失败
-export const websocketonerror = () => {
-  websocket.onerror = function (e: any) {
-    console.log('连接 websocket 失败', e);
+  webSock.onmessage = function (e) {
+    // 接收消息时的处理
+    websocketOnMessage(e);
+  };
+  webSock.onclose = function (e) {
+    // 连接关闭时的处理
+    websocketClose(e);
   };
-};
 
-// socket 断开链接
-export const websocketclose = () => {
-  websocket.onclose = function (e: any) {
-    console.log('断开连接', e);
+  // 连接发生错误的回调方法
+  webSock.onerror = function () {
+    websocketError();
   };
-};
+}
+
+//心跳设置
+const heartCheck = {
+  timeout: 30000, //每段时间发送一次心跳包 这里设置为20s
+  timeoutObj: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)
+
+  start: function () {
+    this.timeoutObj = setInterval(function () {
+      if (connectState) webSock.send(JSON.stringify({ type: 0 }));
+    }, this.timeout);
+  },
 
-// socket 重置心跳
-export const resetHeart = () => {
-  socketHeart = 0;
-  socketError = 0;
-  clearInterval(heartTime);
-  sendSocketHeart();
+  reset: function () {
+    clearTimeout(this.timeoutObj);
+    this.start();
+  }
 };
 
-// socket心跳发送
-export const sendSocketHeart = () => {
-  heartTime = setInterval(() => {
-    // 如果连接正常则发送心跳
-    if (websocket.readyState == 1) {
-      // if (socketHeart <= 30) {
-      websocket.send(
-        JSON.stringify({
-          type: 'ping'
-        })
-      );
-      socketHeart = socketHeart + 1;
-    } else {
-      // 重连
-      reconnect();
+//定义重连函数
+const reConnect = () => {
+  console.log('尝试重新连接');
+  if (connectState) return; //如果已经连上就不在重连了
+  rec && clearTimeout(rec);
+  rec = setTimeout(function () {
+    // 延迟5秒重连  避免过多次过频繁请求重连
+    if (!connectState) {
+      createWebSocket();
     }
-  }, HeartTimeOut);
+  }, 5000);
 };
 
-// socket重连
-export const reconnect = () => {
-  if (socketError <= 2) {
-    clearInterval(heartTime);
-    initWebSocket(socketUrl);
-    socketError = socketError + 1;
-    // eslint-disable-next-line prettier/prettier
-    console.log('socket重连', socketError);
+// 实际调用的方法
+function sendSock(agentData) {
+  if (webSock.readyState === webSock.OPEN) {
+    // 若是ws开启状态
+    webSock.send(agentData);
+  } else if (webSock.readyState === webSock.CONNECTING) {
+    // 若是 正在开启状态,则等待1s后重新调用
+    setTimeout(function () {
+      sendSock(agentData);
+    }, 1000);
   } else {
-    // eslint-disable-next-line prettier/prettier
-    console.log('重试次数已用完');
-    clearInterval(heartTime);
+    // 若未开启 ,则等待1s后重新调用
+    setTimeout(function () {
+      sendSock(agentData);
+    }, 1000);
   }
-};
+}
 
-// socket 发送数据
-export const sendMsg = (data: any) => {
-  websocket.send(data);
-};
+function websocketClose() {
+  connectState = false;
+  webSock = null;
+  global_callback = null;
+  closeFlag = false;
+  heartCheck.timeoutObj && clearTimeout(heartCheck.timeoutObj);
+  // 清除重连定时器
+  rec && clearTimeout(rec);
+}
 
-// socket 接收数据
-export const websocketonmessage = () => {
-  websocket.onmessage = function (e: any) {
-    if (e.data.indexOf('heartbeat') > 0) {
-      resetHeart();
-    }
-    if (e.data.indexOf('ping') > 0) {
-      return;
-    }
-    useNoticeStore().addNotice({
-      message: e.data,
-      read: false,
-      time: new Date().toLocaleString()
-    });
-    ElNotification({
-      title: '消息',
-      message: e.data,
-      type: 'success',
-      duration: 3000
-    });
-    return e.data;
-  };
+// 数据接收
+function websocketOnMessage(msg) {
+  if (!msg || !msg.data) {
+    // 可能得情况 - 心跳机制、无关信息接收
+    console.log('收到数据:空消息');
+    return;
+  }
+
+  // 收到信息为Blob类型时
+  const result = JSON.parse(msg.data);
+  if (result.type === 0 || result.type === '0') {
+    //自己的业务
+  } else {
+    global_callback(result);
+  }
+}
+
+function closeSock({ activeClose = false }) {
+  closeFlag = activeClose;
+  // 清除心跳定时器
+  heartCheck.timeoutObj && clearTimeout(heartCheck.timeoutObj);
+  // 清除重连定时器
+  rec && clearTimeout(rec);
+  if (closeFlag) {
+    // 关闭socket
+    webSock.close();
+  }
+  // 初始化相关变量
+  webSock = null;
+  connectState = false;
+}
+
+const websocketError = () => {
+  closeSock({ activeClose: true });
+  // 执行重连
+  reConnect();
 };
+
+function websocketOpen() {
+  connectState = true;
+  heartCheck.start(); //发送心跳 看个人项目需求
+}
+
+export { sendSock, createWebSocket, closeSock };

+ 139 - 0
src/utils/websocket2.ts

@@ -0,0 +1,139 @@
+/**
+ * @module initWebSocket 初始化
+ * @module websocketonopen 连接成功
+ * @module websocketonerror 连接失败
+ * @module websocketclose 断开连接
+ * @module resetHeart 重置心跳
+ * @module sendSocketHeart 心跳发送
+ * @module reconnect 重连
+ * @module sendMsg 发送数据
+ * @module websocketonmessage 接收数据
+ * @module test 测试收到消息传递
+ * @description socket 通信
+ * @param {any} url socket地址
+ * @param {any} websocket2 websocket2 实例
+ * @param {any} heartTime 心跳定时器实例
+ * @param {number} socketHeart 心跳次数
+ * @param {number} HeartTimeOut 心跳超时时间
+ * @param {number} socketError 错误次数
+ */
+
+import { getToken } from '@/utils/auth';
+import { ElNotification } from 'element-plus';
+import useNoticeStore from '@/store/modules/notice';
+
+let socketUrl: any = ''; // socket地址
+let websocket2: any = null; // websocket2 实例
+let heartTime: any = null; // 心跳定时器实例
+let socketHeart = 0 as number; // 心跳次数
+const HeartTimeOut = 10000; // 心跳超时时间 10000 = 10s
+let socketError = 0 as number; // 错误次数
+
+// 初始化socket
+export const initWebSocket = (url: any) => {
+  if (import.meta.env.VITE_APP_WEBSOCKET === 'false') {
+    return;
+  }
+  socketUrl = url;
+  // 初始化 websocket2
+  websocket2 = new WebSocket(url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID);
+  websocketonopen();
+  websocketonmessage();
+  websocketonerror();
+  websocketclose();
+  sendSocketHeart();
+  return websocket2;
+};
+
+// socket 连接成功
+export const websocketonopen = () => {
+  websocket2.onopen = function () {
+    console.log('连接 websocket2 成功');
+    resetHeart();
+  };
+};
+
+// socket 连接失败
+export const websocketonerror = () => {
+  websocket2.onerror = function (e: any) {
+    console.log('连接 websocket2 失败', e);
+  };
+};
+
+// socket 断开链接
+export const websocketclose = () => {
+  websocket2.onclose = function (e: any) {
+    console.log('断开连接', e);
+  };
+};
+
+// socket 重置心跳
+export const resetHeart = () => {
+  socketHeart = 0;
+  socketError = 0;
+  clearInterval(heartTime);
+  sendSocketHeart();
+};
+
+// socket心跳发送
+export const sendSocketHeart = () => {
+  heartTime = setInterval(() => {
+    // 如果连接正常则发送心跳
+    if (websocket2.readyState == 1) {
+      // if (socketHeart <= 30) {
+      websocket2.send(
+        JSON.stringify({
+          type: 'ping'
+        })
+      );
+      socketHeart = socketHeart + 1;
+    } else {
+      // 重连
+      reconnect();
+    }
+  }, HeartTimeOut);
+};
+
+// socket重连
+export const reconnect = () => {
+  if (socketError <= 2) {
+    clearInterval(heartTime);
+    initWebSocket(socketUrl);
+    socketError = socketError + 1;
+    // eslint-disable-next-line prettier/prettier
+    console.log('socket重连', socketError);
+  } else {
+    // eslint-disable-next-line prettier/prettier
+    console.log('重试次数已用完');
+    clearInterval(heartTime);
+  }
+};
+
+// socket 发送数据
+export const sendMsg = (data: any) => {
+  websocket2.send(data);
+};
+
+// socket 接收数据
+export const websocketonmessage = () => {
+  websocket2.onmessage = function (e: any) {
+    if (e.data.indexOf('heartbeat') > 0) {
+      resetHeart();
+    }
+    if (e.data.indexOf('ping') > 0) {
+      return;
+    }
+    useNoticeStore().addNotice({
+      message: e.data,
+      read: false,
+      time: new Date().toLocaleString()
+    });
+    ElNotification({
+      title: '消息',
+      message: e.data,
+      type: 'success',
+      duration: 3000
+    });
+    return e.data;
+  };
+};

+ 23 - 2
src/views/globalMap/RightMenu/OnlinePlotting/index.vue

@@ -150,12 +150,17 @@ import EditDialog from '@/views/globalMap/RightMenu/OnlinePlotting/EditDialog.vu
 import { Search } from '@element-plus/icons-vue';
 import html2canvas from 'html2canvas';
 import ShareDialog from '@/views/globalMap/RightMenu/OnlinePlotting/ShareDialog.vue';
+import websocketStore from '@/store/modules/websocketStore';
+import { tempData } from './tempData';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const userWebsocket = websocketStore();
 const getDrawTool = inject('getDrawTool');
 const getMap = inject('getMap');
+const getMapUtils = inject('getMapUtils');
 const containerScale = inject('containerScale');
 const { currentState, commit, undo, history, future } = useHistory();
+const emits = defineEmits(['getCollaborationData']);
 const getImageUrl = (name) => {
   return new URL(`../../../../assets/images/map/rightMenu/onlinePlotting/icon/${name}.png`, import.meta.url).href;
 };
@@ -516,7 +521,12 @@ const initDrawMethod = (options) => {
     data.id = id;
     if (options.type == 'marker') {
       const position = obj.getPosition();
-      data.path = [position.lng, position.lat];
+      data.lnglat = [position.lng, position.lat];
+      data.latitude = position.lat;
+      data.longitude = position.lng;
+      data.image = data.icon;
+      data.image = data.icon;
+      data.imageHover = data.icon;
     } else {
       const path = obj.getPath();
       // 将AMap.LngLat对象数组转换为经纬度数组
@@ -649,6 +659,7 @@ const queryParams = reactive({
   pageSize: 9,
   pattern_name: ''
 });
+
 const patternList = ref([]);
 let total = ref(0);
 let editData = ref({
@@ -707,16 +718,26 @@ const handleCloseShare = () => {
 };
 const handleCloseCollaboration = () => {
   collaboration.value = false;
-}
+};
 const handleShareConfirm = (data) => {
   if (shareState.type === '1') {
     // 协同标绘
+    setTimeout(() => {
+      const data = tempData;
+      const mapUtils = getMapUtils();
+      mapUtils.drawData(data);
+    }, 1000);
+    // userWebsocket.init();
   } else {
     // 分享
   }
   shareState.type = '';
   shareState.id = '';
 };
+// watch(userWebsocket.webSocketList, (newVal) => {
+//   console.log('监听数据变化');
+//   console.log(newVal);
+// });
 const handleShowDialog = () => {
   editData.value = {
     id: '',

+ 163 - 0
src/views/globalMap/RightMenu/OnlinePlotting/tempData.ts

@@ -0,0 +1,163 @@
+export const tempData = [
+  {
+    'id': 'cOfh9ErokJ9vX_VGI9M6M',
+    'path': [
+      [110.757811, 21.940275],
+      [110.796284, 21.940275],
+      [110.796284, 21.961091],
+      [110.757811, 21.961091],
+      [110.757811, 21.940275]
+    ],
+    'type': 'rectangle',
+    'fillColor': 'rgb(248,1,2)',
+    'fillOpacity': 1,
+    'strokeColor': 'rgb(248,1,2)',
+    'strokeStyle': 'solid',
+    'strokeWeight': '1',
+    'strokeOpacity': 1
+  },
+  {
+    'id': 'MMTZqPsF4U_JfJkkxnGxZ',
+    'path': [
+      [110.991454, 21.945108],
+      [111.037541, 21.927636],
+      [110.96861, 21.91388],
+      [110.940157, 21.942134],
+      [110.991454, 21.945108]
+    ],
+    'type': 'polygon',
+    'fillColor': 'rgb(248,1,2)',
+    'fillOpacity': 0.45,
+    'strokeColor': 'rgb(248,1,2)',
+    'strokeStyle': 'solid',
+    'strokeWeight': '1',
+    'strokeOpacity': 1
+  },
+  {
+    'id': 'N9butgd8gc8Tsnk0hyWeW',
+    'path': [
+      [110.906888, 21.91388],
+      [110.906815, 21.915162],
+      [110.906599, 21.91643],
+      [110.906241, 21.91767],
+      [110.905745, 21.918868],
+      [110.905117, 21.920012],
+      [110.904363, 21.921088],
+      [110.903492, 21.922086],
+      [110.902514, 21.922994],
+      [110.901439, 21.923801],
+      [110.900278, 21.924501],
+      [110.899045, 21.925083],
+      [110.897754, 21.925543],
+      [110.896417, 21.925875],
+      [110.89505, 21.926076],
+      [110.893669, 21.926143],
+      [110.892287, 21.926076],
+      [110.89092, 21.925875],
+      [110.889584, 21.925543],
+      [110.888292, 21.925083],
+      [110.887059, 21.924501],
+      [110.885898, 21.923801],
+      [110.884823, 21.922994],
+      [110.883845, 21.922086],
+      [110.882974, 21.921088],
+      [110.88222, 21.920012],
+      [110.881592, 21.918868],
+      [110.881096, 21.91767],
+      [110.880738, 21.91643],
+      [110.880522, 21.915162],
+      [110.880449, 21.91388],
+      [110.880522, 21.912598],
+      [110.880738, 21.91133],
+      [110.881096, 21.91009],
+      [110.881592, 21.908891],
+      [110.88222, 21.907748],
+      [110.882974, 21.906671],
+      [110.883845, 21.905673],
+      [110.884823, 21.904765],
+      [110.885898, 21.903958],
+      [110.887059, 21.903258],
+      [110.888292, 21.902676],
+      [110.889584, 21.902215],
+      [110.89092, 21.901883],
+      [110.892287, 21.901682],
+      [110.893669, 21.901615],
+      [110.89505, 21.901682],
+      [110.896417, 21.901883],
+      [110.897754, 21.902215],
+      [110.899045, 21.902676],
+      [110.900278, 21.903258],
+      [110.901439, 21.903958],
+      [110.902514, 21.904765],
+      [110.903492, 21.905673],
+      [110.904363, 21.906671],
+      [110.905117, 21.907748],
+      [110.905745, 21.908891],
+      [110.906241, 21.91009],
+      [110.906599, 21.91133],
+      [110.906815, 21.912598],
+      [110.906888, 21.91388],
+      [110.906888, 21.91388]
+    ],
+    'type': 'circle',
+    'center': [110.893669, 21.91388],
+    'radius': 1365.241,
+    'fillColor': 'rgb(248,1,2)',
+    'fillOpacity': 0.45,
+    'strokeColor': 'rgb(248,1,2)',
+    'strokeStyle': 'solid',
+    'strokeWeight': '1',
+    'strokeOpacity': 1
+  },
+  {
+    'id': 'uDbeoGOKd063MdWqJGnqx',
+    'path': [
+      [110.863211, 21.948453],
+      [110.896073, 21.954029]
+    ],
+    'type': 'straightLine',
+    'strokeColor': 'rgb(248,1,2)',
+    'strokeStyle': 'solid',
+    'strokeWeight': '1',
+    'strokeOpacity': 0.45
+  },
+  {
+    'id': 'RChxq42cV4lTy9kFK4Dd0',
+    'text': '从',
+    'type': 'text',
+    'lnglat': [110.83636, 21.882273],
+    'fontSize': '36px',
+    'fontColor': '#f80102'
+  },
+  {
+    'id': 'gBDaDaNnPeIiFRodTl44j',
+    'area': 28462241,
+    'path': [
+      [111.008288, 22.129065],
+      [111.0751, 22.135941],
+      [111.0751, 22.091238],
+      [111.013856, 22.096397],
+      [111.008288, 22.129065]
+    ],
+    'type': 'measureArea',
+    'fillColor': 'rgb(248,1,2)',
+    'fillOpacity': 1,
+    'strokeColor': 'rgb(248,1,2)',
+    'strokeStyle': 'solid',
+    'strokeWeight': '1',
+    'strokeOpacity': 1
+  },
+  {
+    'id': 'R1y5x7tcg-weSKRzf7aLp',
+    'icon': 'http://localhost:8086/yjdp/src/assets/images/map/rightMenu/onlinePlotting/icon/firePoint.png',
+    'size': [166, 88],
+    'type': 'marker',
+    'image': 'http://localhost:8086/yjdp/src/assets/images/map/rightMenu/onlinePlotting/icon/firePoint.png',
+    'title': '起火点',
+    'anchor': 'bottom-center',
+    'lnglat': [111.094723, 21.945017],
+    'latitude': 21.945017,
+    'longitude': 111.094723,
+    'imageHover': 'http://localhost:8086/yjdp/src/assets/images/map/rightMenu/onlinePlotting/icon/firePoint.png'
+  }
+];

+ 1 - 1
src/views/globalMap/RightMenu/index.vue

@@ -114,7 +114,7 @@ interface Props {
 }
 
 withDefaults(defineProps<Props>(), {});
-const emits = defineEmits(['update:drawing']);
+const emits = defineEmits(['update:drawing', '']);
 const scrollListRef = ref();
 const menuState = reactive({
   showMenu: false,

+ 9 - 0
src/views/globalMap/index.vue

@@ -200,6 +200,14 @@ const selectSearchMarker = (item) => {
 const handleAnalysisData = (data) => {
   rightMenuRef.value.handleMenu('空间分析', data);
 };
+const getMapUtils = () => {
+  if (['imageMap', 'satellite2', 'satellite3'].includes(activeMap.value)) {
+    return map2Ref.value.getMap();
+  } else if (['vectorgraph', 'satellite'].includes(activeMap.value)) {
+    return mapRef.value.getMapUtils();
+  }
+  return {};
+};
 // 获取地图元素操作
 const getMap = () => {
   if (['imageMap', 'satellite2', 'satellite3'].includes(activeMap.value)) {
@@ -292,6 +300,7 @@ onBeforeUnmount(() => {
   }
 });
 
+provide('getMapUtils', getMapUtils);
 provide('getMap', getMap);
 provide('trackPlayback', trackPlayback);
 provide('showDetail', showDetail);