Browse Source

地图右下工具组件

Hwf 5 months ago
parent
commit
40c9a89827

+ 1 - 1
src/api/globalMap/potentialFloodHazard.ts

@@ -18,7 +18,7 @@ export const getWaterloggedAllVideoInfo = (params) => {
 
 
 export const getWaterloggedRoadsUpdateTime = () => {
 export const getWaterloggedRoadsUpdateTime = () => {
   return request({
   return request({
-    url: 'api/gateway/v1/get_waterlogged_roads_update_time',
+    url: '/api/gateway/v1/get_waterlogged_roads_update_time',
     method: 'get'
     method: 'get'
   });
   });
 };
 };

+ 33 - 108
src/components/Map/YztMap/index.vue

@@ -11,22 +11,13 @@
         transformOrigin: '0 0'
         transformOrigin: '0 0'
       }"
       }"
     ></div>
     ></div>
-    <!-- 右下工具  -->
-    <div v-show="mapState.showScale" class="zoom-text">{{ mapState.zoom }}级</div>
-    <div class="right-tool">
-      <!-- 快捷缩放 -->
-      <QuickZoom v-model:zoom="mapState.zoom" @change-step="setMapZoom" />
-      <div class="flex" style="margin-top: 5px; justify-content: center">
-        <div class="mask-btn" @click="handleShowMask">{{ showMask ? '显' : '隐' }}</div>
-        <!--        <div class="model-btn" @click="switchThreeDimensional">{{ mapState.isThreeDimensional ? '3D' : '2D' }}</div>-->
-        <div class="ruler-icon" style="margin-left: 5px" @click="changeScaleControl"></div>
-      </div>
-    </div>
+    <rightTool :mapState="mapState" type="YztMap" :showMask="showMask" @changeShowMask="changeShowMask" />
   </div>
   </div>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
 import 'ol/ol.css';
 import 'ol/ol.css';
+import rightTool from '../rightTool.vue';
 import mmJson from '@/assets/json/mm.json';
 import mmJson from '@/assets/json/mm.json';
 import { olMap } from '@/utils/olMap/olMap';
 import { olMap } from '@/utils/olMap/olMap';
 import { PointType } from '@/api/globalMap/type';
 import { PointType } from '@/api/globalMap/type';
