Browse Source

视频地图打点

Hwf 1 month ago
parent
commit
2921f7fd8c

+ 9 - 0
src/api/globalMap/index.ts

@@ -53,6 +53,15 @@ export const getEmergencyExpertNum = (params) => {
   });
   });
 };
 };
 
 
+// 全域地图-点位信息-详情列表(带视频点位)
+export const getPointInfoList2 = (data) => {
+  return request({
+    url: '/api/spatial_analysis/point/get_details',
+    method: 'post',
+    data: data
+  });
+};
+
 export const getSpatialAnalysis = (params) => {
 export const getSpatialAnalysis = (params) => {
   return request({
   return request({
     url: '/api/spatial_analysis/get_info',
     url: '/api/spatial_analysis/get_info',

+ 14 - 13
src/components/Map/YztMap/index.vue

@@ -17,10 +17,10 @@
 import 'ol/ol.css';
 import 'ol/ol.css';
 import mmJson from '@/assets/json/mm2.json';
 import mmJson from '@/assets/json/mm2.json';
 import { olMap } from '@/utils/olMap/olMap';
 import { olMap } from '@/utils/olMap/olMap';
-import { getPointInfoList } from '@/api/globalMap';
+import { getPointInfoList2 } from '@/api/globalMap';
 import { getDictLabel } from '@/utils/dict';
 import { getDictLabel } from '@/utils/dict';
 import { methodList, titleList } from '../data';
 import { methodList, titleList } from '../data';
-import { pointDetailTemplate } from '@/views/globalMap/data/mapData';
+import { iconList, pointDetailTemplate } from '@/views/globalMap/data/mapData';
 import useAppStore from '@/store/modules/app';
 import useAppStore from '@/store/modules/app';
 import useMapStore from '@/store/modules/map';
 import useMapStore from '@/store/modules/map';
 
 
@@ -118,16 +118,14 @@ const init = () => {
     onMarkerClick: (data) => {
     onMarkerClick: (data) => {
       // 多点位
       // 多点位
       if (data.type === '1') {
       if (data.type === '1') {
-        let path = [];
-        mapStore.pointType.forEach((item) => {
-          path.push(item.component);
-        });
-        getPointInfoList({
-          option: path.toString(),
+        getPointInfoList2({
+          option: mapStore.pointParams.option,
+          dict_value: mapStore.pointParams.dict_value.toString(),
+          zoom_level: mapStore.mapState.zoom,
           longitude: data.longitude.toString(),
           longitude: data.longitude.toString(),
           latitude: data.latitude.toString()
           latitude: data.latitude.toString()
         }).then((res) => {
         }).then((res) => {
-          const data2 = res.data.list;
+          const data2 = res.data;
           let content = document.createElement('div');
           let content = document.createElement('div');
           // content.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
           // content.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
           content.className = 'point-info';
           content.className = 'point-info';
@@ -144,8 +142,10 @@ const init = () => {
           table.className = 'table';
           table.className = 'table';
           table.innerHTML = '<div class="point-item"><div class="td3">主题</div><div class="td3">名称</div></div>';
           table.innerHTML = '<div class="point-item"><div class="td3">主题</div><div class="td3">名称</div></div>';
           data2.forEach((item) => {
           data2.forEach((item) => {
-            item.longitude = data.longitude;
-            item.latitude = data.latitude;
+            item.image = data.image;
+            item.imageHover = data.imageHover;
+            item.size = data.size;
+            item.scale = data.scale;
             const div = document.createElement('div');
             const div = document.createElement('div');
             div.className = 'point-item point-item-hover';
             div.className = 'point-item point-item-hover';
             div.innerHTML =
             div.innerHTML =
@@ -161,7 +161,7 @@ const init = () => {
           closeBtn.className = 'close';
           closeBtn.className = 'close';
           closeBtn.onclick = () => mapUtils.hideInfo(true);
           closeBtn.onclick = () => mapUtils.hideInfo(true);
           content.appendChild(closeBtn);
           content.appendChild(closeBtn);
-          mapUtils.showInfo(content, [data.longitude, data.latitude], true);
+          mapUtils.showInfo(content, [data.longitude, data.latitude], -data.scale * data.size[1], true);
         });
         });
       } else {
       } else {
         handlePointDetails(data);
         handlePointDetails(data);
@@ -255,7 +255,7 @@ const handlePointDetails = (data) => {
       closeBtn.className = 'close';
       closeBtn.className = 'close';
       closeBtn.onclick = () => mapUtils.hideInfo(true);
       closeBtn.onclick = () => mapUtils.hideInfo(true);
       div.appendChild(closeBtn);
       div.appendChild(closeBtn);
-      mapUtils.showInfo(div, [data.longitude, data.latitude], true);
+      mapUtils.showInfo(div, [data.longitude, data.latitude], -data.scale * data.size[1], true);
     }
     }
   });
   });
 };
 };
@@ -308,6 +308,7 @@ const clearMarker = () => {
   mapUtils.clearMarker();
   mapUtils.clearMarker();
 };
 };
 const handleResize = () => {
 const handleResize = () => {
+  if (!containerRef.value) return;
   const containerWidth = containerRef.value.clientWidth * containerScale().scaleX;
   const containerWidth = containerRef.value.clientWidth * containerScale().scaleX;
   const containerHeight = containerRef.value.clientHeight * containerScale().scaleY;
   const containerHeight = containerRef.value.clientHeight * containerScale().scaleY;
   width.value = containerWidth + 'px';
   width.value = containerWidth + 'px';

+ 14 - 28
src/components/Map/index.vue

@@ -7,9 +7,8 @@
 <script setup lang="ts" name="Map">
 <script setup lang="ts" name="Map">
 import { useAMap } from '@/hooks/AMap/useAMap';
 import { useAMap } from '@/hooks/AMap/useAMap';
 import { useDrawTool } from '@/hooks/AMap/useDrawTool';
 import { useDrawTool } from '@/hooks/AMap/useDrawTool';
-import { getPointInfoList } from '@/api/globalMap';
+import { getPointInfoList2 } from '@/api/globalMap';
 import { getDictLabel } from '@/utils/dict';
 import { getDictLabel } from '@/utils/dict';
-import { PointType } from '@/api/globalMap/type';
 import { methodList, titleList } from './data';
 import { methodList, titleList } from './data';
 import { pointDetailTemplate } from '@/views/globalMap/data/mapData';
 import { pointDetailTemplate } from '@/views/globalMap/data/mapData';
 import useAppStore from '@/store/modules/app';
 import useAppStore from '@/store/modules/app';
@@ -77,16 +76,14 @@ const mapUtils = useAMap({
   onMarkerClick: (data) => {
   onMarkerClick: (data) => {
     // 多点位
     // 多点位
     if (data.type === '1') {
     if (data.type === '1') {
-      let path = [];
-      mapStore.pointType.forEach((item) => {
-        path.push(item.component);
-      });
-      getPointInfoList({
-        option: path.toString(),
+      getPointInfoList2({
+        option: mapStore.pointParams.option,
+        dict_value: mapStore.pointParams.dict_value.toString(),
+        zoom_level: mapStore.mapState.zoom,
         longitude: data.longitude.toString(),
         longitude: data.longitude.toString(),
         latitude: data.latitude.toString()
         latitude: data.latitude.toString()
       }).then((res) => {
       }).then((res) => {
-        const data2 = res.data.list;
+        const data2 = res.data;
         let content = document.createElement('div');
         let content = document.createElement('div');
         // content.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
         // content.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
         content.className = 'point-info';
         content.className = 'point-info';
@@ -103,8 +100,9 @@ const mapUtils = useAMap({
         table.className = 'table';
         table.className = 'table';
         table.innerHTML = '<div class="point-item"><div class="td3">主题</div><div class="td3">名称</div></div>';
         table.innerHTML = '<div class="point-item"><div class="td3">主题</div><div class="td3">名称</div></div>';
         data2.forEach((item) => {
         data2.forEach((item) => {
-          item.longitude = data.longitude;
-          item.latitude = data.latitude;
+          item.image = data.image;
+          item.imageHover = data.imageHover;
+          item.size = data.size;
           const div = document.createElement('div');
           const div = document.createElement('div');
           div.className = 'point-item point-item-hover';
           div.className = 'point-item point-item-hover';
           div.innerHTML =
           div.innerHTML =
@@ -120,27 +118,16 @@ const mapUtils = useAMap({
         closeBtn.className = 'close';
         closeBtn.className = 'close';
         closeBtn.onclick = hideInfo;
         closeBtn.onclick = hideInfo;
         content.appendChild(closeBtn);
         content.appendChild(closeBtn);
-        showInfo(content, [data.longitude, data.latitude], true);
+        showInfo(content, [data.longitude, data.latitude], -data.size[1], true);
       });
       });
     } else {
     } else {
       handlePointDetails(data);
       handlePointDetails(data);
     }
     }
   }
   }
 });
 });
-const {
-  getMap,
-  getAMap,
-  switchMap,
-  addMarker,
-  addSearchMarker,
-  clearMarker,
-  showInfo,
-  hideInfo,
-  handleHover,
-  creatMask2,
-  removeMask2,
-  trackPlayback
-} = { ...mapUtils };
+const { getMap, getAMap, switchMap, addSearchMarker, clearMarker, showInfo, hideInfo, handleHover, creatMask2, removeMask2, trackPlayback } = {
+  ...mapUtils
+};
 const handlePointDetails = (data) => {
 const handlePointDetails = (data) => {
   let method = methodList[data.dataType];
   let method = methodList[data.dataType];
   let title = !!titleList[data.dataType] ? titleList[data.dataType] : '信息';
   let title = !!titleList[data.dataType] ? titleList[data.dataType] : '信息';
@@ -227,7 +214,7 @@ const handlePointDetails = (data) => {
       closeBtn.className = 'close';
       closeBtn.className = 'close';
       closeBtn.onclick = hideInfo;
       closeBtn.onclick = hideInfo;
       div.appendChild(closeBtn);
       div.appendChild(closeBtn);
-      showInfo(div, [data.longitude, data.latitude], true);
+      showInfo(div, [data.longitude, data.latitude], -data.size[1], true);
     }
     }
   });
   });
 };
 };
@@ -345,7 +332,6 @@ onUnmounted(() => {
 });
 });
 
 
 defineExpose({
 defineExpose({
-  addMarker,
   addSearchMarker,
   addSearchMarker,
   setCenter,
   setCenter,
   clearMarker,
   clearMarker,

+ 77 - 34
src/hooks/AMap/useAMap.ts

@@ -3,7 +3,7 @@ import { nanoid } from 'nanoid';
 import { deepClone, initDrag } from '@/utils';
 import { deepClone, initDrag } from '@/utils';
 import { mergeGeoJsonPolygons, wgs_gcj_encrypts } from '@/utils/gisUtils';
 import { mergeGeoJsonPolygons, wgs_gcj_encrypts } from '@/utils/gisUtils';
 import carImg from '@/assets/images/car.png';
 import carImg from '@/assets/images/car.png';
-import { getImageUrl } from '@/views/globalMap/data/mapData';
+import { getImageUrl, iconList } from '@/views/globalMap/data/mapData';
 
 
 export function useAMap(options) {
 export function useAMap(options) {
   let AMap, map, scale, cluster;
   let AMap, map, scale, cluster;
@@ -230,42 +230,68 @@ export function useAMap(options) {
   };
   };
   // 添加多个点2 后台做点聚合
   // 添加多个点2 后台做点聚合
   const addMarker2 = (obj) => {
   const addMarker2 = (obj) => {
-    if (plotLayers['points2']) {
-      plotLayers['points2'] = new AMap.TileLayer({
+    // 新增图层
+    if (!plotLayers['points2']) {
+      plotLayers['points2'] = new AMap.OverlayGroup({
         zIndex: 10, // 设置图层层级
         zIndex: 10, // 设置图层层级
         visible: true
         visible: true
       });
       });
       map.add(plotLayers['points2']);
       map.add(plotLayers['points2']);
+    } else {
+      plotLayers['points2'].clearOverlays();
+      addPoints = [];
     }
     }
     Object.keys(obj).forEach((key: string) => {
     Object.keys(obj).forEach((key: string) => {
-      if (obj[key].videos && obj[key].videos.length > 1) {
+      const data = obj[key];
+      if (data.type === '3') {
         // 聚合点
         // 聚合点
+        const div = document.createElement('div');
+        div.style.backgroundColor = 'rgba(78,179,211,.5)';
+        const size = Math.round(25 + Math.pow(1 / 5, 1 / 5) * 20);
+        div.style.width = div.style.height = size + 'px';
+        div.style.border = 'solid 1px rgba(78,179,211,1)';
+        div.style.borderRadius = size / 2 + 'px';
+        div.innerHTML = data.count;
+        div.style.lineHeight = size + 'px';
+        div.style.color = '#ffffff';
+        div.style.fontSize = '12px';
+        div.style.textAlign = 'center';
+        const marker = new AMap.Marker({
+          position: [data.longitude, data.latitude],
+          content: div,
+          anchor: 'center',
+          offset: new AMap.Pixel(0, 0),
+          map: map
+        });
+        marker.setContent(div);
+        marker.on('click', (e) => {
+          const bounds = e.target.getBounds();
+          map.setZoomAndCenter(map.getZoom() + 1, bounds.getCenter());
+        });
+        plotLayers['points2'].addOverlay(marker);
+        addPoints.push(data);
       } else {
       } else {
         // 单个点
         // 单个点
-        const data = obj[key].videos[0];
-        data.image = getImageUrl('31_lakes_video.png');
-        data.imageHover = getImageUrl('31_lakes_video_hover.png');
-        data.icon = data.image;
-        data.size = [40, 40];
-        data.id = data.cameraIndexCode;
-        const content =
-          '<div style="display: flex;flex-direction: column;align-items: center;justify-content: center">' +
-          '<div style="background: url(' +
-          data.icon +
-          ') no-repeat; width: ' +
-          data.size[0] +
-          'px;height: ' +
-          data.size[1] +
-          'px;cursor: pointer; background-size: cover"></div>' +
-          // '<div style="font-size: 36px;white-space: nowrap">'+ context.data[0].name +'</div>' +
-          '</div>';
+        const iconConfig = iconList[data.dataType] || iconList.common;
+        data.image = iconConfig.image;
+        data.imageHover = iconConfig.imageHover;
+        data.size = iconConfig.size;
+        if (data.materia_name) {
+          data.name = data.materia_name;
+        }
+        if (data.dataType === 43) {
+          data.showName = true;
+        }
+        if (!data.id) {
+          data.id = nanoid(8);
+        }
+        data.lnglat = [data.longitude, data.latitude];
         const marker = new AMap.Marker({
         const marker = new AMap.Marker({
           position: [data.longitude, data.latitude],
           position: [data.longitude, data.latitude],
-          content: content,
+          content: getContent(data.image, data.size),
           anchor: 'bottom-center',
           anchor: 'bottom-center',
           offset: new AMap.Pixel(0, 0),
           offset: new AMap.Pixel(0, 0),
-          map: map,
-          layer: plotLayers['points2']
+          map: map
         });
         });
         marker.setExtData(data);
         marker.setExtData(data);
         marker.on('click', function (e) {
         marker.on('click', function (e) {
@@ -273,15 +299,13 @@ export function useAMap(options) {
           let index = 0;
           let index = 0;
           let index2 = 0;
           let index2 = 0;
           for (let i = 0; i < addPoints.length; i++) {
           for (let i = 0; i < addPoints.length; i++) {
-            if (addPoints[i].id === extData.id && addPoints[i].imageHover) {
-              addPoints[i].icon = addPoints[i].imageHover;
-              marker.setContent(content);
+            if (addPoints[i].id === extData.id) {
+              marker.setContent(getContent(data.imageHover, data.size));
               index++;
               index++;
             } else if (!!clickMarker) {
             } else if (!!clickMarker) {
               const extData2 = clickMarker.getExtData();
               const extData2 = clickMarker.getExtData();
               if (addPoints[i].id === extData2.id) {
               if (addPoints[i].id === extData2.id) {
-                addPoints[i].icon = addPoints[i].image;
-                clickMarker.setContent(content);
+                clickMarker.setContent(getContent(extData2.image, extData2.size));
                 index2++;
                 index2++;
               }
               }
             }
             }
@@ -289,14 +313,28 @@ export function useAMap(options) {
               break;
               break;
             }
             }
           }
           }
-          // addMarker(addPoints);
           clickMarker = e.target;
           clickMarker = e.target;
           options.onMarkerClick(extData);
           options.onMarkerClick(extData);
         });
         });
+        plotLayers['points2'].addOverlay(marker);
         addPoints.push(data);
         addPoints.push(data);
       }
       }
     });
     });
   };
   };
+  const getContent = (icon: string, size: number[]) => {
+    const content =
+      '<div style="display: flex;flex-direction: column;align-items: center;justify-content: center">' +
+      '<div style="background: url(' +
+      icon +
+      ') no-repeat; width: ' +
+      size[0] +
+      'px;height: ' +
+      size[1] +
+      'px;cursor: pointer; background-size: cover"></div>' +
+      // '<div style="font-size: 36px;white-space: nowrap">'+ context.data[0].name +'</div>' +
+      '</div>';
+    return content;
+  };
   // 清除所有标加
   // 清除所有标加
   const clearMarker = (id) => {
   const clearMarker = (id) => {
     if (!cluster || !markers[id]) return;
     if (!cluster || !markers[id]) return;
@@ -304,7 +342,10 @@ export function useAMap(options) {
     markers[id] = [];
     markers[id] = [];
   };
   };
   const clearMarker2 = (id) => {
   const clearMarker2 = (id) => {
-
+    if (!!plotLayers['points2']) {
+      plotLayers['points2'].clearOverlays();
+      addPoints = [];
+    }
   };
   };
 
 
   const handleHover = (extData, dataType) => {
   const handleHover = (extData, dataType) => {
@@ -337,14 +378,14 @@ export function useAMap(options) {
 
 
   // 显示信息框
   // 显示信息框
   let infoWindow;
   let infoWindow;
-  const showInfo = (content, position, isCustom) => {
+  const showInfo = (content, position, offsetY, isCustom) => {
     hideInfo();
     hideInfo();
     // 实例化InfoWindow
     // 实例化InfoWindow
     infoWindow = new AMap.InfoWindow({
     infoWindow = new AMap.InfoWindow({
       // 完全自定义
       // 完全自定义
       isCustom: isCustom,
       isCustom: isCustom,
       autoMove: false,
       autoMove: false,
-      offset: new AMap.Pixel(0, -20) // 信息窗体的偏移量
+      offset: new AMap.Pixel(0, offsetY ? offsetY : 0) // 信息窗体的偏移量
       // 可以根据需要设置其他InfoWindow的属性
       // 可以根据需要设置其他InfoWindow的属性
     });
     });
     const lnglat = new AMap.LngLat(position[0], position[1]);
     const lnglat = new AMap.LngLat(position[0], position[1]);
@@ -366,8 +407,9 @@ export function useAMap(options) {
         for (let i = 0; i < addPoints.length; i++) {
         for (let i = 0; i < addPoints.length; i++) {
           if (addPoints[i].id === extData.id) {
           if (addPoints[i].id === extData.id) {
             addPoints[i].icon = addPoints[i].image;
             addPoints[i].icon = addPoints[i].image;
+            clickMarker.setContent(getContent(addPoints[i].icon, addPoints[i].size));
             clickMarker = null;
             clickMarker = null;
-            addMarker(addPoints);
+            // addMarker(addPoints);
             break;
             break;
           }
           }
         }
         }
@@ -746,6 +788,7 @@ export function useAMap(options) {
     addMarker2,
     addMarker2,
     addSearchMarker,
     addSearchMarker,
     clearMarker,
     clearMarker,
+    clearMarker2,
     getScale,
     getScale,
     showInfo,
     showInfo,
     hideInfo,
     hideInfo,

+ 66 - 27
src/store/modules/map.ts

@@ -22,7 +22,7 @@ export const useMapStore = defineStore('map', () => {
   // 地图加载是否完成
   // 地图加载是否完成
   const mapLoaded = ref(false);
   const mapLoaded = ref(false);
   // 当前地图类型
   // 当前地图类型
-  const activeMap = ref<string>('satellite');
+  const activeMap = ref<string>('');
   // 是否显示边界遮罩
   // 是否显示边界遮罩
   const showMask = ref<boolean>(true);
   const showMask = ref<boolean>(true);
   // 高德地图类型
   // 高德地图类型
@@ -41,11 +41,10 @@ export const useMapStore = defineStore('map', () => {
   // 是否在选点
   // 是否在选点
   const isMapSelect = ref(false);
   const isMapSelect = ref(false);
   // 视频打点参数
   // 视频打点参数
-  const videoPointParams = ref({
-    // 触发请求
-    flag: false,
+  const pointParams = ref({
     // 选择条件
     // 选择条件
-    dict_value: ''
+    dict_value: [],
+    option: ''
   });
   });
   // 设置地图加载完成状态
   // 设置地图加载完成状态
   const setMapLoaded = (loaded: boolean) => {
   const setMapLoaded = (loaded: boolean) => {
@@ -72,27 +71,48 @@ export const useMapStore = defineStore('map', () => {
   const setIsMapSelect = (flag: boolean) => {
   const setIsMapSelect = (flag: boolean) => {
     isMapSelect.value = flag;
     isMapSelect.value = flag;
   };
   };
-  // 跳转界面时 初始化所有数据
-  const initData = () => {
-    activeMap.value = 'satellite';
-    showMask.value = true;
-    trackState.show = false;
-    trackState.data = [];
-    isMapSelect.value = false;
-    videoPointParams.value = {
-      flag: false,
-      dict_value: ''
-    };
-    menuState.value = {
-      showMenu: false,
-      activeIndex: 0,
-      menuData: []
-    };
-    initMenuData();
+  // 更多视频界面、设置视频打点标识
+  const setPointParams = (dictValue: string) => {
+    if (dictValue !== '573204ca-e814-11ef-a825-fa163e4bf12e' && !pointParams.value.dict_value.includes(dictValue)) {
+      // 还没选中,则进入选中
+      const data = menuData.value;
+      let shouldBreak = false;
+      for (let i = 0; i < data.length; i++) {
+        if (data[i].children && data[i].children.length > 0) {
+          const data2 = data[i].children;
+          for (let k = 0; k < data2.length; k++) {
+            if (data2[k].name === '图像资源') {
+              if (data2[k].children && data2[k].children.length > 0) {
+                const data3 = data2[k].children;
+                for (let z = 0; z < data3.length; z++) {
+                  // if (dictValue === data3[z].name) {
+                  if (dictValue === '7' && data3[z].name === '台风视频') {
+                    data3[z].checked = true;
+                    shouldBreak = true;
+                    pointParams.value.dict_value.push(dictValue);
+                    break;
+                  }
+                }
+                if (shouldBreak) {
+                  break;
+                }
+              }
+            }
+          }
+          if (shouldBreak) {
+            break;
+          }
+        }
+      }
+    }
   };
   };
-  // 设置视频打点标识
-  const setVideoPointParams = (data: any) => {
-    videoPointParams.value = data;
+  // 打点option变化
+  const setPointOption = () => {
+    const path = [];
+    pointType.value.forEach((item) => {
+      path.push(item.component);
+    });
+    pointParams.value.option = path.toString();
   };
   };
   // 初始化左侧菜单数据
   // 初始化左侧菜单数据
   const initMenuData = () => {
   const initMenuData = () => {
@@ -135,6 +155,24 @@ export const useMapStore = defineStore('map', () => {
       menuData: []
       menuData: []
     };
     };
   };
   };
+  // 跳转界面时 初始化所有数据
+  const initData = () => {
+    activeMap.value = 'satellite';
+    showMask.value = true;
+    trackState.show = false;
+    trackState.data = [];
+    isMapSelect.value = false;
+    pointParams.value = {
+      dict_value: [],
+      option: ''
+    };
+    menuState.value = {
+      showMenu: false,
+      activeIndex: 0,
+      menuData: []
+    };
+    initMenuData();
+  };
   return {
   return {
     mapState,
     mapState,
     menuData,
     menuData,
@@ -148,7 +186,7 @@ export const useMapStore = defineStore('map', () => {
     pointType,
     pointType,
     trackState,
     trackState,
     isMapSelect,
     isMapSelect,
-    videoPointParams,
+    pointParams,
     setMapLoaded,
     setMapLoaded,
     setZoom,
     setZoom,
     setActiveMap,
     setActiveMap,
@@ -156,7 +194,8 @@ export const useMapStore = defineStore('map', () => {
     setTrackState,
     setTrackState,
     setIsMapSelect,
     setIsMapSelect,
     initData,
     initData,
-    setVideoPointParams,
+    setPointParams,
+    setPointOption,
     handleCancelAllChecked
     handleCancelAllChecked
   };
   };
 });
 });

+ 7 - 5
src/types/video.d.ts

@@ -1,7 +1,9 @@
-interface LocationVideosParams {
+interface PointParams {
   zoom_level: number;
   zoom_level: number;
-  longitude_max: string;
-  longitude_min: string;
-  latitude_max: string;
-  latitude_min: string;
+  longitude_max: string | number;
+  longitude_min: string | number;
+  latitude_max: string | number;
+  latitude_min: string | number;
+  option?: string;
+  dict_value?: string;
 }
 }

+ 114 - 27
src/utils/olMap/olMap.ts

@@ -40,6 +40,7 @@ import * as turf from '@turf/turf';
 import { nanoid } from 'nanoid';
 import { nanoid } from 'nanoid';
 import carImg from '@/assets/images/car.png';
 import carImg from '@/assets/images/car.png';
 import { globalHeaders } from '@/utils/request';
 import { globalHeaders } from '@/utils/request';
+import { iconList } from '@/views/globalMap/data/mapData';
 
 
 const tk = 'a8df87f1695d224d2679aa805c1268d9';
 const tk = 'a8df87f1695d224d2679aa805c1268d9';
 const commonUrl = import.meta.env.VITE_APP_BASE_API2 + 'api/oneShare/proxyHandler/gd/';
 const commonUrl = import.meta.env.VITE_APP_BASE_API2 + 'api/oneShare/proxyHandler/gd/';
@@ -79,7 +80,6 @@ export class olMap {
     icon: '',
     icon: '',
     iconName: ''
     iconName: ''
   };
   };
-  private plot;
   private drawVector;
   private drawVector;
   private drawTool;
   private drawTool;
   private vectorLayer;
   private vectorLayer;
@@ -153,37 +153,35 @@ export class olMap {
     this.map.addInteraction(this.select);
     this.map.addInteraction(this.select);
     // 监听Select交互的select事件
     // 监听Select交互的select事件
     this.select.on('select', (event) => {
     this.select.on('select', (event) => {
-      const selectedFeatures = event.selected[0]; // 获取被选中的要素集合
-      const features = selectedFeatures.get('features');
-      if (selectedFeatures && !!features) {
-        const originalFeature = features[0];
-        const size = features.length;
-        if (size === 1) {
-          if (this.selectedFeature !== originalFeature) {
+      const feature = event.selected[0]; // 获取被选中的要素集合
+      const extData = feature.get('extData');
+      if (!!feature) {
+        if(['1', '2'].includes(extData.type)) {
+          // 多点位 单点
+          if (this.selectedFeature !== feature) {
             if (this.selectedFeature) {
             if (this.selectedFeature) {
               this.selectedFeature.set('icon', this.selectedFeature.get('image'));
               this.selectedFeature.set('icon', this.selectedFeature.get('image'));
             }
             }
-            this.selectedFeature = originalFeature;
-            const icon = originalFeature.get('imageHover');
-            const extData = originalFeature.get('extData');
-            originalFeature.set('icon', icon);
+            this.selectedFeature = feature;
+            feature.setStyle(
+              new Style({
+                image: new Icon({
+                  src: extData.imageHover,
+                  scale: extData.scale,
+                  anchor: [0.5, 0.5],
+                  anchorXUnits: 'fraction',
+                  anchorYUnits: 'fraction'
+                })
+              })
+            );
             options.onMarkerClick(extData);
             options.onMarkerClick(extData);
           }
           }
-        } else {
+        } else if (extData.type === '3') {
           // 聚合要素
           // 聚合要素
           this.select.getFeatures().clear();
           this.select.getFeatures().clear();
           const currentZoom = this.map.getView().getZoom();
           const currentZoom = this.map.getView().getZoom();
           this.map.getView().setZoom(currentZoom + 1);
           this.map.getView().setZoom(currentZoom + 1);
-          const points = [];
-          features.forEach((feature) => {
-            const geometry = feature.getGeometry(); // 获取要素的几何对象
-            const type = geometry.getType(); // 获取几何类型
-            if (type === 'Point') {
-              points.push(geometry.getCoordinates());
-            }
-          });
-          const newFeature = getPointsCenter(points);
-          this.map.getView().setCenter(newFeature.geometry.coordinates);
+          this.map.getView().setCenter(feature.geometry.coordinates);
           event.selected = [];
           event.selected = [];
         }
         }
       }
       }
@@ -204,7 +202,8 @@ export class olMap {
     this.vectorLayer = new VectorLayer({
     this.vectorLayer = new VectorLayer({
       source: new VectorSource({
       source: new VectorSource({
         features: []
         features: []
-      })
+      }),
+      zIndex: options.zIndex ? options.zIndex : 100
     });
     });
     this.map.addLayer(this.vectorLayer);
     this.map.addLayer(this.vectorLayer);
     if (typeof this.options.onLoadCompleted === 'function') {
     if (typeof this.options.onLoadCompleted === 'function') {
@@ -701,19 +700,107 @@ export class olMap {
     this.vectorLayer.setStyle(this.clusterStyle);
     this.vectorLayer.setStyle(this.clusterStyle);
     this.vectorLayer.setSource(clusterSource);
     this.vectorLayer.setSource(clusterSource);
   }
   }
+  addMarker2(obj) {
+    this.clearMarker2();
+    Object.keys(obj).forEach((key: string) => {
+      const data = obj[key];
+      if (data.type === '3') {
+        // 聚合点
+        const outerCircle = new CircleStyle({
+          radius: 20,
+          fill: new Fill({
+            color: 'rgba(79, 176, 206, 0.5)'
+          }),
+          stroke: new Stroke({
+            color: 'rgba(79, 176, 206, 1)'
+          })
+        });
+        const feature = new Feature({
+          // 必须是数字类型,字符串不识别
+          geometry: new Point([Number(data.longitude), Number(data.latitude)]),
+          name: data.name,
+          pointer: true,
+          extData: data
+        });
+
+        feature.setStyle(
+          new Style({
+            image: outerCircle,
+            text: new Text({
+              text: data.count.toString(),
+              font: '14px sans-serif',
+              fill: new Fill({
+                color: '#ffff'
+              })
+            })
+          })
+        );
+        this.vectorLayer.getSource().addFeature(feature);
+        this.markers.push(data);
+      } else {
+        // 单个点
+        const iconConfig = iconList[data.dataType] || iconList.common;
+        data.image = iconConfig.image;
+        data.imageHover = iconConfig.imageHover;
+        data.size = iconConfig.size;
+        if (data.materia_name) {
+          data.name = data.materia_name;
+        }
+        if (data.dataType === 43) {
+          data.showName = true;
+        }
+        if (!data.id) {
+          data.id = nanoid(8);
+        }
+        data.lnglat = [data.longitude, data.latitude];
+        const feature = new Feature({
+          // 必须是数字类型,字符串不识别
+          geometry: new Point([Number(data.longitude), Number(data.latitude)]),
+          name: data.name,
+          pointer: true,
+          extData: data
+        });
+        // 设置自定义属性
+        const img = new Image();
+        img.onload = () => {
+          // 图片加载完成后,可以访问其 width 和 height 属性
+          const scale = data.size[0] ? data.size[0] / img.width : 1;
+          data.scale = scale;
+          feature.set('extData', data);
+          feature.setStyle(
+            new Style({
+              image: new Icon({
+                src: data.image,
+                scale: scale,
+                anchor: [0.5, 0.5],
+                anchorXUnits: 'fraction',
+                anchorYUnits: 'fraction'
+              })
+            })
+          );
+          this.vectorLayer.getSource().addFeature(feature);
+        };
+        img.src = data.image; // 设置图片的 URL,触发加载
+        this.markers.push(data);
+      }
+    });
+  }
   // 清除所有标加
   // 清除所有标加
   clearMarker() {
   clearMarker() {
     if (!this.vectorLayer) return;
     if (!this.vectorLayer) return;
     this.vectorLayer.getSource().clear();
     this.vectorLayer.getSource().clear();
   }
   }
-
-  showInfo(content, position, isCustom) {
+  clearMarker2() {
+    if (!this.vectorLayer) return;
+    this.vectorLayer.getSource().clear();
+  }
+  showInfo(content, position, offsetY, isCustom) {
     this.hideInfo();
     this.hideInfo();
     if (!this.infoWindow) {
     if (!this.infoWindow) {
       this.infoWindow = new Overlay({
       this.infoWindow = new Overlay({
         element: content,
         element: content,
         positioning: 'bottom-center', // 你可以根据需要调整定位方式
         positioning: 'bottom-center', // 你可以根据需要调整定位方式
-        offset: [0, -10] // 偏移量,用于调整覆盖层相对于要素的位置
+        offset: [0, offsetY ? offsetY : 0] // 偏移量,用于调整覆盖层相对于要素的位置
       });
       });
     }
     }
     this.infoWindow.setPosition(position);
     this.infoWindow.setPosition(position);

+ 1 - 2
src/views/emergencyCommandMap/LeftSection/VideoMonitorEdit.vue

@@ -122,7 +122,6 @@ const mapStore = useMapStore();
 const emits = defineEmits(['update:modelValue']);
 const emits = defineEmits(['update:modelValue']);
 const proxy = getCurrentInstance()?.proxy;
 const proxy = getCurrentInstance()?.proxy;
 const { district_type2, video_type } = toRefs<any>(proxy?.useDict('district_type2', 'video_type'));
 const { district_type2, video_type } = toRefs<any>(proxy?.useDict('district_type2', 'video_type'));
-
 //查看更多数据
 //查看更多数据
 const queryFormRef = ref();
 const queryFormRef = ref();
 
 
@@ -168,7 +167,7 @@ const getList = (flag?: boolean) => {
   });
   });
 };
 };
 const getVideoInfoList = () => {
 const getVideoInfoList = () => {
-  // mapStore.setPointParams(queryParams.video_tag);
+  mapStore.setPointParams(queryParams.video_tag);
 };
 };
 const selectItem = (item) => {
 const selectItem = (item) => {
   if (editVideo.value) {
   if (editVideo.value) {

+ 10 - 5
src/views/globalMap/data/mapData.ts

@@ -22,11 +22,6 @@ export const iconList = {
     imageHover: getImageUrl('4_easy_flood_point_hover.png'),
     imageHover: getImageUrl('4_easy_flood_point_hover.png'),
     size: [60, 60]
     size: [60, 60]
   },
   },
-  'common': {
-    image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
-    imageHover: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
-    size: [19, 31]
-  },
   '5': {
   '5': {
     image: getImageUrl('5_school.png'),
     image: getImageUrl('5_school.png'),
     imageHover: getImageUrl('5_school_hover.png'),
     imageHover: getImageUrl('5_school_hover.png'),
@@ -221,6 +216,16 @@ export const iconList = {
     image: getImageUrl('45_elderly_care_institution.png'),
     image: getImageUrl('45_elderly_care_institution.png'),
     imageHover: getImageUrl('45_elderly_care_institution_hover.png'),
     imageHover: getImageUrl('45_elderly_care_institution_hover.png'),
     size: [40, 44]
     size: [40, 44]
+  },
+  'video': {
+    image: getImageUrl('31_lakes_video.png'),
+    imageHover: getImageUrl('31_lakes_video_hover.png'),
+    size: [40, 40]
+  },
+  'common': {
+    image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
+    imageHover: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
+    size: [19, 31]
   }
   }
 };
 };
 
 

+ 86 - 56
src/views/globalMap/index.vue

@@ -10,7 +10,7 @@
         @handle-show-track="handleShowTrack"
         @handle-show-track="handleShowTrack"
       />
       />
       <YztMap
       <YztMap
-        v-else
+        v-else-if="!!mapStore.activeMap"
         ref="map2Ref"
         ref="map2Ref"
         @handle-show-video="handleShowVideo"
         @handle-show-video="handleShowVideo"
         @handle-show-warehouse="handleShowWarehouse"
         @handle-show-warehouse="handleShowWarehouse"
@@ -61,12 +61,12 @@ import CommunicationSupport from './RightMenu/CommunicationSupport.vue';
 import GridPointRainfall from './RightMenu/GridPointRainfall.vue';
 import GridPointRainfall from './RightMenu/GridPointRainfall.vue';
 import EmergencyCrew from './RightMenu/EmergencyCrew.vue';
 import EmergencyCrew from './RightMenu/EmergencyCrew.vue';
 import useMapStore from '@/store/modules/map';
 import useMapStore from '@/store/modules/map';
-import { getPointInfo } from '@/api/globalMap';
 import { getVehicleTrajectory } from '@/api/globalMap/KeyVehicles';
 import { getVehicleTrajectory } from '@/api/globalMap/KeyVehicles';
 import { iconList } from './data/mapData';
 import { iconList } from './data/mapData';
-import { deepClone } from '@/utils';
+import { debounce, deepClone } from '@/utils';
 import { parseTime } from '@/utils/ruoyi';
 import { parseTime } from '@/utils/ruoyi';
-import { getLocationVideos } from '@/api/videoMonitor';
+import { getPointInfo2 } from '@/api/videoMonitor';
+import { toLonLat } from 'ol/proj';
 
 
 //dom元素
 //dom元素
 const rightMenuRef = ref(null);
 const rightMenuRef = ref(null);
@@ -89,7 +89,6 @@ const communicationSupport = reactive({
   show: false,
   show: false,
   data: {}
   data: {}
 });
 });
-let markerList = ref([]);
 let addMarkersTimer;
 let addMarkersTimer;
 // 添加打点
 // 添加打点
 const addMarkers = (item) => {
 const addMarkers = (item) => {
@@ -100,16 +99,12 @@ const addMarkers = (item) => {
       if (index > -1) {
       if (index > -1) {
         mapStore.pointType.splice(index, 1);
         mapStore.pointType.splice(index, 1);
       }
       }
-      if (mapStore.pointType && mapStore.pointType.length === 0) {
-        dom.clearMarker('point');
-        return;
-      }
     } else {
     } else {
       // 右侧图层分析状态
       // 右侧图层分析状态
       item.checked2 = true;
       item.checked2 = true;
       mapStore.pointType.push(item);
       mapStore.pointType.push(item);
     }
     }
-    addMarkersMethod();
+    mapStore.setPointOption();
   }
   }
 };
 };
 const adjustPoint = (data) => {
 const adjustPoint = (data) => {
@@ -137,25 +132,66 @@ const adjustPoint = (data) => {
   return data;
   return data;
 };
 };
 
 
-const addMarkersMethod = () => {
-  const dom = mapStore.isAMap ? mapRef.value : map2Ref.value;
-  const path = [];
-  mapStore.pointType.forEach((item) => {
-    path.push(item.component);
-  });
-  getPointInfo(path.toString()).then((res) => {
-    const data = res.data && res.data.list ? res.data?.list : [];
-    markerList.value = adjustPoint(data);
-    dom?.addMarker(data);
-  });
-  if (!path.includes('43') && addMarkersTimer) {
-    clearInterval(addMarkersTimer);
-    addMarkersTimer = null;
-  }
-  if (path.includes('43')) {
-    addMarkersTimer = setInterval(addMarkersMethod, 60 * 1000);
-  }
-};
+const addMarkersMethod = debounce(
+  function () {
+    if (!mapUtils || Object.keys(mapUtils).length === 0) return;
+    const queryParams: PointParams = {
+      zoom_level: mapStore.mapState.zoom,
+      latitude_min: '',
+      latitude_max: '',
+      longitude_min: '',
+      longitude_max: '',
+      // option: '22',
+      option: mapStore.pointParams.option,
+      // dict_value: 'slfh'
+      dict_value: mapStore.pointParams.dict_value.toString()
+    };
+    if (!queryParams.option && !queryParams.dict_value) {
+      return mapUtils.clearMarker2();
+    }
+    if (mapStore.isAMap) {
+      const AMap = mapUtils.getAMap();
+      const pixel = new AMap.Pixel(0, 0);
+      const size = mapRef.value.getMapDomSize();
+      const pixel2 = new AMap.Pixel(size[0], size[1]);
+      const lnglat = map.containerToLngLat(pixel);
+      const lnglat2 = map.containerToLngLat(pixel2);
+      queryParams.longitude_min = lnglat.lng;
+      queryParams.latitude_max = lnglat.lat;
+      queryParams.longitude_max = lnglat2.lng;
+      queryParams.latitude_min = lnglat2.lat;
+    } else {
+      // 获取地图容器尺寸
+      const size = map.getSize();
+      // 获取左上角和右下角像素坐标
+      const topLeftPixel = [0, 0];
+      const bottomRightPixel = [size[0], size[1]];
+      // 转换为地图投影坐标
+      const topLeftMap = map.getCoordinateFromPixel(topLeftPixel);
+      const bottomRightMap = map.getCoordinateFromPixel(bottomRightPixel);
+      // 转换为经纬度
+      const lnglat = toLonLat(topLeftMap, map.getView().getProjection());
+      const lnglat2 = toLonLat(bottomRightMap, map.getView().getProjection());
+      queryParams.longitude_min = lnglat[0];
+      queryParams.latitude_max = lnglat[1];
+      queryParams.longitude_max = lnglat2[0];
+      queryParams.latitude_min = lnglat2[1];
+    }
+    getPointInfo2(queryParams).then((res) => {
+      const data = res.data ? res.data : [];
+      mapUtils.addMarker2(data);
+    });
+    if (!mapStore.pointParams.option.includes('43') && addMarkersTimer) {
+      clearInterval(addMarkersTimer);
+      addMarkersTimer = null;
+    }
+    if (mapStore.pointParams.option.includes('43')) {
+      addMarkersTimer = setInterval(addMarkersMethod, 60 * 1000);
+    }
+  },
+  300,
+  false
+);
 // 跳转指定地点
 // 跳转指定地点
 const toAddress = (item) => {
 const toAddress = (item) => {
   const dom = mapStore.activeMap === 'imageMap' ? map2Ref.value : mapRef.value;
   const dom = mapStore.activeMap === 'imageMap' ? map2Ref.value : mapRef.value;
@@ -396,12 +432,19 @@ const initDataToPlay = (data) => {
   }
   }
 };
 };
 
 
+const mapMoveEnd = () => {
+  if (!mapStore.pointParams.dict_value && !mapStore.pointParams.option) return;
+  addMarkersMethod();
+};
 watch(
 watch(
   () => mapStore.mapLoaded,
   () => mapStore.mapLoaded,
   (loaded) => {
   (loaded) => {
     if (loaded) {
     if (loaded) {
       map = getMap();
       map = getMap();
       mapUtils = getMapUtils();
       mapUtils = getMapUtils();
+      if (!!map) {
+        map.on('moveend', mapMoveEnd);
+      }
     }
     }
   },
   },
   {
   {
@@ -410,34 +453,19 @@ watch(
 );
 );
 // 监听视频打点
 // 监听视频打点
 watch(
 watch(
-  () => mapStore.videoPointParams,
+  () => mapStore.pointParams,
   () => {
   () => {
-    if (!mapStore.videoPointParams.flag) return;
-    const queryParams = {
-      zoom_level: mapStore.mapState.zoom,
-      // zoom_level: 8,
-      latitude_min: '',
-      latitude_max: '',
-      longitude_min: '',
-      longitude_max: '',
-      dict_value: 'slfh'
-      // dict_value: mapStore.videoPointParams.dict_value
-    };
-    if (mapStore.isAMap) {
-      const AMap = mapUtils.getAMap();
-      const pixel = new AMap.Pixel(0, 0);
-      const size = mapRef.value.getMapDomSize();
-      const pixel2 = new AMap.Pixel(size[0], size[1]);
-      const lnglat = map.containerToLngLat(pixel);
-      const lnglat2 = map.containerToLngLat(pixel2);
-      queryParams.longitude_min = lnglat.lng;
-      queryParams.latitude_max = lnglat.lat;
-      queryParams.longitude_max = lnglat2.lng;
-      queryParams.latitude_min = lnglat2.lat;
-    }
-    getLocationVideos(queryParams).then((res) => {
-      mapUtils.addMarker2(res.data);
-    });
+    addMarkersMethod();
+  },
+  {
+    deep: true
+  }
+);
+// 监听层级变化
+watch(
+  () => mapStore.mapState.zoom,
+  () => {
+    mapMoveEnd();
   },
   },
   {
   {
     deep: true
     deep: true
@@ -450,8 +478,10 @@ onBeforeUnmount(() => {
   if (!!map) {
   if (!!map) {
     if (mapStore.isAMap) {
     if (mapStore.isAMap) {
       map.off('click', handleClickMap);
       map.off('click', handleClickMap);
+      map.off('moveend', handleClickMap);
     } else {
     } else {
       map.un('click', handleClickMap);
       map.un('click', handleClickMap);
+      map.un('moveend', handleClickMap);
     }
     }
     mapStore.setIsMapSelect(false);
     mapStore.setIsMapSelect(false);
   }
   }