浏览代码

高德地图 绘制矩形、圆形

Hwf 2 月之前
父节点
当前提交
5e859da699

+ 9 - 5
src/components/LineWidthSelect/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="select-container">
+  <div ref="lineRef" class="select-container">
     <div class="select-box" @click="handleShow">
       <div class="text1" :style="{ height: modelValue + 'px' }"></div>
       <div class="icon"></div>
@@ -13,18 +13,22 @@
 </template>
 
 <script lang="ts" setup name="LineWidthSelect">
-import {ref} from "vue";
+import {onClickOutside} from "@vueuse/core";
 
 interface Props {
-  modelValue: boolean;
+  modelValue: string;
   options: object[];
 }
 const props = withDefaults(defineProps<Props>(), {});
 const emits = defineEmits(['update:modelValue']);
-
+const lineRef = ref();
 let show = ref();
+onClickOutside(lineRef, event => {
+  show.value = false;
+});
+
 const handleShow = () => {
-  show.value = true;
+  show.value = !show.value;
 };
 const handleClick = (value: string) => {
   emits('update:modelValue', value);

+ 89 - 11
src/hooks/AMap/useDrawTool.ts

@@ -96,10 +96,12 @@ export function useDrawTool() {
     closeDraw();
     if (newOptions.graphicsType === 'circle') {
       // 绘制圆形
-      mouseTool.circle(drawOptions);
+      // mouseTool.circle(drawOptions);
+      drawCircle(drawOptions);
     } else if (newOptions.graphicsType === 'rectangle') {
       // 绘制矩形
-      mouseTool.rectangle(drawOptions);
+      // mouseTool.rectangle(drawOptions);
+      drawRectangle(drawOptions);
     } else if (newOptions.graphicsType === 'polygon') {
       // 绘制多边形
       mouseTool.polygon(drawOptions);
@@ -118,6 +120,16 @@ export function useDrawTool() {
       // 测量面积
       mouseTool.polygon(drawOptions);
     }
+    if (newOptions.graphicsType !== 'anyLine') {
+      map.setStatus({
+        showIndoorMap: false,
+        dragEnable: false,
+        keyboardEnable: false,
+        doubleClickZoom: false,
+        zoomEnable: false,
+        rotateEnable: false
+      });
+    }
     return drawOptions;
   };
   // 空间分析绘制图形
@@ -172,9 +184,75 @@ export function useDrawTool() {
     data.id = id;
     return { text, data };
   };
-  let anyLine = null;
+  let drawObj = null;
   let drawing = false;
   let path = null;
+  // 绘制圆
+  const drawCircle = (options) => {
+    map.on('touchstart', handleTouchStart);
+    map.on('touchmove', handleTouchMove1.bind(null, options));
+    document.addEventListener('touchend', handleTouchEnd.bind(null, options));
+    map.on('mousedown', handleTouchStart);
+    map.on('mousemove', handleTouchMove1.bind(null, options));
+    document.addEventListener('mouseup', handleTouchEnd.bind(null, options));
+  };
+  // 绘制矩形
+  const drawRectangle = (options) => {
+    map.on('touchstart', handleTouchStart);
+    map.on('touchmove', handleTouchMove2.bind(null, options));
+    document.addEventListener('touchend', handleTouchEnd.bind(null, options));
+    map.on('mousedown', handleTouchStart);
+    map.on('mousemove', handleTouchMove2.bind(null, options));
+    document.addEventListener('mouseup', handleTouchEnd.bind(null, options));
+  };
+  const handleTouchMove1 = (options, e) => {
+    if (!drawing) return;
+    if (drawObj) {
+      map.remove(drawObj);
+    }
+    const center = path[0]; // 获取圆心坐标
+    const radius = AMap.GeometryUtil.distance(center, e.lnglat);
+    drawObj = new AMap.Circle({
+      center: center, //圆心
+      radius: radius, //半径
+      strokeColor: options.strokeColor, //轮廓线颜色
+      strokeOpacity: options.strokeOpacity, //轮廓线透明度
+      strokeWeight: options.strokeWeight, //轮廓线宽度
+      fillOpacity: options.fillOpacity, //圆形填充透明度
+      fillColor: options.fillColor, //圆形填充颜色
+    });
+    map.add(drawObj);
+  };
+  const handleTouchMove2 = (options, e) => {
+    if (!drawing) return;
+    if (drawObj) {
+      map.remove(drawObj);
+    }
+    const center = path[0]; // 获取圆心坐标
+    const radius = AMap.GeometryUtil.distance(center, e.lnglat);
+    let minLngLat = e.lnglat;
+    let maxLngLat = path[0];
+    if (path[0].lng < e.lnglat.lng) {
+      minLngLat = path[0];
+      maxLngLat = e.lnglat;
+    }
+    const pathArray = [
+      [minLngLat.lng, minLngLat.lat],
+      [minLngLat.lng, maxLngLat.lat],
+      [maxLngLat.lng, maxLngLat.lat],
+      [maxLngLat.lng, minLngLat.lat],
+      [minLngLat.lng, minLngLat.lat],
+    ];
+    drawObj = new AMap.Polygon({
+      path: pathArray,
+      strokeColor: options.strokeColor,
+      strokeOpacity: options.strokeOpacity,
+      strokeWeight: options.strokeWeight,
+      fillColor: options.fillColor,
+      fillOpacity: options.fillOpacity
+    });
+    map.add(drawObj);
+  };
   // 绘制任意线
   const drawAnyLine = (options) => {
     map.on('touchstart', handleTouchStart);
@@ -195,17 +273,17 @@ export function useDrawTool() {
       rotateEnable: false
     });
     path = [e.lnglat];
-    if (anyLine) {
-      map.remove(anyLine);
+    if (drawObj) {
+      map.remove(drawObj);
     }
   };
   const handleTouchMove = (options, e) => {
     if (!drawing) return;
     path.push(e.lnglat);
-    if (anyLine) {
-      map.remove(anyLine);
+    if (drawObj) {
+      map.remove(drawObj);
     }
-    anyLine = new AMap.Polyline({
+    drawObj = new AMap.Polyline({
       path: path,
       strokeColor: options.strokeColor,
       strokeOpacity: options.strokeOpacity,
@@ -213,7 +291,7 @@ export function useDrawTool() {
       strokeStyle: options.strokeStyle,
       lineJoin: 'round'
     });
-    map.add(anyLine);
+    map.add(drawObj);
   };
   const handleTouchEnd = (options) => {
     drawing = false;
@@ -232,9 +310,9 @@ export function useDrawTool() {
     map.off('mousemove', handleTouchMove);
     document.removeEventListener('mouseup', handleTouchEnd);
     if (!!drawEndMethod) {
-      drawEndMethod(options, anyLine);
+      drawEndMethod(options, drawObj);
     }
-    anyLine = null;
+    drawObj = null;
   };
   // 关闭绘制
   const closeDraw = () => {

+ 3 - 0
src/styles/index.less

@@ -252,3 +252,6 @@ a:hover {
     }
   }
 }
+.custom-color-picker {
+  z-index: 10001 !important; /* 需高于 van-popup 的 z-index */
+}

+ 1 - 1
src/utils/websocket.ts

@@ -9,7 +9,7 @@ let global_callback = null;
 const wsUrl = `${import.meta.env.VITE_APP_BASE_WEBSOCKET}/api/pattern/`;
 function createWebSocket(id, callback) {
   if (webSock != null) {
-    return;
+    return webSock;
   }
   webSock = new WebSocket(wsUrl + id + '/ws');
 

+ 38 - 24
src/views/mobileControl/OnlinePlotting/index.vue

@@ -69,7 +69,7 @@ const show = computed({
     emits('update:modelValue', value);
   }
 });
-
+let map;
 const getImageUrl = (name) => {
   return new URL(`../../../assets/images/map/onlinePlotting/icon/${name}.png`, import.meta.url).href;
 };
@@ -106,11 +106,11 @@ const menu = ref([
           //   value: 'straightArrow',
           //   image: getImageUrl('straightArrow')
           // },
-          // {
-          //   name: '矩形',
-          //   value: 'rectangle',
-          //   image: getImageUrl('rectangle')
-          // },
+          {
+            name: '矩形',
+            value: 'rectangle',
+            image: getImageUrl('rectangle')
+          },
           {
             name: '任意面',
             value: 'polygon',
@@ -121,11 +121,11 @@ const menu = ref([
             value: 'anyLine',
             image: getImageUrl('anyLine')
           },
-          // {
-          //   name: '圆',
-          //   value: 'circle',
-          //   image: getImageUrl('circle')
-          // },
+          {
+            name: '圆',
+            value: 'circle',
+            image: getImageUrl('circle')
+          },
           {
             name: '直线',
             value: 'straightLine',
@@ -277,10 +277,11 @@ const clickTab = (item, index) => {
     }
     emits('update:modelValue', false);
     const drawTool = getDrawTool();
-    const newOptions = drawTool.drawGraphics(mouseToolState.value);
-    if (mouseToolState.value.graphicsType !== 'anyLine') {
+    if (['anyLine', 'circle', 'rectangle'].includes(mouseToolState.value.graphicsType)) {
       drawTool.setDrawEndMethod(handleEndDraw);
-    } else if (mouseToolState.value.graphicsType !== 'text') {
+    }
+    if (mouseToolState.value.graphicsType !== 'text') {
+      const newOptions = drawTool.drawGraphics(mouseToolState.value);
       // 绘制完成事件
       initDrawMethod(newOptions);
     }
@@ -355,6 +356,14 @@ const initDrawMethod = (options) => {
 
   const onDraw = (event) => {
     mouseTool.off('draw', onDraw);
+    map.setStatus({
+      showIndoorMap: true,
+      dragEnable: true,
+      keyboardEnable: true,
+      doubleClickZoom: true,
+      zoomEnable: true,
+      rotateEnable: true
+    });
     close();
     const obj = event.obj;
     const id = nanoid();
@@ -389,7 +398,7 @@ const initDrawMethod = (options) => {
       data.path = pathArr;
       if (options.type == 'circle') {
         data.center = [obj.getCenter().lng, obj.getCenter().lat];
-        data.radius = obj.getRadius();
+        data.radius = obj.getRadius() / 100000;
       }
     }
     if (options.type == 'measureArea') {
@@ -431,15 +440,17 @@ const handleEndDraw = (options, obj) => {
   };
   const data: any = deepClone(options);
   data.id = id;
-  if (data.type === 'anyLine') {
-    const path = obj.getPath();
-    // 将AMap.LngLat对象数组转换为经纬度数组
-    const pathArr = path.map((lngLat) => {
-      // 返回经度和纬度的数组
-      return [lngLat.lng, lngLat.lat];
-    });
-    pathArr.push(pathArr[0]);
-    data.path = pathArr;
+  const path = obj.getPath();
+  // 将AMap.LngLat对象数组转换为经纬度数组
+  const pathArr = path.map((lngLat) => {
+    // 返回经度和纬度的数组
+    return [lngLat.lng, lngLat.lat];
+  });
+  pathArr.push(pathArr[0]);
+  data.path = pathArr;
+  if (data.type === 'circle') {
+    data.center = [obj.getCenter().lng, obj.getCenter().lat];
+    data.radius = obj.getRadius() / 100000;
   }
   overlays.push(obj);
   overlaysData.push(data);
@@ -620,4 +631,7 @@ defineExpose({ getWebSocketData })
 .color-container {
   margin-left: 8px;
 }
+:deep(.el-color-picker__panel) {
+  z-index: 9999;
+}
 </style>

+ 17 - 6
src/views/mobileControl/index.vue

@@ -318,7 +318,7 @@ let onlinePlottingId = ref("");
 let columns = ref([]);
 let webSock;
 const onCancel = () => {
-  showOnlinePlotting2.value = false;
+  showOnlinePlotting.value = false;
 };
 const getWebSocketData = data => {
   onlinePlotting.value.getWebSocketData(data);
@@ -326,11 +326,21 @@ const getWebSocketData = data => {
 };
 const onConfirm = data => {
   onlinePlottingId.value = data.selectedValues[0];
-  nextTick(() => {
-    webSock = createWebSocket(onlinePlottingId.value, getWebSocketData);
-    showOnlinePlotting.value = false;
-    showOnlinePlotting2.value = true;
-  });
+  if ((onlinePlottingId.value && onlinePlottingId.value.length > 0)) {
+    nextTick(() => {
+      webSock = createWebSocket(onlinePlottingId.value, getWebSocketData);
+      // 监听错误事件
+      webSock.onerror = (error) => {
+        console.error('WebSocket 连接失败:', error);
+      };
+      // 监听成功事件后再执行后续操作
+      webSock.onopen = (res) => {
+        showOnlinePlotting2.value = true;
+      };
+    });
+  };
+  showOnlinePlotting.value = false;
+  // showOnlinePlotting2.value = true;
 };
 const handleShowOnlinePlotting = () => {
   if (!!onlinePlottingId.value) {
@@ -480,6 +490,7 @@ provide("getDrawTool", getDrawTool);
   position: absolute;
   left: 16px;
   bottom: 16px;
+  //bottom: 160px;
 
   .button2 {
     margin-bottom: 16px;