瀏覽代碼

定点分析

Hwf 6 月之前
父節點
當前提交
445040d0b5

二進制
src/assets/images/map/base.png


二進制
src/assets/images/map/box1.png


二進制
src/assets/images/map/decoration1.png


二進制
src/assets/images/map/layer.png


二進制
src/assets/images/map/position.png


二進制
src/assets/images/map/position2.png


二進制
src/assets/images/map/video.png


+ 22 - 17
src/components/Map/index.vue

@@ -89,26 +89,12 @@ let AMap, map, scale;
 // 鼠标绘制工具
 const drawTool = useDrawTool();
 // 初始化地图
-const {
-  getAMap,
-  getMap,
-  switchMap,
-  addMarker,
-  addSearchMarker,
-  clearMarker,
-  getMarkers,
-  getScale,
-  showInfo,
-  hideInfo,
-  handleHover,
-  creatMask,
-  trackPlayback
-} = useAMap({
+const mapUtils = useAMap({
   key: '30d3d8448efd68cb0b284549fd41adcf', // 申请好的Web端开发者Key,首次调用 load 时必填
   version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
   pitch: mapState.isThreeDimensional ? 45 : 0,
   zoom: mapState.zoom,
-  // center: [],
+  center: [mapState.center[0], mapState.center[1]],
   dragEnable: true,
   scrollWheel: true,
   showScale: true,
@@ -184,6 +170,21 @@ const {
     }
   }
 });
+const {
+  getAMap,
+  getMap,
+  switchMap,
+  addMarker,
+  addSearchMarker,
+  clearMarker,
+  getMarkers,
+  getScale,
+  showInfo,
+  hideInfo,
+  handleHover,
+  creatMask,
+  trackPlayback
+} = { ...mapUtils };
 const handlePointDetails = (data) => {
   let methodList = {
     '1': getEmergencyExpertDetails,
@@ -428,7 +429,11 @@ const setCenter = (item) => {
   map.setCenter([item.longitude, item.latitude]);
 };
 
-defineExpose({ addMarker, addSearchMarker, setCenter, getMarkers, clearMarker, getMap, drawTool, handleHover, trackPlayback });
+const getMapUtils = () => {
+  return mapUtils;
+};
+
+defineExpose({ addMarker, addSearchMarker, setCenter, getMarkers, clearMarker, getMap, drawTool, handleHover, trackPlayback, getMapUtils });
 const handleResize = () => {
   const containerWidth = !!containerScale ? containerRef.value.clientWidth * containerScale().scaleX : 1;
   const containerHeight = !!containerScale ? containerRef.value.clientHeight * containerScale().scaleY : 1;

+ 18 - 6
src/views/comprehensiveGuarantee/electronicDisasterMapManage/index.vue

@@ -34,7 +34,7 @@
     </div>
     <div class="right-section">
       <div class="tag-box" @click="showRight = !showRight">
-<!--        <i class="icon" />-->
+        <!--        <i class="icon" />-->
         <div class="text1">定点分析>></div>
       </div>
       <div v-show="showRight" class="right-box">
@@ -44,6 +44,7 @@
               <i class="icon-position2" />
               <div class="text1" :title="selectData.event_title">{{ selectData.event_title }}</div>
             </div>
+            <div class="common-btn-primary4" @click="toSelect">重新定位</div>
           </div>
           <div v-else class="search-box">
             <div class="text-box">
@@ -125,7 +126,6 @@
             </div>
           </div>
         </div>
-
       </div>
     </div>
   </div>
@@ -329,6 +329,7 @@ const selectEvent = (item, unFitView) => {
   if (!unFitView) {
     map.setFitView([selectMarker]);
   }
+  getList();
 };
 
 const handleRoutes = (item) => {
@@ -677,12 +678,14 @@ const handleClick = (item) => {
 // 搜索列表
 const getList = () => {
   const params = {
+    longitude: selectData.value.longitude,
+    latitude: selectData.value.latitude,
     dataType: queryParams.dataType,
     keyword: queryParams.keyword,
-    distance: ''
+    radius: '30'
   };
-  if (checked1.value) {
-    params.distance = distance.value;
+  if (!!checked1.value) {
+    params.radius = distance.value;
   }
   getEmergencyRescuePointInfoList(params).then((res) => {
     dataList.value = res.rows;
@@ -1017,6 +1020,7 @@ onUnmounted(() => {
           background: #1f2c4e;
           padding: 5px;
           margin-top: 6px;
+          cursor: pointer;
           .text-box1 {
             display: flex;
             .tag0 {
@@ -1056,7 +1060,6 @@ onUnmounted(() => {
             .text-box2 {
               display: flex;
               align-items: center;
-              min-width: 150px;
               .icon1 {
                 display: inline-block;
                 width: 14px;
@@ -1065,6 +1068,14 @@ onUnmounted(() => {
                 background-size: 100% 100%;
                 margin-right: 5px;
               }
+              .icon2 {
+                display: inline-block;
+                width: 13px;
+                height: 16px;
+                background: url('@/assets/images/electronicDisasterMapManage/icon4.png') no-repeat;
+                background-size: 100% 100%;
+                margin-right: 5px;
+              }
               .gradient-text2 {
                 font-size: 16px;
                 font-family: BEBAS-1;
@@ -1079,6 +1090,7 @@ onUnmounted(() => {
               width: 1px;
               height: 10px;
               background-color: #5a6885;
+              margin: 0 20px;
             }
           }
         }

+ 2 - 2
src/views/globalMap/LeftMenu.vue

@@ -203,9 +203,9 @@ defineExpose({ setMenuChange });
     position: absolute;
     top: 30px;
     left: 0;
-    background-color: #0d1d4e;
-    border: 1px solid #2c81ff;
     width: 260px;
+    background: url('@/assets/images/map/box1.png') no-repeat;
+    background-size: 100% 100%;
     color: #00e8ff;
     font-size: 24px;
     z-index: 9;

+ 600 - 25
src/views/globalMap/RightMenu/FixedPointAnalysis.vue

@@ -1,41 +1,616 @@
 <template>
-  <Dialog custom-show title="定点分析" :height="'1000px'" hide-footer @close="handleClose"></Dialog>
-</template>
+  <div class="menu-content">
+    <div class="gradient-text common-dialog-title2">定点分析</div>
+    <div class="scroll-box">
+      <div v-if="!tempState.address" class="search-box">
+        <div class="text-box">
+          <i class="icon-position2" />
+          <div class="text1" :title="selectData.event_title">{{ selectData.event_title }}</div>
+        </div>
+        <div class="common-btn-primary3" @click="toSelect">定点选取</div>
+      </div>
+      <div v-else class="search-box">
+        <div class="text-box">
+          <i class="icon-position2" />
+          <div class="text1" :title="tempState.address">{{ tempState.address }}</div>
+        </div>
+        <div class="common-btn-primary4" @click="confirmSelect">确定定位</div>
+      </div>
+      <div class="search-item">
+        <div class="text1">选择救灾资源:</div>
+        <el-select
+          v-model="queryParams.dataType"
+          class="custom-select select-box"
+          placeholder="请选择"
+          popper-class="custom-select-popper"
+          :teleported="false"
+        >
+          <el-option v-for="item in disaster_relief_material" :key="item.value" :label="item.label" :value="item.value"></el-option>
+        </el-select>
+      </div>
+      <div class="search-item2">
+        <el-input v-model="queryParams.keyword" class="custom-input2" placeholder="请输入关键字搜索" />
+        <div class="common-btn-primary4" @click="getList">搜索</div>
+      </div>
+      <div class="search-item3">
+        <el-checkbox v-model="checked1">自定义距离</el-checkbox>
+        <el-input v-model="distance" class="custom-input2" placeholder="自定义距离(公里)" />
+        <div class="common-btn3" @click="getList">确定</div>
+      </div>
 
-<script lang="ts" setup name="Fireproofing">
+      <div class="list2">
+        <div class="text-box1">
+          总数:
+          <div class="gradient-text2">{{ total }}</div>
+          个
+        </div>
+        <div class="list-content">
+          <div v-for="(item, index) in dataList" :key="index" class="list-item">
+            <div class="text-box2">
+              <div class="text2">{{ item.name }}</div>
+              <div class="text3">{{ item.address }}</div>
+            </div>
+            <div class="operate" @click="handleRoutes(item)">
+              <i class="icon2" />
+              路线
+            </div>
+          </div>
+        </div>
+      </div>
+      <div v-show="!!routeData && routeData.length > 0" class="route-box">
+        <div class="route-item1">
+          <i class="icon-position3" />
+          <div class="text1">路线始点:</div>
+          <div class="text2" :title="routesAddress">{{ routesAddress }}</div>
+          <i class="icon-close2" @click="showAddress = false" />
+        </div>
+        <div class="route-list">
+          <div v-for="(item, index) in routeData" :key="index" class="route-item2" @click="drawRoute(item)">
+            <div class="text-box1">
+              <div :class="'tag' + index">{{ getTag(index) }}</div>
+              <div class="text1">{{ item.policy }}</div>
+            </div>
+            <div class="route-info">
+              <div class="text-box2">
+                <i class="icon1" />
+                <div class="gradient-text2">{{ item.date[0] }}</div>
+                <div class="text2">小时</div>
+                <div class="gradient-text2">{{ item.date[1] }}</div>
+                <div class="text2">分钟</div>
+              </div>
+              <div class="line"></div>
+              <div class="text-box2">
+                <i class="icon2" />
+                <div class="gradient-text2">{{ item.distance / 1000 }}</div>
+                <div class="text2">公里</div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
 
-import AMapLoader from '@amap/amap-jsapi-loader';
-import { getRainfallCode, getRainfallInfo } from '@/api/globalMap/gridPointRainfall';
+<script lang="ts" setup name="FixedPointAnalysis">
+import BigNumber from 'bignumber.js';
+import { getEmergencyRescuePointInfoList } from '@/api/globalMap';
 
 interface Props {
   modelValue: boolean;
   location?: string | number[];
 }
 const props = withDefaults(defineProps<Props>(), {});
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { emergency_resource, disaster_relief_material } = toRefs<any>(proxy?.useDict('emergency_resource', 'disaster_relief_material'));
 const emits = defineEmits(['update:modelValue']);
-let address = ref('');
-const handleClose = () => {
-  emits('update:modelValue', false);
+let getMapUtils = inject('getMapUtils');
+let showAddress = ref(true);
+let routeData = ref([]);
+let routeLine, startMarker, endMarker;
+let routesAddress = ref('');
+let AMap, map, driving, geocoder;
+let eventList = ref([]);
+let selectData = ref({
+  event_title: '',
+  longitude: '',
+  latitude: ''
+});
+let selectMarker;
+let tempState = reactive({
+  address: '',
+  longitude: '',
+  latitude: ''
+});
+let checked1 = ref(false);
+let distance = ref('');
+let queryParams = reactive({
+  keyword: '',
+  dataType: '2'
+});
+let total = ref(0);
+let dataList = ref([]);
+const toSelect = () => {
+  map.on('click', handleClickMap);
+};
+const handleClickMap = (e) => {
+  map.off('click', handleClickMap);
+  tempState.longitude = e.lnglat.getLng();
+  tempState.latitude = e.lnglat.getLat();
+  geocoder.getAddress([tempState.longitude, tempState.latitude], (status, result) => {
+    if (status === 'complete' && result.info === 'OK') {
+      tempState.address = result.regeocode.formattedAddress;
+    }
+  });
+};
+const confirmSelect = () => {
+  selectEvent(
+    {
+      event_title: tempState.address,
+      longitude: tempState.longitude,
+      latitude: tempState.latitude
+    },
+    true
+  );
+};
+// 选中事件
+const selectEvent = (item, unFitView) => {
+  eventList.value.forEach((item2) => {
+    if (item2.event_id === item.event_id) {
+      item2.checked = true;
+    } else {
+      item2.checked = false;
+    }
+  });
+  selectData.value = item;
+  tempState.address = '';
+  tempState.longitude = '';
+  tempState.latitude = '';
+  if (!!selectMarker) {
+    selectMarker.setMap(null);
+    selectMarker = null;
+  }
+  // 以 icon URL 的形式创建一个途经点
+  const icon = new AMap.Icon({
+    size: new AMap.Size(19, 31),
+    image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png'
+  });
+  selectMarker = new AMap.Marker({
+    position: new AMap.LngLat(item.longitude, item.latitude),
+    icon: icon,
+    offset: new AMap.Pixel(-13, -30)
+  });
+  selectMarker.setMap(map);
+  if (!unFitView) {
+    map.setFitView([selectMarker]);
+  }
+  getList();
+};
+
+const handleRoutes = (item) => {
+  const start = [item.longitude, item.latitude];
+  const end = [selectData.value.longitude, selectData.value.latitude];
+  showAddress.value = true;
+  routesAddress.value = item.address;
+  calculateRoutes(start, end, 0);
+};
+// 计算并展示三条路线
+const calculateRoutes = (start, end, index) => {
+  if (index >= 3) {
+    return;
+  }
+  // 不同的策略或参数来生成不同的路线
+  const policyMap = [
+    AMap.DrivingPolicy.LEAST_TIME, // 最短时间
+    AMap.DrivingPolicy.LEAST_DISTANCE, // 最短距离
+    AMap.DrivingPolicy.LEAST_FEE // 最少费用
+  ];
+  driving.setPolicy(policyMap[index]);
+
+  driving.search(new AMap.LngLat(start[0], start[1]), new AMap.LngLat(end[0], end[1]), function (status, result) {
+    if (status === 'complete' && result.info === 'OK') {
+      const route = result.routes[0];
+      if (index === 0) {
+        routeData.value = [];
+      }
+      route.date = formatDate(route.time);
+      routeData.value.push(route);
+    }
+
+    // 计算下一条路线
+    calculateRoutes(start, end, index + 1);
+  });
+};
+const drawRoute = (route) => {
+  const path = parseRouteToPath(route);
+  if (!!startMarker) {
+    map.remove(startMarker);
+    startMarker = null;
+  }
+  if (!!endMarker) {
+    map.remove(endMarker);
+    endMarker = null;
+  }
+  if (!!routeLine) {
+    routeLine.setMap(null);
+    routeLine = null;
+  }
+  const icon1 = new AMap.Icon({
+    size: new AMap.Size(19, 31),
+    image: 'https://webapi.amap.com/theme/v1.3/markers/n/start.png'
+  });
+  const icon2 = new AMap.Icon({
+    size: new AMap.Size(19, 31),
+    image: 'https://webapi.amap.com/theme/v1.3/markers/n/end.png'
+  });
+  startMarker = new AMap.Marker({
+    position: path[0],
+    icon: icon1,
+    offset: new AMap.Pixel(-13, -30),
+    map: map
+  });
+
+  endMarker = new AMap.Marker({
+    position: path[path.length - 1],
+    icon: icon2,
+    offset: new AMap.Pixel(-13, -30),
+    map: map
+  });
+  routeLine = new AMap.Polyline({
+    path: path,
+    isOutline: true,
+    outlineColor: '#ffeeee',
+    borderWeight: 2,
+    strokeWeight: 5,
+    strokeColor: '#0091ff',
+    lineJoin: 'round'
+  });
+  routeLine.setMap(map);
+
+  // 调整视野达到最佳显示区域
+  map.setFitView([startMarker, endMarker, routeLine]);
+};
+
+// 解析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];
+
+    for (var j = 0, n = step.path.length; j < n; j++) {
+      path.push(step.path[j]);
+    }
+  }
+
+  return path;
+};
+function formatDate(seconds: number) {
+  // 将秒数转换为BigNumber
+  const secondsBn = new BigNumber(seconds);
+
+  // 计算小时数
+  const hoursBn = secondsBn.dividedBy(3600).integerValue(BigNumber.ROUND_DOWN);
+  // 计算剩余的秒数,然后转换为分钟数
+  const remainingSecondsBn = secondsBn.minus(hoursBn.times(3600));
+  const minutesBn = remainingSecondsBn.dividedBy(60).integerValue();
+
+  // 将BigNumber转换为字符串,并使用padStart添加前导零
+  const hours = hoursBn.toString();
+
+  const minutes = minutesBn.toString();
+
+  // 返回包含小时和分钟的数组
+  return [hours, minutes];
+}
+const getTag = (index) => {
+  let tag = '路线' + index;
+  if (index === 0) {
+    tag = '路线A';
+  } else if (index === 1) {
+    tag = '路线B';
+  } else if (index === 2) {
+    tag = '路线C';
+  }
+  return tag;
+};
+// 搜索列表
+const getList = () => {
+  const params = {
+    longitude: selectData.value.longitude,
+    latitude: selectData.value.latitude,
+    dataType: queryParams.dataType,
+    keyword: queryParams.keyword,
+    radius: '30'
+  };
+  if (!!checked1.value) {
+    params.radius = distance.value;
+  }
+  getEmergencyRescuePointInfoList(params).then((res) => {
+    dataList.value = res.rows;
+    total.value = res.total;
+  });
 };
-let AMap, geocoder;
 onMounted(() => {
-  AMapLoader.load({
-    key: '30d3d8448efd68cb0b284549fd41adcf', // 申请好的Web端开发者Key,首次调用 load 时必填
-    version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
-    plugins: ['AMap.PlaceSearch', 'AMap.ContextMenu', 'AMap.PolygonEditor', 'AMap.Geocoder'] // 插件列表
-  }).then((res) => {
-    AMap = res;
-    geocoder = new AMap.Geocoder({
-      // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
-      city: '010'
-    });
-    geocoder.getAddress(props.location, (status, result) => {
-      if (status === 'complete' && result.info === 'OK') {
-        address.value = result.regeocode.formattedAddress;
-      }
-    });
+  AMap = getMapUtils().getAMap();
+  map = getMapUtils().getMap();
+  geocoder = new AMap.Geocoder({
+    // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
+    city: '010'
+  });
+  tempState.longitude = props.location[0];
+  tempState.latitude = props.location[1];
+  geocoder.getAddress(props.location, (status, result) => {
+    if (status === 'complete' && result.info === 'OK') {
+      tempState.address = result.regeocode.formattedAddress;
+    }
   });
+  //构造路线导航类
+  driving = new AMap.Driving({});
 });
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.menu-content {
+  width: 573px;
+  height: 764px;
+  background: url('@/assets/images/map/rightMenu/layerAnalysis/dialog.png') no-repeat;
+  background-size: 100% 100%;
+  padding: 60px 10px 10px 15px;
+  font-size: 14px;
+  position: relative;
+  color: #fff;
+  .scroll-box {
+    width: 100%;
+    height: 100%;
+    position: relative;
+    overflow-y: auto;
+  }
+  .search-box {
+    width: 497px;
+    height: 75px;
+    background: url('@/assets/images/electronicDisasterMapManage/box6.png') no-repeat;
+    background-size: 100% 100%;
+    padding: 0 10px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .text-box {
+      display: flex;
+      align-items: center;
+      .icon-position2 {
+        flex-shrink: 0;
+        display: inline-block;
+        width: 65px;
+        height: 71px;
+        background: url('@/assets/images/electronicDisasterMapManage/position2.png') no-repeat;
+        background-size: 100% 100%;
+      }
+      .text1 {
+        margin-left: 10px;
+        font-size: 14px;
+        color: #f7f8fb;
+        display: -webkit-box;
+        -webkit-box-orient: vertical;
+        -webkit-line-clamp: 2;
+        overflow: hidden;
+        text-overflow: ellipsis;
+      }
+    }
+    .common-btn-primary4 {
+      flex-shrink: 0;
+    }
+  }
+  .search-item {
+    margin: 6px 0 3px;
+    display: flex;
+    align-items: center;
+    .text1 {
+      font-size: 14px;
+      flex-shrink: 0;
+    }
+    .custom-select {
+      flex: 1;
+    }
+  }
+  .search-item2 {
+    margin: 3px 0;
+    display: flex;
+    align-items: center;
+    .custom-input2 {
+      flex: 1;
+    }
+    .common-btn-primary4 {
+      flex-shrink: 0;
+      margin-right: -12px;
+    }
+  }
+  .search-item3 {
+    margin: 3px 0;
+    display: flex;
+    align-items: center;
+    .el-checkbox {
+      color: #8fa8be;
+      margin-right: 10px;
+      flex-shrink: 0;
+    }
+    .custom-input2 {
+      flex: 1;
+      margin-right: 10px;
+    }
+    .common-btn3 {
+      flex-shrink: 0;
+    }
+  }
+  .list2 {
+    padding: 8px;
+    border-radius: 2px;
+    background: #1c356d;
+    color: #ebf5f7;
+    .text-box1 {
+      font-size: 14px;
+      .gradient-text2 {
+        font-size: 18px;
+        font-family: BEBAS-1;
+      }
+    }
+    .list-content {
+      height: 210px;
+      overflow-y: auto;
+      .list-item {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 7px 0;
+        border-bottom: 1px solid #4574d5;
+        .text-box2 {
+          .text2 {
+            font-size: 14px;
+            line-height: 28px;
+          }
+          .text3 {
+            font-size: 13px;
+            line-height: 26px;
+          }
+        }
+        .operate {
+          flex-shrink: 0;
+          display: flex;
+          align-items: center;
+          font-size: 14px;
+          color: transparent;
+          background-image: linear-gradient(to bottom, #ffffff 25%, #2b72d6 100%);
+          -webkit-background-clip: text;
+          background-clip: text;
+          cursor: pointer;
+          .icon2 {
+            display: inline-block;
+            width: 33px;
+            height: 33px;
+            background: url('@/assets/images/electronicDisasterMapManage/icon2.png') no-repeat;
+            background-size: 100% 100%;
+          }
+        }
+      }
+    }
+  }
+  .route-box {
+    .route-item1 {
+      display: flex;
+      align-items: center;
+      background-color: #1d366e;
+      padding: 0 5px;
+      margin-top: 6px;
+      .icon-position3 {
+        display: inline-block;
+        width: 23px;
+        height: 26px;
+        background: url('@/assets/images/electronicDisasterMapManage/position3.png') no-repeat;
+        background-size: 100% 100%;
+        flex-shrink: 0;
+      }
+      .text1 {
+        font-size: 14px;
+        color: #cfe4fe;
+        flex-shrink: 0;
+      }
+      .text2 {
+        font-size: 14px;
+        color: #f1fbff;
+        flex: 1;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+      .icon-close2 {
+        flex-shrink: 0;
+        width: 30px;
+        height: 30px;
+        background: url('@/assets/images/electronicDisasterMapManage/close.png') no-repeat;
+        background-size: 100% 100%;
+        margin-left: 5px;
+      }
+    }
+    .route-item2 {
+      width: 100%;
+      background: #1f2c4e;
+      padding: 5px;
+      margin-top: 6px;
+      cursor: pointer;
+      .text-box1 {
+        display: flex;
+        .tag0 {
+          color: #fff;
+          background-color: #e65d63;
+          border-radius: 10px;
+          padding: 2px 6px;
+          font-size: 12px;
+        }
+        .tag1 {
+          color: #fff;
+          background-color: #f0b13c;
+          border-radius: 10px;
+          padding: 2px 6px;
+          font-size: 12px;
+        }
+        .tag2 {
+          color: #fff;
+          background-color: #6bc26b;
+          border-radius: 10px;
+          padding: 2px 6px;
+          font-size: 12px;
+        }
+        .text1 {
+          font-size: 14px;
+          margin-left: 5px;
+        }
+      }
+      .route-info {
+        display: flex;
+        background-color: #2b3858;
+        border: 1px solid #2e5174;
+        padding: 3px 5px;
+        margin-top: 10px;
+        display: flex;
+        align-items: center;
+        .text-box2 {
+          display: flex;
+          align-items: center;
+          .icon1 {
+            display: inline-block;
+            width: 14px;
+            height: 13px;
+            background: url('@/assets/images/electronicDisasterMapManage/icon3.png') no-repeat;
+            background-size: 100% 100%;
+            margin-right: 5px;
+          }
+          .icon2 {
+            display: inline-block;
+            width: 13px;
+            height: 16px;
+            background: url('@/assets/images/electronicDisasterMapManage/icon4.png') no-repeat;
+            background-size: 100% 100%;
+            margin-right: 5px;
+          }
+          .gradient-text2 {
+            font-size: 16px;
+            font-family: BEBAS-1;
+            margin: 0 3px;
+          }
+          .text2 {
+            font-size: 14px;
+            color: #95a9c1;
+          }
+        }
+        .line {
+          width: 1px;
+          height: 10px;
+          background-color: #5a6885;
+          margin: 0 20px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 3 - 7
src/views/globalMap/RightMenu/index.vue

@@ -186,6 +186,9 @@ const updateMenu = (type, menu, location?: any) => {
       if (index === -1) {
         menuState.menuData.push(menu);
       }
+    } else if (menu.name === '定点分析') {
+      menuState.menuData.push(menu);
+      location2.value = location;
     } else {
       menuState.menuData.push(menu);
     }
@@ -196,13 +199,6 @@ const updateMenu = (type, menu, location?: any) => {
       menuState.menuData.splice(index, 1);
       menuState.activeIndex = 0;
     }
-  } else if (type === '4') {
-    let index = menuState.menuData.findIndex((item) => item.name === menu.name);
-    if (index > -1) {
-      menuState.menuData.splice(index, 1);
-      menuState.activeIndex = 0;
-    }
-    location2.value = location;
   }
 };
 const getMenuState = () => {

+ 20 - 6
src/views/globalMap/index.vue

@@ -157,11 +157,15 @@ const clickMenu = (item, dataList) => {
     communicationSupport.show = !communicationSupport.show;
     communicationSupport.data = item;
   } else if (item.path === '4') {
-    tempMenu.value = item;
-    // 附近视频
-    map = getMap();
-    //为地图注册click事件获取鼠标点击出的经纬度坐标
-    map.on('click', handleClickMap);
+    if (!item.checked) {
+      rightMenuRef.value.updateMenu('2', item);
+    } else {
+      tempMenu.value = item;
+      // 附近视频
+      map = getMap();
+      //为地图注册click事件获取鼠标点击出的经纬度坐标
+      map.on('click', handleClickMap);
+    }
   }
 };
 const handleHideCommunicationSupport = () => {
@@ -212,6 +216,14 @@ const getMap = () => {
   }
   return {};
 };
+const getMapUtils = () => {
+  if (['imageMap', 'satellite2', 'satellite3'].includes(activeMap.value)) {
+    return map2Ref.value.getMap();
+  } else if (['vectorgraph', 'satellite'].includes(activeMap.value)) {
+    return mapRef.value.getMapUtils();
+  }
+  return {};
+};
 const showDetail = (data, dataType) => {
   if (['imageMap', 'satellite2', 'satellite3'].includes(activeMap.value)) {
     return map2Ref.value.handleHover(data, dataType);
@@ -280,9 +292,10 @@ const handleClickMap = (e) => {
     showRainfall.value = true;
   } else if (!!tempMenu.value && tempMenu.value.name === '定点分析') {
     const item = deepClone(tempMenu.value);
+    const nowLocation = deepClone(location.value);
     tempMenu.value = {};
     map.off('click', handleClickMap);
-    rightMenuRef.value.updateMenu(item.checked ? '1' : '2', item, location.value);
+    rightMenuRef.value.updateMenu(item.checked ? '1' : '2', item, nowLocation);
   }
 };
 let showWarehouse = ref(false);
@@ -301,6 +314,7 @@ onBeforeUnmount(() => {
 });
 
 provide('getMap', getMap);
+provide('getMapUtils', getMapUtils);
 provide('trackPlayback', trackPlayback);
 provide('showDetail', showDetail);
 provide('getDrawTool', getDrawTool);