Browse Source

项目工作空间-实时轨迹

李富豪 1 year ago
parent
commit
1d0fb00c7d

+ 6 - 2
Web/src/components/GMap.vue

@@ -690,6 +690,12 @@ export default defineComponent({
       }, 1000)
     }, { deep: true })
 
+    watch(() => store.state.realTimeTrajectory, newData => {// 实时轨迹绘制
+      const trajectoryHook = useGMapTrajectory()
+      const deviceInfo = store.state.deviceState.deviceInfo[newData.sn]
+      trajectoryHook.drawDynamicTrajectory(newData.sn, deviceInfo, newData.host)
+    }, { deep: true })
+
     watch(() => store.state.deviceStatusEvent, (data: any) => {
       if (Object.keys(data.deviceOnline).length !== 0) {
         deviceTsaUpdateHook.initMarker(data.deviceOnline.domain, data.deviceOnline.device_callsign, data.deviceOnline.sn)
@@ -779,12 +785,10 @@ export default defineComponent({
         store.state.wsEvent.mapElementCreat = {}
       }
       if (Object.keys(event.mapElementUpdate).length !== 0) {
-        console.log(event.mapElementUpdate)
         console.log('该功能还未实现,请开发商自己增加')
         store.state.wsEvent.mapElementUpdate = {}
       }
       if (Object.keys(event.mapElementDelete).length !== 0) {
-        console.log(event.mapElementDelete)
         console.log('该功能还未实现,请开发商自己增加')
         store.state.wsEvent.mapElementDelete = {}
       }

+ 0 - 1
Web/src/components/g-map/DeviceSettingBox.vue

@@ -171,7 +171,6 @@ const deviceSettingFormModel = ref(cloneDeep(initDeviceSettingFormModel)) // 真
 watch(() => props.deviceInfo, (value) => {
   updateDeviceSettingInfoByOsd(deviceSetting.value, value)
   updateDeviceSettingFormModelByOsd(deviceSettingFormModelFromOsd.value, value)
-  // console.log('deviceInfo', value)
 }, {
   immediate: true,
   deep: true

+ 0 - 1
Web/src/components/livestream-others.vue

@@ -153,7 +153,6 @@ const onRefresh = async () => {
   videoSelected.value = null
   await getLiveCapacity({})
     .then(res => {
-      console.log(res)
       if (res.code === 0) {
         if (res.data === null) {
           console.warn('警告:获取直播容量为空!!')

+ 121 - 1
Web/src/hooks/use-g-map-trajectory.ts

@@ -1,9 +1,18 @@
 import { getRoot } from '/@/root'
 import hardstandSrc from '/@/assets/icons/hardstand.png'
+import droneIcon from '/@/assets/icons/drone.png'
+import { wgs84togcj02 } from '/@/vendors/coordtransform'
+import rootStore from '/@/store'
 
 export function useGMapTrajectory() {
   const root = getRoot();
   let AMap = root.$aMap;
+  const store = rootStore
+  const coverMap = store.state.coverMap
+
+  // 删除
+  // coverMap[id].forEach(cover => root.$map.remove(cover))
+  // coverMap[id] = []
 
   // 绘制轨迹
   const drawTrajectory = (list: any[]) => {
@@ -81,7 +90,118 @@ export function useGMapTrajectory() {
     root.$map.setFitView([startMarker, polyline]);
   }
 
+  // 绘制动态轨迹
+  const drawDynamicTrajectory = (sn: string, deviceInfo: any, host: any[]) => {
+    if (coverMap[sn] && coverMap[sn].length) {// 如果地图已经画过了,先清除掉之前的绘画结果
+      coverMap[sn].forEach(cover => root.$map.remove(cover))
+      coverMap[sn] = []
+    }
+    const list = host.map((item: any) => {
+      const data = {
+        ...item,
+        paths: wgs84togcj02(item.longitude, item.latitude),
+      }
+      delete data.latitude;
+      delete data.longitude;
+      return data;
+    });
+    const paths = list.map(item => item.paths);
+    // 绘制轨迹折线
+    const polyline = new AMap.Polyline({
+      path: paths,
+      strokeColor: '#2D8CF0',
+      showDir: true,// 显示路线白色方向箭头
+      strokeOpacity: 1,// 轮廓线透明度
+      strokeWeight: 6,//线宽
+      strokeStyle: 'solid',
+    })
+    const serialList = list.filter((item) => item.type === 1);
+    // 序号
+    const text = serialList.map((item, index) => {
+      return new AMap.Text({
+        position: new AMap.LngLat(item.paths[0], item.paths[1]),
+        offset: new AMap.Pixel(-8, -30),
+        text: index + 1,
+        style: {
+          backgroundColor: 'transparent',
+          borderColor: 'transparent',
+        }
+      })
+    })
+    // 序号下方圆形标记
+    const circles = serialList.map((item, index) => {
+      return new AMap.Circle({
+        center: new AMap.LngLat(item.paths[0], item.paths[1]),
+        radius: 0.5, // 半径
+        // strokeColor: 'white',
+        fillColor: 'white',
+        fillOpacity: 1,
+        strokeWeight: 2,
+      });
+    })
+    // 计算并显示每段线的距离
+    const distances = [];
+    const serialPaths = serialList.map(item => item.paths)
+    for (let i = 0; i < serialPaths.length - 1; i++) {
+      const distance = AMap.GeometryUtil.distance(new AMap.LngLat(serialPaths[i][0], serialPaths[i][1]), new AMap.LngLat(serialPaths[i + 1][0], serialPaths[i + 1][1]));
+      // 计算两个点之间的中点坐标
+      const midLng = (serialPaths[i][0] + serialPaths[i + 1][0]) / 2;
+      const midLat = (serialPaths[i][1] + serialPaths[i + 1][1]) / 2;
+      const midPoint = new AMap.LngLat(midLng, midLat);
+      // 在中点位置放置文本以显示距离
+      const distanceText = new AMap.Text({
+        position: midPoint,
+        offset: new AMap.Pixel(-16, 10),
+        text: `${distance.toFixed(1)} m`,// 距离
+        style: {
+          fontSize: '10px',
+          color: '#FFFFFF',
+          backgroundColor: 'rgba(0, 0, 0, 0.75)',
+          borderColor: 'transparent',
+        },
+      });
+      distances.push(distanceText);
+    }
+    const other = [polyline, ...text, ...circles, ...distances]
+    // 获取起飞点
+    const homeList = list.filter(item => item.type === 0);
+    if (homeList.length) {
+      const startPosition = homeList[0].paths;
+      const startIcon = new AMap.Icon({
+        size: new AMap.Size(30, 30),
+        image: hardstandSrc,
+        imageSize: new AMap.Size(30, 30)
+      })
+      const startMarker = new AMap.Marker({
+        position: new AMap.LngLat(startPosition[0], startPosition[startPosition.length - 1]),
+        icon: startIcon,
+        offset: new AMap.Pixel(-20, -35),// 位置偏移
+      })
+      other.push(startMarker);
+    }
+    // 绘制小飞机图标
+    if (list.length) {
+      const path = list[list.length - 1].paths;
+      const angle = deviceInfo.attitude_head;// 角度
+      const startIcon = new AMap.Icon({
+        size: new AMap.Size(40, 40),
+        image: droneIcon,
+        imageSize: new AMap.Size(40, 40)
+      })
+      const endMarker = new AMap.Marker({
+        position: new AMap.LngLat(path[0], path[path.length - 1]),
+        icon: startIcon,
+        offset: new AMap.Pixel(-20, -20),// 位置偏移
+        angle: angle,// 旋转角度
+      })
+      other.push(endMarker);
+    }
+    root.$map.add(other)
+    coverMap[sn] = [other]
+  }
+
   return {
-    drawTrajectory
+    drawTrajectory,
+    drawDynamicTrajectory
   }
 }

+ 0 - 1
Web/src/pages/page-web/home.vue

@@ -53,7 +53,6 @@ onMounted(() => {
     root.$router.push(ERouterName.PROJECT)
   }
 })
-
 </script>
 
 <style lang="scss" scoped>

+ 0 - 5
Web/src/pages/page-web/projects/media/index/index.vue

@@ -287,11 +287,6 @@ const onClickDownload = async (record: any) => {
     state.downloadLoading = false;
   }
 }
-
-// 点击轨迹回放
-const onClickTrajectory = () => {
-  router.push({ path: '/trajectory' })
-}
 </script>
 
 <style lang="scss">

+ 4 - 0
Web/src/pages/page-web/projects/workspace.vue

@@ -28,6 +28,10 @@ const messageHandler = async (payload: any) => {
     return
   }
   switch (payload.biz_code) {
+    case EBizCode.DroneFlyTrack: {// 实时轨迹
+      store.commit('SET_REAL_TIME_TRAJECTORY', payload.data)
+      break
+    }
     case EBizCode.GatewayOsd: {
       store.commit('SET_GATEWAY_INFO', payload.data)
       break

+ 7 - 0
Web/src/store/index.ts

@@ -9,6 +9,10 @@ import { DevicesCmdExecuteInfo } from '/@/types/device-cmd'
 
 const initStateFunc = () => ({
   trajectoryList: [],// 轨迹列表
+  realTimeTrajectory: {// 实时轨迹
+    sn: '',
+    host: []
+  },
   mapClickElement: {
     id: '',
     type: '',
@@ -106,6 +110,9 @@ const mutations: MutationTree<RootStateType> = {
   SET_TRAJECTORY_LIST(state, list) {
     state.trajectoryList = list
   },
+  SET_REAL_TIME_TRAJECTORY(state, info) {
+    state.realTimeTrajectory = info
+  },
   SET_MAP_CLICK_ELEMENT(state, info) {
     state.mapClickElement = info
   },

+ 1 - 0
Web/src/types/enums.ts

@@ -86,6 +86,7 @@ export enum EUserType {
 }
 
 export enum EBizCode {
+    DroneFlyTrack = 'drone_fly_track',// 实时飞行轨迹
     GatewayOsd = 'gateway_osd',
     DeviceOsd = 'device_osd',
     DockOsd = 'dock_osd',