Selaa lähdekoodia

粤政图 空间分析

Hwf 6 kuukautta sitten
vanhempi
commit
d166922022

+ 7 - 2
src/components/Map/YztMap/index.vue

@@ -24,6 +24,7 @@ import { getPointInfoList } from '@/api/globalMap';
 import { getDictLabel } from '@/utils/dict';
 import { methodList, titleList } from '../data';
 import { pointDetailTemplate } from '@/views/globalMap/data/mapData';
+import useAppStore from '@/store/modules/app';
 
 interface Props {
   activeMap: string;
@@ -35,7 +36,7 @@ const props = withDefaults(defineProps<Props>(), {});
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { point_type } = toRefs<any>(proxy?.useDict('point_type'));
 const appStore = useAppStore();
-const emits = defineEmits(['update:drawing', 'update:showMask', 'selectGraphics', 'handleShowWarehouse', 'handleShowVideo', 'handleShowPeople']);
+const emits = defineEmits(['update:showMask', 'selectGraphics', 'handleShowWarehouse', 'handleShowVideo', 'handleShowPeople']);
 
 const mapRef = ref(null);
 const mapState = reactive({
@@ -141,6 +142,7 @@ const init = () => {
       if (props.showMask) {
         mapUtils.createVecByJson2(mmJson, { strokeWeight: 2 });
       }
+      // let drawTool = new DrawTool({ mapUtils, map });
       handleResize();
     },
     onMarkerClick: (data) => {
@@ -353,6 +355,9 @@ const getScale = () => {
 const getMapUtils = () => {
   return mapUtils;
 };
+const getDrawTool = () => {
+  return mapUtils.getDrawTool();
+};
 // 加载事件
 onMounted(() => {
   init();
@@ -365,7 +370,7 @@ onUnmounted(() => {
 provide('getMapUtils', getMapUtils);
 provide('getMap', getMap);
 provide('getScale', getScale);
-defineExpose({ getMapUtils, addMarker, clearMarker });
+defineExpose({ getMap, getDrawTool, getMapUtils, addMarker, clearMarker });
 </script>
 
 <style scoped>

+ 9 - 9
src/hooks/AMap/useAMap.ts

@@ -125,7 +125,7 @@ export function useAMap(options) {
     }
     addPoints = points;
     const count = points.length;
-    const _renderClusterMarker = function(context) {
+    const _renderClusterMarker = function (context) {
       // 聚合中点个数
       const clusterCount = context.count;
       const div = document.createElement('div');
@@ -146,7 +146,7 @@ export function useAMap(options) {
         map.setZoomAndCenter(map.getZoom() + 1, bounds.getCenter());
       });
     };
-    const _renderMarker = function(context) {
+    const _renderMarker = function (context) {
       const content =
         '<div style="display: flex;flex-direction: column;align-items: center;justify-content: center">' +
         '<div style="background: url(' +
@@ -162,7 +162,7 @@ export function useAMap(options) {
       context.marker.setContent(content);
       context.marker.setOffset(offset);
       context.marker.setExtData(context.data[0]);
-      context.marker.on('click', function(e) {
+      context.marker.on('click', function (e) {
         const extData = e.target.getExtData();
         let index = 0;
         let index2 = 0;
@@ -284,7 +284,7 @@ export function useAMap(options) {
     new AMap.DistrictSearch({
       extensions: 'all',
       subdistrict: 0
-    }).search(name, function(status, result) {
+    }).search(name, function (status, result) {
       // 外多边形坐标数组和内多边形坐标数组
       const outer = [
         new AMap.LngLat(-360, 90, true),
@@ -294,7 +294,7 @@ export function useAMap(options) {
       ];
       options.forEach((option) => {
         const holes = result.districtList[0].boundaries;
-        let pathArray = [outer];
+        const pathArray = [outer];
         pathArray.push.apply(pathArray, holes);
         maskPolygon = new AMap.Polygon({
           pathL: pathArray,
@@ -322,7 +322,7 @@ export function useAMap(options) {
         polygon.show();
       });
     } else {
-      data = convertCoordinates(data);
+      // data = convertCoordinates(data);
       // 遮罩部分
       // const outer = [
       //   new AMap.LngLat(-180, 90, true),
@@ -431,12 +431,12 @@ export function useAMap(options) {
       strokeWeight: 6 //线宽
     });
 
-    moveMarker.on('moving', function(e) {
+    moveMarker.on('moving', function (e) {
       movePassedPolyline.setPath(e.passedPath);
       map.setCenter(e.target.getPosition(), true);
     });
 
-    moveMarker.on('moveend', function(e) {
+    moveMarker.on('moveend', function (e) {
       index++;
       if (index === lineArr.length - 1) {
         timerId = setTimeout(() => {
@@ -455,7 +455,7 @@ export function useAMap(options) {
   };
 
   const drawData = (data) => {
-    let res = [];
+    const res = [];
     data.forEach((item) => {
       let graphic;
       if (['rectangle', 'polygon', 'anyLine'].includes(item.type)) {

+ 23 - 0
src/utils/index.ts

@@ -412,3 +412,26 @@ export const formatToTwoDecimalPlaces = (str) => {
     return str; // 直接返回原始字符串表示
   }
 };
+
+export const hexToRgba = (hex, alpha) => {
+  // 确保输入是一个有效的十六进制颜色值,并以 # 开头
+  hex = hex.replace(/^#/, '');
+  // 如果十六进制颜色值是3位的简写形式(如 #f80),则扩展为6位
+  if (hex.length === 3) {
+    hex = hex
+      .split('')
+      .map((x) => x + x)
+      .join('');
+  }
+  // 如果十六进制颜色值的长度不是6位,则抛出错误
+  if (hex.length !== 6) {
+    return hex;
+  }
+  // 解析红、绿、蓝分量
+  const bigint = parseInt(hex, 16);
+  const r = (bigint >> 16) & 255;
+  const g = (bigint >> 8) & 255;
+  const b = bigint & 255;
+  // 返回 RGBA 字符串
+  return `rgba(${r}, ${g}, ${b}, ${alpha || 1})`;
+};

+ 170 - 20
src/utils/olMap/olMap.ts

@@ -25,17 +25,24 @@ import { fromLonLat } from 'ol/proj';
 import axios from 'axios';
 import { fromExtent } from 'ol/geom/Polygon';
 import { LinearRing, LineString, Polygon } from 'ol/geom';
-import {Graticule} from "ol/layer";
+import { Graticule } from 'ol/layer';
 import { getPointsCenter, mergeGeoJsonPolygons } from '@/utils/gisUtils';
 import { Cluster } from 'ol/source';
 import CircleStyle from 'ol/style/Circle';
 import Overlay from 'ol/Overlay';
-import { Select } from 'ol/interaction';
+import { Draw, Select } from 'ol/interaction';
 import { click } from 'ol/events/condition';
+import Circle from 'ol/geom/Circle';
+import { hexToRgba } from '@/utils';
+import { createBox } from 'ol/interaction/Draw';
 
+const tk = 'a8df87f1695d224d2679aa805c1268d9';
 const commonUrl = import.meta.env.VITE_APP_BASE_API2 + 'api/oneShare/proxyHandler/gd/';
 // proj4.defs('EPSG:4490', '+proj=longlat +ellps=GRS80 +no_defs +type=crs');
-proj4.defs('EPSG:4490', 'GEOGCS["China Geodetic Coordinate System 2000",DATUM["China_2000",SPHEROID["CGCS2000",6378137,298.257222101,AUTHORITY["EPSG","1024"]],AUTHORITY["EPSG","1043"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4490"]]');
+proj4.defs(
+  'EPSG:4490',
+  'GEOGCS["China Geodetic Coordinate System 2000",DATUM["China_2000",SPHEROID["CGCS2000",6378137,298.257222101,AUTHORITY["EPSG","1024"]],AUTHORITY["EPSG","1043"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4490"]]'
+);
 // proj4.defs('EPSG:4525', '+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs');
 register(proj4);
 const projection = new Projection({
@@ -43,8 +50,8 @@ const projection = new Projection({
   units: 'degrees',
   axisOrientation: 'neu'
 });
-projection.setExtent([-180, -90, 180, 90])
-projection.setWorldExtent([-180, -90, 180, 90])
+projection.setExtent([-180, -90, 180, 90]);
+projection.setWorldExtent([-180, -90, 180, 90]);
 const projectionExtent = [-180, -90, 180, 90];
 const size = getWidth(projectionExtent) / 256;
 const resolutions = [];
@@ -66,6 +73,8 @@ export class olMap {
     strokeStyle: 'solid'
   };
   private plot;
+  private drawVector;
+  private drawTool;
   private vectorLayer;
   // 边界遮罩图层
   private maskLayer;
@@ -168,12 +177,14 @@ export class olMap {
     // 添加新的图层
     if (Array.isArray(options.id)) {
       for (const layer of options.id) {
-        if (typeof layer === "string") {
+        if (typeof layer === 'string') {
           await this.formatXml(layer); // 等待当前 layer 处理完成
         } else {
           await this.formatXml(layer.id, layer.minZoom, layer.maxZoom, layer.zIndex, layer.visible); // 等待当前 layer 处理完成
         }
       }
+    } else if (options.id === 'tianditu') {
+      await this.formatXml2();
     } else if (options.id) {
       // 如果 options.id 不是数组,但确实是一个图层,则直接处理
       await this.formatXml(options.id, options.minZoom, options.maxZoom, options.zIndex, options.visible);
@@ -189,7 +200,30 @@ export class olMap {
       this.options.onLoadCompleted(this.map);
     }
   }
-
+  formatXml2() {
+    const baseUrl = 'https://t{0-7}.tianditu.gov.cn/';
+    const vecType = 'vec'; // 矢量图层类型
+    const projType = 'w'; // 投影类型:web mercator
+    const reqParams = {
+      SERVICE: 'WMTS',
+      REQUEST: 'GetTile',
+      VERSION: '1.0.0',
+      LAYER: '',
+      STYLE: 'default',
+      TILEMATRIXSET: projType,
+      FORMAT: 'tiles',
+      TILECOL: '{x}',
+      TILEROW: '{y}',
+      TILEMATRIX: '{z}',
+      tk: key
+    };
+    const newParams = Object.assign({}, params, { LAYER: dataType });
+    let paramsStr = '';
+    for (const [k, v] of Object.entries(newParams)) {
+      paramsStr += `${k}=${v}&`;
+    }
+    return `${baseUrl}${dataType}_${projType}/wmts?${paramsStr.slice(0, -1)}`;
+  }
   formatXml(code: string, minZoom?: number, maxZoom?: number, zIndex?: number, visible?: boolean) {
     const xml = new WMTSCapabilities();
     return this.getCapabilities(code).then((lists) => {
@@ -250,11 +284,13 @@ export class olMap {
       fillOpacity: options.drawType === '1' ? 0 : 0.5,
       strokeStyle: 'solid'
     };
-    // this.plot = new olPlot(this.map, {
-    //   zoomToExtent: true,
-    //   ...this.drawOptions
-    // });
-    // this.plot.plotDraw.on('drawEnd', this.onDrawEnd.bind(this));
+    // 创建矢量图层用于绘制
+    this.drawVector = new Vector({
+      source: new VectorSource({
+        features: []
+      })
+    });
+    this.map.addLayer(this.drawVector);
   }
 
   // 绘制结束事件
@@ -281,10 +317,60 @@ export class olMap {
       this.plot.plotDraw.activate('FreePolygon');
     }
   }
-
+  // 空间分析绘制图形
+  drawGraphics2(newOptions: MouseTool) {
+    const typeList = {
+      circle: 'Circle',
+      rectangle: 'Circle',
+      polygon: 'Polygon'
+    };
+    let geometryFunction = null;
+    if (newOptions.graphicsType === 'rectangle') {
+      // 绘制矩形的方法
+      geometryFunction = createBox();
+    }
+    if (!!typeList[newOptions.graphicsType]) {
+      this.drawOptions = {
+        type: newOptions.graphicsType,
+        strokeColor: newOptions.color,
+        strokeOpacity: 1,
+        strokeWeight: 1,
+        fillColor: newOptions.color,
+        fillOpacity: newOptions.drawType === '1' ? '0' : '0.5',
+        strokeStyle: 'solid'
+      };
+      this.closeDraw();
+      // 创建绘制交互
+      const style = new Style({
+        stroke: new Stroke({
+          color: hexToRgba(this.drawOptions.strokeColor, this.drawOptions.strokeOpacity),
+          width: this.drawOptions.strokeWeight
+        }),
+        fill: new Fill({
+          color: hexToRgba(this.drawOptions.fillColor, this.drawOptions.fillOpacity)
+        })
+      });
+      this.drawTool = new Draw({
+        source: this.drawVector.getSource(),
+        type: typeList[newOptions.graphicsType],
+        geometryFunction: geometryFunction,
+        style: style
+      });
+      // 添加绘制交互到地图
+      this.map.addInteraction(this.drawTool);
+      // 监听绘制结束事件
+      this.drawTool.on('drawend', (event) => {
+        const feature = event.feature;
+        // 获取几何对象
+        feature.setStyle(style);
+      });
+    }
+  }
   // 关闭绘制
   closeDraw() {
-    this.plot.plotDraw.deactivate();
+    if (!this.drawTool) return;
+    this.map.removeInteraction(this.drawTool);
+    // this.drawTool.abortDrawing();
   }
 
   // 切换图层
@@ -296,7 +382,7 @@ export class olMap {
 
     if (Array.isArray(newLayers)) {
       for (const layer of newLayers) {
-        if (typeof layer === "string") {
+        if (typeof layer === 'string') {
           await this.formatXml(layer); // 等待当前 layer 处理完成
         } else {
           await this.formatXml(layer.id, layer.minZoom, layer.maxZoom, layer.zIndex, layer.visible); // 等待当前 layer 处理完成
@@ -631,12 +717,13 @@ export class olMap {
     const graticule = new Graticule({
       name: 'Graticule',
       showLabels: true, // 为每条刻度线绘制一个带有各自纬度/经度的标签
-      wrapX: false,     // 是否水平重复经纬网
+      wrapX: false, // 是否水平重复经纬网
       targetSize: 230,
       zIndex: 99999,
-      strokeStyle: new Stroke({ // 用于绘制刻度线的样式
+      strokeStyle: new Stroke({
+        // 用于绘制刻度线的样式
         color: '#dcdcdc', // 线条颜色
-        width: 1,       // 线条宽度
+        width: 1 // 线条宽度
       }),
       lonLabelStyle: new Text({
         font: '12px Calibri,sans-serif',
@@ -656,9 +743,9 @@ export class olMap {
       })
     });
     if (visible) {
-      this.map.addLayer(graticule)
+      this.map.addLayer(graticule);
     } else {
-      this.removeLayer('Graticule')
+      this.removeLayer('Graticule');
     }
   }
   /**
@@ -674,10 +761,73 @@ export class olMap {
       }
     });
   }
+  // 创建图形
+  createGraphics(data: any) {
+    if (data.type === 'circle') {
+      // 绘制圆形
+      return this.createCircle(data);
+    } else if (['polygon', 'rectangle'].includes(data.type)) {
+      // 绘制矩形、多边形
+      return this.createPolygon(data);
+    }
+    // else if (data.type === 'marker') {
+    //   // 绘制图标
+    //   return createMarker(data);
+    // } else if (data.type === 'measureArea') {
+    //   // 绘制面积
+    //   return createMeasureArea(data);
+    // } else if (data.type === 'text') {
+    //   // 文字
+    //   return addText(data);
+    // } else if (data.type === 'straightLine') {
+    //   // 直线
+    //   return createStraightLine(data);
+    // }
+  }
+  createCircle(data) {
+    const circle = new Circle(data.center, data.radius);
+    const feature = new Feature(circle);
+    feature.setStyle(
+      new Style({
+        stroke: new Stroke({
+          color: hexToRgba(data.strokeColor, data.strokeOpacity),
+          width: data.strokeWeight
+        }),
+        fill: new Fill({
+          color: hexToRgba(data.fillColor, data.fillOpacity)
+        })
+      })
+    );
+    this.drawVector.getSource().addFeature(feature);
+    return feature;
+  }
+  createPolygon(data) {
+    const polygon = new Polygon([data.path]);
+    const feature = new Feature(polygon);
+    feature.setStyle(
+      new Style({
+        stroke: new Stroke({
+          color: hexToRgba(data.strokeColor, data.strokeOpacity),
+          width: data.strokeWeight
+        }),
+        fill: new Fill({
+          color: hexToRgba(data.fillColor, data.fillOpacity)
+        })
+      })
+    );
+    this.drawVector.getSource().addFeature(feature);
+    return feature;
+  }
   getVectorLayer() {
     return this.vectorLayer;
   }
+  getDrawVector() {
+    return this.drawVector;
+  }
   getMap() {
     return this.map;
   }
+  getMouseTool() {
+    return this.drawTool;
+  }
 }

+ 0 - 1
src/views/emergencyCommandMap/LeftSection/VideoMonitor.vue

@@ -86,7 +86,6 @@
 <script lang="ts" setup name="VideoMonitor">
 import { getEmergencyVideoCata, getUserVideoPoints, getVideoListByUser, updateUserVideoPoints } from '@/api/videoMonitor';
 import { deepClone } from '@/utils';
-import AMapLoader from '@amap/amap-jsapi-loader';
 import useAppStore from '@/store/modules/app';
 
 const props = defineProps({

+ 176 - 15
src/views/globalMap/RightMenu/DrawTools.vue

@@ -59,13 +59,20 @@
 import { useHistory } from '@/hooks/useHistory';
 import { nanoid } from 'nanoid';
 import { deepClone } from '@/utils';
+import * as turf from '@turf/turf';
+import Overlay from 'ol/Overlay';
 
 interface ListItem {
   label: string;
   value: string;
 }
+const props = defineProps({
+  activeMap: String
+});
+const AMapType = ['vectorgraph', 'satellite'];
 const getDrawTool = inject('getDrawTool');
 const getMap = inject('getMap');
+const getMapUtils = inject('getMapUtils');
 const emits = defineEmits(['handleAnalysisData']);
 const { currentState, commit, undo, history, future } = useHistory();
 const mouseToolState = reactive({
@@ -76,6 +83,13 @@ const mouseToolState = reactive({
   // 图形形状  circle圆形 rectangle矩形 polygon多边形
   graphicsType: 'circle'
 });
+let popup;
+let map = computed(() => {
+  return getMap();
+});
+let mapUtils = computed(() => {
+  return getMapUtils();
+});
 watch(
   mouseToolState,
   () => {
@@ -85,10 +99,18 @@ watch(
       drawOptions.drawType = mouseToolState.drawType;
       drawOptions.graphicsType = mouseToolState.graphicsType;
       drawTool.drawGraphics2(drawOptions);
-      drawTool.getMouseTool().on('draw', onDraw);
+      if (AMapType.includes(props.activeMap)) {
+        drawTool.getMouseTool().on('draw', onDraw);
+      } else {
+        drawTool.getMouseTool().on('drawend', onDraw2);
+        map.value.un('click', onMapClick);
+      }
     } else {
       mouseToolState.drawing = false;
       drawTool.closeDraw();
+      if (!AMapType.includes(props.activeMap)) {
+        map.value.on('click', onMapClick);
+      }
     }
   },
   {
@@ -175,6 +197,7 @@ onClickOutside(selectBoxRef3, () => {
 const openDraw = () => {
   mouseToolState.drawing = !mouseToolState.drawing;
 };
+// 高德地图绘制结束
 const onDraw = (event) => {
   const obj = event.obj;
   const id = nanoid();
@@ -201,7 +224,6 @@ const onDraw = (event) => {
   overlays.push(obj);
   overlaysData.push(data);
   commit(deepClone(overlaysData));
-  console.log(data);
   // 右击进入编辑
   obj.on('rightclick', handleRightClick);
   if (overlaysData.length === 1) {
@@ -215,6 +237,41 @@ const onDraw = (event) => {
     }
   });
 };
+// 粤政图绘制结束
+const onDraw2 = (event) => {
+  const feature = event.feature;
+  const geometry = feature.getGeometry();
+  const geometryType = geometry.getType();
+  const id = nanoid();
+  feature.set('id', id);
+  feature.set('dotType', 'analysisSpatial');
+  const data: any = {
+    id: id,
+    type: drawOptions.graphicsType,
+    color: drawOptions.color,
+    drawType: drawOptions.drawType
+  };
+  feature.set('extraData', data);
+  if (geometryType === 'Circle') {
+    data.center = geometry.getCenter();
+    data.radius = geometry.getRadius();
+    const data2 = turf.sector(data.center, data.radius, 0, 360);
+    const pathArr = data2.geometry.coordinates[0];
+    data.path = pathArr;
+  } else if (geometryType === 'Polygon') {
+    const coordinates = geometry.getCoordinates();
+    data.path = coordinates[0];
+  }
+  overlays.push(feature);
+  overlaysData.push(data);
+  commit(deepClone(overlaysData));
+  // 右击进入编辑
+  let map = getMap();
+  map.on('contextmenu', handleRightClick2);
+  if (overlaysData.length === 1) {
+    analysisSpatial(data);
+  }
+};
 let rightClickObj;
 // 图形右击事件
 let initContextMenu = false;
@@ -235,13 +292,67 @@ const handleRightClick = (event) => {
   }
   contextMenu.open(getMap(), event.lnglat);
 };
+const handleRightClick2 = (event) => {
+  event.preventDefault(); // 阻止默认的右键菜单弹出
+  map.value.un('click', onMapClick);
+  if (popup) {
+    map.value.removeOverlay(popup);
+    popup = undefined;
+  }
+  rightClickObj = map.value.forEachFeatureAtPixel(event.pixel, (feature2) => {
+    return feature2;
+  });
+  let dotType = rightClickObj.get('dotType');
+  if (!!rightClickObj && dotType === 'analysisSpatial') {
+    const dom = document.createElement('div');
+    const dom2 = document.createElement('div');
+    dom.id = 'analysisSpatial-popup';
+    dom2.className = 'menu-item';
+    dom2.innerHTML = '删除';
+    dom2.onclick = function () {
+      map.value.on('click', onMapClick);
+      deleteGraphics();
+    };
+    dom.appendChild(dom2);
+    popup = new Overlay({
+      element: dom,
+      autoPan: true,
+      positioning: 'bottom-right',
+      stopEvent: false,
+      offset: [0, 0]
+    });
+
+    const geometry = rightClickObj.getGeometry();
+    const geometryType = geometry.getType();
+    let coordinate = [];
+    if (geometryType === 'Circle') {
+      coordinate = geometry.getCenter();
+    } else {
+      const points = geometry.getCoordinates();
+      const features = turf.points(points[0]);
+      const center = turf.center(features);
+      if (center && center.geometry && center.geometry.coordinates) {
+        coordinate = center.geometry.coordinates;
+      }
+    }
+    popup.setPosition(coordinate);
+    map.value.addOverlay(popup);
+  }
+};
 // 删除图形
 const deleteGraphics = () => {
-  const id = rightClickObj.getExtData()?.id;
-  if (id) {
+  let id;
+  if (AMapType.includes(props.activeMap)) {
+    id = rightClickObj.getExtData()?.id;
+  } else {
+    unMapClick();
+    id = rightClickObj.get('id');
+  }
+  if (!!id) {
     for (let i = 0; i < overlays.length; i++) {
       const overlay = Array.isArray(overlays[i]) ? overlays[i][0] : overlays[i];
-      if (overlay?.getExtData().id === id) {
+      const itemId = AMapType.includes(props.activeMap) ? overlay?.getExtData().id : overlay.get('id');
+      if (itemId === id) {
         removeOverlayByIndex(i);
         commit(deepClone(overlaysData));
         rightClickObj = null;
@@ -281,14 +392,21 @@ const handleUndo = () => {
           strokeOpacity: 1,
           strokeWeight: '1',
           fillColor: restoreData.color,
-          fillOpacity: restoreData.drawType === '1' ? 0 : 0.5
+          fillOpacity: restoreData.drawType === '1' ? '0' : '0.5'
         };
-        if (restoreData.type === 'circlr') {
+        if (restoreData.type === 'circle') {
           newData.center = restoreData.center;
           newData.radius = restoreData.radius;
         }
-        const obj = getDrawTool().createGraphics(newData);
-        overlays.push(obj);
+        let obj;
+        if (AMapType.includes(props.activeMap)) {
+          obj = getDrawTool().createGraphics(newData);
+        } else {
+          obj = getDrawTool().createGraphics(newData);
+        }
+        if (!!obj) {
+          overlays.push(obj);
+        }
       }
     }
     undo();
@@ -299,15 +417,28 @@ const handleUndo = () => {
 // 根据索引移除覆盖物
 const removeOverlayByIndex = (index: number) => {
   const map = getMap();
-  if (Array.isArray(overlays[index])) {
-    overlays[index].forEach((overlay) => {
+  if (AMapType.includes(props.activeMap)) {
+    if (Array.isArray(overlays[index])) {
+      overlays[index].forEach((overlay) => {
+        // 移除地图上覆盖物
+        map.remove(overlay);
+      });
+    } else {
       // 移除地图上覆盖物
-      map.remove(overlay);
-    });
+      map.remove(overlays[index]);
+    }
   } else {
-    // 移除地图上覆盖物
-    map.remove(overlays[index]);
+    if (Array.isArray(overlays[index])) {
+      overlays[index].forEach((overlay) => {
+        // 移除地图上覆盖物
+        mapUtils.value.getDrawVector().getSource().removeFeature(overlay);
+      });
+    } else {
+      // 移除地图上覆盖物
+      mapUtils.value.getDrawVector().getSource().removeFeature(overlays[index]);
+    }
   }
+
   overlays.splice(index, 1);
   overlaysData.splice(index, 1);
 };
@@ -340,6 +471,36 @@ const analysisSpatial = (data) => {
   }
   emits('handleAnalysisData', location);
 };
+const onMapClick = (event) => {
+  // 没在编辑时
+  if (!mouseToolState.drawing && event.pixel) {
+    const feature = map.value.forEachFeatureAtPixel(event.pixel, (feature2) => {
+      return feature2;
+    });
+    const data = feature.get('extraData');
+    analysisSpatial(data);
+  }
+  unMapClick(event);
+};
+const unMapClick = (event) => {
+  const overlayElement = popup?.getElement();
+  const isClickOnOverlay =
+    event && overlayElement && (overlayElement.contains(event.originalEvent.target) || overlayElement === event.originalEvent.target);
+  if (!isClickOnOverlay && popup) {
+    map.value.removeOverlay(popup);
+    popup = undefined;
+  }
+};
+onMounted(() => {
+  if (!AMapType.includes(props.activeMap)) {
+    map.value.on('click', onMapClick);
+  }
+});
+onBeforeUnmount(() => {
+  if (!AMapType.includes(props.activeMap)) {
+    map.value.un('click', onMapClick);
+  }
+});
 </script>
 
 <style lang="scss" scoped>

+ 4 - 4
src/views/globalMap/index.vue

@@ -35,7 +35,7 @@
       <SwitchMapTool :active-map="activeMap" class="tool-box" @switch-map="switchMap" />
       <!--时间轴-->
       <TimeAxis />
-      <DrawTools v-if="showDrawTools" @handle-analysis-data="handleAnalysisData" />
+      <DrawTools v-if="showDrawTools" :active-map="activeMap" @handle-analysis-data="handleAnalysisData" />
       <NearbyVideos v-if="showNearbyVideos" v-model="showNearbyVideos" :location="location" />
       <GridPointRainfall v-if="showRainfall" v-model="showRainfall" :location="location" />
       <MaterialDetail v-if="showWarehouse" v-model="showWarehouse" :warehouse-data="warehouseData" />
@@ -71,7 +71,7 @@ let map2Ref = ref(null);
 let leftMenuRef = ref(null);
 let showMask = ref(true);
 //  vectorgraph satellite imageMap 废弃:logical satellite2 satellite3
-let activeMap = ref('satellite');
+let activeMap = ref('imageMap');
 // 附近视频菜单数据
 let tempMenu = ref({
   name: '',
@@ -246,7 +246,7 @@ const getMap = () => {
 };
 const getMapUtils = () => {
   if (['imageMap', 'satellite2', 'satellite3'].includes(activeMap.value)) {
-    return map2Ref.value.getMap();
+    return map2Ref.value.getMapUtils();
   } else if (['vectorgraph', 'satellite'].includes(activeMap.value)) {
     return mapRef.value.getMapUtils();
   }
@@ -262,7 +262,7 @@ const showDetail = (data, dataType) => {
 };
 const getDrawTool = () => {
   if (['imageMap', 'satellite2', 'satellite3'].includes(activeMap.value)) {
-    return map2Ref.value.drawTool;
+    return map2Ref.value.getMapUtils();
   } else if (['vectorgraph', 'satellite'].includes(activeMap.value)) {
     return mapRef.value.drawTool;
   }