瀏覽代碼

粤政图 车辆轨迹

Hwf 4 月之前
父節點
當前提交
0336f57754

二進制
src/assets/images/car.png


+ 1 - 1
src/components/Map/YztMap/index.vue

@@ -72,7 +72,7 @@ watch(
   }
   }
 );
 );
 const mapList = reactive({
 const mapList = reactive({
-  satellite2: ['YZT1715739306532', 'YZT1695608158269'],
+  satellite2: ['YZT1712111943104', 'YZT1695608158269'],
   satellite3: ['YZT1708679726700', 'YZT1695608158269'],
   satellite3: ['YZT1708679726700', 'YZT1695608158269'],
   imageMap: ['YZT1640925052482', 'YZT1695608158269'],
   imageMap: ['YZT1640925052482', 'YZT1695608158269'],
   imageMap2: ['YZT1640925052482', 'YZT1695608158269']
   imageMap2: ['YZT1640925052482', 'YZT1695608158269']

+ 2 - 1
src/hooks/AMap/useAMap.ts

@@ -2,6 +2,7 @@ import AMapLoader from '@amap/amap-jsapi-loader';
 import { nanoid } from 'nanoid';
 import { nanoid } from 'nanoid';
 import { deepClone, initDrag } from '@/utils';
 import { deepClone, initDrag } from '@/utils';
 import { mergeGeoJsonPolygons, wgs_gcj_encrypts } from '@/utils/gisUtils';
 import { mergeGeoJsonPolygons, wgs_gcj_encrypts } from '@/utils/gisUtils';
+import carImg from '@/assets/images/car.png';
 
 
 export function useAMap(options) {
 export function useAMap(options) {
   let AMap, map, nowLayer, labelsLayer, scale, cluster;
   let AMap, map, nowLayer, labelsLayer, scale, cluster;
@@ -407,7 +408,7 @@ export function useAMap(options) {
     let index = 0;
     let index = 0;
     const icon = new AMap.Icon({
     const icon = new AMap.Icon({
       size: new AMap.Size(26, 52),
       size: new AMap.Size(26, 52),
-      image: 'https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png'
+      image: carImg
     });
     });
     moveMarker = new AMap.Marker({
     moveMarker = new AMap.Marker({
       map: map,
       map: map,

+ 3 - 0
src/types/auto-imports.d.ts

@@ -43,6 +43,7 @@ declare global {
   const getCurrentInstance: typeof import('vue')['getCurrentInstance']
   const getCurrentInstance: typeof import('vue')['getCurrentInstance']
   const getCurrentScope: typeof import('vue')['getCurrentScope']
   const getCurrentScope: typeof import('vue')['getCurrentScope']
   const h: typeof import('vue')['h']
   const h: typeof import('vue')['h']
+  const iconFeature: typeof import('~icons/fe/ature')['default']
   const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
   const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
   const inject: typeof import('vue')['inject']
   const inject: typeof import('vue')['inject']
   const injectLocal: typeof import('@vueuse/core')['injectLocal']
   const injectLocal: typeof import('@vueuse/core')['injectLocal']
@@ -349,6 +350,7 @@ declare module 'vue' {
     readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
     readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
     readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
     readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
     readonly h: UnwrapRef<typeof import('vue')['h']>
     readonly h: UnwrapRef<typeof import('vue')['h']>
+    readonly iconFeature: UnwrapRef<typeof import('~icons/fe/ature')['default']>
     readonly ignorableWatch: UnwrapRef<typeof import('@vueuse/core')['ignorableWatch']>
     readonly ignorableWatch: UnwrapRef<typeof import('@vueuse/core')['ignorableWatch']>
     readonly inject: UnwrapRef<typeof import('vue')['inject']>
     readonly inject: UnwrapRef<typeof import('vue')['inject']>
     readonly injectLocal: UnwrapRef<typeof import('@vueuse/core')['injectLocal']>
     readonly injectLocal: UnwrapRef<typeof import('@vueuse/core')['injectLocal']>
@@ -648,6 +650,7 @@ declare module '@vue/runtime-core' {
     readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
     readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
     readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
     readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
     readonly h: UnwrapRef<typeof import('vue')['h']>
     readonly h: UnwrapRef<typeof import('vue')['h']>
+    readonly iconFeature: UnwrapRef<typeof import('~icons/fe/ature')['default']>
     readonly ignorableWatch: UnwrapRef<typeof import('@vueuse/core')['ignorableWatch']>
     readonly ignorableWatch: UnwrapRef<typeof import('@vueuse/core')['ignorableWatch']>
     readonly inject: UnwrapRef<typeof import('vue')['inject']>
     readonly inject: UnwrapRef<typeof import('vue')['inject']>
     readonly injectLocal: UnwrapRef<typeof import('@vueuse/core')['injectLocal']>
     readonly injectLocal: UnwrapRef<typeof import('@vueuse/core')['injectLocal']>

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

@@ -37,6 +37,7 @@ import { deepClone, hexToRgba, initDrag } from '@/utils';
 import { createBox } from 'ol/interaction/Draw';
 import { createBox } from 'ol/interaction/Draw';
 import * as turf from '@turf/turf';
 import * as turf from '@turf/turf';
 import { nanoid } from 'nanoid';
 import { nanoid } from 'nanoid';
+import carImg from '@/assets/images/car.png';
 
 
 const tk = 'a8df87f1695d224d2679aa805c1268d9';
 const tk = 'a8df87f1695d224d2679aa805c1268d9';
 const commonUrl = import.meta.env.VITE_APP_BASE_API2 + 'api/oneShare/proxyHandler/gd/';
 const commonUrl = import.meta.env.VITE_APP_BASE_API2 + 'api/oneShare/proxyHandler/gd/';
@@ -86,6 +87,10 @@ export class olMap {
   // 显示信息框
   // 显示信息框
   private infoWindow;
   private infoWindow;
   private select;
   private select;
+  // 车辆轨迹
+  private carLayer;
+  private carFeature;
+  private traceFeature;
 
 
   constructor(options) {
   constructor(options) {
     this.options = options;
     this.options = options;
@@ -927,6 +932,95 @@ export class olMap {
     this.drawVector.getSource().addFeature(feature);
     this.drawVector.getSource().addFeature(feature);
     return feature;
     return feature;
   }
   }
+  trackPlayback(lineArr) {
+    if (!!this.carFeature) {
+      this.carLayer.getSource().removeFeature(this.carFeature);
+    }
+    if (!!this.traceFeature) {
+      this.carLayer.getSource().removeFeature(this.traceFeature);
+    }
+    const getAngle = (point1, point2) => {
+      let arc = 0;
+      if (point2 && point2.length && point1 && point1.length) {
+        if ((point2[0] - point1[0] >= 0 && point2[1] - point1[1] >= 0) || (point2[0] - point1[0] < 0 && point2[1] - point1[1] > 0)) {
+          arc = Math.atan((point2[0] - point1[0]) / (point2[1] - point1[1]));
+        } else if ((point2[0] - point1[0] > 0 && point2[1] - point1[1] < 0) || (point2[0] - point1[0] < 0 && point2[1] - point1[1] < 0)) {
+          arc = Math.PI + Math.atan((point2[0] - point1[0]) / (point2[1] - point1[1]));
+        }
+      }
+      return arc;
+    };
+    let lastTime = Date.now();
+    const source = new VectorSource();
+    let distance = 0;
+    const angle = getAngle(lineArr[0], lineArr[1]);
+    const speed = 500;
+    let animationFlag = false;
+    this.carFeature = new Feature({
+      geometry: new Point(lineArr[0])
+    });
+    const icon = new Icon({
+      crossOrigin: 'anonymous',
+      src: carImg,
+      width: 26,
+      height: 52,
+      rotation: angle
+    });
+    this.carFeature.setStyle(
+      new Style({
+        image: icon
+      })
+    );
+    this.traceFeature = new Feature({
+      geometry: new LineString(lineArr)
+    });
+    let route = new LineString(lineArr);
+    this.carLayer = new VectorLayer({
+      source: source,
+      style: new Style({
+        stroke: new Stroke({
+          color: 'rgb(37,232,142)',
+          width: 5
+        })
+      })
+    });
+    this.carLayer.getSource().addFeatures([this.carFeature, this.traceFeature]);
+    const move = (e) => {
+      const time = e.frameState.time;
+      // 时间戳差(毫秒)
+      const elapsedTime = time - lastTime;
+      // 距离(其实是比例的概念)
+      distance = distance + (speed * elapsedTime) / 1e6;
+      if (distance >= 1) {
+        distance = 0;
+        animationFlag = false;
+        stopAnimation();
+        return;
+      }
+      // 保存当前时间
+      lastTime = time;
+      // 上次坐标
+      const lastCoord = this.carFeature.getGeometry().getCoordinates();
+      // 获取新位置的坐标点
+      const curCoord = route.getCoordinateAt(distance);
+      // 设置新坐标
+      this.carFeature.getGeometry().setCoordinates(curCoord);
+      this.map.getView().setCenter(curCoord);
+      // 设置角度
+      this.carFeature.getStyle().getImage().setRotation(getAngle(lastCoord, curCoord));
+      // 调用地图渲染
+      this.map.render();
+    };
+
+    const stopAnimation = () => {
+      this.carLayer.un('postrender', move);
+    };
+    this.map.addLayer(this.carLayer);
+    this.carLayer.on('postrender', move);
+    // 触发地图渲染
+    const geo = this.carFeature.getGeometry().clone();
+    this.carFeature.setGeometry(geo);
+  }
   getVectorLayer() {
   getVectorLayer() {
     return this.vectorLayer;
     return this.vectorLayer;
   }
   }

+ 1 - 1
src/views/globalMap/index.vue

@@ -285,7 +285,7 @@ const getPlaceSearch = () => {
 };
 };
 const trackPlayback = (data) => {
 const trackPlayback = (data) => {
   if (YMapType.includes(activeMap.value)) {
   if (YMapType.includes(activeMap.value)) {
-    return map2Ref.value.trackPlayback(data);
+    return map2Ref.value.getMapUtils().trackPlayback(data);
   } else if (AMapType.includes(activeMap.value)) {
   } else if (AMapType.includes(activeMap.value)) {
     return mapRef.value.trackPlayback(data);
     return mapRef.value.trackPlayback(data);
   }
   }