Bladeren bron

地图调整

Hwf 6 maanden geleden
bovenliggende
commit
0a46c543ef
2 gewijzigde bestanden met toevoegingen van 174 en 101 verwijderingen
  1. 3 4
      src/hooks/AMap/useAMap.ts
  2. 171 97
      src/utils/olMap/olMap.ts

+ 3 - 4
src/hooks/AMap/useAMap.ts

@@ -398,14 +398,13 @@ export function useAMap(options) {
     }
   };
   let moveMarker, movePolyline, movePassedPolyline, timerId;
-  const trackPlayback = (lineArr) => {
+  const trackPlayback = (lineArr, speed = 1000) => {
     if (timerId) {
       clearTimeout(timerId);
     }
     movePolyline?.remove();
     movePassedPolyline?.remove();
     moveMarker?.remove();
-    let index = 0;
     const icon = new AMap.Icon({
       size: new AMap.Size(13, 26),
       image: carImg
@@ -450,11 +449,11 @@ export function useAMap(options) {
     // });
     moveMarker.moveAlong(lineArr, {
       // 每一段的时长
-      duration: 1000, //可根据实际采集时间间隔设置
+      duration: speed, //可根据实际采集时间间隔设置
       // JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
       autoRotation: true
     });
-    return [movePolyline, movePassedPolyline, moveMarker];
+    return { movePolyline, movePassedPolyline, moveMarker };
   };
 
   const drawData = (data) => {

+ 171 - 97
src/utils/olMap/olMap.ts

@@ -30,7 +30,7 @@ import { getPointsCenter, mergeGeoJsonPolygons } from '@/utils/gisUtils';
 import { Cluster } from 'ol/source';
 import CircleStyle from 'ol/style/Circle';
 import Overlay from 'ol/Overlay';
-import { Draw, Select } from 'ol/interaction';
+import { DoubleClickZoom, DragPan, Draw, Select } from 'ol/interaction';
 import { click } from 'ol/events/condition';
 import Circle from 'ol/geom/Circle';
 import { deepClone, getRgba, hexToRgba, initDrag, rgbToRgba } from '@/utils';
@@ -93,6 +93,7 @@ export class olMap {
   private traceFeature;
   // 自定义绘制结束调用方法
   private drawEndMethod;
+  private selectedFeature;
 
   constructor(options) {
     this.options = options;
@@ -136,6 +137,7 @@ export class olMap {
     // 创建选择交互
     this.select = new Select({
       condition: click,
+      style: null,
       filter: (feature, layer) => {
         // 只有vectorLayer图层可选择
         return layer === this.vectorLayer;
@@ -150,20 +152,16 @@ export class olMap {
         const originalFeature = features[0];
         const size = features.length;
         if (size === 1) {
-          // 设置新的样式(更换图标)
-          selectedFeatures.setStyle(
-              new Style({
-                image: new Icon({
-                  anchor: [0.5, 0.5],
-                  scale: 0.146,
-                  anchorXUnits: 'fraction',
-                  anchorYUnits: 'pixels',
-                  src: originalFeature.get('imageHover')
-                })
-              })
-          );
-          const extData = originalFeature.get('extData');
-          options.onMarkerClick(extData);
+          if (this.selectedFeature !== originalFeature) {
+            if (this.selectedFeature) {
+              this.selectedFeature.set('icon', this.selectedFeature.get('image'));
+            }
+            this.selectedFeature = originalFeature;
+            const icon = originalFeature.get('imageHover');
+            const extData = originalFeature.get('extData');
+            originalFeature.set('icon', icon);
+            options.onMarkerClick(extData);
+          }
         } else {
           // 聚合要素
           this.select.getFeatures().clear();
@@ -311,7 +309,6 @@ export class olMap {
     // 继续编辑编辑
     this.drawGraphics(this.drawOptions.graphicsType);
   }
-
   // 绘制图形
   drawGraphics(newOptions: MouseTool) {
     const typeList = {
@@ -321,9 +318,9 @@ export class olMap {
       measureArea: 'Polygon',
       straightLine: 'LineString',
       marker: 'Point',
-      text: 'Point'
+      text: 'Point',
+      anyLine: 'AnyLine'
     };
-    debugger
     const data = getRgba(newOptions.color);
     let geometryFunction = null;
     if (newOptions.graphicsType === 'rectangle') {
@@ -359,52 +356,56 @@ export class olMap {
           this.drawOptions.size = newOptions.size;
         }
         this.closeDraw();
-        // 创建绘制交互
-        let style = new Style({
-          stroke: new Stroke({
-            color: rgbToRgba(this.drawOptions.strokeColor, this.drawOptions.strokeOpacity),
-            width: this.drawOptions.strokeWeight
-          }),
-          fill: new Fill({
-            color: rgbToRgba(this.drawOptions.fillColor, this.drawOptions.fillOpacity)
-          })
-        });
-        this.drawTool = new Draw({
-          source: this.drawVector.getSource(),
-          type: typeList[newOptions.graphicsType],
-          geometryFunction: geometryFunction,
-          style: style
-        });
-        // 添加绘制交互到地图
-        this.map.addInteraction(this.drawTool);
-        // 监听绘制结束事件
-        this.drawTool.on('drawend', (event) => {
-          const feature = event.feature;
-          // 获取几何对象
-          if (newOptions.graphicsType !== 'marker') {
-            if (newOptions.graphicsType === 'measureArea') {
-              const geometry = feature.getGeometry();
-              const coordinates = geometry.getCoordinates();
-              const pathArr = coordinates[0];
-              const area = turf.area(turf.polygon([pathArr]));
-              style = new Style({
-                stroke: style.getStroke(),
-                fill: style.getFill(),
-                text: new Text({
-                  text: '区域面积' + area.toFixed(2) + '平方米',
-                  font: '14px Calibri,sans-serif',
-                  fill: new Fill({ color: '#000' }),
-                  stroke: new Stroke({
-                    color: '#fff',
-                    width: 3
-                  }),
-                  overflow: true
-                })
-              });
+        if (newOptions.graphicsType === 'anyLine') {
+          this.drawAnyLine();
+        } else {
+          // 创建绘制交互
+          let style = new Style({
+            stroke: new Stroke({
+              color: rgbToRgba(this.drawOptions.strokeColor, this.drawOptions.strokeOpacity),
+              width: this.drawOptions.strokeWeight
+            }),
+            fill: new Fill({
+              color: rgbToRgba(this.drawOptions.fillColor, this.drawOptions.fillOpacity)
+            })
+          });
+          this.drawTool = new Draw({
+            source: this.drawVector.getSource(),
+            type: typeList[newOptions.graphicsType],
+            geometryFunction: geometryFunction,
+            style: style
+          });
+          // 添加绘制交互到地图
+          this.map.addInteraction(this.drawTool);
+          // 监听绘制结束事件
+          this.drawTool.on('drawend', (event) => {
+            const feature = event.feature;
+            // 获取几何对象
+            if (newOptions.graphicsType !== 'marker') {
+              if (newOptions.graphicsType === 'measureArea') {
+                const geometry = feature.getGeometry();
+                const coordinates = geometry.getCoordinates();
+                const pathArr = coordinates[0];
+                const area = turf.area(turf.polygon([pathArr]));
+                style = new Style({
+                  stroke: style.getStroke(),
+                  fill: style.getFill(),
+                  text: new Text({
+                    text: '区域面积' + area.toFixed(2) + '平方米',
+                    font: '14px Calibri,sans-serif',
+                    fill: new Fill({ color: '#000' }),
+                    stroke: new Stroke({
+                      color: '#fff',
+                      width: 3
+                    }),
+                    overflow: true
+                  })
+                });
+              }
+              feature.setStyle(style);
             }
-            feature.setStyle(style);
-          }
-        });
+          });
+        }
       }
     }
     return this.drawOptions;
@@ -484,6 +485,74 @@ export class olMap {
     data.id = id;
     return { text, data };
   }
+  drawAnyLine() {
+    document.addEventListener('touchend', this.handleTouchEnd);
+    this.map.on('pointerdown', this.handleTouchStart);
+    this.map.on('pointermove', this.handleTouchMove.bind(null, this.options));
+    document.addEventListener('mouseup', this.handleTouchEnd.bind(null, this.options));
+  }
+  handleTouchStart(e) {
+    this.drawing = true;
+    const interactions = this.map.getInteractions();
+    interactions.forEach((interaction) => {
+      if (interaction instanceof DragPan || interaction instanceof DoubleClickZoom) {
+        interaction.setActive(false); // 修改为需要的值,true或false
+      }
+    });
+
+    this.path = [e.lnglat];
+    // if (this.anyLine) {
+    //   map.remove(anyLine);
+    // }
+  }
+  handleTouchMove(options, e) {
+    if (!this.drawing) return;
+    this.path.push(e.lnglat);
+    // if (anyLine) {
+    //   map.remove(anyLine);
+    // }
+    this.anyLine = new Feature({
+      geometry: new LineString(this.path) // path为坐标数组,如[[x1,y1], [x2,y2]]
+    });
+    const lineStyle = new Style({
+      stroke: new Stroke({
+        color: hexToRgba(options.strokeColor, options.strokeOpacity), // 合并颜色与透明度
+        width: options.strokeWeight,
+        lineJoin: 'round' // 线段连接处圆角
+      })
+    });
+    this.anyLine.setStyle(lineStyle);
+    //   new AMap.Polyline({
+    //   path: path,
+    //   strokeColor: options.strokeColor,
+    //   strokeOpacity: options.strokeOpacity,
+    //   strokeWeight: options.strokeWeight,
+    //   strokeStyle: options.strokeStyle,
+    //   lineJoin: 'round'
+    // });
+    this.drawVector.getSource().addFeature(this.anyLine);
+  }
+  handleTouchEnd(options) {
+    // drawing = false;
+    // map.setStatus({
+    //   showIndoorMap: true,
+    //   dragEnable: true,
+    //   keyboardEnable: true,
+    //   doubleClickZoom: true,
+    //   zoomEnable: true,
+    //   rotateEnable: true
+    // });
+    // map.off('touchstart', handleTouchStart);
+    // map.on('touchmove', handleTouchMove.bind(null, options));
+    // document.addEventListener('touchend', handleTouchEnd.bind(null, options));
+    // map.off('mousedown', handleTouchStart);
+    // map.off('mousemove', handleTouchMove);
+    // document.removeEventListener('mouseup', handleTouchEnd);
+    // if (!!drawEndMethod) {
+    //   drawEndMethod(options, anyLine);
+    // }
+    // anyLine = null;
+  }
   // 关闭绘制
   closeDraw() {
     if (!this.drawTool) return;
@@ -551,21 +620,46 @@ export class olMap {
         })
       ];
     }
-
-    return new Style({
+    const pointSize = originalFeature.get('size');
+    const originalWidth = originalFeature.get('originalWidth');
+    const originalHeight = originalFeature.get('originalHeight');
+    const icon = originalFeature.get('icon');
+    const name = originalFeature.get('name');
+    const showName = originalFeature.get('showName');
+    const scale = !!pointSize[0] ? pointSize[0] / originalWidth : 1;
+    const style = new Style({
       geometry: originalFeature.getGeometry(),
       image: new Icon({
+        src: icon,
+        scale: scale,
         anchor: [0.5, 0.5],
-        scale: 0.146,
         anchorXUnits: 'fraction',
-        anchorYUnits: 'pixels',
-        src: originalFeature.get('icon')
+        anchorYUnits: 'fraction'
       })
     });
+    if (!!showName) {
+      style.setText(
+          new Text({
+            text: name,
+            font: '12px sans-serif',
+            fill: new Fill({
+              color: '#000'
+            }),
+            stroke: new Stroke({
+              color: '#fff',
+              width: 3
+            }),
+            offsetY: (originalHeight / 2) * scale + 4
+          })
+      );
+    }
+    return style;
   }
   addMarker(points) {
     this.clearMarker();
-    const features = [];
+    const vectorSource = new VectorSource({
+      features: []
+    });
     points.forEach((point) => {
       // 创建标注点
       const feature = new Feature({
@@ -573,47 +667,27 @@ export class olMap {
         geometry: new Point([Number(point.longitude), Number(point.latitude)]),
         name: point.name,
         icon: point.icon,
+        image: point.icon,
         imageHover: point.imageHover,
         size: point.size,
+        showName: point.showName,
         pointer: true,
         extData: point
       });
       // 设置自定义属性
-      feature.set('pointer', true);
       const img = new Image();
       img.onload = () => {
         // 图片加载完成后,可以访问其 width 和 height 属性
         const width = img.width;
-        const height = img.height;
-        const style = new Style({
-          image: new Icon({
-            anchor: [0.5, 0.5],
-            anchorXUnits: 'fraction',
-            anchorYUnits: 'pixels',
-            src: point.icon,
-            size: [width, height],
-            scale: !!point.size[0] ? point.size[0] / width : 1
-          }),
-          text: new Text({
-            text: point.name,
-            fill: new Fill({
-              color: '#000'
-            }),
-            stroke: new Stroke({
-              color: '#fff',
-              width: 3
-            })
-          })
-        });
-        features.setStyle(style);
+        const height = img.width;
+        feature.set('originalWidth', width);
+        feature.set('originalHeight', height);
+        feature.set('img', img);
+        vectorSource.addFeature(feature);
       };
       img.src = point.icon; // 设置图片的 URL,触发加载
-      features.push(feature);
       this.markers.push(point);
     });
-    const vectorSource = new VectorSource({
-      features: features
-    });
     const clusterSource = new Cluster({
       distance: 30,
       source: vectorSource
@@ -1004,7 +1078,7 @@ export class olMap {
     this.traceFeature = new Feature({
       geometry: new LineString(lineArr)
     });
-    let route = new LineString(lineArr);
+    const route = new LineString(lineArr);
     this.carLayer = new VectorLayer({
       source: source,
       style: new Style({