Selaa lähdekoodia

图标替换、事件点击跳转

Hwf 7 kuukautta sitten
vanhempi
commit
1fa879c7ca

BIN
src/assets/images/tab10.png


BIN
src/assets/images/tab10_checked.png


BIN
src/assets/images/tab11.png


BIN
src/assets/images/tab11_checked.png


BIN
src/assets/images/tab8.png


BIN
src/assets/images/tab8_checked.png


BIN
src/assets/images/tab9.png


BIN
src/assets/images/tab9_checked.png


+ 118 - 23
src/hooks/AMap/useAMap.ts

@@ -13,10 +13,12 @@ export function useAMap(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 : ['AMap.Scale', 'AMap.RangingTool', 'AMap.MouseTool', 'AMap.PolygonEditor', 'AMap.MarkerCluster']
+      plugins: options.plugins
+          ? options.plugins
+          : ['AMap.Scale', 'AMap.RangingTool', 'AMap.MouseTool', 'AMap.PolygonEditor', 'AMap.MarkerCluster', 'AMap.DistrictSearch', 'AMap.MoveAnimation']
     }).then((res) => {
       AMap = res;
-      map = new AMap.Map('aMap', {
+      map = new AMap.Map(options.el ? options.el : 'aMap', {
         WebGLParams: {
           preserveDrawingBuffer: true
         },
@@ -74,8 +76,6 @@ export function useAMap(options) {
     addPoints = points;
     const count = points.length;
     const _renderClusterMarker = function (context) {
-      console.log(context);
-      console.log('21312', context.clusterData);
       // 聚合中点个数
       const clusterCount = context.count;
       const div = document.createElement('div');
@@ -92,20 +92,22 @@ export function useAMap(options) {
       context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2));
       context.marker.setContent(div);
       context.marker.on('click', (e) => {
+        const bounds = e.target.getBounds();
+        map.setZoomAndCenter(map.getZoom() + 1, bounds.getCenter());
       });
     };
     const _renderMarker = function (context) {
       const content =
-        '<div style="display: flex;flex-direction: column;align-items: center;justify-content: center">' +
-        '<div style="background: url(' +
-        context.data[0].icon +
-        ') no-repeat; width: ' +
-        context.data[0].size[0] +
-        'px;height: ' +
-        context.data[0].size[1] +
-        'px;cursor: pointer; background-size: cover"></div>' +
-        // '<div style="font-size: 36px;white-space: nowrap">'+ context.data[0].name +'</div>' +
-        '</div>';
+          '<div style="display: flex;flex-direction: column;align-items: center;justify-content: center">' +
+          '<div style="background: url(' +
+          context.data[0].icon +
+          ') no-repeat; width: ' +
+          context.data[0].size[0] +
+          'px;height: ' +
+          context.data[0].size[1] +
+          'px;cursor: pointer; background-size: cover"></div>' +
+          // '<div style="font-size: 36px;white-space: nowrap">'+ context.data[0].name +'</div>' +
+          '</div>';
       const offset = new AMap.Pixel(-9, -9);
       context.marker.setContent(content);
       context.marker.setOffset(offset);
@@ -137,13 +139,13 @@ export function useAMap(options) {
       });
     };
     cluster = new AMap.MarkerCluster(
-      map, //地图实例
-      points, //海量点数据,数据中需包含经纬度信息字段 lnglat
-      {
-        gridSize: 30, //数据聚合计算时网格的像素大小
-        renderClusterMarker: _renderClusterMarker, //上述步骤的自定义聚合点样式
-        renderMarker: _renderMarker //上述步骤的自定义非聚合点样式
-      }
+        map, //地图实例
+        points, //海量点数据,数据中需包含经纬度信息字段 lnglat
+        {
+          gridSize: 30, //数据聚合计算时网格的像素大小
+          renderClusterMarker: _renderClusterMarker, //上述步骤的自定义聚合点样式
+          renderMarker: _renderMarker //上述步骤的自定义非聚合点样式
+        }
     );
     points.forEach((item) => {
       markers['point'].push(item);
@@ -205,9 +207,13 @@ export function useAMap(options) {
     // 打开InfoWindow,并设置其内容和位置
     infoWindow.setContent(content);
     infoWindow.open(map, lnglat);
+    // 解决2.0版本无法滚动问题
+    infoWindow.on('mouseover', () => map.setStatus({ zoomEnable: false }));
+    infoWindow.on('mouseout', () => map.setStatus({ zoomEnable: true }));
   };
 
   const hideInfo = (e) => {
+    map.setStatus({ zoomEnable: true });
     if (!!infoWindow) {
       infoWindow.close();
       if (!!clickMarker && e) {
@@ -224,8 +230,95 @@ export function useAMap(options) {
     }
   };
 
+  const creatMask = (options, name = '茂名市') => {
+    new AMap.DistrictSearch({
+      extensions: 'all',
+      subdistrict: 0
+    }).search(name, function (status, result) {
+      // 外多边形坐标数组和内多边形坐标数组
+      const outer = [
+        new AMap.LngLat(-360, 90, true),
+        new AMap.LngLat(-360, -90, true),
+        new AMap.LngLat(360, -90, true),
+        new AMap.LngLat(360, 90, true)
+      ];
+      options.forEach((option) => {
+        const holes = result.districtList[0].boundaries;
+        // if (option.offset) {
+        //
+        //   holes.forEach((items) => {
+        //
+        //   })
+        // }
+        let pathArray = [outer];
+        pathArray.push.apply(pathArray, holes);
+        const polygon = new AMap.Polygon({
+          pathL: pathArray,
+          strokeColor: option.strokeColor ? option.strokeColor : '#268ab9',
+          strokeOpacity: option.strokeOpacity ? option.strokeOpacity : 1,
+          strokeWeight: option.strokeWeight ? option.strokeWeight : 1,
+          fillColor: option.fillColor ? option.fillColor : '#10243b',
+          fillOpacity: option.fillOpacity ? option.fillOpacity : 0.65
+        });
+        polygon.setPath(pathArray);
+        map.add(polygon);
+      });
+    });
+  };
+
+  let moveMarker, movePolyline, movePassedPolyline, timerId;
+  const trackPlayback = (lineArr) => {
+    if (timerId) {
+      clearTimeout(timerId);
+    }
+    movePolyline?.remove();
+    movePassedPolyline?.remove();
+    moveMarker?.remove();
+    moveMarker = new AMap.Marker({
+      map: map,
+      position: [116.478935, 39.997761],
+      icon: 'https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png',
+      offset: new AMap.Pixel(-13, -26)
+    });
+    // 绘制轨迹
+    movePolyline = new AMap.Polyline({
+      map: map,
+      path: lineArr,
+      showDir: true,
+      strokeColor: '#28F', //线颜色
+      // strokeOpacity: 1,     //线透明度
+      strokeWeight: 6 //线宽
+      // strokeStyle: "solid"  //线样式
+    });
+
+    movePassedPolyline = new AMap.Polyline({
+      map: map,
+      strokeColor: '#AF5', //线颜色
+      strokeWeight: 6 //线宽
+    });
+
+    moveMarker.on('moving', function (e) {
+      movePassedPolyline.setPath(e.passedPath);
+      map.setCenter(e.target.getPosition(), true);
+    });
 
-  initMap(options);
+    moveMarker.on('moveend', function (e) {
+      timerId = setTimeout(() => {
+        movePolyline.remove();
+        movePassedPolyline.remove();
+        moveMarker.remove();
+      }, 2000);
+    });
+    moveMarker.moveAlong(lineArr, {
+      // 每一段的时长
+      duration: 1000, //可根据实际采集时间间隔设置
+      // JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
+      autoRotation: true
+    });
+  };
+  onMounted(() => {
+    initMap(options);
+  });
   return {
     getAMap,
     getMap,
@@ -237,6 +330,8 @@ export function useAMap(options) {
     getScale,
     showInfo,
     hideInfo,
-    handleHover
+    handleHover,
+    creatMask,
+    trackPlayback
   };
 }

+ 119 - 8
src/utils/olMap/olMap.ts

@@ -18,8 +18,14 @@ import { Fill, Stroke } from 'ol/style';
 import proj4 from 'proj4';
 import { register } from 'ol/proj/proj4';
 import { defaults } from 'ol/control';
+import Vector from 'ol/layer/Vector';
+import SourceVector from 'ol/source/Vector';
+import GeoJSON from 'ol/format/GeoJSON';
 import { fromLonLat } from 'ol/proj';
 import axios from 'axios';
+import { fromExtent } from 'ol/geom/Polygon';
+import { LinearRing, Polygon } from 'ol/geom';
+import { Tile } from 'ol';
 // import olPlot from 'ol-plot';
 // import { activate } from '../ol-plot/ol-plot'
 
@@ -57,6 +63,7 @@ export class olMap {
   private graphicsType = '';
   private plot;
   private vectorLayer;
+  private maskLayer;
 
   constructor(options) {
     this.options = options;
@@ -94,7 +101,7 @@ export class olMap {
       // 如果 options.id 不是数组,但确实是一个图层,则直接处理
       await this.formatXml(options.id);
     }
-    console.log('wan')
+    console.log('wan');
     // 创建Vector层并添加到地图上
     this.vectorLayer = new VectorLayer({
       source: new VectorSource({
@@ -156,7 +163,7 @@ export class olMap {
     layer.set('layerName', code);
 
     this.map.addLayer(layer);
-    console.log(code)
+    console.log(code);
   }
 
   // 初始化绘画工具
@@ -170,7 +177,6 @@ export class olMap {
       fillOpacity: options.drawType === '1' ? 0 : 0.5,
       strokeStyle: 'solid'
     };
-    // debugger
     // this.plot = new olPlot(this.map, {
     //   zoomToExtent: true,
     //   ...this.drawOptions
@@ -233,25 +239,24 @@ export class olMap {
     this.map.addLayer(this.vectorLayer);
     const point = JSON.parse(JSON.stringify(this.markers));
     this.markers = [];
-    this.addMarker(point)
+    this.addMarker(point);
   }
 
   addMarker(points) {
-
+    this.clearMarker('point');
     points.forEach((point) => {
       // 创建标注点
       const feature = new Feature({
-        geometry: new Point([point.longitude, point.latitude]),
+        geometry: new Point(point.lnglat),
         name: point.name
       });
-
       // 定义样式
       const style = new Style({
         image: new Icon({
           anchor: [0.5, point.size[1]],
           anchorXUnits: 'fraction',
           anchorYUnits: 'pixels',
-          src: point.image
+          src: point.icon
         }),
         text: new Text({
           text: point.name,
@@ -276,4 +281,110 @@ export class olMap {
     if (!this.vectorLayer) return;
     this.vectorLayer.getSource().clear();
   }
+
+  /**
+   *
+   * @param {Geojon} chaozhou 根据geojson对象创建Featrue对象
+   * @param {String} layerName 图层名称
+   * @returns VectorLayer
+   */
+  createVecByJson(json, layerName = '') {
+    const format = new GeoJSON();
+    const fs = format.readFeatures(json);
+    const converLayer = new VectorLayer({
+      source: new VectorSource(),
+      style: new Style({
+        fill: new Fill({
+          color: 'rgba(16, 36, 59, 0.65)'
+        }),
+        stroke: new Stroke({
+          color: 'rgba(38, 138, 185, 1)',
+          width: 2
+        })
+      }),
+      zIndex: 99
+    });
+    this.map.addLayer(converLayer);
+    const extent = [-180, -90, 180, 90];
+    const polygonRing = fromExtent(extent);
+    fs.forEach((x) => {
+      const ft = x.values_.geometry;
+      const coords = ft.getCoordinates();
+      coords.forEach((coord) => {
+        const linearRing = new LinearRing(coord[0]);
+        polygonRing.appendLinearRing(linearRing);
+      });
+    });
+    const convertFt = new Feature({
+      geometry: polygonRing
+    });
+    converLayer.getSource().addFeature(convertFt);
+  }
+
+  /**
+   * @description 创建矢量图层
+   * @param {String} layerName 图层名称
+   * @param {Number} zIndex 地图层级默认是0
+   * @returns
+   */
+  createVecLayer(layerName = '', zIndex = 0) {
+    const source = new SourceVector({
+      crossOrigin: 'anonymous'
+    });
+    const layer = new Vector({
+      source,
+      zIndex
+    });
+    layer.set('layerName', layerName);
+    return layer;
+  }
+  // 分布图遮罩层
+  createMask(data) {
+    this.removeMask();
+    if (!data || data.length === 0) return;
+    data.forEach((item) => {
+      if (!item.points || item.points.length === 0) return;
+      // 遮罩图层的样式
+      const maskStyle = new Style({
+        fill: new Fill({
+          color: item.color // 红色遮罩,50%透明度
+        }),
+        stroke: new Stroke({
+          color: 'rgba(159,159,159,0.7)',
+          width: 1
+        })
+      });
+
+      // 遮罩图层的矢量数据源(初始为空)
+      const maskSource = new VectorSource();
+      // 创建一个多边形特征
+      const polygonFeature = new Feature({
+        geometry: new Polygon(item.points)
+      });
+      const maskLayer = new VectorLayer({
+        source: maskSource,
+        style: maskStyle,
+        properties: {
+          name: 'mask'
+        }
+      });
+      this.map.addLayer(maskLayer);
+      // 将多边形特征添加到遮罩数据源中
+      maskSource.addFeature(polygonFeature);
+    });
+  }
+  removeMask() {
+    //移除图层
+    const layersArray = this.map.getLayers().getArray();
+    const layers = [];
+    layersArray.forEach((layer) => {
+      // 检查图层是否有自定义属性,并且该属性是否匹配你要移除的图层的标识符
+      if (layer.get('name') === 'mask') {
+        layers.push(layer);
+      }
+    });
+    layers.forEach((layer) => {
+      this.map.removeLayer(layer);
+    });
+  }
 }

+ 4 - 1
src/views/mobileControl/index.vue

@@ -51,7 +51,7 @@
           <i class="material-btn" />
           <div>物资</div>
         </div>
-        <div class="button2">
+        <div class="button2" @click="handleJumpEvent">
           <i class="event-btn" />
           <div>事件</div>
         </div>
@@ -222,6 +222,9 @@ let showPositionSelect = ref(false);
 const handleShowPosition = () => {
   showPositionSelect.value = true;
 };
+const handleJumpEvent = () => {
+  router.push({ name: 'EventList' });
+}
 const handleEnterCommand = res => {
   temp.value = true;
   eventId.value = res.event_id;

+ 8 - 8
src/views/worker/rescueManagement/index.vue

@@ -78,28 +78,28 @@ const handleClickTab = (id) => {
     overflow-y: auto;
   }
   .tab1 {
-    background: url("@/assets/images/tab4.png") no-repeat;
+    background: url("@/assets/images/tab8.png") no-repeat;
   }
   .tab1_checked {
-    background: url("@/assets/images/tab4_checked.png") no-repeat;
+    background: url("@/assets/images/tab8_checked.png") no-repeat;
   }
   .tab2 {
-    background: url("@/assets/images/tab5.png") no-repeat;
+    background: url("@/assets/images/tab9.png") no-repeat;
   }
   .tab2_checked {
-    background: url("@/assets/images/tab5_checked.png") no-repeat;
+    background: url("@/assets/images/tab9_checked.png") no-repeat;
   }
   .tab3 {
-    background: url("@/assets/images/tab6.png") no-repeat;
+    background: url("@/assets/images/tab10.png") no-repeat;
   }
   .tab3_checked {
-    background: url("@/assets/images/tab6_checked.png") no-repeat;
+    background: url("@/assets/images/tab10_checked.png") no-repeat;
   }
   .tab4 {
-    background: url("@/assets/images/tab7.png") no-repeat;
+    background: url("@/assets/images/tab11.png") no-repeat;
   }
   .tab4_checked {
-    background: url("@/assets/images/tab7_checked.png") no-repeat;
+    background: url("@/assets/images/tab11_checked.png") no-repeat;
   }
   .tab1, .tab1_checked, .tab2, .tab2_checked, .tab3, .tab3_checked, .tab4, .tab4_checked {
     width: 48px;