Hwf 9 місяців тому
батько
коміт
6f468381bc

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

@@ -1,4 +1,5 @@
 import request from '@/utils/request';
+import qs from 'qs'
 import { MapQuery } from './type';
 
 // 加载粤政图服务
@@ -17,3 +18,28 @@ export const getMapProduct2 = (query: MapQuery) => {
     params: query
   });
 };
+
+// 动态接口请求
+export const getRescueMateria = (url) => {
+  return request({
+    url: '/api/gateway/v1/' + url,
+    method: 'get'
+  });
+};
+
+// 空间分析接口 多边形
+export const getEmergencyExpertNum = (params) => {
+  return request({
+    url: '/api/gateway/v1/emergency_expert_num',
+    method: 'post',
+    data: params
+  });
+};
+// 空间分析接口 圆形
+export const getEmergencyExpertNumRound = (params) => {
+  return request({
+    url: '/api/gateway/v1/emergency_expert_num_round',
+    method: 'post',
+    data: params
+  });
+};

+ 1 - 1
src/api/system/menu/index.ts

@@ -5,7 +5,7 @@ import { MenuQuery, MenuVO, MenuForm, MenuTreeOption, RoleMenuTree } from './typ
 // 查询菜单列表
 export const listMenu = (query?: MenuQuery): AxiosPromise<MenuVO[]> => {
   return request({
-    url: '/system/menu/list',
+    url: '/system/menu/qydt/getRouters',
     method: 'get',
     params: query
   });

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

@@ -5,7 +5,7 @@
     <div v-show="mapState.showScale" class="zoom-text">{{ mapState.zoom }}级</div>
     <div class="right-tool">
       <!-- 快捷缩放 -->
-      <QuickZoom :step="mapState.zoom" :min-step="mapState.minZoom" :max-step="mapState.maxZoom" @change-step="setMapZoom" />
+      <QuickZoom v-model:zoom="mapState.zoom" @change-step="setMapZoom" />
       <div class="flex" style="margin-top: 5px">
         <div class="model-btn" @click="switchThreeDimensional">{{ mapState.isThreeDimensional ? '3D' : '2D' }}</div>
         <div class="model-btn" style="margin-left: 5px" @click="changeScaleControl">尺</div>
@@ -23,8 +23,6 @@ import QuickZoom from './quickZoom.vue';
 import { useAMap } from '@/hooks/AMap/useAMap';
 import { useDrawTool } from '@/hooks/AMap/useDrawTool';
 import { useRuler } from '@/hooks/AMap/useRuler';
-import { countCircleArea, countRectangleArea } from "@/utils/geometryUtil";
-import { deepClone } from "@/utils";
 
 interface Props {
   activeMap: string;
@@ -39,9 +37,9 @@ const emits = defineEmits(['update:drawing', 'selectGraphics']);
 
 const mapState = reactive({
   center: [110.93154257997, 21.669064031332],
-  zoom: 9,
+  zoom: 15,
   minZoom: 6,
-  maxZoom: 16,
+  maxZoom: 20,
   isThreeDimensional: false,
   // 是否显示比例尺
   showScale: true
@@ -54,7 +52,18 @@ const { initMouseTool, drawGraphics, setColor, setDrawType, setGraphicsType, clo
   history } = useDrawTool({
   color: props.color,
   drawType: props.drawType,
-  graphicsType: props.graphicsType
+  graphicsType: props.graphicsType,
+  // 绘制完成事件
+  onDrawCompleted: (data, overlaysData, obj) => {
+    emits('selectGraphics', data, overlaysData.length.toString());
+    // 点击空间分析
+    obj.on('click', function () {
+      // 没在编辑时
+      if (props.drawing) {
+        emits('selectGraphics', data);
+      }
+    });
+  }
 });
 // 测距工具
 const { initRuler, isRanging, toggleRangingTool } = useRuler();
@@ -62,7 +71,6 @@ const { initRuler, isRanging, toggleRangingTool } = useRuler();
 const { getAMap, getMap, switchMap, addMarker, clearMarker, getMarkers } = useAMap({
   key: '30d3d8448efd68cb0b284549fd41adcf', // 申请好的Web端开发者Key,首次调用 load 时必填
   version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
-  plugins: ['AMap.Scale', 'AMap.RangingTool', 'AMap.MouseTool', 'AMap.PolygonEditor'],
   pitch: mapState.isThreeDimensional ? 45 : 0,
   zoom: mapState.zoom,
   center: [mapState.center[0], mapState.center[1]],
@@ -82,12 +90,6 @@ const { getAMap, getMap, switchMap, addMarker, clearMarker, getMarkers } = useAM
     map.on('zoomchange', zoomChangeHandler);
     initMouseTool({ map, AMap });
     initRuler(map, AMap);
-  },
-  // 绘制完成事件
-  onDrawCompleted: (data, overlaysData) => {
-    if (overlaysData.length === 1) {
-      emits('selectGraphics', data);
-    }
   }
 });
 // 监听地图类型变化
@@ -152,13 +154,13 @@ const setMapZoom = (value) => {
     map.setZoom(11);
   } else if (value === 3) {
     map.setCenter([110.93154257997, 21.669064031332]);
-    map.setZoom(12);
+    map.setZoom(13);
   } else if (value === 4) {
     map.setCenter([110.93154257997, 21.669064031332]);
     map.setZoom(15);
   } else if (value === 5) {
     map.setCenter([110.93154257997, 21.669064031332]);
-    map.setZoom(16);
+    map.setZoom(18);
   }
 };
 

+ 25 - 17
src/components/Map/quickZoom.vue

@@ -4,14 +4,7 @@
       <el-icon size="14"><Plus /></el-icon>
     </div>
     <div style="margin: 8px 0 6px; position: relative">
-      <el-slider
-        v-model="step"
-        :min="1"
-        :max="4"
-        vertical
-        height="100px"
-        @input="changeStep"
-      />
+      <el-slider v-model="step" :min="1" :max="5" vertical height="100px" @input="changeStep" />
       <div v-show="step === 1" class="tooltip">省</div>
       <div v-show="step === 2" class="tooltip" style="bottom: 22px">市</div>
       <div v-show="step === 3" class="tooltip" style="bottom: 54px">区</div>
@@ -25,17 +18,32 @@
 </template>
 
 <script lang="ts" setup>
-import { CSSProperties } from 'vue';
-
-interface Mark {
-  style: CSSProperties;
-  label: string;
-}
-
-type Marks = Record<number, Mark | string>;
 const emits = defineEmits(['changeStep']);
+interface Props {
+  zoom: number;
+}
+const props = withDefaults(defineProps<Props>(), {});
+const step = ref(2);
+watch(
+  () => props.zoom,
+  (zoom) => {
+    if (zoom <= 8) {
+      step.value = 1;
+    } else if (zoom >= 8 && zoom < 12) {
+      step.value = 2;
+    } else if (zoom >= 12 && zoom <= 14) {
+      step.value = 3;
+    } else if (zoom >= 14 && zoom < 16) {
+      step.value = 4;
+    } else if (zoom >= 16) {
+      step.value = 5;
+    }
+  },
+  {
+    immediate: true
+  }
+);
 
-let step = ref(2);
 // 发生变化时
 const changeStep = (value) => {
   console.log(122, value);

+ 58 - 21
src/hooks/AMap/useAMap.ts

@@ -1,14 +1,14 @@
 import AMapLoader from '@amap/amap-jsapi-loader';
 
 export function useAMap(options) {
-  let AMap, map, nowLayer;
+  let AMap, map, nowLayer, labelsLayer;
   const markers = [];
   // 初始化事件
   const initMap = (options) => {
     AMapLoader.load({
       key: options.key, // 申请好的Web端开发者Key,首次调用 load 时必填
       version: !!options.version ? options.version : '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
-      plugins: options.plugins ? options.plugins : []
+      plugins: options.plugins ? options.plugins : ['AMap.Scale', 'AMap.RangingTool', 'AMap.MouseTool', 'AMap.PolygonEditor']
     }).then((res) => {
       AMap = res;
       map = new AMap.Map('aMap', {
@@ -51,34 +51,71 @@ export function useAMap(options) {
   };
   // 实例化点标记
   const addMarker = (item) => {
-    // 点标记显示内容,HTML要素字符串
-    const markerContent =
-      '' +
-      '<div class="custom-content-marker" style="display: flex;align-items: center;flex-direction: column;width: 100px;color: #000;font-size: 16px;">' +
-      '<div>' +
-      item.label +
-      '</div>' +
-      '   <img src="//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png" style="width: 20px;">' +
-      '</div>';
-    const marker = new AMap.Marker({
-      size: new AMap.Size(25, 34),
-      content: markerContent,
-      position: [item.center[0], item.center[1]],
-      offset: new AMap.Pixel(-13, -30)
+    if (!labelsLayer) {
+      console.log(1);
+      createLabelsLayer();
+    }
+
+    //设置一个图标对象
+    const icon = {
+      type: 'image', //图标类型,现阶段只支持 image 类型
+      image: item.image ? item.image : 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png', //可访问的图片 URL
+      size: item.size ? item.size : [15, 22.5], //图片尺寸
+      anchor: 'center' //图片相对 position 的锚点,默认为 bottom-center
+    };
+    //设置文字对象
+    const text = {
+      content: item.name, //要展示的文字内容
+      direction: 'top', //文字方向,有 icon 时为围绕文字的方向,没有 icon 时,则为相对 position 的位置
+      offset: [0, 0], //在 direction 基础上的偏移量
+      //文字样式
+      style: {
+        fontSize: 14, //字体大小
+        fillColor: '#000', //字体颜色
+        strokeColor: '#fff', //描边颜色
+        strokeWidth: 2 //描边宽度
+      }
+    };
+    const labelMarker = new AMap.LabelMarker({
+      // 标注位置
+      position: [item.longitude, item.latitude],
+      // 标注在同一图层内的显示层级
+      zIndex: 1,
+      // 避让优先级
+      rank: 1,
+      // 标注图标
+      icon: icon,
+      text: text
     });
-    marker.setMap(map);
-    if (markers[item.id]) {
-      markers[item.id].push(marker);
+    // 将LabelMarker添加到LabelsLayer图层
+    labelsLayer.add(labelMarker);
+    if (markers[item.parentId]) {
+      markers[item.parentId].push(labelMarker);
     } else {
-      markers[item.id] = [marker];
+      markers[item.parentId] = [labelMarker];
     }
   };
+  // 创建LabelsLayer图层
+  const createLabelsLayer = () => {
+    labelsLayer = new AMap.LabelsLayer({
+      // 标注层展示的层级范围
+      zooms: [3, 20],
+      // 标注层与其它图层的叠加顺序
+      zIndex: 1000,
+      // 标注层内的标注是否避让
+      collision: false,
+      // 标注层内的标注是否允许其它标注层对它避让
+      allowCollision: false
+    });
+    // 将图层添加到地图
+    map.add(labelsLayer);
+  };
 
   // 清除所有标加
   const clearMarker = (id) => {
     if (!markers[id]) return;
     markers[id].forEach((marker) => {
-      marker.remove();
+      labelsLayer.remove(marker);
     });
     delete markers[id];
   };

+ 2 - 19
src/hooks/AMap/useDrawTool.ts

@@ -58,14 +58,6 @@ export function useDrawTool(options: DrawToolOptions) {
       if (data.type === 'circle') {
         data.center = [obj.getCenter().lng, obj.getCenter().lat];
         data.radius = obj.getRadius();
-        const area = countCircleArea(data.center, data.radius);
-        // 计算区域面积
-        const text = new AMap.Text({
-          position: new AMap.LngLat(data.center[0], data.center[1]),
-          text: '区域面积' + area + '平方米',
-          offset: new AMap.Pixel(-20, -20)
-        });
-        map.add(text);
       } else if (data.type === 'rectangle') {
         const bounds = obj.getBounds();
         // 从bounds中获取西南角和东北角的坐标
@@ -82,14 +74,6 @@ export function useDrawTool(options: DrawToolOptions) {
             [southWest.lng, northEast.lat]
           ]
         ];
-        const area = countRectangleArea(pathArr);
-        // 计算区域面积
-        const text = new AMap.Text({
-          position: new AMap.LngLat(southWest.lng, northEast.lat),
-          text: '区域面积' + area + '平方米',
-          offset: new AMap.Pixel(-20, -20)
-        });
-        map.add(text);
       } else if (data.type === 'polygon') {
         const path = obj.getPath();
         // 将AMap.LngLat对象数组转换为经纬度数组
@@ -100,15 +84,14 @@ export function useDrawTool(options: DrawToolOptions) {
         data.path = pathArr;
         const newPathArr = deepClone(pathArr);
         newPathArr.push(newPathArr[0]);
-        const area = countRectangleArea([newPathArr]);
       }
       overlays.push(obj);
       overlaysData.push(data);
       commit(deepClone(overlaysData));
       if (typeof options.onDrawCompleted === 'function') {
-        options.onDrawCompleted(data, overlaysData, event);
+        options.onDrawCompleted(data, overlaysData, obj, event);
       }
-      // 右击进入编辑
+      // 右击菜单
       obj.on('rightclick', handleRightClick);
     });
   };

+ 11 - 6
src/views/globalMap/AnalyzeDataDialog.vue

@@ -13,13 +13,17 @@
       <div class="item-value">{{ analysisSpatialData.area }}平方米</div>
     </div>
     <div class="item">
-      <div class="item-label">最近一年GDP</div>
-      <div class="item-value">{{ analysisSpatialData.gdp }}元</div>
-    </div>
-    <div class="item">
-      <div class="item-label">易涝点</div>
-      <div class="item-value">{{ analysisSpatialData.easyFloodPoint }}个</div>
+      <div class="item-label">专家</div>
+      <div class="item-value">{{ analysisSpatialData.expert }}个</div>
     </div>
+<!--    <div class="item">-->
+<!--      <div class="item-label">最近一年GDP</div>-->
+<!--      <div class="item-value">{{ analysisSpatialData.gdp }}元</div>-->
+<!--    </div>-->
+<!--    <div class="item">-->
+<!--      <div class="item-label">易涝点</div>-->
+<!--      <div class="item-value">{{ analysisSpatialData.easyFloodPoint }}个</div>-->
+<!--    </div>-->
     <div class="item">
       <div class="item-label">医院</div>
       <div class="item-value">{{ analysisSpatialData.medicalInstitutionNum }}个</div>
@@ -35,6 +39,7 @@ interface AnalysisSpatialData {
   gdp: string;
   easyFloodPoint: string;
   medicalInstitutionNum: string;
+  expert: string;
 }
 interface Props {
   analysisSpatialData: AnalysisSpatialData;

+ 10 - 67
src/views/globalMap/LeftMenu.vue

@@ -10,18 +10,18 @@
         <div v-show="menuState.isExpand">
           <div class="menu-header">
             <div
-              v-for="(item, index) in menuState.menuData"
+              v-for="(item, index) in menuData"
               :key="index"
               :class="menuState.activeIndex === index ? 'menu-item active' : 'menu-item'"
               @click="changeActive(index)"
             >
-              {{ item.label }}
+              {{ item.name }}
             </div>
           </div>
           <div class="menu-content">
-            <div v-for="(item, index) in menuState.menuData[menuState.activeIndex]?.childrens" :key="index" class="content-box">
+            <div v-for="(item, index) in menuData[menuState.activeIndex]?.children" :key="index" class="content-box">
               <div class="box-header">
-                <div>{{ item.label }}</div>
+                <div>{{ item.name }}</div>
                 <el-icon class="icon" color="#53aee6" size="24" @click="changeBoxShow(item)">
                   <CaretBottom v-show="item.show" />
                   <CaretTop v-show="!item.show" />
@@ -29,7 +29,7 @@
               </div>
               <Transition>
                 <div v-show="item.show" class="box-content">
-                  <div v-for="(item2, index2) in item.childrens" :key="index2" class="box-item" @click="handleClick(item2)">{{ item2.label }}</div>
+                  <div v-for="(item2, index2) in item.children" :key="index2" class="box-item" @click="handleClick(item2)">{{ item2.name }}</div>
                 </div>
               </Transition>
             </div>
@@ -41,12 +41,10 @@
 </template>
 
 <script lang="ts" setup>
-import DrawTools from '@/views/globalMap/drawTools.vue';
-
-// interface Props {
-//   activeMap: string;
-// }
-// const props = withDefaults(defineProps<Props>(), {});
+interface Props {
+  menuData: object;
+}
+const props = withDefaults(defineProps<Props>(), {});
 const emits = defineEmits(['swtichMap', 'addMarkers', 'clickMenu']);
 
 const searchText = ref('');
@@ -57,7 +55,6 @@ const changeSearchText = () => {
 let menuState = reactive({
   // 是否展开菜单
   isExpand: true,
-  menuData: [],
   activeIndex: 0
 });
 
@@ -76,68 +73,14 @@ const changeBoxShow = (item) => {
   item.show = !item.show;
 };
 
-const initData = () => {
-  const menuData = [
-    {
-      label: '监测预警',
-      childrens: [
-        {
-          label: '防风防汛',
-          childrens: [
-            { label: '卫星云图', type: 1, url: '' },
-            { label: '雷达图', type: 1, url: '' },
-            { label: '气温实况图', type: 1, url: '' }
-          ]
-        },
-        {
-          label: '危化品安全监测',
-          childrens: [
-            { type: 2, id: 1, label: '重大风险源', url: '' },
-            { type: 2, id: 2, label: '危化企业', url: '' },
-            { type: 2, id: 2, label: '医院', url: '' }
-          ]
-        }
-      ]
-    },
-    {
-      label: '基本信息',
-      childrens: [
-        {
-          label: '基本信息1',
-          childrens: [{ label: '信息', url: '' }]
-        }
-      ]
-    },
-    {
-      label: '分析工具',
-      childrens: [
-        {
-          label: '工具',
-          childrens: [{ label: '空间分析', url: '' }]
-        }
-      ]
-    }
-  ];
-  menuData.forEach((item) => {
-    item.childrens?.forEach((item2) => {
-      item2.show = true;
-    });
-  });
-  menuState.menuData = menuData;
-};
-
 // 处理菜单点击事件
 const handleClick = (item) => {
-  if (item.type === 2) {
+  if (item.component === '2') {
     emits('addMarkers', item);
   } else {
     emits('clickMenu', item);
   }
 };
-
-onMounted(() => {
-  initData();
-});
 </script>
 
 <style lang="scss" scoped>

+ 11 - 0
src/views/globalMap/data/mapData.ts

@@ -4111,3 +4111,14 @@ export const logicalData = {
     ]
   ]
 }
+
+export const iconList = {
+  'rescue_materia': {
+    image: 'https://a.amap.com/jsapi_demos/static/demo-center/marker/express2.png',
+    size: [64, 30]
+  },
+  'emergency_expert': {
+    image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
+    size: [20, 30]
+  }
+};

+ 112 - 45
src/views/globalMap/index.vue

@@ -1,42 +1,42 @@
 <template>
   <div class="global-map">
-    <MapLogical v-if="activeMap === 'logical'" :mapData="mapData" />
+    <MapLogical v-if="activeMap === 'logical'" :map-data="mapData" />
     <!--<YztMap v-else-if="activeMap === 'satellite2'" ref="map2Ref" :activeMap="activeMap" />-->
     <YMap
       v-else-if="activeMap === 'satellite2'"
       ref="map2Ref"
       v-model:drawing="mouseToolState.drawing"
       :color="mouseToolState.color"
-      :drawType="mouseToolState.drawType"
-      :graphicsType="mouseToolState.graphicsType"
-      :activeMap="activeMap"
+      :draw-type="mouseToolState.drawType"
+      :graphics-type="mouseToolState.graphicsType"
+      :active-map="activeMap"
     />
     <Map
       v-else
       ref="mapRef"
       v-model:drawing="mouseToolState.drawing"
       :color="mouseToolState.color"
-      :drawType="mouseToolState.drawType"
-      :graphicsType="mouseToolState.graphicsType"
-      :activeMap="activeMap"
-      @selectGraphics="analysisSpatial"
+      :draw-type="mouseToolState.drawType"
+      :graphics-type="mouseToolState.graphicsType"
+      :active-map="activeMap"
+      @select-graphics="analysisSpatial"
     />
     <!--左侧菜单-->
-    <LeftMenu @addMarkers="addMarkers" @click-menu="clickMenu" style="position: absolute; top: 20px; left: 20px" />
+    <LeftMenu :menu-data="menuData" style="position: absolute; top: 20px; left: 20px" @add-markers="addMarkers" @click-menu="clickMenu" />
     <!--更换地图类型-->
-    <SwitchMapTool :activeMap="activeMap" @swtichMap="swtichMap" class="tool-box" />
+    <SwitchMapTool :active-map="activeMap" class="tool-box" @swtich-map="swtichMap" />
     <!--时间轴-->
     <TimeAxis />
     <DrawTools
       v-if="showDrawTools"
-      class="absoluteTool"
       v-model:drawing="mouseToolState.drawing"
       v-model:color="mouseToolState.color"
       v-model:drawType="mouseToolState.drawType"
       v-model:graphicsType="mouseToolState.graphicsType"
+      class="absoluteTool"
       @undo="undo"
     />
-    <AnalyzeDataDialog :analysisSpatialData="analysisSpatialData" />
+    <AnalyzeDataDialog v-if="analysisSpatialDataShow" :analysis-spatial-data="analysisSpatialData" />
   </div>
 </template>
 
@@ -45,14 +45,16 @@ import Map from '@/components/Map/index.vue';
 import YztMap from '@/components/Map/YztMap/index.vue';
 import YMap from '@/components/Map/YMap.vue';
 import MapLogical from '@/components/Map/MapLogical.vue';
-import { logicalData } from './data/mapData';
+import { iconList, logicalData } from './data/mapData';
 import SwitchMapTool from '@/views/globalMap/SwitchMapTool.vue';
 import LeftMenu from './LeftMenu.vue';
 import TimeAxis from '@/components/TimeAxis/index.vue';
 import DrawTools from '@/views/globalMap/DrawTools.vue';
 import AnalyzeDataDialog from '@/views/globalMap/AnalyzeDataDialog.vue';
-import { countCircleArea, countRectangleArea } from "@/utils/geometryUtil";
-import { deepClone } from "@/utils";
+import { countCircleArea, countRectangleArea } from '@/utils/geometryUtil';
+import { deepClone } from '@/utils';
+import { getEmergencyExpertNum, getEmergencyExpertNumRound, getRescueMateria } from '@/api/globalMap';
+import { listMenu } from '@/api/system/menu';
 
 const mapData = reactive(logicalData);
 let mapRef = ref(null);
@@ -63,20 +65,50 @@ let activeMap = ref('vectorgraph');
 const swtichMap = (key) => {
   activeMap.value = key;
 };
-
+let menuData = ref([]);
+const initData = () => {
+  listMenu().then((res: any) => {
+    const data = res.data[0]?.children;
+    data.forEach((item) => {
+      item.show = true;
+      item.name = item.meta?.title;
+      item.children?.forEach((item2) => {
+        item2.show = true;
+        item2.name = item2.meta?.title;
+        item2.children?.forEach((item3) => {
+          item3.name = item3.meta?.title;
+          if (item3.component === '2' && !!item3.path) {
+            item3.active = true;
+            // addMarkers(item3);
+          }
+        });
+      });
+    });
+    menuData.value = data;
+    console.log(menuData.value);
+  });
+};
 const addMarkers = (item) => {
   const dom = activeMap.value === 'satellite2' ? map2Ref.value : mapRef.value;
   if (dom) {
     const markers = dom.getMarkers();
-    if (markers[item.id]) {
-      dom.clearMarker(item.id);
+    if (markers[item.path]) {
+      dom.clearMarker(item.path);
     } else {
-      let data = [{ id: item.id, label: '标注点1', center: [110.93154257997, 21.669064031332] },{ id: item.id, label: '标注点2', center: [110.93154257997, 21.969064031332] }];
-      if (item.id === 2) {
-        data = [{ id: item.id, label: '标注点3', center: [111.1315257997, 21.569064031332] }];
-      }
-      data.forEach((item) => {
-        dom.addMarker(item);
+      getRescueMateria(item.path).then((res) => {
+        const data = res.data && res.data.list ? res.data?.list : [];
+        data.forEach((item2) => {
+          // 获取图标
+          if (iconList[item.path]) {
+            item2.image = iconList[item.path].image;
+            item2.size = iconList[item.path].size;
+          }
+          if (item2.materia_name) {
+            item2.name = item2.materia_name;
+          }
+          item2.parentId = item.path;
+          dom.addMarker(item2);
+        });
       });
     }
   }
@@ -85,7 +117,7 @@ const addMarkers = (item) => {
 let showDrawTools = ref(false);
 // 点击菜单
 const clickMenu = (item) => {
-  if (item.label === '空间分析') {
+  if (item.path === 'spatial') {
     showDrawTools.value = !showDrawTools.value;
   }
 };
@@ -105,42 +137,77 @@ const undo = () => {
 };
 interface AnalysisSpatialData {
   townName: string;
-  area: string;
+  area: number | undefined;
   populationNum: string;
   gdp: string;
   easyFloodPoint: string;
   medicalInstitutionNum: string;
+  expert: string;
 }
+let analysisSpatialDataShow = ref(false);
 // 空间分析数据
 const analysisSpatialData = reactive<AnalysisSpatialData>({
   townName: '',
-  area: '',
+  area: undefined,
   populationNum: '',
   gdp: '',
   easyFloodPoint: '',
-  medicalInstitutionNum: ''
+  medicalInstitutionNum: '',
+  expert: ''
 });
 // 空间分析数据
-const analysisSpatial = (data) => {
+const analysisSpatial = (data, len?: string) => {
+  if (!!len && len !== '1') {
+    analysisSpatialDataShow.value = false;
+    return;
+  }
   if (data.type === 'circle') {
-    analysisSpatialData.area = countCircleArea(data.center, data.radius);
-  } else if (data.type === 'rectangle') {
-    const pathArr = [
-      [
-        [data.southWest[0], data.northEast[1]],
-        data.northEast,
-        [data.northEast[0], data.southWest[1]],
-        data.southWest,
-        [data.southWest[0], data.northEast[1]]
-      ]
-    ];
-    analysisSpatialData.area = countRectangleArea(pathArr);
-  } else if (data.type === 'polygon') {
-    const newPathArr = deepClone(data.path);
-    newPathArr.push(newPathArr[0]);
-    analysisSpatialData.area = countRectangleArea([newPathArr]);
+    const params = {
+      location: `POINT(${data.center.join(' ')})`,
+      radius: data.radius.toString()
+    };
+    getEmergencyExpertNumRound(params).then((res) => {
+      analysisSpatialData.area = countCircleArea(data.center, data.radius);
+      analysisSpatialData.expert = res.data.list[0].expertNum?.toString();
+      analysisSpatialDataShow.value = true;
+    });
+  } else {
+    let location = '';
+    let pathArr = [];
+    if (data.type === 'rectangle') {
+      pathArr = [
+        [
+          [data.southWest[0], data.northEast[1]],
+          data.northEast,
+          [data.northEast[0], data.southWest[1]],
+          data.southWest,
+          [data.southWest[0], data.northEast[1]]
+        ]
+      ];
+    } else if (data.type === 'polygon') {
+      pathArr = deepClone(data.path);
+      pathArr.push(deepClone(pathArr[0]));
+      pathArr = [pathArr];
+    }
+    let pathStr = '';
+    pathArr[0].forEach((innerArr, index) => {
+      if (index > 0) {
+        pathStr += ',';
+      }
+      pathStr += innerArr.reverse().join(' ');
+    });
+    location = `POLYGON((${pathStr}))`;
+    getEmergencyExpertNum({ location }).then((res) => {
+      analysisSpatialData.area = countRectangleArea(pathArr);
+      analysisSpatialData.expert = res.data.list[0].expertNum?.toString();
+      analysisSpatialDataShow.value = true;
+    });
   }
 };
+
+onMounted(() => {
+  initData();
+});
 </script>
 
 <style lang="scss" scoped>