@@ -54,16 +45,16 @@ const mapState = reactive({
 const containerRef = ref();
 const containerRef = ref();
 const width = ref('100%');
 const width = ref('100%');
 const height = ref('100%');
 const height = ref('100%');
-let yztMap, map;
+let map, mapUtils;
 
 
 // 监听是否开启绘制
 // 监听是否开启绘制
 watch(
 watch(
   () => props.drawing,
   () => props.drawing,
   (value) => {
   (value) => {
     if (value) {
     if (value) {
-      map.drawGraphics(props.graphicsType);
+      mapUtils.drawGraphics(props.graphicsType);
     } else {
     } else {
-      map.closeDraw();
+      mapUtils.closeDraw();
     }
     }
   }
   }
 );
 );
@@ -77,23 +68,23 @@ const mapList = reactive({
 watch(
 watch(
   () => props.activeMap,
   () => props.activeMap,
   () => {
   () => {
-    if (!map) return;
-    map.replaceLayers(mapList[props.activeMap]);
+    if (!mapUtils) return;
+    mapUtils.replaceLayers(mapList[props.activeMap]);
   }
   }
 );
 );
 watch(
 watch(
   () => props.showMask,
   () => props.showMask,
   () => {
   () => {
     if (props.showMask) {
     if (props.showMask) {
-      map.createVecByJson(mmJson, '茂名市');
+      mapUtils.createVecByJson(mmJson, '茂名市');
     } else {
     } else {
-      map.removeMask();
+      mapUtils.removeMask2();
     }
     }
   }
   }
 );
 );
-let scaleLine;
+let scale;
 const init = () => {
 const init = () => {
-  map = new olMap({
+  mapUtils = new olMap({
     dom: mapRef.value,
     dom: mapRef.value,
     id: mapList[props.activeMap],
     id: mapList[props.activeMap],
     center: mapState.center,
     center: mapState.center,
@@ -118,65 +109,31 @@ const init = () => {
       }
       }
     },
     },
     // 加载完成事件
     // 加载完成事件
-    onLoadCompleted: (yMap) => {
-      yztMap = yMap;
-      // initMouseTool(map);
-      scaleLine = new ScaleLine();
-      yztMap.addControl(scaleLine);
-      yztMap.getView().on('change:resolution', () => {
-        mapState.zoom = yztMap.getView().getZoom().toFixed(2);
+    onLoadCompleted: (YztMap) => {
+      map = YztMap;
+      // initMouseTool(mapUtils);
+      scale = new ScaleLine();
+      map.addControl(scale);
+      map.getView().on('change:resolution', () => {
+        mapState.zoom = map.getView().getZoom().toFixed(2);
       });
       });
       if (props.showMask) {
       if (props.showMask) {
-        map.createVecByJson(mmJson, '茂名市');
+        mapUtils.createVecByJson(mmJson, '茂名市');
       }
       }
       handleResize();
       handleResize();
     }
     }
   });
   });
 };
 };
 const addMarker = (points) => {
 const addMarker = (points) => {
-  map.addMarker(points);
-};
-// 设置地图层级
-const setMapZoom = (value) => {
-  if (!yztMap) return;
-  const view = yztMap.getView();
-  if (value === 1) {
-    view.setCenter([110.925175, 21.678955]);
-    view.setZoom(7.9);
-  } else if (value === 2) {
-    view.setCenter([110.925175, 21.6789558]);
-    view.setZoom(9.21);
-  } else if (value === 3) {
-    view.setCenter([110.925175, 21.678955]);
-    view.setZoom(11.38);
-  } else if (value === 4) {
-    view.setCenter([110.925175, 21.678955]);
-    view.setZoom(12.83);
-  }
-};
-// 切换2D、3D
-const switchThreeDimensional = () => {
-  const view = yztMap.map.getView();
-  mapState.isThreeDimensional = !mapState.isThreeDimensional;
-  const pitch = mapState.isThreeDimensional ? 45 : 0;
-  view.setPitch(pitch);
-};
-// 切换比例尺
-const changeScaleControl = () => {
-  mapState.showScale = !mapState.showScale;
-  if (mapState.showScale) {
-    yztMap.addControl(scaleLine);
-  } else {
-    yztMap.removeControl(scaleLine);
-  }
+  mapUtils.addMarker(points);
 };
 };
 const clearMarker = () => {
 const clearMarker = () => {
-  map.clearMarker();
+  mapUtils.clearMarker();
 };
 };
-const handleShowMask = () => {
+const changeShowMask = () => {
   emits('update:showMask', !props.showMask);
   emits('update:showMask', !props.showMask);
 };
 };
-defineExpose({ addMarker, clearMarker });
+
 let inverseScale = ref({
 let inverseScale = ref({
   inverseScaleX: 1,
   inverseScaleX: 1,
   inverseScaleY: 1
   inverseScaleY: 1
@@ -188,7 +145,13 @@ const handleResize = () => {
   const containerHeight = containerRef.value.clientHeight * containerScale().scaleY;
   const containerHeight = containerRef.value.clientHeight * containerScale().scaleY;
   width.value = containerWidth + 'px';
   width.value = containerWidth + 'px';
   height.value = containerHeight + 'px';
   height.value = containerHeight + 'px';
-  yztMap.updateSize();
+  map.updateSize();
+};
+const getMap = () => {
+  return map;
+};
+const getScale = () => {
+  return scale;
 };
 };
 // 加载事件
 // 加载事件
 onMounted(() => {
 onMounted(() => {
@@ -199,6 +162,9 @@ onMounted(() => {
 onUnmounted(() => {
 onUnmounted(() => {
   window.removeEventListener('resize', handleResize);
   window.removeEventListener('resize', handleResize);
 });
 });
+provide('getMap', getMap);
+provide('getScale', getScale);
+defineExpose({ addMarker, clearMarker });
 </script>
 </script>
 
 
 <style scoped>
 <style scoped>
@@ -206,47 +172,6 @@ onUnmounted(() => {
   width: 100%;
   width: 100%;
   height: 100%;
   height: 100%;
   position: relative;
   position: relative;
-  .zoom-text {
-    position: absolute;
-    bottom: 120px;
-    right: 170px;
-    color: #eaf3fc;
-    font-size: 25.73px;
-  }
-  .right-tool {
-    position: absolute;
-    bottom: 160px;
-    right: 175px;
-    z-index: 2;
-  }
-  .mask-btn {
-    background-color: #04327c;
-    font-size: 25.73px;
-    border: 1px solid #91cfff;
-    color: #eaf3fc;
-    cursor: pointer;
-    padding: 3px 3px;
-    border-radius: 5px;
-    //margin-right: 5px;
-    cursor: pointer;
-  }
-  .model-btn {
-    background-color: #04327c;
-    font-size: 25.73px;
-    font-family: 'SourceHanSansCN';
-    border: 1px solid #91cfff;
-    color: #eaf3fc;
-    cursor: pointer;
-    padding: 3px 3px;
-    border-radius: 5px;
-  }
-  .ruler-icon {
-    width: 42px;
-    height: 42px;
-    background: url('@/assets/images/map/ruler.png') no-repeat;
-    background-size: 100% 100%;
-    cursor: pointer;
-  }
   :deep(.ol-scale-line) {
   :deep(.ol-scale-line) {
     left: unset;
     left: unset;
     bottom: 16px;
     bottom: 16px;

+ 34 - 106
src/components/Map/index.vue

@@ -1,22 +1,21 @@
 <template>
 <template>
   <div ref="containerRef" class="map-container">
   <div ref="containerRef" class="map-container">
-    <div id="aMap" class="map-container2" :style="{ width: width, height: height, transform: 'scale(' + inverseScale.inverseScaleX + ', ' + inverseScale.inverseScaleY + ')', transformOrigin: '0 0' }"></div>
-    <!-- 右下工具  -->
-    <div v-show="mapState.showScale" class="zoom-text">{{ mapState.zoom }}级</div>
-    <div class="right-tool">
-      <!-- 快捷缩放 -->
-      <QuickZoom v-model:zoom="mapState.zoom" @change-step="setMapZoom" />
-      <div class="flex" style="margin-top: 5px">
-        <div class="mask-btn" @click="handleShowMask">{{ showMask ? '显' : '隐' }}</div>
-        <div class="model-btn" @click="switchThreeDimensional">{{ mapState.isThreeDimensional ? '3D' : '2D' }}</div>
-        <div class="ruler-icon" style="margin-left: 5px" @click="changeScaleControl"></div>
-      </div>
-    </div>
+    <div
+      id="aMap"
+      class="map-container2"
+      :style="{
+        width: width,
+        height: height,
+        transform: 'scale(' + inverseScale.inverseScaleX + ', ' + inverseScale.inverseScaleY + ')',
+        transformOrigin: '0 0'
+      }"
+    />
+    <rightTool :mapState="mapState" type="AMap" :showMask="showMask" @changeShowMask="changeShowMask" />
   </div>
   </div>
 </template>
 </template>
 
 
 <script setup lang="ts" name="Map">
 <script setup lang="ts" name="Map">
-import QuickZoom from './quickZoom.vue';
+import rightTool from './rightTool.vue';
 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 { getPointInfoList } from '@/api/globalMap';
@@ -83,7 +82,7 @@ const containerRef = ref();
 const width = ref('100%');
 const width = ref('100%');
 const height = ref('100%');
 const height = ref('100%');
 
 
-const mapState = reactive({
+const mapState = reactive<MapState>({
   center: [110.925175, 21.978955],
   center: [110.925175, 21.978955],
   zoom: 8.5,
   zoom: 8.5,
   minZoom: 6,
   minZoom: 6,
@@ -441,41 +440,6 @@ const zoomChangeHandler = () => {
   mapState.zoom = map.getZoom();
   mapState.zoom = map.getZoom();
 };
 };
 
 
-// 切换比例尺
-const changeScaleControl = () => {
-  mapState.showScale = !mapState.showScale;
-  if (mapState.showScale) {
-    map.addControl(scale);
-  } else {
-    map.removeControl(scale);
-  }
-};
-
-// 设置地图层级
-const setMapZoom = (value) => {
-  if (!map) return;
-  if (value === 1) {
-    map.setCenter([110.925175, 21.678955]);
-    map.setZoom(7.9);
-  } else if (value === 2) {
-    map.setCenter([110.925175, 21.6789558]);
-    map.setZoom(9.21);
-  } else if (value === 3) {
-    map.setCenter([110.925175, 21.678955]);
-    map.setZoom(11.38);
-  } else if (value === 4) {
-    map.setCenter([110.925175, 21.678955]);
-    map.setZoom(12.83);
-  }
-};
-
-// 切换2D、3D
-const switchThreeDimensional = () => {
-  mapState.isThreeDimensional = !mapState.isThreeDimensional;
-  const pitch = mapState.isThreeDimensional ? 45 : 0;
-  map.setPitch(pitch);
-};
-
 const setCenter = (item) => {
 const setCenter = (item) => {
   map.setCenter([item.longitude, item.latitude]);
   map.setCenter([item.longitude, item.latitude]);
 };
 };
@@ -486,22 +450,7 @@ const getMapUtils = () => {
 const getPlaceSearch = () => {
 const getPlaceSearch = () => {
   return placeSearch;
   return placeSearch;
 };
 };
-const handleShowMask = () => {
-  emits('update:showMask', !props.showMask);
-};
-defineExpose({
-  addMarker,
-  addSearchMarker,
-  setCenter,
-  getMarkers,
-  clearMarker,
-  getMap,
-  drawTool,
-  handleHover,
-  trackPlayback,
-  getMapUtils,
-  getPlaceSearch
-});
+
 let inverseScale = ref({
 let inverseScale = ref({
   inverseScaleX: 1,
   inverseScaleX: 1,
   inverseScaleY: 1
   inverseScaleY: 1
@@ -515,6 +464,10 @@ const handleResize = () => {
   height.value = containerHeight + 'px';
   height.value = containerHeight + 'px';
   map.resize();
   map.resize();
 };
 };
+
+const changeShowMask = () => {
+  emits('update:showMask', !props.showMask);
+};
 watch(
 watch(
   () => appStore.showLeftSection,
   () => appStore.showLeftSection,
   () => {
   () => {
@@ -541,6 +494,22 @@ onUnmounted(() => {
   }
   }
   window.removeEventListener('resize', handleResize);
   window.removeEventListener('resize', handleResize);
 });
 });
+
+provide('getMap', getMap);
+provide('getScale', getScale);
+defineExpose({
+  addMarker,
+  addSearchMarker,
+  setCenter,
+  getMarkers,
+  clearMarker,
+  getMap,
+  drawTool,
+  handleHover,
+  trackPlayback,
+  getMapUtils,
+  getPlaceSearch
+});
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
@@ -554,47 +523,6 @@ onUnmounted(() => {
 .map-container {
 .map-container {
   width: 100%;
   width: 100%;
   height: 100%;
   height: 100%;
-  .zoom-text {
-    position: absolute;
-    bottom: 120px;
-    right: 170px;
-    color: #eaf3fc;
-    font-size: 25.73px;
-  }
-  .right-tool {
-    position: absolute;
-    bottom: 160px;
-    right: 175px;
-    z-index: 2;
-  }
-  .mask-btn {
-    background-color: #04327c;
-    font-size: 25.73px;
-    border: 1px solid #91cfff;
-    color: #eaf3fc;
-    cursor: pointer;
-    padding: 3px 3px;
-    border-radius: 5px;
-    margin-right: 5px;
-    cursor: pointer;
-  }
-  .model-btn {
-    background-color: #04327c;
-    font-size: 25.73px;
-    font-family: 'SourceHanSansCN';
-    border: 1px solid #91cfff;
-    color: #eaf3fc;
-    cursor: pointer;
-    padding: 3px 3px;
-    border-radius: 5px;
-  }
-  .ruler-icon {
-    width: 42px;
-    height: 42px;
-    background: url('@/assets/images/map/ruler.png') no-repeat;
-    background-size: 100% 100%;
-    cursor: pointer;
-  }
   :deep(.amap-scalecontrol) {
   :deep(.amap-scalecontrol) {
     left: unset !important;
     left: unset !important;
     background-color: unset !important;
     background-color: unset !important;

+ 2 - 3
src/components/Map/quickZoom.vue

@@ -80,7 +80,6 @@ const reduceStep = () => {
   bottom: -23px;
   bottom: -23px;
   color: #fff;
   color: #fff;
   padding-left: 14px;
   padding-left: 14px;
-  padding-top: 4px;
   font-size: 32px;
   font-size: 32px;
   min-width: 80px;
   min-width: 80px;
   height: 63px;
   height: 63px;
@@ -94,8 +93,8 @@ const reduceStep = () => {
     border-bottom: 45px solid #3b71eb;
     border-bottom: 45px solid #3b71eb;
     border-left: 45px solid transparent;
     border-left: 45px solid transparent;
     position: absolute;
     position: absolute;
-    top: 10px;
-    right: -20px;
+    top: 9px;
+    right: -22px;
     transform: rotate(-45deg);
     transform: rotate(-45deg);
   }
   }
 }
 }

+ 117 - 0
src/components/Map/rightTool.vue

@@ -0,0 +1,117 @@
+<template>
+  <!-- 右下工具  -->
+  <div v-show="mapState.showScale" class="zoom-text">{{ mapState.zoom }}级</div>
+  <div class="right-tool">
+    <!-- 快捷缩放 -->
+    <QuickZoom v-model:zoom="mapState.zoom" @change-step="setMapZoom" />
+    <div class="flex" style="margin-top: 5px">
+      <div class="mask-btn" @click="handleShowMask">{{ showMask ? '显' : '隐' }}</div>
+      <div v-if="type !== 'YztMap'" class="model-btn" @click="switchThreeDimensional">{{ mapState.isThreeDimensional ? '3D' : '2D' }}</div>
+      <div class="ruler-icon" style="margin-left: 5px" @click="changeScaleControl"></div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import QuickZoom from './quickZoom.vue';
+interface Props {
+  mapState: MapState;
+  type: string;
+  showMask: boolean;
+}
+
+const props = withDefaults(defineProps<Props>(), {
+  type: 'AMap'
+});
+const emits = defineEmits(['changeShowMask']);
+const getMap = inject('getMap');
+const getScale = inject('getScale');
+// 设置地图层级
+const setMapZoom = (value) => {
+  const map = props.type === 'AMap' ? getMap() : getMap().getView();
+  if (!map) return;
+  if (value === 1) {
+    map.setCenter([110.925175, 21.678955]);
+    map.setZoom(7.9);
+  } else if (value === 2) {
+    map.setCenter([110.925175, 21.6789558]);
+    map.setZoom(9.21);
+  } else if (value === 3) {
+    map.setCenter([110.925175, 21.678955]);
+    map.setZoom(11.38);
+  } else if (value === 4) {
+    map.setCenter([110.925175, 21.678955]);
+    map.setZoom(12.83);
+  }
+};
+
+// 切换2D、3D
+const switchThreeDimensional = () => {
+  const map = props.type === 'AMap' ? getMap() : getMap().getView();
+  props.mapState.isThreeDimensional = !props.mapState.isThreeDimensional;
+  const pitch = props.mapState.isThreeDimensional ? 45 : 0;
+  map.setPitch(pitch);
+};
+// 显隐遮罩层
+const handleShowMask = () => {
+  emits('changeShowMask');
+};
+
+// 切换比例尺
+const changeScaleControl = () => {
+  const map = getMap();
+  const scale = getScale();
+  props.mapState.showScale = !props.mapState.showScale;
+  if (props.mapState.showScale) {
+    map.addControl(scale);
+  } else {
+    map.removeControl(scale);
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.zoom-text {
+  position: absolute;
+  bottom: 120px;
+  right: 170px;
+  color: #eaf3fc;
+  font-size: 25.73px;
+}
+.right-tool {
+  position: absolute;
+  bottom: 160px;
+  right: 175px;
+  z-index: 2;
+
+  .mask-btn {
+    background-color: #04327c;
+    font-size: 25.73px;
+    border: 1px solid #91cfff;
+    color: #eaf3fc;
+    cursor: pointer;
+    border-radius: 5px;
+    margin-right: 5px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  .model-btn {
+    background-color: #04327c;
+    font-size: 25.73px;
+    font-family: 'SourceHanSansCN';
+    border: 1px solid #91cfff;
+    color: #eaf3fc;
+    cursor: pointer;
+    padding: 3px 3px;
+    border-radius: 5px;
+  }
+  .ruler-icon {
+    width: 42px;
+    height: 42px;
+    background: url('@/assets/images/map/ruler.png') no-repeat;
+    background-size: 100% 100%;
+    cursor: pointer;
+  }
+}
+</style>

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

@@ -92,6 +92,7 @@ declare module 'vue' {
     ParentView: typeof import('./../components/ParentView/index.vue')['default']
     ParentView: typeof import('./../components/ParentView/index.vue')['default']
     QuickZoom: typeof import('./../components/Map/quickZoom.vue')['default']
     QuickZoom: typeof import('./../components/Map/quickZoom.vue')['default']
     Render: typeof import('./../components/BuildCode/render.vue')['default']
     Render: typeof import('./../components/BuildCode/render.vue')['default']
+    RightTool: typeof import('./../components/Map/rightTool.vue')['default']
     RightToolbar: typeof import('./../components/RightToolbar/index.vue')['default']
     RightToolbar: typeof import('./../components/RightToolbar/index.vue')['default']
     RoleSelect: typeof import('./../components/RoleSelect/index.vue')['default']
     RoleSelect: typeof import('./../components/RoleSelect/index.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterLink: typeof import('vue-router')['RouterLink']

+ 9 - 0
src/types/map.d.ts

@@ -11,3 +11,12 @@ interface MouseTool {
   icon?: string;
   icon?: string;
   size?: number[];
   size?: number[];
 }
 }
+
+interface MapState {
+  center: number[];
+  zoom: number;
+  minZoom: number;
+  maxZoom: number;
+  isThreeDimensional: boolean;
+  showScale: boolean;
+}

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

@@ -121,6 +121,7 @@ export class olMap {
     //   '</wfs:GetFeature>');
     //   '</wfs:GetFeature>');
     return this.getCapabilities(code).then((lists) => {
     return this.getCapabilities(code).then((lists) => {
       const geojson = xml.read(lists.data);
       const geojson = xml.read(lists.data);
+      debugger
       const data = geojson.Contents.Layer[0];
       const data = geojson.Contents.Layer[0];
       const layerParam = {
       const layerParam = {
         layerName: data.Abstract,
         layerName: data.Abstract,

+ 2 - 1
src/views/globalMap/SwitchMapTool.vue

@@ -144,10 +144,11 @@ const handleExpand = () => {
   }
   }
   .item-text {
   .item-text {
     position: absolute;
     position: absolute;
-    right: 0;
+    right: 1px;
     bottom: 0;
     bottom: 0;
     width: 168px;
     width: 168px;
     height: 60px;
     height: 60px;
+    padding-right: 5px;
     line-height: 60px;
     line-height: 60px;
     background-image: url('@/assets/images/map/bg-default.png');
     background-image: url('@/assets/images/map/bg-default.png');
     background-repeat: no-repeat;
     background-repeat: no-repeat;