Browse Source

Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	src/types/components.d.ts
yangyuxuan 3 months ago
parent
commit
92d242c0d2

+ 5 - 1
src/components/HKVideo/video-dialog.vue

@@ -8,6 +8,7 @@
     hide-footer
     height="500px"
     draggable
+    @close="handleClose"
     @changeTagsData="changeTagsData"
   >
     <div class="video-box">
@@ -24,7 +25,7 @@ interface Props {
 }
 
 const props = defineProps<Props>();
-const emits = defineEmits(['update:modelValue', 'changeTagsData']);
+const emits = defineEmits(['update:modelValue', 'changeTagsData', 'close']);
 const show = computed({
   get() {
     return props.modelValue;
@@ -36,6 +37,9 @@ const show = computed({
 const changeTagsData = (data: any) => {
   emits('changeTagsData', data);
 };
+const handleClose = () => {
+  emits('close');
+};
 </script>
 
 <style lang="scss" scoped>

+ 17 - 12
src/hooks/AMap/useAMap.ts

@@ -3,7 +3,7 @@ import { nanoid } from 'nanoid';
 import { deepClone, initDrag } from '@/utils';
 import { mergeGeoJsonPolygons, wgs_gcj_encrypts } from '@/utils/gisUtils';
 import carImg from '@/assets/images/car.png';
-import { getImageUrl, iconList } from '@/views/globalMap/data/mapData';
+import { iconList } from '@/views/globalMap/data/mapData';
 
 export function useAMap(options) {
   let AMap, map, scale, cluster;
@@ -415,20 +415,24 @@ export function useAMap(options) {
     map.setStatus({ zoomEnable: true });
     if (!!infoWindow) {
       infoWindow.close();
-      if (!!clickMarker && flag) {
-        const extData = clickMarker.getExtData ? clickMarker.getExtData() : clickMarker;
-        for (let i = 0; i < addPoints.length; i++) {
-          if (addPoints[i].id === extData.id) {
-            addPoints[i].icon = addPoints[i].image;
-            clickMarker.setContent(getContent(addPoints[i].icon, addPoints[i].size));
-            clickMarker = null;
-            // addMarker(addPoints);
-            break;
-          }
-        }
+      if (flag) {
+        clearHoverMarker();
       }
     }
   };
+  const clearHoverMarker = () => {
+    if (!!clickMarker) {
+      const extData = clickMarker.getExtData ? clickMarker.getExtData() : clickMarker;
+      for (let i = 0; i < addPoints.length; i++) {
+        if (addPoints[i].id === extData.id) {
+          addPoints[i].icon = addPoints[i].image;
+          clickMarker.setContent(getContent(addPoints[i].icon, addPoints[i].size));
+          clickMarker = null;
+          break;
+        }
+      }
+    }
+  }
   let maskPolygon;
   const creatMask = (options, name = '茂名市') => {
     new AMap.DistrictSearch({
@@ -805,6 +809,7 @@ export function useAMap(options) {
     getScale,
     showInfo,
     hideInfo,
+    clearHoverMarker,
     creatMask,
     removeMask,
     creatMask2,

+ 0 - 42
src/types/components.d.ts

@@ -24,50 +24,11 @@ declare module 'vue' {
     DistributionMap: typeof import('./../components/Map/YztMap/DistributionMap.vue')['default']
     DrawMap: typeof import('./../components/Map/YztMap/DrawMap.vue')['default']
     Editor: typeof import('./../components/Editor/index.vue')['default']
-    ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
-    ElBadge: typeof import('element-plus/es')['ElBadge']
     ElButton: typeof import('element-plus/es')['ElButton']
-    ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
-    ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
-    ElCol: typeof import('element-plus/es')['ElCol']
-    ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
-    ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
     ElDialog: typeof import('element-plus/es')['ElDialog']
-    ElDivider: typeof import('element-plus/es')['ElDivider']
-    ElDrawer: typeof import('element-plus/es')['ElDrawer']
-    ElDropdown: typeof import('element-plus/es')['ElDropdown']
-    ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
-    ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
-    ElEmpty: typeof import('element-plus/es')['ElEmpty']
-    ElForm: typeof import('element-plus/es')['ElForm']
-    ElFormItem: typeof import('element-plus/es')['ElFormItem']
-    ElIcon: typeof import('element-plus/es')['ElIcon']
-    ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
-    ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
-    ElMenu: typeof import('element-plus/es')['ElMenu']
-    ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
-    ElOption: typeof import('element-plus/es')['ElOption']
-    ElPagination: typeof import('element-plus/es')['ElPagination']
-    ElPopover: typeof import('element-plus/es')['ElPopover']
-    ElRow: typeof import('element-plus/es')['ElRow']
-    ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
-    ElSelect: typeof import('element-plus/es')['ElSelect']
-    ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
-    ElSkeletonItem: typeof import('element-plus/es')['ElSkeletonItem']
-    ElSlider: typeof import('element-plus/es')['ElSlider']
-    ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
-    ElSwitch: typeof import('element-plus/es')['ElSwitch']
-    ElTable: typeof import('element-plus/es')['ElTable']
-    ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
-    ElTag: typeof import('element-plus/es')['ElTag']
-    ElText: typeof import('element-plus/es')['ElText']
-    ElTimeline: typeof import('element-plus/es')['ElTimeline']
-    ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
-    ElTooltip: typeof import('element-plus/es')['ElTooltip']
     ElTree: typeof import('element-plus/es')['ElTree']
-    ElUpload: typeof import('element-plus/es')['ElUpload']
     ExcelEditor: typeof import('./../components/ExcelEditor/index.vue')['default']
     FileUpload: typeof import('./../components/FileUpload/index.vue')['default']
     FlvVideo: typeof import('./../components/FlvVideo/index.vue')['default']
@@ -114,7 +75,4 @@ declare module 'vue' {
     VideoTagEdit: typeof import('./../components/VideoTagEdit/index.vue')['default']
     YztMap: typeof import('./../components/Map/YztMap/index.vue')['default']
   }
-  export interface ComponentCustomProperties {
-    vLoading: typeof import('element-plus/es')['ElLoadingDirective']
-  }
 }

+ 7 - 1
src/utils/olMap/olMap.ts

@@ -623,6 +623,7 @@ export class olMap {
       }
     };
     const handleTouchMove = (e) => {
+      e.preventDefault(); // 阻止默认滚动
       if (!this.drawing) return;
       this.path.push(e.coordinate);
       // 移除旧的线段
@@ -988,7 +989,12 @@ export class olMap {
   hideInfo(flag?: boolean) {
     this.map.removeOverlay(this.infoWindow);
     this.infoWindow = null;
-    if (!!flag && this.clickMarker) {
+    if (!!flag) {
+      this.clearHoverMarker();
+    }
+  }
+  clearHoverMarker() {
+    if (this.clickMarker) {
       const selectData = this.clickMarker.get('extData');
       this.clickMarker.setStyle(
         new Style({

+ 1 - 1
src/utils/request.ts

@@ -134,7 +134,7 @@ service.interceptors.response.use(
         }).then(() => {
           isRelogin.show = false;
           useUserStore().logout().then(() => {
-              location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index';
+              location.href = import.meta.env.VITE_APP_CONTEXT_PATH + '#' + 'index';
             });
         }).catch(() => {
           isRelogin.show = false;

+ 48 - 40
src/views/globalMap/RightMenu/FixedPointAnalysis.vue

@@ -87,7 +87,7 @@
           >
             <div class="text-box1">
               <div :class="'tag tag' + index">{{ getTag(index) }}</div>
-              <!--              <div class="text1">{{ item.strategy }}</div>-->
+              <div class="text1">{{ item.strategy }}</div>
             </div>
             <div class="route-info">
               <div class="text-box2">
@@ -100,7 +100,7 @@
               <div class="line"></div>
               <div class="text-box2">
                 <i class="icon2" />
-                <div class="gradient-text2">{{ item.distance / 1000 }}</div>
+                <div class="gradient-text2">{{ item.distance }}</div>
                 <div class="text2">公里</div>
               </div>
             </div>
@@ -137,6 +137,7 @@ const getMap = inject('getMap');
 const getMapUtils = inject('getMapUtils');
 const mapStore = useMapStore();
 const amapKey = 'e45d4caa2bef3c84714a2ed9b1e27d98';
+const tkKey = 'a8df87f1695d224d2679aa805c1268d9';
 let inputRef = ref();
 let showAddress = ref(true);
 let routeData = ref([]);
@@ -186,18 +187,22 @@ const toSelect = () => {
   map.on('click', handleClickMap);
   mapStore.setIsMapSelect(true);
   showAddress.value = false;
+  dataList.value = [];
   routeData.value = [];
   clearMarker();
   clearLine();
 };
 const handleClickMap = (e) => {
+  let path;
   if (mapStore.isAMap) {
     map.off('click', handleClickMap);
+    path = [e.lnglat.getLng(), e.lnglat.getLat()];
   } else {
     map.un('click', handleClickMap);
+    path = e.coordinate;
   }
   mapStore.setIsMapSelect(false);
-  getAddress([e.lnglat.getLng(), e.lnglat.getLat()]);
+  getAddress(path);
 };
 const confirmSelect = () => {
   selectEvent(
@@ -247,50 +252,71 @@ const createMarks = (item, unFitView) => {
       width: 19,
       height: 31
     });
-    const feature = new Feature({
+    selectMarker = new Feature({
       geometry: new Point([item.longitude, item.latitude])
     });
-    feature.setStyle(
+    selectMarker.setStyle(
       new Style({
         image: icon
       })
     );
     const vectorLayer = mapUtils.getVectorLayer();
-    vectorLayer.getSource().addFeature(feature);
+    vectorLayer.getSource().addFeature(selectMarker);
     if (!unFitView) {
       map.getView().setCenter([item.longitude, item.latitude]);
     }
   }
 };
 let selectIndex = ref(-1);
+let startPath = ref([]);
+let endPath = ref([]);
 const handleRoutes = async (item) => {
   selectIndex.value = -1;
-  const lnglat = gcoord.transform([item.longitude, item.latitude], gcoord.WGS84, gcoord.GCJ02);
-  const lnglat2 = gcoord.transform([selectData.value.longitude, selectData.value.latitude], gcoord.WGS84, gcoord.GCJ02);
+  const lnglat = [Number(item.longitude), Number(item.latitude)];
+  const lnglat2 = [Number(selectData.value.longitude), Number(selectData.value.latitude)];
   const start = [lnglat[0].toFixed(6), lnglat[1].toFixed(6)];
   const end = [lnglat2[0].toFixed(6), lnglat2[1].toFixed(6)];
+  startPath.value = [Number(item.longitude), Number(item.latitude)];
+  endPath.value = [selectData.value.longitude, selectData.value.latitude];
   showAddress.value = true;
   routesAddress.value = item.address;
-  const url = `https://restapi.amap.com/v5/direction/driving?origin=${start.toString()}&destination=${end.toString()}&key=${amapKey}`;
-  const response = await fetch(url + '&strategy=32&show_fields=polyline,cost');
-
-  if (!!response.ok) {
-    const data = await response.json();
-    if (data.route && data.route.paths) {
-      data.route.paths.forEach((item) => {
-        item.duration = formatDate(item.cost?.duration);
+  const ststrategy = ['最快路线', '最短路线', '避开高速'];
+  routeData.value = [];
+  for (let i = 0; i < 3; i++) {
+    const url = `http://api.tianditu.gov.cn/drive?postStr={"orig":"${start}","dest":"${end}","style":"${i}"}&type=search&tk=${tkKey}`;
+    const response = await fetch(url);
+    if (response.status == 200) {
+      const parser = new DOMParser();
+      const xmlString = await response.text();
+      const xmlDoc = parser.parseFromString(xmlString, 'application/xml');
+      const routelatlon = xmlDoc.getElementsByTagName('routelatlon')[0].textContent;
+      const distance = xmlDoc.getElementsByTagName('distance')[0].textContent;
+      const duration = xmlDoc.getElementsByTagName('duration')[0].textContent;
+      const parameters = xmlDoc.getElementsByTagName('parameters')[0].textContent;
+      console.log(parameters);
+      const coordinates = routelatlon
+        .split(';') // 按分号分割为单个坐标点
+        .filter(Boolean) // 过滤空字符串(如末尾分号)
+        .map((pair) => {
+          const [lng, lat] = pair.split(',').map(Number); // 按逗号分割为经纬度
+          return [lng, lat]; // 返回二维数组格式
+        });
+      routeData.value.push({
+        duration: formatDate(Number(duration)),
+        distance: Number(distance).toFixed(3),
+        coordinates: coordinates,
+        strategy: ststrategy[i]
       });
-      routeData.value = data.route.paths;
       // 默认展示第一条
-      drawRoute(routeData.value[0], 0);
-    } else {
-      routeData.value = [];
+      if (i === 0) {
+        drawRoute(routeData.value[0], 0);
+      }
     }
   }
 };
 const drawRoute = (route, index) => {
   selectIndex.value = index;
-  const path = parseRouteToPath(route);
+  const path = route.coordinates;
   clearLine();
   if (mapStore.isAMap) {
     const icon1 = new AMap.Icon({
@@ -371,25 +397,6 @@ const drawRoute = (route, index) => {
     source.addFeature(endMarker);
   }
 };
-
-// 解析DrivingRoute对象,构造成AMap.Polyline的path参数需要的格式
-// DrivingResult对象结构参考文档 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DriveRoute
-const parseRouteToPath = (route) => {
-  var path = [];
-
-  for (var i = 0, l = route.steps.length; i < l; i++) {
-    var step = route.steps[i];
-
-    // 按分号分割字符串,得到一个包含经纬度对的数组
-    const coordinatesPairs = step.polyline.split(';');
-    // 将每个经纬度对进一步分割成经度和纬度,并转换为一个对象
-    path = coordinatesPairs.map((pair) => {
-      const [longitude, latitude] = pair.split(',');
-      return gcoord.transform([longitude, latitude], gcoord.GCJ02, gcoord.WGS84);
-    });
-  }
-  return path;
-};
 function formatDate(seconds: number) {
   // 将秒数转换为BigNumber
   const secondsBn = new BigNumber(seconds);
@@ -550,6 +557,7 @@ onMounted(() => {
 
 onUnmounted(() => {
   clearMarker();
+  clearLine();
 });
 </script>
 

+ 2 - 16
src/views/globalMap/RightMenu/LayerAnalysis.vue

@@ -91,20 +91,6 @@ const getColor = (checked, index) => {
   }
 };
 
-// 得到选中的标签的类型
-const getOption = (data, key = 'dataType') => {
-  if (!data) {
-    return;
-  }
-  let path = [];
-  data.forEach((item) => {
-    if (item.checked) {
-      path.push(item[key]);
-    }
-  });
-  return path.toString();
-};
-
 const handleClickLegend = (item) => {
   item.checked = !item.checked;
   const newSelected = {};
@@ -120,7 +106,7 @@ watch(
     if (!mapStore.pointType || mapStore.pointType.length === 0) {
       return;
     }
-    getCountPointInfo({ option: getOption(mapStore.pointType, 'component') }).then((res) => {
+    getCountPointInfo({ option: mapStore.pointParams.option }).then((res) => {
       res.data.list.forEach((item) => {
         item.checked = true;
       });
@@ -146,7 +132,7 @@ watch(
       return;
     }
     // 各区县
-    getCountPointInfoAreaList({ option: getOption(checkedData) }).then((res) => {
+    getCountPointInfoAreaList({ option: mapStore.pointParams.option }).then((res) => {
       const data = res.data.list;
       if (data.length > 0) {
         // 使用reduce方法合并相同area的num

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

@@ -51,7 +51,7 @@
       <!--应急人员详情-->
       <EmergencyCrew v-if="showPeople" v-model="showPeople" :id="teamId" />
       <!--视频详情-->
-      <VideoDialog v-if="showVideoDetail" v-model="showVideoDetail" :videoMonitorData="videoDetail" />
+      <VideoDialog v-if="showVideoDetail" v-model="showVideoDetail" :videoMonitorData="videoDetail" @close="handleVideoDetailClose" />
     </div>
   </div>
 </template>
@@ -295,7 +295,7 @@ const handleHideCommunicationSupport = () => {
 const findChecked = (dataList, name) => {
   let index = 0;
   dataList.forEach((item) => {
-    if (item.name !== name && !item.isVideo && item.path === '2' && !!item.checked) {
+    if (!['易涝隐患点', '省政务无人机', '铁塔运行监测', '通讯保障', '救援队伍', '重点车辆', '附近视频'].includes(item.name) && item.name !== name && !item.isVideo && item.path === '2' && !!item.checked) {
       index++;
     }
     if (item.children && item.children.length > 0) {
@@ -413,6 +413,10 @@ const handleShowVideo2 = (data, flag) => {
   videoDetail.value = data;
   showVideoDetail.value = true;
 };
+const handleVideoDetailClose = () => {
+  videoDetail.value = [];
+  mapUtils.clearHoverMarker();
+};
 const handleClickMap = (e) => {
   if (mapStore.isAMap) {
     location.value = [e.lnglat.lng, e.lnglat.lat];
@@ -499,7 +503,7 @@ watch(
     if (loaded) {
       map = getMap();
       mapUtils = getMapUtils();
-       if (!!map && Object.keys(map).length !== 0) {
+      if (!!map && Object.keys(map).length !== 0) {
         map.on('moveend', mapMoveEnd);
       }
       if (eventId.value) {
@@ -547,7 +551,7 @@ watch(
     if (mapStore.updateMenu && !!mapStore.updateMenu.name) {
       // 视频修改的值,需要显示左侧辅助分析、显示右侧菜单
       leftMenuRef.value.setMenuIndex(2);
-      rightMenuRef.value.updateMenu('1', mapStore.updateMenu);
+      // rightMenuRef.value.updateMenu('1', mapStore.updateMenu);
       mapStore.setUpdateMenu({});
     }
     addMarkersMethod();