From a0f008e1b176ab0c844bc4721f282e12d18f855c Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Mon, 24 Feb 2025 18:20:11 +0800
Subject: [PATCH] 调整详情和修改地图渲染功能

---
 src/views/DronePilotDetails-copy1.vue    |  754 ++++++++++
 src/views/DronePilotDetails-copy3.vue    |  675 +++++++++
 src/views/DronePilotDetails.vue          |  170 +
 src/main.ts                              |    3 
 src/api/http/request.ts                  |   54 
 src/views/DronePilotDetails-copy2.vue    |  708 +++++++++
 src/views/components/ptzControl.vue      |   76 
 src/views/DronePilotDetails-copy.vue     |    2 
 src/views/hooks/droneFly-copy.ts         |  664 +++++++++
 src/views/hooks/droneFly.ts              |  393 +---
 src/api/http/request-copy.ts             |  212 ++
 src/views/components/ptzControl-copy.vue |  564 +++++++
 src/router/index.ts                      |    4 
 src/views/DronePilotList.vue             |   11 
 src/views/components/controlConsole.vue  |    6 
 15 files changed, 3,858 insertions(+), 438 deletions(-)

diff --git a/src/api/http/request-copy.ts b/src/api/http/request-copy.ts
new file mode 100644
index 0000000..5186bda
--- /dev/null
+++ b/src/api/http/request-copy.ts
@@ -0,0 +1,212 @@
+/**
+ * 全站http配置
+ *
+ * axios参数说明
+ * isSerialize是否开启form表单提交
+ * isToken是否需要token
+ */
+import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
+import store from '@/store/user'
+import router from '@/router';
+import { serialize } from '@/utils/common'
+import { getToken } from '@/utils/auth';
+import { ElMessage } from 'element-plus';
+import website from '@/config/website';
+import { Base64 } from 'js-base64'
+// import NProgress from 'nprogress';
+// import 'nprogress/nprogress.css';
+import { ELocalStorageKey } from '@/utils/enums';
+export * from './type'
+
+// 自定义响应类型
+interface CustomAxiosResponse<T = any> extends AxiosResponse<T> {
+  data: T
+}
+
+// 定义你的请求类型
+interface CustomAxiosRequestConfig extends AxiosRequestConfig {
+  // 是否开启鉴权
+  authorization?: boolean
+}
+
+type CustomAxiosConfig = {
+  [x: string]: any
+  <T = any, R = CustomAxiosResponse<T>, D = CustomAxiosRequestConfig>(config: D): Promise<R>
+}
+
+const REQUEST_ID = 'X-Request-Id'
+
+const getAuthToken = () => {
+  return localStorage.getItem(ELocalStorageKey.Token)
+}
+
+const instance: CustomAxiosConfig = axios.create({
+  // withCredentials: true,
+  headers: {
+    'Content-Type': 'application/json',
+  },
+  baseURL: '/api',
+  // timeout: 12000,
+  withCredentials: true,
+})
+
+instance.interceptors.request.use(
+  (config: {
+    data: any
+    method: string
+    token: any
+    text: boolean
+    json: boolean
+    meta: {
+      isSerialize: boolean
+      isToken: boolean
+      noCookie: boolean
+    }
+    headers: { [x: string]: string | null }
+    url: string
+    authorization: boolean
+  }) => {
+    if(config.url.includes('h5')) {
+      config.url = '/drone-h5' + config.url
+    } else if (!config.url.includes('/blade-') && !config.url.includes('https://') && !config.url.includes('http://')) {
+      config.url = '/drone-yw' + config.url
+    }
+    const authorization = config.authorization === false
+    if (!authorization) {
+      config.headers.Authorization = `Basic ${Base64.encode(`${website.clientId}:${website.clientSecret}`)}`
+    }
+    // 让每个请求携带token
+    const meta = config.meta || {}
+    const isToken = meta.isToken === false
+    if (getToken() && !isToken) {
+      config.headers[website.tokenHeader] = 'bearer ' + getToken()
+    }
+    if (meta.noCookie) {
+      delete config.headers.cookie
+    }
+    // headers中配置text请求
+    if (config.text === true) {
+      config.headers['Content-Type'] = 'text/plain'
+    }
+    // headers配置JSON请求
+    if (config.json === true) {
+      config.headers['Content-Type'] = 'application/json'
+    }
+    // 水情预报接口调用
+    if (config.token) {
+      config.headers.Authorization = config.token
+    }
+    // headers中配置serialize为true开启序列化
+    if (config.method === 'post' && meta.isSerialize === true) {
+      config.data = serialize(config.data)
+    }
+    // config.headers[ELocalStorageKey.Token] = localStorage.getItem(ELocalStorageKey.Token)
+    // config.headers[REQUEST_ID] = uuidv4()
+    // config.baseURL = CURRENT_CONFIG.baseURL
+    return config
+  },
+  (error: any) => {
+    return Promise.reject(error)
+  },
+)
+
+instance.interceptors.response.use(
+  (res: { data: { code: any; msg: any; message: any; error_description: any }; status: any; config: { url: string; meta: { noCookie: boolean } } }) => {
+    const status = res.data.code || res.status
+    const message = res.data.msg || res.data.message || res.data.error_description || '未知错误'
+    // 如果是401则跳转到登录页面
+    // const store = useMyStore()
+    if (status === 401) {
+      store.dispatch('FedLogOut').then(() => router.push({ path: '/login' }))
+      // return
+    }
+    // 如果请求为非200否者默认统一处理
+    if (status !== 200) {
+      // 排除海康 code 为 0  情况
+      if (status === 0) {
+        return res
+      }
+      if ('meta' in res.config && 'noCookie' in res.config.meta && res.config.meta.noCookie === true) {
+        return Promise.reject(new Error(message))
+      }
+      if (message === '缺失令牌,鉴权失败') {
+        // message({
+        //   message: '登录信息已过期,请重新登录',
+        //   type: 'warning',
+        // })
+        ElMessage.warning('登录信息已过期,请重新登录')
+      }
+      if (
+        ![
+          '没有收到消息回复。',
+          '未知消息',
+          '设备端退出drc模式',
+          '未能恢复航路作业。错误码:: 319042',
+          'success',
+          '缺失令牌,鉴权失败',
+        ].includes(message)
+      ) {
+        ElMessage.warning(message)
+      }
+      return Promise.reject(new Error(message))
+    }
+    // console.info('URL: ' + response.config.baseURL + response.config.url, '\nData: ', response.data, '\nResponse:', response)
+    // const whiteList = ['/manage/api/v1/live/streams/stop']
+    // if (whiteList.includes(response.config.url)) {
+    //   return Promise.reject(response.data)
+    // }
+    // 处理消息返回
+    // if (response.data.code && !response.data.success) {
+    //   message.error(response.data.message)
+    // }
+    // if (response.data.code && response.data.code !== 0) {
+    //   message.error(response.data.message)
+    // }
+    return res
+  },
+  (err: {
+    config: { headers: { [x: string]: any }; url: any; method: any }
+    response: { data: { message: string; result: { message: string } }; status: number }
+  }) => {
+    const requestId = err?.config?.headers && err?.config?.headers[REQUEST_ID]
+    if (requestId) {
+      console.info(REQUEST_ID, ':', requestId)
+    }
+    console.info('url: ', err?.config?.url, `【${err?.config?.method}】 \n>>>> err: `, err)
+
+    let description = '-'
+    if (err.response?.data && err.response.data.message) {
+      description = err.response.data.message
+    }
+    if (err.response?.data && err.response.data.result) {
+      description = err.response.data.result.message
+    }
+    // @See: https://github.com/axios/axios/issues/383
+    if (!err.response || !err.response.status) {
+      ElMessage.error('网络异常,请检查后端服务后重试')
+      return
+    }
+    if (err.response?.status !== 200) {
+      ElMessage.error(`错误码: ${err.response?.status}`)
+    }
+    // if (err.response?.status === 403) {
+    //   // window.location.href = '/'
+    // }
+    if (err.response?.status === 401) {
+      console.error(err.response)
+      store.dispatch('FedLogOut').then(() => router.push({ path: '/login' }))
+      // const flag: number = Number(localStorage.getItem(ELocalStorageKey.Flag))
+      // switch (flag) {
+      //   case EUserType.Web:
+      //     router.push(ERouterName.PROJECT_LIST)
+      //     break
+      //   case EUserType.Pilot:
+      //     router.push(ERouterName.PILOT)
+      //     break
+      // }
+    }
+    return Promise.reject(err)
+  },
+)
+
+export default instance
diff --git a/src/api/http/request.ts b/src/api/http/request.ts
index 5186bda..6488409 100644
--- a/src/api/http/request.ts
+++ b/src/api/http/request.ts
@@ -6,7 +6,8 @@
  * isToken是否需要token
  */
 import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
-import store from '@/store/user'
+// import store from '@/store/user'
+import { useMyStore } from '@/store'
 import router from '@/router';
 import { serialize } from '@/utils/common'
 import { getToken } from '@/utils/auth';
@@ -100,9 +101,6 @@
     if (config.method === 'post' && meta.isSerialize === true) {
       config.data = serialize(config.data)
     }
-    // config.headers[ELocalStorageKey.Token] = localStorage.getItem(ELocalStorageKey.Token)
-    // config.headers[REQUEST_ID] = uuidv4()
-    // config.baseURL = CURRENT_CONFIG.baseURL
     return config
   },
   (error: any) => {
@@ -115,10 +113,8 @@
     const status = res.data.code || res.status
     const message = res.data.msg || res.data.message || res.data.error_description || '未知错误'
     // 如果是401则跳转到登录页面
-    // const store = useMyStore()
-    if (status === 401) {
-      store.dispatch('FedLogOut').then(() => router.push({ path: '/login' }))
-      // return
+    if (status == 401) {
+      router.push({ path: '/login' })
     }
     // 如果请求为非200否者默认统一处理
     if (status !== 200) {
@@ -130,10 +126,6 @@
         return Promise.reject(new Error(message))
       }
       if (message === '缺失令牌,鉴权失败') {
-        // message({
-        //   message: '登录信息已过期,请重新登录',
-        //   type: 'warning',
-        // })
         ElMessage.warning('登录信息已过期,请重新登录')
       }
       if (
@@ -150,18 +142,6 @@
       }
       return Promise.reject(new Error(message))
     }
-    // console.info('URL: ' + response.config.baseURL + response.config.url, '\nData: ', response.data, '\nResponse:', response)
-    // const whiteList = ['/manage/api/v1/live/streams/stop']
-    // if (whiteList.includes(response.config.url)) {
-    //   return Promise.reject(response.data)
-    // }
-    // 处理消息返回
-    // if (response.data.code && !response.data.success) {
-    //   message.error(response.data.message)
-    // }
-    // if (response.data.code && response.data.code !== 0) {
-    //   message.error(response.data.message)
-    // }
     return res
   },
   (err: {
@@ -181,29 +161,21 @@
     if (err.response?.data && err.response.data.result) {
       description = err.response.data.result.message
     }
-    // @See: https://github.com/axios/axios/issues/383
     if (!err.response || !err.response.status) {
       ElMessage.error('网络异常,请检查后端服务后重试')
       return
     }
     if (err.response?.status !== 200) {
-      ElMessage.error(`错误码: ${err.response?.status}`)
+      if (err.response.data?.msg) {
+        ElMessage.error(err.response.data?.msg)
+      } else if (err.response.data?.error_description) {
+        ElMessage.error(err.response.data?.error_description)
+      } else {
+        ElMessage.error(`错误码: ${err.response?.status}`)
+      }
     }
-    // if (err.response?.status === 403) {
-    //   // window.location.href = '/'
-    // }
-    if (err.response?.status === 401) {
-      console.error(err.response)
-      store.dispatch('FedLogOut').then(() => router.push({ path: '/login' }))
-      // const flag: number = Number(localStorage.getItem(ELocalStorageKey.Flag))
-      // switch (flag) {
-      //   case EUserType.Web:
-      //     router.push(ERouterName.PROJECT_LIST)
-      //     break
-      //   case EUserType.Pilot:
-      //     router.push(ERouterName.PILOT)
-      //     break
-      // }
+    if (err.response?.status == 401) {
+      router.push({ path: '/login' })
     }
     return Promise.reject(err)
   },
diff --git a/src/main.ts b/src/main.ts
index 44a7ddd..84dd574 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -8,6 +8,8 @@
 import store, { storeKey } from './store'
 import { createInstance } from '../root'
 import * as Cesium from 'cesium';
+import Vant from 'vant';
+import 'vant/lib/index.css'; // 引入样式文件
 
 // 初始化 Cesium Viewer
 window.cesiumViewer = null
@@ -15,6 +17,7 @@
 const app = createInstance(App) // 引入css
 
 app.use(ElementPlus);
+app.use(Vant);
 app.use(store, storeKey)
 app.use(router)
 
diff --git a/src/router/index.ts b/src/router/index.ts
index 922833c..ee65479 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -26,6 +26,10 @@
   // },
   {
     path: '/',
+    redirect: '/login',
+  },
+  {
+    path: '/login',
     name: ERouterName.LOGIN,
     component: () => import('@/views/Login.vue')
   },
diff --git a/src/views/DronePilotDetails-copy.vue b/src/views/DronePilotDetails-copy.vue
index 160a8e6..50fb190 100644
--- a/src/views/DronePilotDetails-copy.vue
+++ b/src/views/DronePilotDetails-copy.vue
@@ -120,7 +120,7 @@
 // 获取机场/遥控器sn
 let localData = ref<any>(window.localStorage.getItem('sbInfo'))
 const sbInfo: deviceInfo = JSON.parse(localData.value) as deviceInfo;
-// console.log('哒哒哒', sbInfo)
+
 // 无人机sn 
 const sn = ref<String>(sbInfo.sn)
 // 机场sn 
diff --git a/src/views/DronePilotDetails-copy1.vue b/src/views/DronePilotDetails-copy1.vue
new file mode 100644
index 0000000..6104fed
--- /dev/null
+++ b/src/views/DronePilotDetails-copy1.vue
@@ -0,0 +1,754 @@
+<template>
+  <div class="drone-pilot-details" :style="{ width: screenWidth,height: screenHeight}">
+    <!-- 横屏模式 -->
+    <div id="landscapeBox" class="landscape-box" :style="{ width: screenWidth + 'px', height: (screenHeight) + 'px'}">
+      <div id="videoModule" class="l-video" :style="{ width: screenWidthVideo + 'px', height: (screenHeightVideo) + 'px'}">
+        <video v-show="videoUrl" ref="videoPlayerBig" :style="{ width: screenWidthVideo + 'px', height: screenHeightVideo + 'px'}" controls autoplay muted playsinline style="text-align: left; object-fit: fill">
+          Your browser is too old which doesn't support HTML5 video.
+        </video>
+        <el-empty v-show="videoUrl == ''" description="当前设备已关机,无法进行直播" :image="imageUrl"></el-empty>
+      </div>
+      <div class="l-map" :style="{ width: screenWidthVideo + 'px', height: (screenHeightVideo) + 'px'}">
+        <div id="cesiumContainerBigMap" :style="{ width: screenWidthMap + 'px', height: (screenHeightMap) + 'px'}"></div>
+        <div class="l-zp" id="lZp">
+          <comPass :cesiumViewe="globalViewer"/>
+        </div>
+        <div class="l-zoom" id="lZoom">
+          <div class="zoom">
+            <img v-if="!isBigMap" src="@/assets/images/fang.png" @touchstart="changeModelMap" />
+            <img v-else src="@/assets/images/suo.png" @touchstart="changeModelMap" />
+          </div>
+        </div>
+      </div>
+      <div class="right-box">
+        <ptzControl :sn="sn" :osdVisible="sbInfo" />
+        <controlConsole :sn="sn" :osdVisible="sbInfo" :cesiumViewe="globalViewer" />
+      </div>
+    </div>
+    <!-- 竖屏 -->
+    <!-- <div class="portrait-screen" v-else>
+      <div class="l-video" :style="{ width: screenWidth + 'px', height: (screenHeight/2)+40 + 'px'}">
+        <video v-show="videoUrl" ref="videoPlayerBig" :style="{ width: screenWidth + 'px', height: (screenHeight/2)+40 + 'px'}" controls autoplay muted playsinline style="text-align: left; object-fit: fill">
+          Your browser is too old which doesn't support HTML5 video.
+        </video>
+        <el-empty v-show="videoUrl == ''" description="当前设备已关机,无法进行直播" :image="imageUrl"></el-empty>
+      </div>
+      <div class="l-map" :style="{ width: screenWidth + 'px', height: (screenHeight/2)-40 + 'px'}">
+        <div id="cesiumContainerMap"></div>
+        <div class="l-zp" id="lZp">
+          <comPass :cesiumViewe="globalViewer"/>
+        </div>
+      </div>
+      <div class="right-box">
+        <ptzControl :sn="sn" :osdVisible="sbInfo" />
+        <controlConsole :sn="sn" :osdVisible="sbInfo" />
+      </div>
+    </div> -->
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted, onBeforeUnmount, nextTick, reactive, computed, watch } from 'vue';
+import { EDeviceTypeName, EHmsLevel } from '@/types/enums'
+import { getRoot } from '../../root'
+import { startLivestream, getLiveVideoUrl } from '@/api/manage'
+import { CURRENT_CONFIG as config } from '@/api/http/config'
+// import videojs from 'video.js'
+// import 'video.js/dist/video-js.css';
+import { getLnglatDist, cartesian3Convert, getLnglatAltitude, createCircleBillboard } from '@/utils/cesium/mapUtil'
+import cesiumOperation from '@/utils/cesium-tsa.js';
+const { _init, viewerDestory } = cesiumOperation();
+import * as Cesium from 'cesium';
+
+// import { cesiumOperation } from '@/hooks/use-cesium-tsa'
+// const { _init } = cesiumOperation();
+import { useMyStore } from '@/store'
+import { getWaylineFile } from '@/api/manage'
+import comPass from './components/comPass.vue'
+import ptzControl from './components/ptzControl.vue'
+import controlConsole from './components/controlConsole.vue'
+import { useConnectWebSocket } from '@/utils/websocket/connect-websocket'
+import { getWebsocketUrl } from '@/websocket/util/config'
+import { EBizCode, ELocalStorageKey, ERouterName } from '@/types'
+import VConsole from 'vconsole';
+import { any } from 'video.js/dist/types/utils/events';
+import { analyzeKmzFile, XMLToJSON } from '@/utils/cesium/kmz.js'
+import { initPointWayLine } from './hooks/initPointWayline'
+import { initPlanarWayline } from './hooks/initPlanarWayline'
+import { droneFly } from './hooks/droneFly'
+import flvjs from 'flv.js';
+const { pointWayline } = initPointWayLine()
+const { planarWayline } = initPlanarWayline()
+const { initDock } = droneFly()
+
+const {
+  removeAllPoint,
+  removeAllDataSource,
+  globalCesium,
+  getEntityById,
+  removeById,
+  loadLAYER,
+} = cesiumOperation()
+
+// const vConsole = new VConsole();
+
+let globalViewer = null
+
+// 使用 ref 来存储屏幕宽度和高度
+const screenWidth = ref(window.innerWidth);
+const screenHeight = ref(window.innerHeight);
+// 地图切换
+const screenWidthMap = ref((window.innerHeight/2)*2)// ref(window.innerWidth);
+const screenHeightMap = ref((window.innerHeight/2));
+// 视频切换
+const screenWidthVideo = ref(window.innerWidth);
+const screenHeightVideo = ref(window.innerHeight/2);
+const isBigMap = ref(false)
+
+// 更新屏幕尺寸的函数
+const updateScreenSize = () => {
+  screenWidth.value = window.innerWidth;
+  screenHeight.value = window.innerHeight;
+  if (isLandscape.value) { //横屏
+    screenWidthMap.value = window.innerWidth/2
+    screenHeightMap.value = window.innerHeight
+    screenWidthVideo.value = window.innerWidth/2
+    screenHeightVideo.value = window.innerHeight
+  } else {//竖屏
+    screenWidthMap.value = (window.innerHeight/2)*2
+    screenHeightMap.value = (window.innerHeight/2)
+    screenWidthVideo.value = window.innerWidth
+    screenHeightVideo.value = (window.innerHeight/2)
+  }
+};
+
+const store = useMyStore()
+// 获取路由
+const root = getRoot()
+
+interface deviceInfo {
+  dockSn: string;
+  latitude?:number;// 机场经纬度
+  longitude?:number;
+  height?:number; // 机场高度
+  isOnline: boolean;
+  name: string; // 可选字段
+  sn: string;
+  workspaceId:string;
+  children?: {  };
+}
+// 获取机场/遥控器sn
+let localData = ref<any>(window.localStorage.getItem('sbInfo'))
+const sbInfo: deviceInfo = JSON.parse(localData.value) as deviceInfo;
+
+// 无人机sn 
+const sn = ref<String>(sbInfo.sn)
+// 机场sn 
+const dockSn = ref<String>(sbInfo.dockSn)
+
+// 记录横竖屏模式
+const isLandscape = ref(false);
+
+// 记录视频地址
+const videoUrl = ref<String>('');
+
+// 设置图片地址
+const imageUrl = new URL('@/assets/images/norecord.png', import.meta.url).href
+
+const imageMapSrc = new URL('@/assets/images/mapdock.png', import.meta.url).href
+
+const meMapSrc = new URL('@/assets/images/me.png', import.meta.url).href
+
+const jgbMapSrc = new URL('@/assets/images/jgb.png', import.meta.url).href
+
+const mapswitching = new URL('@/assets/images/mapswitching.png', import.meta.url).href
+
+const videoWH = ref<any>(null)
+
+// 视频宽高
+const drawCanvasWidth = ref<Number>(0)
+const drawCanvasHeight = ref<Number>(0)
+
+// 鹰眼视频
+const timer = null;
+const videoPlayer = ref<any>(null); // 视频播放器实例
+let webrtcPlayer = null; // video.js 播放器
+
+// 大屏幕视频
+const timerBig = null;
+const videoPlayerBig = ref<any>(null); // 视频播放器实例
+let webrtcPlayerBig = null
+
+let player = null; // video.js 播放器
+
+// 无人机实时飞行链接
+let ssLinePath = ref(null)
+
+// 实时定位
+let viewDroneInfo = {}
+// 机场高度
+let droneHeight = ref(0)
+
+// 监听
+let connectWs = ref<any>(null)
+
+let workspaceId = ref<String>(sbInfo.workspaceId)
+localStorage.setItem('bs_workspace_id', workspaceId.value)
+// store.commit('SET_SELECTED_WORKSPACE_ID', workspaceId.value);
+
+// RTCWEB 加载视频
+const playBig = () => {
+  webrtcPlayerBig = new window.ZLMRTCClient.Endpoint({
+    element: videoPlayerBig.value, // video 标签
+    debug: true, // 是否打印日志
+    zlmsdpUrl: videoUrl.value, //流地址
+    simulecast: false,
+    useCamera: false,
+    audioEnable: true,
+    videoEnable: true,
+    recvOnly: true,
+    usedatachannel: false,
+  })
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,
+    (e) => {
+      // ICE 协商出错
+      console.error('ICE 协商出错')
+      // this.eventcallbacK('ICE ERROR', 'ICE 协商出错')
+    },
+  )
+
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,
+    (e) => {
+      //获取到了远端流,可以播放
+      console.log('播放成功', e.streams)
+      // this.eventcallbacK('playing', '播放成功')
+    },
+  )
+
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,
+    (e) => {
+      // offer anwser 交换失败
+      console.error('offer anwser 交换失败', e)
+      // this.eventcallbacK('OFFER ANSWER ERROR ', 'offer anwser 交换失败')
+      if (e.code == -400 && e.msg == '流不存在') {
+        console.log('流不存在')
+        timerBig = setTimeout(() => {
+          webrtcPlayerBig.close()
+          playBig()
+        }, 100)
+      }
+    },
+  )
+
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,
+    (s) => {
+      // 获取到了本地流
+
+      // document.getElementById('selfVideo').srcObject=s;
+      // this.eventcallbacK('LOCAL STREAM', '获取到了本地流')
+    },
+  )
+}
+// const play = () => {
+//   webrtcPlayer = new window.ZLMRTCClient.Endpoint({
+//     element: videoPlayer.value, // video 标签
+//     debug: true, // 是否打印日志
+//     zlmsdpUrl: videoUrl.value, //Rtc地址
+//     simulecast: false,
+//     useCamera: false,
+//     audioEnable: true,
+//     videoEnable: true,
+//     recvOnly: true,
+//     usedatachannel: false,
+//   })
+//   webrtcPlayer.on(
+//     window.ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,
+//     (e) => {
+//       // ICE 协商出错
+//       console.error('ICE 协商出错')
+//       // this.eventcallbacK('ICE ERROR', 'ICE 协商出错')
+//     },
+//   )
+
+//   webrtcPlayer.on(
+//     window.ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,
+//     (e) => {
+//       //获取到了远端流,可以播放
+//       console.log('播放成功', e.streams)
+//       // this.eventcallbacK('playing', '播放成功')
+//     },
+//   )
+
+//   webrtcPlayer.on(
+//     window.ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,
+//     (e) => {
+//       // offer anwser 交换失败
+//       console.error('offer anwser 交换失败', e)
+//       // this.eventcallbacK('OFFER ANSWER ERROR ', 'offer anwser 交换失败')
+//       if (e.code == -400 && e.msg == '流不存在') {
+//         console.log('流不存在')
+//         timer = setTimeout(() => {
+//           webrtcPlayer.close()
+//           play()
+//         }, 100)
+//       }
+//     },
+//   )
+
+//   webrtcPlayer.on(
+//     window.ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,
+//     (s) => {
+//     },
+//   )
+// }
+const videoUrlFlv = ref<String>('')
+// 加载该设备的视频信息
+const loadVideo = async () => {
+  await getLiveVideoUrl(sn.value).then((res) => {
+    if (res.data.code != 0) return
+    // 获取高度
+    if (videoWH.value) {
+      drawCanvasWidth.value = videoWH.value.offsetWidth;
+      drawCanvasHeight.value = videoWH.value.offsetHeight;
+    }
+    videoUrl.value =  res.data.data.rtcs_url
+    videoUrlFlv.value = res.data.data.url
+    // 播放
+    // play()
+    playBig()
+    // flv
+    // initFlvPlayer()
+  })
+}
+
+// flv
+const videoPlayerFlv = ref(null); // 引用 video 元素
+let flvPlayer = null; // 用于存储 flv.js 播放器实例
+ // 初始化 flv.js 播放器
+ 
+const initFlvPlayer = () => {
+  if (flvjs.isSupported()) {
+    const videoElement = videoPlayerFlv.value; // 获取 video 元素
+    flvPlayer = flvjs.createPlayer({
+      type: 'flv', // 视频格式
+      url: videoUrlFlv.value, // FLV 视频地址
+    });
+    flvPlayer.attachMediaElement(videoElement); // 绑定 video 元素
+    flvPlayer.load(); // 加载视频
+    flvPlayer.play(); // 播放视频
+  } else {
+    console.error('Your browser does not support flv.js.');
+  }
+};
+
+//===============================
+
+// 监听ws
+const messageHandler = async (payload: any) => {
+  // if (!payload) {
+  //   return
+  // }
+  switch (payload.biz_code) {
+    case EBizCode.GatewayOsd: { // 遥控器
+      store.commit('SET_GATEWAY_INFO', payload.data)
+      break
+    }
+    case EBizCode.DeviceOsd: {
+      store.commit('SET_DEVICE_INFO', payload.data)
+      store.commit('SET_WS_MESSAGE', payload)
+      break
+    }
+    case EBizCode.DockOsd: { // 机场
+      store.commit('SET_DOCK_INFO', payload.data)
+      break
+    }
+  }
+  
+}
+
+const webSorketUrl = getWebsocketUrl() + '&workspace-id=' + workspaceId.value
+// 监听ws 消息
+useConnectWebSocket(messageHandler, webSorketUrl)
+
+
+let savedMapState = null; // 保存地图状态
+// 销毁之前先保存状态
+const destroyViewer = () => {
+  if ( window.cesiumViewer) {
+    // 保存当前地图状态(如相机位置)
+    // savedMapState = window.cesiumViewer.camera.view;
+    window.cesiumViewer.destroy();
+    window.cesiumViewer = null;
+  }
+}
+
+// 地图全屏切换
+const changeModelMap = () => {
+  isBigMap.value = !isBigMap.value
+  const cesiumContainer = document.getElementById('cesiumContainerBigMap');
+  const lZp = document.getElementById('lZp');
+  const lZoom = document.getElementById('lZoom');
+  
+  if (isBigMap.value) { // 全屏
+    cesiumContainer.style.position = 'fixed';
+    cesiumContainer.style.top = '0';
+    cesiumContainer.style.left = '0';
+    cesiumContainer.style.width = '100%';
+    cesiumContainer.style.height = '100%';
+    lZp.style.right = '40%';
+    lZoom.style.left = '0';
+  } else { // 缩放
+    cesiumContainer.style.position = 'static';
+    cesiumContainer.style.width = `${screenWidthMap.value}`
+    cesiumContainer.style.height = `${screenHeight.value}`
+    lZp.style.right = '16%';
+    lZoom.style.left = '50%';
+    
+  }
+}
+
+const checkOrientation = async () => {
+  const landscapeBox = document.getElementById('landscapeBox');
+  const cesiumContainer = document.getElementById('cesiumContainerBigMap');
+  const videoModule = document.getElementById('videoModule');
+  const lZp = document.getElementById('lZp');
+  const lZoom = document.getElementById('lZoom');
+  // 横屏再加载视频请求
+  // destroyViewer()
+  
+  // loadVideo()
+  if (window.innerWidth > window.innerHeight) {
+    isLandscape.value = true;
+    updateScreenSize()
+    landscapeBox.style.display = 'flex';
+    lZp.style.right = '16%';
+    lZoom.style.display = 'block';
+    lZoom.style.position = 'fixed';
+    // await nextTick();
+    // await _init('cesiumContainerBigMap');
+    // await getWrjSsLx();
+  } else {
+    isLandscape.value = false;
+    updateScreenSize()
+    landscapeBox.style.display = 'inherit';
+    lZp.style.right = '32%';
+    lZoom.style.display = 'none';
+    // landscapeBox.style.width = `${screenWidth}`
+    // landscapeBox.style.height = `${screenHeight}`
+    // videoModule.style.width = `${screenWidth}`
+    // videoModule.style.height = `${screenHeight}`
+    // await nextTick();
+    // await _init('cesiumContainerMap');
+    // await getWrjSsLx();
+  }
+};
+
+// 获取实时航线
+const getWrjSsLx = () => {
+  getWaylineFile(sbInfo.sn).then((res:any) => {
+    if (res.code != 200) return
+    ssLinePath.value = res.data
+    globalViewer = window.cesiumViewer
+    // 先有航线,再飞行
+    generateCourse()
+  })
+}
+
+// 切换航线轨迹
+const courseTrack = (data:any) => {
+  if (window.cesiumViewer== null) return 
+  const currentSn = dockSn.value
+  const longitude = data.dockInfo[currentSn]?.basic_osd?.longitude || null
+  const latitude = data.dockInfo[currentSn]?.basic_osd?.latitude || null
+  const height = data.dockInfo[currentSn]?.basic_osd?.height || null
+  let getLongOk = ref(0)
+  if (!getEntityById('drone_dock')) {
+    getLnglatAltitude(longitude, latitude,  window.cesiumViewer).then(res => {
+      removeById('drone_dock')
+       window.cesiumViewer.entities.add({
+        position: globalCesium.Cartesian3.fromDegrees(
+          longitude,
+          latitude,
+          res.height,
+        ),
+        id: 'drone_dock',
+        billboard: {
+          image: imageMapSrc,
+          outlineWidth: 0,
+          width: 36,
+          height: 36,
+          scale: 1.0,
+        }
+      })
+       window.cesiumViewer.scene.camera.setView({
+        destination: globalCesium.Cartesian3.fromDegrees(
+          Number(longitude),
+          Number(latitude),
+          10000.0,
+        ),
+      })
+      droneHeight.value = res.height
+    })
+  } else {
+    // 当机场坐标存在时,判断获取的位置与机场坐标位置是否一致,若不是,重新更新位置
+    let dornePoint = cartesian3Convert(getEntityById('drone_dock')._position._value, window.cesiumViewer,)
+    getLongOk = getLnglatDist(
+      dornePoint.longitude,
+      dornePoint.latitude,
+      longitude,
+      latitude,
+    )
+    if (getLongOk.value > 100) {
+      removeById('drone_dock')
+    }
+  }
+  if (getLongOk.value > 100) return
+  initDock(data, sn.value, dockSn.value, workspaceId.value, ssLinePath.value, viewDroneInfo)
+}
+
+// 监听
+watch(() => store.state.deviceState, (newValue, oldValue) => {
+  // 试试
+  if (newValue) {
+    nextTick()
+    courseTrack(newValue)
+  }
+}, {deep: true})
+
+watch(() => store.state.wsMessage, (newValue, oldValue) => {
+  // 控制台报 Expected longitude to be typeof number, actual typeof was undefined 是因为这里没有及时拿到longitude数据
+  if (newValue) {
+    viewDroneInfo.longitude = newValue?.longitude
+    viewDroneInfo.latitude = newValue?.latitude
+    viewDroneInfo.elevation = Number(newValue?.elevation.toFixed(2)) + droneHeight.value
+  }
+}, {deep: true})
+
+
+
+// 生成航线轨迹
+const generateCourse = async () => {
+  console.log('有木有航线值', ssLinePath.value)
+  if (!ssLinePath.value) return
+  const { fileInfoObj } = await analyzeKmzFile(`${ssLinePath.value}?_t=${new Date().getTime()}`)
+  const xmlStr = await fileInfoObj['wpmz/template.kml']
+  const xmlJson = XMLToJSON(xmlStr)?.['Document']
+  const placemark = xmlJson.Folder.Placemark
+  console.log('看看航线值', placemark.Polygon)
+  if (placemark?.Polygon) {
+    // return 'planar'
+    planarWayline(ssLinePath.value, sbInfo.longitude, sbInfo.latitude)
+  } else {
+    // return 'point'
+    pointWayline(ssLinePath.value, sbInfo.longitude, sbInfo.latitude)
+  }
+}
+
+const me_latitude = ref(0);
+const me_longitude = ref(0);
+// 获取自身定位
+const getLocation = () => {
+  if (window.cesiumViewer == null) return 
+  if (navigator.geolocation) {
+    navigator.geolocation.getCurrentPosition(
+      (position) => {
+        me_latitude.value =  position.coords.latitude;
+        me_longitude.value = position.coords.longitude;
+        // 开始给自己定位
+        getLnglatAltitude(me_longitude.value, me_latitude.value,  window.cesiumViewer).then(res => {
+          removeById('me_coordinate')
+          window.cesiumViewer.entities.add({
+            position: globalCesium.Cartesian3.fromDegrees(
+              me_longitude.value,
+              me_latitude.value,
+              res.height || 0,
+            ),
+            id: 'me_coordinate',
+            billboard: {
+              image: meMapSrc,
+              outlineWidth: 0,
+              width: 36,
+              height: 36,
+              scale: 1.0,
+            }
+          })
+        })
+      },
+      (err) => {
+        console.log('定位有误')
+      }
+    );
+  } else {
+    console.log('您的浏览器不支持地理定位')
+  }
+};
+
+onMounted(async () => {
+  window.addEventListener('orientationchange', checkOrientation);
+  window.addEventListener('resize', checkOrientation); // 兼容某些设备
+  checkOrientation(); // 初始化时检查一次
+  loadVideo()
+  await nextTick();
+  await _init('cesiumContainerBigMap');
+  await getWrjSsLx();
+
+  await getLocation()
+  
+});
+
+onBeforeUnmount(() => {
+  window.removeEventListener('orientationchange', checkOrientation);
+  window.removeEventListener('resize', checkOrientation);
+  if (player) {
+    player.dispose();
+  }
+  if (flvPlayer) {
+    flvPlayer.pause(); // 暂停播放
+    flvPlayer.unload(); // 卸载视频
+    flvPlayer.detachMediaElement(); // 解绑 video 元素
+    flvPlayer.destroy(); // 销毁播放器
+    flvPlayer = null;
+  }
+});
+
+
+
+</script>
+
+<style lang="scss" scoped>
+.drone-pilot-details {
+  .landscape-box {
+    position: relative;
+    display: flex;
+    .l-map {
+      .l-zp {
+        position: fixed;
+        right: 16%;
+        bottom: 0;
+      }
+      .l-zoom {
+        position: fixed;
+        bottom: 0;
+        left: 50%;
+        .zoom {
+          width: 2rem;
+          height: 2rem;
+          border-radius: 3px;
+          background-color: rgba(0, 0, 0, 0.8);
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          overflow: hidden;
+          cursor: pointer;
+          pointer-events: all;
+          img {
+            width: 1.6rem;
+            height: 1.6rem;
+          }
+        }
+      }
+    }
+  }
+  .l-video {
+    .el-empty {
+      width: 100%;
+      height: 100%;
+      padding: 0;
+      ::v-deep(.el-empty__image) {
+        width: 50%;
+        height: 50%;
+      }
+      ::v-deep(.el-empty__description) {
+        margin: 0;
+      }
+    }
+  }
+  #cesiumContainerBigMap {
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+
+    :deep() {
+      .cesium-viewer {
+        width: 100%;
+        height: 100%;
+
+        .cesium-viewer-cesiumWidgetContainer {
+          width: 100%;
+          height: 100%;
+
+          .cesium-widget {
+            width: 100%;
+            height: 100%;
+
+            canvas {
+              width: 100%;
+              height: 100%;
+            }
+          }
+        }
+      }
+    }
+  }
+  #cesiumContainerMap {
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+
+    :deep() {
+      .cesium-viewer {
+        width: 100%;
+        height: 100%;
+
+        .cesium-viewer-cesiumWidgetContainer {
+          width: 100%;
+          height: 100%;
+
+          .cesium-widget {
+            width: 100%;
+            height: 100%;
+
+            canvas {
+              width: 100%;
+              height: 100%;
+            }
+          }
+        }
+      }
+    }
+  }
+  .portrait-screen {
+    .l-map {
+      .l-zp {
+        position: fixed;
+        right: 28%;
+        bottom: 0;
+      }
+      .l-zoom {
+        position: fixed;
+        bottom: 0;
+        .zoom {
+          width: 2rem;
+          height: 2rem;
+          border-radius: 3px;
+          background-color: rgba(0, 0, 0, 0.8);
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          overflow: hidden;
+          cursor: pointer;
+          pointer-events: all;
+          img {
+            width: 1.6rem;
+            height: 1.6rem;
+          }
+        }
+      }
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/DronePilotDetails-copy2.vue b/src/views/DronePilotDetails-copy2.vue
new file mode 100644
index 0000000..17d0c63
--- /dev/null
+++ b/src/views/DronePilotDetails-copy2.vue
@@ -0,0 +1,708 @@
+<template>
+  <div class="drone-pilot-details" :style="{ width: screenWidth,height: screenHeight}">
+    <!-- 横屏模式 -->
+    <div id="landscapeBox" class="landscape-box" :style="{ width: screenWidth + 'px', height: (screenHeight) + 'px'}">
+      <div id="videoModule" class="l-video" :style="{ width: screenWidthVideo + 'px', height: (screenHeightVideo) + 'px'}">
+        <video v-show="videoUrl" ref="videoPlayerBig" :style="{ width: screenWidthVideo + 'px', height: screenHeightVideo + 'px'}" controls autoplay muted playsinline style="text-align: left; object-fit: fill">
+          Your browser is too old which doesn't support HTML5 video.
+        </video>
+        <el-empty v-show="videoUrl == ''" description="当前设备已关机,无法进行直播" :image="imageUrl"></el-empty>
+      </div>
+      <div class="l-map" :style="{ width: screenWidthMap + 'px', height: (screenHeightMap) + 'px'}">
+        <div id="cesiumContainerBigMap"></div>
+        <div class="l-zp" id="lZp">
+          <comPass :cesiumViewe="globalViewer"/>
+        </div>
+        <div class="l-zoom" id="lZoom">
+          <div class="zoom">
+            <img v-if="!isBigMap" src="@/assets/images/fang.png" @touchstart="changeModelMap" />
+            <img v-else src="@/assets/images/suo.png" @touchstart="changeModelMap" />
+          </div>
+        </div>
+      </div>
+      <div class="right-box">
+        <ptzControl :sn="sn" :osdVisible="sbInfo" />
+        <controlConsole :sn="sn" :osdVisible="sbInfo" :cesiumViewe="globalViewer" />
+      </div>
+    </div>
+    <!-- 竖屏 -->
+    <!-- <div class="portrait-screen" v-else>
+      <div class="l-video" :style="{ width: screenWidth + 'px', height: (screenHeight/2)+40 + 'px'}">
+        <video v-show="videoUrl" ref="videoPlayerBig" :style="{ width: screenWidth + 'px', height: (screenHeight/2)+40 + 'px'}" controls autoplay muted playsinline style="text-align: left; object-fit: fill">
+          Your browser is too old which doesn't support HTML5 video.
+        </video>
+        <el-empty v-show="videoUrl == ''" description="当前设备已关机,无法进行直播" :image="imageUrl"></el-empty>
+      </div>
+      <div class="l-map" :style="{ width: screenWidth + 'px', height: (screenHeight/2)-40 + 'px'}">
+        <div id="cesiumContainerMap"></div>
+        <div class="l-zp" id="lZp">
+          <comPass :cesiumViewe="globalViewer"/>
+        </div>
+      </div>
+      <div class="right-box">
+        <ptzControl :sn="sn" :osdVisible="sbInfo" />
+        <controlConsole :sn="sn" :osdVisible="sbInfo" />
+      </div>
+    </div> -->
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted, onBeforeUnmount, nextTick, reactive, computed, watch } from 'vue';
+import { EDeviceTypeName, EHmsLevel } from '@/types/enums'
+import { getRoot } from '../../root'
+import { startLivestream, getLiveVideoUrl } from '@/api/manage'
+import { CURRENT_CONFIG as config } from '@/api/http/config'
+// import videojs from 'video.js'
+// import 'video.js/dist/video-js.css';
+import { getLnglatDist, cartesian3Convert, getLnglatAltitude, createCircleBillboard } from '@/utils/cesium/mapUtil'
+import cesiumOperation from '@/utils/cesium-tsa.js';
+const { _init, viewerDestory } = cesiumOperation();
+import * as Cesium from 'cesium';
+
+// import { cesiumOperation } from '@/hooks/use-cesium-tsa'
+// const { _init } = cesiumOperation();
+import { useMyStore } from '@/store'
+import { getWaylineFile } from '@/api/manage'
+import comPass from './components/comPass.vue'
+import ptzControl from './components/ptzControl.vue'
+import controlConsole from './components/controlConsole.vue'
+import { useConnectWebSocket } from '@/utils/websocket/connect-websocket'
+import { getWebsocketUrl } from '@/websocket/util/config'
+import { EBizCode, ELocalStorageKey, ERouterName } from '@/types'
+import VConsole from 'vconsole';
+import { any } from 'video.js/dist/types/utils/events';
+import { analyzeKmzFile, XMLToJSON } from '@/utils/cesium/kmz.js'
+import { initPointWayLine } from './hooks/initPointWayline'
+import { initPlanarWayline } from './hooks/initPlanarWayline'
+import { droneFly } from './hooks/droneFly'
+import flvjs from 'flv.js';
+const { pointWayline } = initPointWayLine()
+const { planarWayline } = initPlanarWayline()
+const { initDock } = droneFly()
+
+const {
+  removeAllPoint,
+  removeAllDataSource,
+  globalCesium,
+  getEntityById,
+  removeById,
+  loadLAYER,
+} = cesiumOperation()
+
+// const vConsole = new VConsole();
+
+let globalViewer = null
+
+// 使用 ref 来存储屏幕宽度和高度
+const screenWidth = ref(window.innerWidth);
+const screenHeight = ref(window.innerHeight);
+// 地图切换
+const screenWidthMap = ref(window.innerWidth);
+const screenHeightMap = ref((window.innerHeight/2)+40);
+// 视频切换
+const screenWidthVideo = ref(window.innerWidth);
+const screenHeightVideo = ref(window.innerHeight/2);
+const isBigMap = ref(false)
+
+// 更新屏幕尺寸的函数
+const updateScreenSize = () => {
+  screenWidth.value = window.innerWidth;
+  screenHeight.value = window.innerHeight;
+  if (isLandscape.value) { //横屏
+    screenWidthMap.value = window.innerWidth/2
+    screenHeightMap.value = window.innerHeight
+    screenWidthVideo.value = window.innerWidth/2
+    screenHeightVideo.value = window.innerHeight
+  } else {//竖屏
+    screenWidthMap.value = window.innerWidth
+    screenHeightMap.value = (window.innerHeight/2)-40
+    screenWidthVideo.value = window.innerWidth
+    screenHeightVideo.value = (window.innerHeight/2)+40
+  }
+};
+
+const store = useMyStore()
+// 获取路由
+const root = getRoot()
+
+interface deviceInfo {
+  dockSn: string;
+  latitude?:number;// 机场经纬度
+  longitude?:number;
+  height?:number; // 机场高度
+  isOnline: boolean;
+  name: string; // 可选字段
+  sn: string;
+  workspaceId:string;
+  children?: {  };
+}
+// 获取机场/遥控器sn
+let localData = ref<any>(window.localStorage.getItem('sbInfo'))
+const sbInfo: deviceInfo = JSON.parse(localData.value) as deviceInfo;
+// console.log('哒哒哒', sbInfo)
+// 无人机sn 
+const sn = ref<String>(sbInfo.sn)
+// 机场sn 
+const dockSn = ref<String>(sbInfo.dockSn)
+
+// 记录横竖屏模式
+const isLandscape = ref(false);
+
+// 记录视频地址
+const videoUrl = ref<String>('');
+
+// 设置图片地址
+const imageUrl = new URL('@/assets/images/norecord.png', import.meta.url).href
+
+const imageMapSrc = new URL('@/assets/images/mapdock.png', import.meta.url).href
+
+const mapswitching = new URL('@/assets/images/mapswitching.png', import.meta.url).href
+
+const videoWH = ref<any>(null)
+
+// 视频宽高
+const drawCanvasWidth = ref<Number>(0)
+const drawCanvasHeight = ref<Number>(0)
+
+// 鹰眼视频
+const timer = null;
+const videoPlayer = ref<any>(null); // 视频播放器实例
+let webrtcPlayer = null; // video.js 播放器
+
+// 大屏幕视频
+const timerBig = null;
+const videoPlayerBig = ref<any>(null); // 视频播放器实例
+let webrtcPlayerBig = null
+
+let player = null; // video.js 播放器
+
+// 无人机实时飞行链接
+let ssLinePath = ref(null)
+
+// 实时定位
+let viewDroneInfo = {}
+// 机场高度
+let droneHeight = ref(0)
+
+// 监听
+let connectWs = ref<any>(null)
+
+let workspaceId = ref<String>(sbInfo.workspaceId)
+localStorage.setItem('bs_workspace_id', workspaceId.value)
+// store.commit('SET_SELECTED_WORKSPACE_ID', workspaceId.value);
+
+// RTCWEB 加载视频
+const playBig = () => {
+  webrtcPlayerBig = new window.ZLMRTCClient.Endpoint({
+    element: videoPlayerBig.value, // video 标签
+    debug: true, // 是否打印日志
+    zlmsdpUrl: videoUrl.value, //流地址
+    simulecast: false,
+    useCamera: false,
+    audioEnable: true,
+    videoEnable: true,
+    recvOnly: true,
+    usedatachannel: false,
+  })
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,
+    (e) => {
+      // ICE 协商出错
+      console.error('ICE 协商出错')
+      // this.eventcallbacK('ICE ERROR', 'ICE 协商出错')
+    },
+  )
+
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,
+    (e) => {
+      //获取到了远端流,可以播放
+      console.log('播放成功', e.streams)
+      // this.eventcallbacK('playing', '播放成功')
+    },
+  )
+
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,
+    (e) => {
+      // offer anwser 交换失败
+      console.error('offer anwser 交换失败', e)
+      // this.eventcallbacK('OFFER ANSWER ERROR ', 'offer anwser 交换失败')
+      if (e.code == -400 && e.msg == '流不存在') {
+        console.log('流不存在')
+        timerBig = setTimeout(() => {
+          webrtcPlayerBig.close()
+          playBig()
+        }, 100)
+      }
+    },
+  )
+
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,
+    (s) => {
+      // 获取到了本地流
+
+      // document.getElementById('selfVideo').srcObject=s;
+      // this.eventcallbacK('LOCAL STREAM', '获取到了本地流')
+    },
+  )
+}
+// const play = () => {
+//   webrtcPlayer = new window.ZLMRTCClient.Endpoint({
+//     element: videoPlayer.value, // video 标签
+//     debug: true, // 是否打印日志
+//     zlmsdpUrl: videoUrl.value, //Rtc地址
+//     simulecast: false,
+//     useCamera: false,
+//     audioEnable: true,
+//     videoEnable: true,
+//     recvOnly: true,
+//     usedatachannel: false,
+//   })
+//   webrtcPlayer.on(
+//     window.ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,
+//     (e) => {
+//       // ICE 协商出错
+//       console.error('ICE 协商出错')
+//       // this.eventcallbacK('ICE ERROR', 'ICE 协商出错')
+//     },
+//   )
+
+//   webrtcPlayer.on(
+//     window.ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,
+//     (e) => {
+//       //获取到了远端流,可以播放
+//       console.log('播放成功', e.streams)
+//       // this.eventcallbacK('playing', '播放成功')
+//     },
+//   )
+
+//   webrtcPlayer.on(
+//     window.ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,
+//     (e) => {
+//       // offer anwser 交换失败
+//       console.error('offer anwser 交换失败', e)
+//       // this.eventcallbacK('OFFER ANSWER ERROR ', 'offer anwser 交换失败')
+//       if (e.code == -400 && e.msg == '流不存在') {
+//         console.log('流不存在')
+//         timer = setTimeout(() => {
+//           webrtcPlayer.close()
+//           play()
+//         }, 100)
+//       }
+//     },
+//   )
+
+//   webrtcPlayer.on(
+//     window.ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,
+//     (s) => {
+//     },
+//   )
+// }
+const videoUrlFlv = ref<String>('')
+// 加载该设备的视频信息
+const loadVideo = async () => {
+  await getLiveVideoUrl(sn.value).then((res) => {
+    if (res.data.code != 0) return
+    // 获取高度
+    if (videoWH.value) {
+      drawCanvasWidth.value = videoWH.value.offsetWidth;
+      drawCanvasHeight.value = videoWH.value.offsetHeight;
+    }
+    videoUrl.value =  res.data.data.rtcs_url
+    videoUrlFlv.value = res.data.data.url
+    // 播放
+    // play()
+    playBig()
+    // flv
+    // initFlvPlayer()
+  })
+}
+
+// flv
+const videoPlayerFlv = ref(null); // 引用 video 元素
+let flvPlayer = null; // 用于存储 flv.js 播放器实例
+ // 初始化 flv.js 播放器
+ 
+const initFlvPlayer = () => {
+  if (flvjs.isSupported()) {
+    const videoElement = videoPlayerFlv.value; // 获取 video 元素
+    flvPlayer = flvjs.createPlayer({
+      type: 'flv', // 视频格式
+      url: videoUrlFlv.value, // FLV 视频地址
+    });
+    flvPlayer.attachMediaElement(videoElement); // 绑定 video 元素
+    flvPlayer.load(); // 加载视频
+    flvPlayer.play(); // 播放视频
+  } else {
+    console.error('Your browser does not support flv.js.');
+  }
+};
+
+//===============================
+
+// 监听ws
+const messageHandler = async (payload: any) => {
+  // if (!payload) {
+  //   return
+  // }
+  switch (payload.biz_code) {
+    case EBizCode.GatewayOsd: { // 遥控器
+      store.commit('SET_GATEWAY_INFO', payload.data)
+      break
+    }
+    case EBizCode.DeviceOsd: {
+      // console.log('低调点',payload)
+      store.commit('SET_DEVICE_INFO', payload.data)
+      store.commit('SET_WS_MESSAGE', payload)
+      break
+    }
+    case EBizCode.DockOsd: { // 机场
+      store.commit('SET_DOCK_INFO', payload.data)
+      break
+    }
+  }
+  
+}
+
+const webSorketUrl = getWebsocketUrl() + '&workspace-id=' + workspaceId.value
+// 监听ws 消息
+useConnectWebSocket(messageHandler, webSorketUrl)
+
+
+let savedMapState = null; // 保存地图状态
+// 销毁之前先保存状态
+const destroyViewer = () => {
+  if ( window.cesiumViewer) {
+    // 保存当前地图状态(如相机位置)
+    // savedMapState = window.cesiumViewer.camera.view;
+    window.cesiumViewer.destroy();
+    window.cesiumViewer = null;
+  }
+}
+
+// 地图全屏切换
+const changeModelMap = () => {
+  isBigMap.value = !isBigMap.value
+  const cesiumContainer = document.getElementById('cesiumContainerBigMap');
+  const lZp = document.getElementById('lZp');
+  const lZoom = document.getElementById('lZoom');
+  
+  if (isBigMap.value) { // 全屏
+    cesiumContainer.style.position = 'fixed';
+    cesiumContainer.style.top = '0';
+    cesiumContainer.style.left = '0';
+    cesiumContainer.style.width = '100%';
+    cesiumContainer.style.height = '100%';
+    lZp.style.right = '40%';
+    lZoom.style.left = '0';
+  } else { // 缩放
+    cesiumContainer.style.position = 'static';
+    cesiumContainer.style.width = `${screenWidthMap.value}`
+    cesiumContainer.style.height = `${screenHeight.value}`
+    lZp.style.right = '16%';
+    lZoom.style.left = 'auto';
+    
+  }
+}
+
+const checkOrientation = async () => {
+  const landscapeBox = document.getElementById('landscapeBox');
+  const cesiumContainer = document.getElementById('cesiumContainerBigMap');
+  const videoModule = document.getElementById('videoModule');
+  const lZp = document.getElementById('lZp');
+  const lZoom = document.getElementById('lZoom');
+  // 横屏再加载视频请求
+  // destroyViewer()
+  
+  // loadVideo()
+  if (window.innerWidth > window.innerHeight) {
+    isLandscape.value = true;
+    updateScreenSize()
+    landscapeBox.style.display = 'flex';
+    lZp.style.right = '16%';
+    lZoom.style.display = 'block';
+    lZoom.style.position = 'fixed';
+    // await nextTick();
+    // await _init('cesiumContainerBigMap');
+    // await getWrjSsLx();
+  } else {
+    console.log('是否进来',landscapeBox)
+    isLandscape.value = false;
+    updateScreenSize()
+    landscapeBox.style.display = 'inherit';
+    lZp.style.right = '28%';
+    lZoom.style.display = 'none';
+    // landscapeBox.style.width = `${screenWidth}`
+    // landscapeBox.style.height = `${screenHeight}`
+    // videoModule.style.width = `${screenWidth}`
+    // videoModule.style.height = `${screenHeight}`
+    // await nextTick();
+    // await _init('cesiumContainerMap');
+    // await getWrjSsLx();
+  }
+};
+
+// 获取实时航线
+const getWrjSsLx = () => {
+  getWaylineFile(sbInfo.sn).then((res:any) => {
+    if (res.code != 200) return
+    ssLinePath.value = res.data
+    globalViewer = window.cesiumViewer
+    // 先有航线,再飞行
+    generateCourse()
+  })
+}
+
+// 切换航线轨迹
+const courseTrack = (data:any) => {
+  if (window.cesiumViewer== null) return 
+  const currentSn = dockSn.value
+  const longitude = data.dockInfo[currentSn]?.basic_osd?.longitude || null
+  const latitude = data.dockInfo[currentSn]?.basic_osd?.latitude || null
+  const height = data.dockInfo[currentSn]?.basic_osd?.height || null
+  let getLongOk = ref(0)
+  if (!getEntityById('drone_dock')) {
+    getLnglatAltitude(longitude, latitude,  window.cesiumViewer).then(res => {
+      removeById('drone_dock')
+       window.cesiumViewer.entities.add({
+        position: globalCesium.Cartesian3.fromDegrees(
+          longitude,
+          latitude,
+          res.height,
+        ),
+        id: 'drone_dock',
+        billboard: {
+          image: imageMapSrc,
+          outlineWidth: 0,
+          width: 36,
+          height: 36,
+          scale: 1.0,
+        }
+      })
+       window.cesiumViewer.scene.camera.setView({
+        destination: globalCesium.Cartesian3.fromDegrees(
+          Number(longitude),
+          Number(latitude),
+          10000.0,
+        ),
+      })
+      droneHeight.value = res.height
+    })
+  } else {
+    // 当机场坐标存在时,判断获取的位置与机场坐标位置是否一致,若不是,重新更新位置
+    let dornePoint = cartesian3Convert(
+      getEntityById('drone_dock')._position._value,
+       window.cesiumViewer,
+    )
+    getLongOk = getLnglatDist(
+      dornePoint.longitude,
+      dornePoint.latitude,
+      longitude,
+      latitude,
+    )
+    if (getLongOk.value > 100) {
+      removeById('drone_dock')
+    }
+  }
+  if (getLongOk.value > 100) return
+  initDock(data, sn.value, dockSn.value, workspaceId.value, ssLinePath.value, viewDroneInfo)
+}
+
+// 监听
+watch(() => store.state.deviceState, (newValue, oldValue) => {
+  // 试试
+  if (newValue) {
+    nextTick()
+    courseTrack(newValue)
+  }
+}, {deep: true})
+
+watch(() => store.state.wsMessage, (newValue, oldValue) => {
+  viewDroneInfo.longitude = newValue?.longitude
+  viewDroneInfo.latitude = newValue?.latitude
+  viewDroneInfo.elevation = Number(newValue?.elevation.toFixed(2)) + droneHeight.value
+}, {deep: true})
+
+
+
+// 生成航线轨迹
+const generateCourse = async () => {
+  if (!ssLinePath.value) return
+  const { fileInfoObj } = await analyzeKmzFile(`${ssLinePath.value}?_t=${new Date().getTime()}`)
+  const xmlStr = await fileInfoObj['wpmz/template.kml']
+  const xmlJson = XMLToJSON(xmlStr)?.['Document']
+  const placemark = xmlJson.Folder.Placemark
+  if (placemark?.Polygon) {
+    // return 'planar'
+    planarWayline(ssLinePath.value, sbInfo.longitude, sbInfo.latitude)
+  } else {
+    // return 'point'
+    pointWayline(ssLinePath.value, sbInfo.longitude, sbInfo.latitude)
+  }
+}
+
+onMounted(async () => {
+  window.addEventListener('orientationchange', checkOrientation);
+  window.addEventListener('resize', checkOrientation); // 兼容某些设备
+  checkOrientation(); // 初始化时检查一次
+  loadVideo()
+  await nextTick();
+  await _init('cesiumContainerBigMap');
+  await getWrjSsLx();
+  
+});
+
+onBeforeUnmount(() => {
+  window.removeEventListener('orientationchange', checkOrientation);
+  window.removeEventListener('resize', checkOrientation);
+  if (player) {
+    player.dispose();
+  }
+  if (flvPlayer) {
+    flvPlayer.pause(); // 暂停播放
+    flvPlayer.unload(); // 卸载视频
+    flvPlayer.detachMediaElement(); // 解绑 video 元素
+    flvPlayer.destroy(); // 销毁播放器
+    flvPlayer = null;
+  }
+});
+
+
+
+</script>
+
+<style lang="scss" scoped>
+.drone-pilot-details {
+  .landscape-box {
+    position: relative;
+    display: flex;
+    .l-map {
+      .l-zp {
+        position: fixed;
+        right: 16%;
+        bottom: 0;
+      }
+      .l-zoom {
+        position: fixed;
+        bottom: 0;
+        .zoom {
+          width: 2rem;
+          height: 2rem;
+          border-radius: 3px;
+          background-color: rgba(0, 0, 0, 0.8);
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          overflow: hidden;
+          cursor: pointer;
+          pointer-events: all;
+          img {
+            width: 1.6rem;
+            height: 1.6rem;
+          }
+        }
+      }
+    }
+  }
+  .l-video {
+    .el-empty {
+      width: 100%;
+      height: 100%;
+      padding: 0;
+      ::v-deep(.el-empty__image) {
+        width: 50%;
+        height: 50%;
+      }
+      ::v-deep(.el-empty__description) {
+        margin: 0;
+      }
+    }
+  }
+  #cesiumContainerBigMap {
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+
+    :deep() {
+      .cesium-viewer {
+        width: 100%;
+        height: 100%;
+
+        .cesium-viewer-cesiumWidgetContainer {
+          width: 100%;
+          height: 100%;
+
+          .cesium-widget {
+            width: 100%;
+            height: 100%;
+
+            canvas {
+              width: 100%;
+              height: 100%;
+            }
+          }
+        }
+      }
+    }
+  }
+  #cesiumContainerMap {
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+
+    :deep() {
+      .cesium-viewer {
+        width: 100%;
+        height: 100%;
+
+        .cesium-viewer-cesiumWidgetContainer {
+          width: 100%;
+          height: 100%;
+
+          .cesium-widget {
+            width: 100%;
+            height: 100%;
+
+            canvas {
+              width: 100%;
+              height: 100%;
+            }
+          }
+        }
+      }
+    }
+  }
+  .portrait-screen {
+    .l-map {
+      .l-zp {
+        position: fixed;
+        right: 28%;
+        bottom: 0;
+      }
+      .l-zoom {
+        position: fixed;
+        bottom: 0;
+        .zoom {
+          width: 2rem;
+          height: 2rem;
+          border-radius: 3px;
+          background-color: rgba(0, 0, 0, 0.8);
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          overflow: hidden;
+          cursor: pointer;
+          pointer-events: all;
+          img {
+            width: 1.6rem;
+            height: 1.6rem;
+          }
+        }
+      }
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/DronePilotDetails-copy3.vue b/src/views/DronePilotDetails-copy3.vue
new file mode 100644
index 0000000..82f8ac0
--- /dev/null
+++ b/src/views/DronePilotDetails-copy3.vue
@@ -0,0 +1,675 @@
+<template>
+  <div class="drone-pilot-details" :style="{ width: screenWidth,height: screenHeight}">
+    <div id="landscapeBox" class="landscape-box" :style="{ width: screenWidth + 'px', height: (screenHeight) + 'px'}">
+      <div id="videoModule" class="l-video" :style="{ width: screenWidthVideo + 'px', height: (screenHeightVideo) + 'px'}">
+        <video v-show="videoUrl" ref="videoPlayerBig" :style="{ width: screenWidthVideo + 'px', height: screenHeightVideo + 'px'}" controls autoplay muted playsinline style="text-align: left; object-fit: fill">
+          Your browser is too old which doesn't support HTML5 video.
+        </video>
+        <el-empty v-show="videoUrl == ''" description="当前设备已关机,无法进行直播" :image="imageUrl"></el-empty>
+      </div>
+      <div class="l-map" :style="{ width: screenWidthVideo + 'px', height: (screenHeightVideo) + 'px'}">
+        <div id="cesiumContainerBigMap"></div>
+        <div class="l-zp" id="lZp">
+          <comPass :cesiumViewe="globalViewer"/>
+        </div>
+        <div class="l-zoom" id="lZoom">
+          <div class="zoom">
+            <img src="@/assets/images/me.png" @touchstart="getLocation" />
+          </div>
+          <div class="zoom" @touchstart="onChangeD">
+            <img v-if="is2d" src="@/assets/images/stand.png" />
+            <img v-else src="@/assets/images/satellite.png" />
+          </div>
+          <div class="zoom">
+            <img v-if="!isBigMap" src="@/assets/images/fang.png" @touchstart="changeModelMap" />
+            <img v-else src="@/assets/images/suo.png" @touchstart="changeModelMap" />
+          </div>
+        </div>
+      </div>
+      <div class="right-box">
+        <ptzControl :sn="sn" :osdVisible="sbInfo" />
+        <controlConsole :sn="sn" :osdVisible="sbInfo" :cesiumViewe="globalViewer" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted, onBeforeUnmount, nextTick, reactive, computed, watch } from 'vue';
+import { EDeviceTypeName, EHmsLevel } from '@/types/enums'
+import { getRoot } from '../../root'
+import { startLivestream, getLiveVideoUrl } from '@/api/manage'
+import { CURRENT_CONFIG as config } from '@/api/http/config'
+// import videojs from 'video.js'
+// import 'video.js/dist/video-js.css';
+import { getLnglatDist, cartesian3Convert, getLnglatAltitude, createCircleBillboard } from '@/utils/cesium/mapUtil'
+import cesiumOperation from '@/utils/cesium-tsa.js';
+const { _init, viewerDestory } = cesiumOperation();
+import * as Cesium from 'cesium';
+
+// import { cesiumOperation } from '@/hooks/use-cesium-tsa'
+// const { _init } = cesiumOperation();
+import { useMyStore } from '@/store'
+import { getWaylineFile } from '@/api/manage'
+import comPass from './components/comPass.vue'
+import ptzControl from './components/ptzControl.vue'
+import controlConsole from './components/controlConsole.vue'
+import { useConnectWebSocket } from '@/utils/websocket/connect-websocket'
+import { getWebsocketUrl } from '@/websocket/util/config'
+import { EBizCode, ELocalStorageKey, ERouterName } from '@/types'
+import VConsole from 'vconsole';
+import { any } from 'video.js/dist/types/utils/events';
+import { analyzeKmzFile, XMLToJSON } from '@/utils/cesium/kmz.js'
+import { initPointWayLine } from './hooks/initPointWayline'
+import { initPlanarWayline } from './hooks/initPlanarWayline'
+import { droneFly } from './hooks/droneFly'
+import flvjs from 'flv.js';
+const { pointWayline } = initPointWayLine()
+const { planarWayline } = initPlanarWayline()
+const { initDock } = droneFly()
+
+const {
+  removeAllPoint,
+  removeAllDataSource,
+  globalCesium,
+  getEntityById,
+  removeById,
+  loadLAYER,
+} = cesiumOperation()
+
+const vConsole = new VConsole();
+
+let globalViewer = null
+
+// 使用 ref 来存储屏幕宽度和高度
+const screenWidth = ref(window.innerWidth);
+const screenHeight = ref(window.innerHeight);
+// 地图切换
+const screenWidthMap = ref((window.innerHeight/2)*2)// ref(window.innerWidth);
+const screenHeightMap = ref((window.innerHeight/2));
+// 视频切换
+const screenWidthVideo = ref(window.innerWidth);
+const screenHeightVideo = ref(window.innerHeight/2);
+const isBigMap = ref(false)
+
+// 显示高德地图矢量还是影像(2D/3D)
+let is2d = ref(true)
+
+const onChangeD = () => {
+  is2d.value = !is2d.value
+  store.commit('SET_MAP_SETTING_MODE', is2d.value?2:3);
+  loadLAYER();
+}
+
+const store = useMyStore()
+// 获取路由
+const root = getRoot()
+
+interface deviceInfo {
+  dockSn: string;
+  latitude?:number;// 机场经纬度
+  longitude?:number;
+  height?:number; // 机场高度
+  isOnline: boolean;
+  name: string; // 可选字段
+  sn: string;
+  workspaceId:string;
+  children?: {  };
+}
+// 获取机场/遥控器sn
+let localData = ref<any>(window.localStorage.getItem('sbInfo'))
+const sbInfo: deviceInfo = JSON.parse(localData.value) as deviceInfo;
+
+// 无人机sn 
+const sn = ref<String>(sbInfo.sn)
+// 机场sn 
+const dockSn = ref<String>(sbInfo.dockSn)
+
+// 记录横竖屏模式
+const isLandscape = ref(false);
+
+// 记录视频地址
+const videoUrl = ref<String>('');
+
+// 设置图片地址
+const imageUrl = new URL('@/assets/images/norecord.png', import.meta.url).href
+
+const imageMapSrc = new URL('@/assets/images/mapdock.png', import.meta.url).href
+
+const meMapSrc = new URL('@/assets/images/me.png', import.meta.url).href
+
+const jgbMapSrc = new URL('@/assets/images/jgb.png', import.meta.url).href
+
+const mapswitching = new URL('@/assets/images/mapswitching.png', import.meta.url).href
+
+const videoWH = ref<any>(null)
+
+// 视频宽高
+const drawCanvasWidth = ref<Number>(0)
+const drawCanvasHeight = ref<Number>(0)
+
+// 鹰眼视频
+const timer = null;
+const videoPlayer = ref<any>(null); // 视频播放器实例
+let webrtcPlayer = null; // video.js 播放器
+
+// 大屏幕视频
+const timerBig = null;
+const videoPlayerBig = ref<any>(null); // 视频播放器实例
+let webrtcPlayerBig = null
+
+let player = null; // video.js 播放器
+
+// 无人机实时飞行链接
+let ssLinePath = ref(null)
+
+// 实时定位
+let viewDroneInfo = {}
+// 机场高度
+let droneHeight = ref(0)
+
+// 监听
+let connectWs = ref<any>(null)
+
+let workspaceId = ref<String>(sbInfo.workspaceId)
+localStorage.setItem('bs_workspace_id', workspaceId.value)
+// store.commit('SET_SELECTED_WORKSPACE_ID', workspaceId.value);
+
+// 自身定位
+let me_latitude = 0;
+let me_longitude = 0;
+
+// RTCWEB 加载视频
+const playBig = () => {
+  webrtcPlayerBig = new window.ZLMRTCClient.Endpoint({
+    element: videoPlayerBig.value, // video 标签
+    debug: true, // 是否打印日志
+    zlmsdpUrl: videoUrl.value, //流地址
+    simulecast: false,
+    useCamera: false,
+    audioEnable: true,
+    videoEnable: true,
+    recvOnly: true,
+    usedatachannel: false,
+  })
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,
+    (e) => {
+      // ICE 协商出错
+      console.error('ICE 协商出错')
+      // this.eventcallbacK('ICE ERROR', 'ICE 协商出错')
+    },
+  )
+
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,
+    (e) => {
+      //获取到了远端流,可以播放
+      console.log('播放成功', e.streams)
+      // this.eventcallbacK('playing', '播放成功')
+    },
+  )
+
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,
+    (e) => {
+      // offer anwser 交换失败
+      console.error('offer anwser 交换失败', e)
+      // this.eventcallbacK('OFFER ANSWER ERROR ', 'offer anwser 交换失败')
+      if (e.code == -400 && e.msg == '流不存在') {
+        console.log('流不存在')
+        timerBig = setTimeout(() => {
+          webrtcPlayerBig.close()
+          playBig()
+        }, 100)
+      }
+    },
+  )
+
+  webrtcPlayerBig.on(
+    window.ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,
+    (s) => {
+      // 获取到了本地流
+
+      // document.getElementById('selfVideo').srcObject=s;
+      // this.eventcallbacK('LOCAL STREAM', '获取到了本地流')
+    },
+  )
+}
+
+
+// 加载该设备的视频信息
+const loadVideo = async () => {
+  await getLiveVideoUrl(sn.value).then((res) => {
+    if (res.data.code != 0) return
+    // 获取高度
+    if (videoWH.value) {
+      drawCanvasWidth.value = videoWH.value.offsetWidth;
+      drawCanvasHeight.value = videoWH.value.offsetHeight;
+    }
+    videoUrl.value =  res.data.data.rtcs_url
+    // 播放
+    playBig()
+  })
+}
+
+//===============================
+
+// 监听ws
+const messageHandler = async (payload: any) => {
+  // if (!payload) {
+  //   return
+  // }
+  switch (payload.biz_code) {
+    case EBizCode.GatewayOsd: { // 遥控器
+      store.commit('SET_GATEWAY_INFO', payload.data)
+      break
+    }
+    case EBizCode.DeviceOsd: {
+      store.commit('SET_DEVICE_INFO', payload.data)
+      store.commit('SET_WS_MESSAGE', payload)
+      break
+    }
+    case EBizCode.DockOsd: { // 机场
+      store.commit('SET_DOCK_INFO', payload.data)
+      break
+    }
+  }
+  
+}
+
+const webSorketUrl = getWebsocketUrl() + '&workspace-id=' + workspaceId.value
+// 监听ws 消息
+useConnectWebSocket(messageHandler, webSorketUrl)
+
+
+let savedMapState = null; // 保存地图状态
+// 销毁之前先保存状态
+const destroyViewer = () => {
+  if ( window.cesiumViewer) {
+    // 保存当前地图状态(如相机位置)
+    // savedMapState = window.cesiumViewer.camera.view;
+    window.cesiumViewer.destroy();
+    window.cesiumViewer = null;
+  }
+}
+
+// 地图全屏切换
+const changeModelMap = () => {
+  isBigMap.value = !isBigMap.value
+  const cesiumContainer = document.getElementById('cesiumContainerBigMap');
+  const lZp = document.getElementById('lZp');
+  // const lZoom = document.getElementById('lZoom');
+  if (isLandscape.value) { // 横屏
+    if (isBigMap.value) { // 全屏
+      cesiumContainer.style.position = 'fixed';
+      cesiumContainer.style.top = '0';
+      cesiumContainer.style.left = '0';
+      cesiumContainer.style.width = `${screenWidthMap.value * 2}px`
+      cesiumContainer.style.height = `${screenHeightMap.value}px`
+      lZp.style.right = '40%';
+      // lZoom.style.left = '0';
+    } else { // 缩放
+      cesiumContainer.style.width = `${screenWidthMap.value}px`
+      cesiumContainer.style.height = `${screenHeightMap.value}px`
+      cesiumContainer.style.position = 'static';
+      lZp.style.right = '16%';
+      // lZoom.style.left = '50%';
+      
+    }
+  } else {
+    if (isBigMap.value) { // 全屏
+      cesiumContainer.style.position = 'fixed';
+      cesiumContainer.style.top = '0';
+      cesiumContainer.style.left = '0';
+      cesiumContainer.style.width = `${screenWidthMap.value}px`
+      cesiumContainer.style.height = `${screenHeightMap.value * 2}px`
+      lZp.style.right = '30%';
+      // lZoom.style.right = '0';
+    } else { // 缩放
+    console.log('竖屏宽度',screenWidthMap.value)
+    console.log('竖屏高度度',screenHeightMap.value)
+      cesiumContainer.style.width = `${screenWidthMap.value}px`
+      cesiumContainer.style.height = `${screenHeightMap.value}px`
+      cesiumContainer.style.position = 'static';
+      lZp.style.right = '30%';
+      // lZoom.style.right = '0';
+      
+    }
+  }
+}
+
+// 更新屏幕尺寸的函数
+// const updateScreenSize = () => {
+//   const cesiumContainer = document.getElementById('cesiumContainerBigMap');
+//   screenWidth.value = window.innerWidth;
+//   screenHeight.value = window.innerHeight;
+//   console.log('屏幕自身宽度',window.innerWidth)
+//   console.log('屏幕自身高度',window.innerHeight)
+//   if (isLandscape.value) { //横屏
+//     screenWidthMap.value = window.innerWidth/2
+//     screenHeightMap.value = window.innerHeight
+//     screenWidthVideo.value = window.innerWidth/2
+//     screenHeightVideo.value = window.innerHeight
+//     cesiumContainer.style.width = `${screenWidthMap.value}px`
+//     cesiumContainer.style.height = `${screenHeightMap.value}px`
+//   } else {//竖屏
+//     screenWidthMap.value = window.innerHeight
+//     screenHeightMap.value = (window.innerHeight/2)
+//     screenWidthVideo.value = window.innerWidth
+//     screenHeightVideo.value = (window.innerHeight/2)
+//     // 重新给赋值宽高
+//     cesiumContainer.style.width = `${screenWidthMap.value}px`
+//     cesiumContainer.style.height = `${screenHeightMap.value}px`
+//     console.log('切换竖屏宽度',screenWidthMap.value)
+//     console.log('切换竖屏高度度',screenHeightMap.value)
+//   }
+  
+// };
+
+const checkOrientation = async () => {
+  screenWidth.value = window.innerWidth;
+  screenHeight.value = window.innerHeight;
+  console.log('屏幕宽度', screenWidth.value)
+  console.log('屏幕高度', screenHeight.value)
+  const landscapeBox = document.getElementById('landscapeBox');
+  let cesiumContainer = document.getElementById('cesiumContainerBigMap');
+  const videoModule = document.getElementById('videoModule');
+  const lZp = document.getElementById('lZp');
+  const lZoom = document.getElementById('lZoom');
+
+  if (window.innerWidth > window.innerHeight) {//横屏
+    screenWidthVideo.value = window.innerWidth/2
+    screenHeightVideo.value = window.innerHeight
+    isLandscape.value = true;
+    // updateScreenSize()
+    landscapeBox.style.display = 'flex';
+    lZp.style.right = '16%';
+    lZoom.style.position = 'fixed';
+    cesiumContainer.style.width = `${screenWidth.value/2}px`
+    cesiumContainer.style.height = `${screenHeight.value}px`
+  } else { //竖屏
+    isLandscape.value = false;
+    screenWidthVideo.value = window.innerWidth
+    screenHeightVideo.value = (window.innerHeight/2)
+    // updateScreenSize()
+    landscapeBox.style.display = 'inherit';
+    landscapeBox.style.overflow = 'hidden';
+    lZp.style.right = '32%';
+    cesiumContainer.style.width = `${screenHeight.value}px`
+    cesiumContainer.style.height = `${screenHeight.value/2}px`
+  }
+};
+
+// 获取实时航线
+const getWrjSsLx = () => {
+  globalViewer = window.cesiumViewer;
+  // ssLinePath.value = 'https://wrj.shuixiongit.com/minio/cloud-bucket/wayline/20250211/wayline_1739254562374.kmz'
+  // generateCourse()
+  // return
+  getWaylineFile(sbInfo.sn).then((res:any) => {
+    if (res.code != 200) return
+    ssLinePath.value = res.data
+    // globalViewer = window.cesiumViewer
+    // 先有航线,再飞行
+    generateCourse()
+  })
+}
+
+// 切换航线轨迹
+const courseTrack = (data:any) => {
+  if (window.cesiumViewer== null) return 
+  const currentSn = dockSn.value
+  const longitude = data.dockInfo[currentSn]?.basic_osd?.longitude || null
+  const latitude = data.dockInfo[currentSn]?.basic_osd?.latitude || null
+  const height = data.dockInfo[currentSn]?.basic_osd?.height || null
+  let getLongOk = ref(0)
+  if (!getEntityById('drone_dock')) {
+    getLnglatAltitude(longitude, latitude,  window.cesiumViewer).then(res => {
+      removeById('drone_dock')
+       window.cesiumViewer.entities.add({
+        position: globalCesium.Cartesian3.fromDegrees(
+          longitude,
+          latitude,
+          res.height,
+        ),
+        id: 'drone_dock',
+        billboard: {
+          image: imageMapSrc,
+          outlineWidth: 0,
+          width: 36,
+          height: 36,
+          scale: 1.0,
+        }
+      })
+      window.cesiumViewer.scene.camera.setView({
+        destination: globalCesium.Cartesian3.fromDegrees(
+          Number(longitude),
+          Number(latitude),
+          10000.0,
+        ),
+      })
+      droneHeight.value = res.height
+    })
+  } else {
+    // 当机场坐标存在时,判断获取的位置与机场坐标位置是否一致,若不是,重新更新位置
+    let dornePoint = cartesian3Convert(getEntityById('drone_dock')._position._value, window.cesiumViewer,)
+    getLongOk = getLnglatDist(
+      dornePoint.longitude,
+      dornePoint.latitude,
+      longitude,
+      latitude,
+    )
+    if (getLongOk.value > 100) {
+      removeById('drone_dock')
+    }
+  }
+  if (getLongOk.value > 100) return
+  initDock(data, sn.value, dockSn.value, workspaceId.value, ssLinePath.value, viewDroneInfo, me_latitude, me_longitude)
+}
+
+// 监听
+watch(() => store.state.deviceState, (newValue, oldValue) => {
+  // 试试
+  if (newValue) {
+    nextTick()
+    courseTrack(newValue)
+  }
+}, {deep: true})
+
+watch(() => store.state.wsMessage, (newValue, oldValue) => {
+  // 控制台报 Expected longitude to be typeof number, actual typeof was undefined 是因为这里没有及时拿到longitude数据
+  if (newValue) {
+    viewDroneInfo.longitude = newValue?.longitude
+    viewDroneInfo.latitude = newValue?.latitude
+    viewDroneInfo.elevation = Number(newValue?.elevation.toFixed(2)) + droneHeight.value
+  }
+}, {deep: true})
+
+
+
+// 生成航线轨迹
+const generateCourse = async () => {
+  // ssLinePath.value = 'https://wrj.shuixiongit.com/minio/cloud-bucket/wayline/20250211/wayline_1739254562374.kmz'
+  if (!ssLinePath.value) return
+  const { fileInfoObj } = await analyzeKmzFile(`${ssLinePath.value}?_t=${new Date().getTime()}`)
+  const xmlStr = await fileInfoObj['wpmz/template.kml']
+  const xmlJson = XMLToJSON(xmlStr)?.['Document']
+  const placemark = xmlJson.Folder.Placemark
+  console.log('看看航线值', sbInfo)
+  if (placemark?.Polygon) {
+    // return 'planar'
+    planarWayline(ssLinePath.value, sbInfo.longitude, sbInfo.latitude)
+  } else {
+    // return 'point'
+    pointWayline(ssLinePath.value, sbInfo.longitude, sbInfo.latitude)
+  }
+}
+
+// 获取自身定位
+const getLocation = () => {
+  if (window.cesiumViewer == null) return 
+  // 获取设备朝向
+    if (window.DeviceOrientationEvent) {
+      window.addEventListener('deviceorientation', (event) => {
+        const alpha = event.alpha; // 方位角
+        const beta = event.beta;   // 前后倾斜
+        const gamma = event.gamma; // 左右倾斜
+
+        if (alpha !== null && beta !== null && gamma !== null) {
+          updateCesiumCamera(alpha, beta, gamma);
+        }
+      });
+    } else {
+      console.log('Device Orientation API is not supported.');
+    }
+  // if (navigator.geolocation) {
+  //   navigator.geolocation.getCurrentPosition(
+  //     (position) => {
+        me_latitude =  28.624647955787974;// position.coords.latitude;
+        me_longitude = 115.85635808986208;// position.coords.longitude;
+        // 开始给自己定位
+        getLnglatAltitude(me_longitude, me_latitude,  window.cesiumViewer).then(res => {
+          removeById('me_coordinate')
+          window.cesiumViewer.entities.add({
+            position: globalCesium.Cartesian3.fromDegrees(
+              me_longitude,
+              me_latitude,
+              res.height || 0,
+            ),
+            id: 'me_coordinate',
+            billboard: {
+              image: meMapSrc,
+              outlineWidth: 0,
+              width: 36,
+              height: 36,
+              scale: 1.0,
+            }
+          })
+          window.cesiumViewer.scene.camera.setView({
+            destination: globalCesium.Cartesian3.fromDegrees(
+              Number(me_longitude),
+              Number(me_latitude),
+              10000.0,
+            ),
+          })
+        })
+  //     },
+  //     (err) => {
+  //       console.log('定位有误')
+  //     }
+  //   );
+  // } else {
+  //   console.log('您的浏览器不支持地理定位')
+  // }
+};
+
+onMounted(async () => {
+  window.addEventListener('orientationchange', checkOrientation);
+  window.addEventListener('resize', checkOrientation); // 兼容某些设备
+  checkOrientation(); // 初始化时检查一次
+  loadVideo()
+  await nextTick();
+  await _init('cesiumContainerBigMap');
+  await getWrjSsLx();
+  // await generateCourse()
+  await getLocation()
+
+  
+  
+});
+
+onBeforeUnmount(() => {
+  window.removeEventListener('orientationchange', checkOrientation);
+  window.removeEventListener('resize', checkOrientation);
+  if (player) {
+    player.dispose();
+  }
+});
+
+
+
+</script>
+
+<style lang="scss" scoped>
+.drone-pilot-details {
+  .landscape-box {
+    overflow: hidden;
+    // position: relative;
+    // display: flex;
+    .l-map {
+      .l-zp {
+        position: fixed;
+        right: 16%;
+        bottom: 0;
+      }
+      .l-zoom {
+        position: fixed;
+        bottom: 0;
+        right: 0;
+        .zoom {
+          width: 2rem;
+          height: 2rem;
+          margin: 0.2rem 0.4rem;
+          border-radius: 3px;
+          background-color: rgba(0, 0, 0, 0.8);
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          overflow: hidden;
+          cursor: pointer;
+          pointer-events: all;
+          img {
+            width: 1.6rem;
+            height: 1.6rem;
+          }
+        }
+      }
+    }
+  }
+  .l-video {
+    .el-empty {
+      width: 100%;
+      height: 100%;
+      padding: 0;
+      ::v-deep(.el-empty__image) {
+        width: 50%;
+        height: 50%;
+      }
+      ::v-deep(.el-empty__description) {
+        margin: 0;
+      }
+    }
+  }
+  #cesiumContainerBigMap {
+    width: 100%;
+    height: 100%;
+    margin: 0;
+    padding: 0;
+    overflow: hidden;
+
+    :deep() {
+      .cesium-viewer {
+        width: 100%;
+        height: 100%;
+
+        .cesium-viewer-cesiumWidgetContainer {
+          width: 100%;
+          height: 100%;
+
+          .cesium-widget {
+            width: 100%;
+            height: 100%;
+
+            canvas {
+              width: 100%;
+              height: 100%;
+            }
+          }
+        }
+      }
+    }
+  }
+  .right-box {}
+}
+</style>
\ No newline at end of file
diff --git a/src/views/DronePilotDetails.vue b/src/views/DronePilotDetails.vue
index ad9d030..b3ce7be 100644
--- a/src/views/DronePilotDetails.vue
+++ b/src/views/DronePilotDetails.vue
@@ -1,12 +1,21 @@
 <template>
   <div class="drone-pilot-details" :style="{ width: screenWidth,height: screenHeight}">
-    <div id="landscapeBox" class="landscape-box" :style="{ width: screenWidth + 'px', height: (screenHeight) + 'px'}">
+    <van-nav-bar
+      title="详情"
+      left-arrow
+      @click-left="onClickLogin"
+    />
+    <div id="landscapeBox" class="landscape-box" :style="{ width: boxWidth + 'px', height: boxHeight + 'px'}">
       <div id="videoModule" class="l-video" :style="{ width: screenWidthVideo + 'px', height: (screenHeightVideo) + 'px'}">
         <video v-show="videoUrl" ref="videoPlayerBig" :style="{ width: screenWidthVideo + 'px', height: screenHeightVideo + 'px'}" controls autoplay muted playsinline style="text-align: left; object-fit: fill">
           Your browser is too old which doesn't support HTML5 video.
         </video>
         <el-empty v-show="videoUrl == ''" description="当前设备已关机,无法进行直播" :image="imageUrl"></el-empty>
         <div v-if="videoUrl" class="center-point"></div>
+        <div class="right-box">
+          <ptzControl :sn="sn" :osdVisible="sbInfo"/>
+          <controlConsole :sn="sn" :osdVisible="sbInfo" :cesiumViewe="globalViewer" />
+        </div>
       </div>
       <div class="l-map" :style="{ width: screenWidthVideo + 'px', height: (screenHeightVideo) + 'px'}">
         <div id="cesiumContainerBigMap"></div>
@@ -26,10 +35,6 @@
             <img v-else src="@/assets/images/suo.png" @touchstart="changeModelMap" />
           </div>
         </div>
-      </div>
-      <div class="right-box">
-        <ptzControl :sn="sn" :osdVisible="sbInfo" />
-        <controlConsole :sn="sn" :osdVisible="sbInfo" :cesiumViewe="globalViewer" />
       </div>
     </div>
   </div>
@@ -84,12 +89,15 @@
 // 使用 ref 来存储屏幕宽度和高度
 const screenWidth = ref(window.innerWidth);
 const screenHeight = ref(window.innerHeight);
+// 加了头部
+const boxWidth = ref(window.innerWidth);
+const boxHeight = ref(window.innerHeight - 46);
 // 地图切换
-const screenWidthMap = ref((window.innerHeight/2)*2)// ref(window.innerWidth);
-const screenHeightMap = ref((window.innerHeight/2));
+const screenWidthMap = ref(boxWidth.value)// ref(((boxHeight.value)/2)*2)
+const screenHeightMap = ref(((boxHeight.value)/2));
 // 视频切换
-const screenWidthVideo = ref(window.innerWidth);
-const screenHeightVideo = ref(window.innerHeight/2);
+const screenWidthVideo = ref(boxWidth.value);
+const screenHeightVideo = ref(boxHeight.value/2);
 const isBigMap = ref(false)
 
 // 显示高德地图矢量还是影像(2D/3D)
@@ -147,12 +155,10 @@
 const drawCanvasHeight = ref<Number>(0)
 
 // 鹰眼视频
-const timer = null;
-const videoPlayer = ref<any>(null); // 视频播放器实例
-let webrtcPlayer = null; // video.js 播放器
+// const timer = null;
 
 // 大屏幕视频
-const timerBig = null;
+// const timerBig = null;
 const videoPlayerBig = ref<any>(null); // 视频播放器实例
 let webrtcPlayerBig = null
 
@@ -255,7 +261,6 @@
 // 获取实时航线
 const getWrjSsLx = () => {
   if (window.cesiumViewer== null) return 
-  globalViewer = window.cesiumViewer;
   getWaylineFile(sbInfo.sn).then((res:any) => {
     if (res.code != 200) return
     ssLinePath.value = res.data
@@ -294,6 +299,7 @@
     case EBizCode.DeviceOsd: {
       store.commit('SET_DEVICE_INFO', payload.data)
       store.commit('SET_WS_MESSAGE', payload)
+      getviewDrone(payload)
       break
     }
     case EBizCode.DockOsd: { // 机场
@@ -302,10 +308,9 @@
     }
     case EBizCode.FlightTaskProgress: { // 获取进度
       // 如果点击列表进入没有获取到航线文件,那么这里重新请求一次
-      console.log('航线有么111?',ssLinePath.value)
-      if (!ssLinePath || !ssLinePath.value) {
-        getWrjSsLx()
-      }
+      // if (!ssLinePath || !ssLinePath.value) {
+      //   getWrjSsLx()
+      // }
       break
     }
   }
@@ -316,17 +321,45 @@
 // 监听ws 消息
 useConnectWebSocket(messageHandler, webSorketUrl)
 
-
-let savedMapState = null; // 保存地图状态
-// 销毁之前先保存状态
-const destroyViewer = () => {
-  if ( window.cesiumViewer) {
-    // 保存当前地图状态(如相机位置)
-    // savedMapState = window.cesiumViewer.camera.view;
-    window.cesiumViewer.destroy();
-    window.cesiumViewer = null;
+// 定义方法直接监听机场消息
+const getviewDrone = (newValue) => {
+  if (newValue.data.host) {
+    viewDroneInfo.longitude = newValue.data.host?.longitude
+    viewDroneInfo.latitude = newValue.data.host?.latitude
+    viewDroneInfo.elevation = Number(newValue.data.host?.elevation.toFixed(2)) + droneHeight.value
   }
 }
+
+
+// let savedMapState = null; // 保存地图状态
+// // 销毁之前先保存状态
+// const destroyViewer = () => {
+//   if ( window.cesiumViewer) {
+//     // 保存当前地图状态(如相机位置)
+//     // savedMapState = window.cesiumViewer.camera.view;
+//     window.cesiumViewer.destroy();
+//     window.cesiumViewer = null;
+//   }
+// }
+
+// 视频全屏切换
+
+// const changeModelVideo = (value:Boolean) => {
+//   const videoModule = document.getElementById('videoModule');
+//   // 不管是否竖/横屏都一样
+//   if (value) { // 全屏
+//     videoModule.style.width = `${screenWidth.value}px`
+//     videoModule.style.height = `${screenHeight.value}px`
+//   } else {
+//     if (isLandscape.value) {
+//       videoModule.style.width = `${screenWidth.value/2}px`
+//       videoModule.style.height = `${screenHeight.value}px`
+//     } else {
+//       videoModule.style.height = `${screenHeight.value/2}px`
+//       videoModule.style.width = `${screenWidth.value}px`
+//     }
+//   }
+// }
 
 // 地图全屏切换
 const changeModelMap = () => {
@@ -337,34 +370,32 @@
   if (isLandscape.value) { // 横屏
     if (isBigMap.value) { // 全屏
       cesiumContainer.style.position = 'fixed';
-      cesiumContainer.style.top = '0';
+      cesiumContainer.style.top = '46px';
       cesiumContainer.style.left = '0';
-      cesiumContainer.style.width = `${screenWidthMap.value * 2}px`
-      cesiumContainer.style.height = `${screenHeightMap.value}px`
+      cesiumContainer.style.width = `${boxWidth.value}px`
+      // cesiumContainer.style.height = `${screenHeightMap.value}px`
       lZp.style.right = '40%';
       // lZoom.style.left = '0';
     } else { // 缩放
-      cesiumContainer.style.width = `${screenWidthMap.value}px`
-      cesiumContainer.style.height = `${screenHeightMap.value}px`
+      cesiumContainer.style.width = `${boxWidth.value/2}px`
+      // cesiumContainer.style.height = `${screenHeightMap.value}px`
       cesiumContainer.style.position = 'static';
       lZp.style.right = '16%';
       // lZoom.style.left = '50%';
       
     }
   } else {
-    if (isBigMap.value) { // 全屏
+    if (isBigMap.value) { // 竖-全屏
       cesiumContainer.style.position = 'fixed';
-      cesiumContainer.style.top = '0';
+      cesiumContainer.style.top = '46px';
       cesiumContainer.style.left = '0';
-      cesiumContainer.style.width = `${screenWidthMap.value}px`
-      cesiumContainer.style.height = `${screenHeightMap.value * 2}px`
+      // cesiumContainer.style.width = `${boxHeight.value}px`
+      cesiumContainer.style.height = `${boxHeight.value}px`
       lZp.style.right = '30%';
       // lZoom.style.right = '0';
     } else { // 缩放
-    console.log('竖屏宽度',screenWidthMap.value)
-    console.log('竖屏高度度',screenHeightMap.value)
-      cesiumContainer.style.width = `${screenWidthMap.value}px`
-      cesiumContainer.style.height = `${screenHeightMap.value}px`
+      cesiumContainer.style.width = `${boxHeight.value}px`
+      cesiumContainer.style.height = `${boxHeight.value/2}px`
       cesiumContainer.style.position = 'static';
       lZp.style.right = '30%';
       // lZoom.style.right = '0';
@@ -402,39 +433,36 @@
 // };
 
 const checkOrientation = async () => {
-  screenWidth.value = window.innerWidth;
-  screenHeight.value = window.innerHeight;
-  console.log('屏幕宽度', screenWidth.value)
-  console.log('屏幕高度', screenHeight.value)
+  boxWidth.value = window.innerWidth;
+  boxHeight.value = window.innerHeight - 46;
   const landscapeBox = document.getElementById('landscapeBox');
   let cesiumContainer = document.getElementById('cesiumContainerBigMap');
-  const videoModule = document.getElementById('videoModule');
   const lZp = document.getElementById('lZp');
   const lZoom = document.getElementById('lZoom');
 
   if (window.innerWidth > window.innerHeight) {//横屏
-    screenWidthVideo.value = window.innerWidth/2
-    screenHeightVideo.value = window.innerHeight
+    screenWidthVideo.value = boxWidth.value/2
+    screenHeightVideo.value = boxHeight.value
     isLandscape.value = true;
     // updateScreenSize()
     landscapeBox.style.display = 'flex';
     lZp.style.right = '16%';
     lZoom.style.position = 'fixed';
-    cesiumContainer.style.width = `${screenWidth.value/2}px`
-    cesiumContainer.style.height = `${screenHeight.value}px`
+    cesiumContainer.style.width = `${boxWidth.value/2}px`
+    cesiumContainer.style.height = `${boxHeight.value}px`
     cesiumContainer.style.position = 'static'
     cesiumContainer.style.right = '0'
     cesiumContainer.style.marginLeft = '0%'
   } else { //竖屏
     isLandscape.value = false;
-    screenWidthVideo.value = window.innerWidth
-    screenHeightVideo.value = (window.innerHeight/2)
+    screenWidthVideo.value = boxWidth.value
+    screenHeightVideo.value = boxHeight.value/2
     // updateScreenSize()
     landscapeBox.style.display = 'inherit';
     landscapeBox.style.overflow = 'hidden';
     lZp.style.right = '32%';
-    cesiumContainer.style.width = `${screenHeight.value}px`
-    cesiumContainer.style.height = `${screenHeight.value/2}px`
+    cesiumContainer.style.width = `${boxHeight.value}px`
+    cesiumContainer.style.height = `${boxHeight.value/2}px`
     // cesiumContainer.style.position = 'absolute'
     cesiumContainer.style.marginLeft = '-32%'
   }
@@ -501,17 +529,26 @@
   }
 }, {deep: true})
 
-watch(() => store.state.wsMessage, (newValue, oldValue) => {
-  // 控制台报 Expected longitude to be typeof number, actual typeof was undefined 是因为这里没有及时拿到longitude数据
-  if (newValue) {
-    viewDroneInfo.longitude = newValue?.longitude
-    viewDroneInfo.latitude = newValue?.latitude
-    viewDroneInfo.elevation = Number(newValue?.elevation.toFixed(2)) + droneHeight.value
-  }
-}, {deep: true})
+// watch(() => store.state.wsMessage, (newValue, oldValue) => {
+//   // 控制台报 Expected longitude to be typeof number, actual typeof was undefined 是因为这里没有及时拿到longitude数据
+//   if (newValue) {
+//     viewDroneInfo.longitude = newValue?.longitude
+//     viewDroneInfo.latitude = newValue?.latitude
+//     viewDroneInfo.elevation = Number(newValue?.elevation.toFixed(2)) + droneHeight.value
+//   }
+// }, {deep: true})
 
 
 let intervalId = null;
+
+const onClickLogin = () => {
+  history.back();
+}
+
+// 为组件赋值
+const getGlobalViewer = () => {
+  globalViewer = window.cesiumViewer;
+}
 
 onMounted(async () => {
   window.addEventListener('orientationchange', checkOrientation);
@@ -520,16 +557,16 @@
   loadVideo()
   await nextTick();
   await _init('cesiumContainerBigMap');
+  await getGlobalViewer()
   await getWrjSsLx();
   // 判断是遥控器还是机场
   let domain = sessionStorage.getItem('domain')
   if (domain !== '0') {
     await getPhoneLocation(workspaceId.value)
-    clickPhoneLocation()
   // // // 设置定时器,每隔 5 秒刷新一次数据
-    intervalId = setInterval(()=> {
-      getPhoneLocation(workspaceId.value)
-    }, 5000);
+    // intervalId = setInterval(()=> {
+    //   getPhoneLocation(workspaceId.value)
+    // }, 5000);
   }
 });
 
@@ -611,6 +648,7 @@
       transform: translate(-50%, -50%);
       justify-content: center;
     }
+    .right-box {}
   }
   #cesiumContainerBigMap {
     width: 100%;
@@ -641,6 +679,6 @@
       }
     }
   }
-  .right-box {}
+  
 }
 </style>
\ No newline at end of file
diff --git a/src/views/DronePilotList.vue b/src/views/DronePilotList.vue
index f677d5a..ed47927 100644
--- a/src/views/DronePilotList.vue
+++ b/src/views/DronePilotList.vue
@@ -1,5 +1,10 @@
 <template>
   <div class="drone-pilot-list-warp">
+    <van-nav-bar
+      title="机场/遥控器"
+      left-arrow
+      @click-left="onClickLogin"
+    />
     <div class="drone-pilot-list">
       <template v-if="droneOrPilotTxt == 'drone'">
       <div class="box-info" v-for="item in cardList" :key="item.sn">
@@ -103,6 +108,10 @@
   
 }
 
+const onClickLogin = () => {
+  history.back();
+}
+
 onMounted(() => {
   init()
   // 设置定时器,每隔 3 秒刷新一次数据
@@ -123,7 +132,7 @@
   background-color: #b8b3b338;
   // background-image: url('@/assets/images/newcon_box.png');
   .drone-pilot-list {
-    height: calc(100vh - 10%);
+    height: calc(100vh - 50px - 46px);
     overflow: auto;
     .box-info {
       background-color: #fff;
diff --git a/src/views/components/controlConsole.vue b/src/views/components/controlConsole.vue
index ca5f142..bed1403 100644
--- a/src/views/components/controlConsole.vue
+++ b/src/views/components/controlConsole.vue
@@ -205,9 +205,9 @@
 .control-console {
   
   .control {
-    position: fixed;
-    top: 0.2rem;
-    left: 0.2rem;
+    position: absolute;
+    bottom: 12.8rem;
+    right: 0.2rem;
     width: 2rem;
     height: 2rem;
     border-radius: 3px;
diff --git a/src/views/components/ptzControl-copy.vue b/src/views/components/ptzControl-copy.vue
new file mode 100644
index 0000000..62b818d
--- /dev/null
+++ b/src/views/components/ptzControl-copy.vue
@@ -0,0 +1,564 @@
+<template>
+  <div class="ptz-control">
+    <!-- <div class="ptz" :class="isPtz?'actived-blue':''">
+      <img src="@/assets/images/yt.png" @touchstart="ptzClick" />
+    </div> -->
+    <div class="btn-group">
+      <div class="btn-item" :class="isPtz?'actived-blue':''" @touchstart="ptzClick">
+        <img src="@/assets/images/yt.png" />
+      </div>
+      <div class="btn-item" @touchstart="onTakeCameraPhoto">
+        <img src="@/assets/images/photo.png" />
+      </div>
+      <div class="btn-item" v-if="!isCameraRecording" @touchstart="onStartCameraRecording">
+        <img src="@/assets/images/sx-open.png" />
+      </div>
+      <div class="btn-item" v-else @touchstart="onStopCameraRecording">
+        <img src="@/assets/images/sx-close.png"/>
+      </div>
+      <div class="btn-item" @touchstart="onZoom(true)">
+        <img src="@/assets/images/fangda.png" />
+      </div>
+      <div class="btn-item" @touchstart="onZoom(false)">
+        <img src="@/assets/images/suoxiao.png" />
+      </div>
+      <!-- <div class="btn-item">
+        <img v-if="!isBigVideo" src="@/assets/images/fang.png" @touchstart="changeModelVideo(true)" />
+        <img v-else src="@/assets/images/suo.png" @touchstart="changeModelVideo(false)" />
+      </div> -->
+    </div>
+    <div class="circle-box" v-show="isPtz">
+      <div class="top" @click="ytClick('up')" @mousedown="onMouseDown(KeyCode.ARROW_UP)" @mouseup="onMouseUp"
+        @touchstart="onMouseDown(KeyCode.ARROW_UP)" @touchend="onMouseUp" @mouseleave="onMouseUp"></div>
+      <div class="left" @click="ytClick('left')" @mousedown="onMouseDown(KeyCode.ARROW_LEFT)" @mouseup="onMouseUp"
+        @touchstart="onMouseDown(KeyCode.ARROW_LEFT)" @touchend="onMouseUp" @mouseleave="onMouseUp"></div>
+      <div class="bottom" @click="ytClick('down')" @mousedown="onMouseDown(KeyCode.ARROW_DOWN)" @mouseup="onMouseUp"
+        @touchstart="onMouseDown(KeyCode.ARROW_DOWN)" @touchend="onMouseUp" @mouseleave="onMouseUp"></div>
+      <div class="right" @click="ytClick('right')" @mousedown="onMouseDown(KeyCode.ARROW_RIGHT)" @mouseup="onMouseUp"
+        @touchstart="onMouseDown(KeyCode.ARROW_RIGHT)" @touchend="onMouseUp" @mouseleave="onMouseUp"></div>
+      <div class="reset-center" @click="onResetGimbal(0)">
+        <el-icon><Refresh /></el-icon>
+      </div>
+      <div class="blue-bgc"></div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ElMessage } from 'element-plus'
+import { Refresh } from '@element-plus/icons-vue';
+import { ControlSource, EModeCode } from '@/types/device'
+import { CameraMode } from '@/types/live-stream'
+import { ref, onMounted, onBeforeUnmount, nextTick, reactive, computed, watch } from 'vue';
+import { postPayloadCommands, postPayloadAuth } from '@/api/drone/payload'
+import { switchLivestream } from '@/api/drone'
+import { usePayloadControl } from './use-payload-control'
+import { useDroneControlWsEvent } from '@/utils/websocket/drone-ws-control'
+import cesiumOperation from '@/utils/cesium-tsa.js';
+import { useMyStore } from '@/store'
+import { fa } from 'element-plus/es/locale';
+
+const { loadLAYER } = cesiumOperation()
+
+const {
+  checkPayloadAuth,
+  authPayload,
+  resetGimbal,
+  switchCameraMode,
+  takeCameraPhoto,
+  startCameraRecording,
+  stopCameraRecording,
+  changeCameraFocalLength,
+} = usePayloadControl()
+
+const props = defineProps({
+  sn: {
+    type: String,
+    required: true,
+  },
+  osdVisible: {
+    type: Object,
+    required: true,
+  },
+  cesiumViewe: {
+    type: Object,
+    required: true,
+  }
+});
+const emitEvents = defineEmits(['changeModelVideo'])
+
+// 放大和缩小
+// let isBigVideo = ref<Boolean>(false)
+
+// 录像
+let isCameraRecording = ref<Boolean>(false)
+// 
+let isActionComplete = ref<Boolean>(false)
+
+let payloadCameraMode = ref<String>('wide')
+
+// 缩放监听更新值
+let zoom_factor_watch = ref(0)
+// 缩放初始值
+let zoom_factor_start = ref(0)
+// 缩放变化值
+let zoom_factor = ref(0)
+// is_First 记录第一次
+let is_First = ref<Boolean>(false)
+
+// 是否显示云台图标
+let isPtz = ref(false)
+
+// 显示高德地图矢量还是影像(2D/3D)
+// let is2d = ref(true)
+
+let yaw_speed = ref((payloadCameraMode.value == 'wide'? 1 : Math.ceil(zoom_factor.value))*10) // 云台横向角度
+let pitch_speed = ref((payloadCameraMode.value == 'wide'? 1 : Math.ceil(zoom_factor.value))*10) // 云台纵向角度
+
+let resultProps = reactive<any>(props.osdVisible.children.payloads_list[0])
+// console.log(resultProps, '现在勒')
+const store = useMyStore()
+// 负载控制
+const payloadSelectInfo = reactive<any>({
+  value: resultProps.payload_sn,
+  controlSource: resultProps.control_source,
+  options: [],
+  payloadIndex: resultProps.payload_index,
+  camera: '', // 当前负载osd信息
+})
+
+watch(() => store.state.wsMessage, (newValue, oldValue) => {
+  if (newValue && newValue.cameras) {
+    // console.log('监控值', newValue.cameras)
+    zoom_factor_watch.value = Math.ceil(newValue.cameras[0].zoom_factor)
+    if (!is_First.value) {
+      zoom_factor.value = zoom_factor_watch.value
+      zoom_factor_start.value = zoom_factor_watch.value
+      is_First.value = true
+    }
+    
+    payloadSelectInfo.camera = newValue.cameras.find(
+      (item:any) =>
+        item.payload_index === payloadSelectInfo.payloadIndex,
+    )
+  } else {
+    payloadSelectInfo.camera = undefined
+  }
+},
+{ 
+  deep: true,
+})
+// ws 消息通知
+const { droneControlSource, payloadControlSource } = useDroneControlWsEvent(props.sn, payloadSelectInfo.value)
+watch(() => payloadControlSource, (controlSource) => {
+  payloadSelectInfo.controlSource = 'A'// controlSource.value
+}, {
+  immediate: true,
+  deep: true
+})
+
+
+// 切换是否出现云台上下左右图
+const ptzClick = () => {
+  isPtz.value = !isPtz.value
+}
+
+// 拍照
+const onTakeCameraPhoto =  () => {
+  if (!checkPayloadAuth(payloadSelectInfo.controlSource)) {
+    return
+  }
+
+  if (isActionComplete.value) {
+    ElMessage.warning('当前相机动作暂未完成,请勿点击!!')
+    return
+  }
+  if (payloadSelectInfo.camera?.recording_state) {
+    ElMessage.warning('当前摄像头正在录制视频,请先结束视频录制!!')
+    return
+  }
+
+  if (payloadSelectInfo.camera?.camera_mode !== CameraMode.Photo) {
+    const res = switchCamera(CameraMode.Photo)
+    res.then((response:any) => {
+      if (!response) return
+
+      if (payloadSelectInfo.camera?.camera_mode !== CameraMode.Photo) {
+        curTaskCameraPhoto(2000)
+      } else {
+        curTaskCameraPhoto(0)
+      }
+    })
+
+    return
+  }
+
+  curTaskCameraPhoto(0)
+}
+const curTaskCameraPhoto =  (time:any) => {
+  isActionComplete.value = true
+
+  ElMessage({
+    message: '请稍后,正在拍摄中。。。',
+    duration: 2000,
+  })
+  setTimeout(() => {
+    let cameraType = ref('wide')
+    if (payloadCameraMode.value === 'zoom') {
+      cameraType.value = payloadCameraMode
+    }
+    console.log('1111',cameraType.value)
+    takeCameraPhoto(
+      props.osdVisible.dockSn,
+      payloadSelectInfo.payloadIndex,
+      cameraType.value
+    ).then((photoRes:any) => {
+      if (!photoRes) {
+        return
+      }
+
+      isActionComplete.value = false
+    })
+  }, time)
+}
+const switchCamera =  (camera_mode:any) => {
+  if (!checkPayloadAuth(payloadSelectInfo.controlSource)) {
+    return
+  }
+  return switchCameraMode(props.osdVisible.dockSn, {
+    payload_index: payloadSelectInfo.payloadIndex,
+    camera_mode: camera_mode,
+    video_type: payloadCameraMode.value,
+  })
+}
+
+// 相机操作
+const onAuthPayload = ()  => {
+  //负载控制
+  authPayload(props.osdVisible.dockSn, payloadSelectInfo.payloadIndex).then(
+    (payloadRes:any) => {
+      if (payloadRes.code !== 0)
+        return ElMessage.error('获得有效载荷控制失败,请稍后重试!!')
+      payloadControlSource.value = ControlSource.A
+      ElMessage.success('成功获得有效载荷控制')
+    },
+  )
+}
+// 开始录像
+const onStartCameraRecording = () => {
+  if (!checkPayloadAuth(payloadSelectInfo.controlSource)) {
+    return
+  }
+  if (isActionComplete.value) {
+    ElMessage.warning('当前相机动作暂未完成,请勿点击!!')
+    return
+  }
+
+  if (payloadSelectInfo.camera?.recording_state) {
+    return ElMessage.warning(
+      '当前摄像头正在录制视频,请勿重复点击!!',
+    )
+  }
+
+  if (payloadSelectInfo.camera?.camera_mode !== CameraMode.Video) {
+    const res = switchCamera(CameraMode.Video)
+    res.then((response) => {
+      if (!response) return
+      if (payloadSelectInfo.camera?.camera_mode !== CameraMode.Video) {
+        curStartCameraRecording(2000)
+      } else {
+        curStartCameraRecording(0)
+      }
+    })
+
+    return
+  }
+
+  curStartCameraRecording(0)
+}
+
+  const curStartCameraRecording = (time:any) => {
+    isActionComplete.value = true
+
+    ElMessage({
+      message: '请稍后,正在开启视频录制。。。',
+      duration: 2000,
+    })
+
+    setTimeout(() => {
+      startCameraRecording(props.osdVisible.dockSn, payloadSelectInfo.payloadIndex)
+        .then((res) => {
+          if (res.code !== 0)
+            return ElMessage.warning('开始录制失败,请稍后重试!!')
+          ElMessage.success('开始录制成功')
+          // 开始录像
+          isCameraRecording.value = true
+          isActionComplete.value = false
+        }).catch((e) => {
+          isActionComplete.value = false
+        })
+    }, time)
+  }
+
+// 停止录像
+const onStopCameraRecording = () => {
+  if (!checkPayloadAuth(payloadSelectInfo.controlSource)) {
+    return
+  }
+  if (isActionComplete.value) {
+    ElMessage.warning('当前相机动作暂未完成,请勿点击!!')
+    return
+  }
+  isActionComplete.value = true
+  stopCameraRecording(props.osdVisible.dockSn, payloadSelectInfo.payloadIndex)
+    .then((res) => {
+      if (res.code !== 0)
+        return ElMessage.warning('停止录制失败,请稍后重试!!')
+      ElMessage.success('停止录制成功')
+      // 停止录像
+      isCameraRecording.value = false
+      isActionComplete.value = false
+    })
+    .catch((e) => {
+      isActionComplete.value = false
+    })
+}
+    
+
+// 缩放
+const onZoom = (value:any) => {
+  if (value) {
+    zoom_factor.value += 1
+    if (zoom_factor.value >= 200) {
+      zoom_factor.value = 200
+    }
+  } else {
+    zoom_factor.value -= 1
+    if (zoom_factor.value <= 2) {
+      zoom_factor.value = 2
+    }
+    console.log('9999', zoom_factor.value)
+  }
+  switchLivestream({
+    video_id: `${props.osdVisible.dockSn}/${payloadSelectInfo.payloadIndex}/normal-0`,
+    video_type: 'zoom',
+  }).then((res:any) => {
+    if (res.data.code != 0) return
+    // 只考虑 广角:wide模式
+    changeCameraFocalLength(props.osdVisible.dockSn, {
+        payload_index: payloadSelectInfo.payloadIndex,
+        camera_type: 'zoom',
+        zoom_factor: zoom_factor.value,
+      }, value)
+  })
+}
+
+// const onChangeD = () => {
+//   is2d.value = !is2d.value
+//   store.commit('SET_MAP_SETTING_MODE', is2d.value?2:3);
+//   loadLAYER();
+// }
+
+// 重置云台角度
+const onResetGimbal = async (resetMode:any) => {
+  try {
+    await resetGimbal(props.osdVisible.dockSn, {
+      payload_index: payloadSelectInfo.payloadIndex,
+      reset_mode: resetMode,
+    })
+    await changeCameraFocalLength(props.osdVisible.dockSn, {
+      payload_index: payloadSelectInfo.payloadIndex,
+      camera_type: 'zoom',
+      zoom_factor: zoom_factor_start.value,
+    })
+    // this.zoomMultiple = 8 // 设置步长
+  } catch (err) {
+    console.log(err)
+  }
+}
+// 记得加loading
+// 云台上 下 左 右
+const ytClick = async (value:String) => {
+  if (payloadCameraMode.value == 'zoom' && zoom_factor.value > 35 && (value == 'up' || value == 'right')) { pitch_speed.value = 350 }
+  if (payloadCameraMode.value == 'zoom' && zoom_factor.value > 35 && (value == 'left' || value == 'down')) { pitch_speed.value = -350 }
+  if (value == 'up' || value == 'down') {
+    postPayloadCommands(props.osdVisible.dockSn, {cmd: 'camera_screen_drag',
+    data: {
+      locked: false,
+      payload_index: payloadSelectInfo.payloadIndex,
+      pitch_speed: value == 'up' ? pitch_speed.value : -pitch_speed.value,
+      yaw_speed: 0,
+    }})
+  } else if ((value == 'left' || value == 'right')) {
+    postPayloadCommands(props.osdVisible.dockSn, {cmd: 'camera_screen_drag',
+    data: {
+      locked: false,
+      payload_index: payloadSelectInfo.payloadIndex,
+      pitch_speed: 0,
+      yaw_speed: value == 'right' ? pitch_speed.value : -pitch_speed.value,
+    }})
+  } 
+}
+
+// 视频大小的缩放
+// const changeModelVideo = (value:Boolean) => {
+//   isBigVideo.value = value
+//   emitEvents('changeModelVideo', value)
+// }
+
+</script>
+
+<style lang="scss" scoped>
+.ptz-control {
+  .btn-group {
+    position: absolute;
+    left: 0.2rem;
+    bottom: 2rem;
+    .btn-item {
+      width: 2rem;
+      height: 2rem;
+      border-radius: 3px;
+      background-color: rgba(0, 0, 0, 0.5);
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      overflow: hidden;
+      cursor: pointer;
+      margin-bottom: 0.5rem;
+      pointer-events: all;
+      img {
+        width: 1.6rem;
+        height: 1.6rem;
+      }
+    }
+    .actived-blue {
+      background-image: none;
+      background-color: rgba(23, 124, 198, 0.7);
+    }
+  }
+  .circle-box {
+    width: 100px;
+    height: 100px;
+    border-radius: 50%;
+    overflow: hidden;
+    background-color: rgba(0, 0, 0, 0.5);
+    position: fixed;
+    top: 0;
+    right: 4rem;
+
+    .top,
+    .left,
+    .bottom,
+    .right {
+      width: 10px;
+      height: 10px;
+      position: absolute;
+      cursor: pointer;
+      z-index: 2;
+    }
+
+    .top {
+      top: -2px;
+      left: 50%;
+      transform: translateX(-50%);
+      border-top: 10px solid transparent;
+      border-right: 10px solid transparent;
+      border-left: 10px solid transparent;
+      border-bottom: 10px solid #fff;
+
+      &:hover {
+        &~.blue-bgc {
+          border-top: 50px solid #409eff;
+        }
+      }
+    }
+
+    .left {
+      top: 50%;
+      left: -2px;
+      transform: translateY(-50%);
+      border-top: 10px solid transparent;
+      border-right: 10px solid #fff;
+      border-left: 10px solid transparent;
+      border-bottom: 10px solid transparent;
+
+      &:hover {
+        &~.blue-bgc {
+          border-left: 50px solid #409eff;
+        }
+      }
+    }
+
+    .bottom {
+      bottom: -2px;
+      left: 50%;
+      transform: translateX(-50%);
+      border-top: 10px solid #fff;
+      border-right: 10px solid transparent;
+      border-left: 10px solid transparent;
+      border-bottom: 10px solid transparent;
+
+      &:hover {
+        &~.blue-bgc {
+          border-bottom: 50px solid #409eff;
+        }
+      }
+    }
+
+    .right {
+      top: 50%;
+      right: -2px;
+      transform: translateY(-50%);
+      border-top: 10px solid transparent;
+      border-right: 10px solid transparent;
+      border-left: 10px solid #fff;
+      border-bottom: 10px solid transparent;
+
+      &:hover {
+        &~.blue-bgc {
+          border-right: 50px solid #409eff;
+        }
+      }
+    }
+
+    .reset-center {
+      position: absolute;
+      width: 40%;
+      height: 40%;
+      left: 50%;
+      top: 50%;
+      transform: translate(-50%, -50%);
+      border-radius: 50%;
+      background-color: rgb(63, 66, 68);
+      z-index: 2;
+      cursor: pointer;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+
+      i {
+        color: #fff;
+        font-size: 20px;
+        font-weight: bolder;
+      }
+
+      &:hover {
+        background-color: #409eff;
+      }
+    }
+
+    .blue-bgc {
+      width: 100px;
+      height: 100px;
+      position: absolute;
+      top: 0;
+      left: 0;
+      z-index: 1;
+      border-top: 50px solid transparent;
+      border-right: 50px solid transparent;
+      border-left: 50px solid transparent;
+      border-bottom: 50px solid transparent;
+    }
+  }
+}
+</style>
diff --git a/src/views/components/ptzControl.vue b/src/views/components/ptzControl.vue
index 68f83ae..458f8c0 100644
--- a/src/views/components/ptzControl.vue
+++ b/src/views/components/ptzControl.vue
@@ -1,9 +1,9 @@
 <template>
   <div class="ptz-control">
-    <div class="ptz" :class="isPtz?'actived-blue':''">
-      <img src="@/assets/images/yt.png" @touchstart="ptzClick" />
-    </div>
     <div class="btn-group">
+      <div class="btn-item" :class="isPtz?'actived-blue':''" @touchstart="ptzClick">
+        <img src="@/assets/images/yt.png" />
+      </div>
       <div class="btn-item" @touchstart="onTakeCameraPhoto">
         <img src="@/assets/images/photo.png" />
       </div>
@@ -19,20 +19,16 @@
       <div class="btn-item" @touchstart="onZoom(false)">
         <img src="@/assets/images/suoxiao.png" />
       </div>
-      <!-- <div class="btn-item" @touchstart="onChangeD">
-        <img v-if="is2d" src="@/assets/images/stand.png" />
-        <img v-else src="@/assets/images/satellite.png" />
+      <!-- <div class="btn-item">
+        <img v-if="!isBigVideo" src="@/assets/images/fang.png" @touchstart="changeModelVideo(true)" />
+        <img v-else src="@/assets/images/suo.png" @touchstart="changeModelVideo(false)" />
       </div> -->
     </div>
     <div class="circle-box" v-show="isPtz">
-      <div class="top" @click="ytClick('up')" @mousedown="onMouseDown(KeyCode.ARROW_UP)" @mouseup="onMouseUp"
-        @touchstart="onMouseDown(KeyCode.ARROW_UP)" @touchend="onMouseUp" @mouseleave="onMouseUp"></div>
-      <div class="left" @click="ytClick('left')" @mousedown="onMouseDown(KeyCode.ARROW_LEFT)" @mouseup="onMouseUp"
-        @touchstart="onMouseDown(KeyCode.ARROW_LEFT)" @touchend="onMouseUp" @mouseleave="onMouseUp"></div>
-      <div class="bottom" @click="ytClick('down')" @mousedown="onMouseDown(KeyCode.ARROW_DOWN)" @mouseup="onMouseUp"
-        @touchstart="onMouseDown(KeyCode.ARROW_DOWN)" @touchend="onMouseUp" @mouseleave="onMouseUp"></div>
-      <div class="right" @click="ytClick('right')" @mousedown="onMouseDown(KeyCode.ARROW_RIGHT)" @mouseup="onMouseUp"
-        @touchstart="onMouseDown(KeyCode.ARROW_RIGHT)" @touchend="onMouseUp" @mouseleave="onMouseUp"></div>
+      <div class="top" @click="ytClick('up')"></div>
+      <div class="left" @click="ytClick('left')"></div>
+      <div class="bottom" @click="ytClick('down')"></div>
+      <div class="right" @click="ytClick('right')"></div>
       <div class="reset-center" @click="onResetGimbal(0)">
         <el-icon><Refresh /></el-icon>
       </div>
@@ -53,6 +49,7 @@
 import { useDroneControlWsEvent } from '@/utils/websocket/drone-ws-control'
 import cesiumOperation from '@/utils/cesium-tsa.js';
 import { useMyStore } from '@/store'
+import { fa } from 'element-plus/es/locale';
 
 const { loadLAYER } = cesiumOperation()
 
@@ -81,6 +78,10 @@
     required: true,
   }
 });
+const emitEvents = defineEmits(['changeModelVideo'])
+
+// 放大和缩小
+// let isBigVideo = ref<Boolean>(false)
 
 // 录像
 let isCameraRecording = ref<Boolean>(false)
@@ -238,7 +239,6 @@
 }
 // 开始录像
 const onStartCameraRecording = () => {
-  console.log('设施',payloadSelectInfo.controlSource)
   if (!checkPayloadAuth(payloadSelectInfo.controlSource)) {
     return
   }
@@ -393,40 +393,20 @@
   } 
 }
 
+// 视频大小的缩放
+// const changeModelVideo = (value:Boolean) => {
+//   isBigVideo.value = value
+//   emitEvents('changeModelVideo', value)
+// }
 
 </script>
 
 <style lang="scss" scoped>
 .ptz-control {
-  .ptz {
-    position: fixed;
-    top: 3rem;
-    left: 0.2rem;
-    width: 2rem;
-    height: 2rem;
-    border-radius: 3px;
-    background-color: rgba(0, 0, 0, 0.5);
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    overflow: hidden;
-    cursor: pointer;
-    margin-bottom: 1rem;
-    pointer-events: all;
-    img {
-      width: 1.6rem;
-      height: 1.6rem;
-    }
-  }
-  .actived-blue {
-    background-image: none;
-    background-color: rgba(23, 124, 198, 0.7);
-  }
   .btn-group {
-    position: fixed;
-    top: 5.8rem;
-    left: 0.2rem;
-    // padding: 4px;
+    position: absolute;
+    right: 0.2rem;
+    bottom: 0rem;
     .btn-item {
       width: 2rem;
       height: 2rem;
@@ -437,12 +417,16 @@
       justify-content: center;
       overflow: hidden;
       cursor: pointer;
-      margin-bottom: 1rem;
+      margin-bottom: 0.5rem;
       pointer-events: all;
       img {
         width: 1.6rem;
         height: 1.6rem;
       }
+    }
+    .actived-blue {
+      background-image: none;
+      background-color: rgba(23, 124, 198, 0.7);
     }
   }
   .circle-box {
@@ -452,8 +436,8 @@
     overflow: hidden;
     background-color: rgba(0, 0, 0, 0.5);
     position: fixed;
-    top: 0;
-    right: 4rem;
+    top: 20%;
+    left: 1%;
 
     .top,
     .left,
diff --git a/src/views/hooks/droneFly-copy.ts b/src/views/hooks/droneFly-copy.ts
new file mode 100644
index 0000000..c49b3da
--- /dev/null
+++ b/src/views/hooks/droneFly-copy.ts
@@ -0,0 +1,664 @@
+
+import { EDeviceTypeName, EHmsLevel } from '@/types/enums'
+import cesiumOperation from '@/utils/cesium-tsa'
+import { analyzeKmzFile, XMLToJSON } from '@/utils/cesium/kmz.js'
+import IndexedDBService from '@/utils/indexDB'
+import CreateFrustum from '@/utils/cesium/frustum/CreateFrustum'
+import { useMyStore } from '@/store'
+import { getTwoPointInfo } from '@/api/manage'
+
+const { getEntityById, removeById, globalCesium, addLeftClickEvent, removeLeftClickEvent, flyTo } = cesiumOperation()
+// 无人机实体
+let droneEntity = null
+
+// 激光实体
+let laserEntity = null
+
+// 两点之间线实体
+let twoLineEntity = null
+let myAppEntity = null;
+export function droneFly () {
+  const store = useMyStore()
+  let deviceInfo = {} // 无人机信息
+  let dockInfo = {} // 机场信息
+  let previousPositions = []
+  let wId = ''
+  let snCode = []
+  let viewDroneInfo = {} // 获取实时经纬度
+  let waylinePoints = [] // 当前航线点
+  let currentTaskCreateTime = null // 当前飞行任务创建时间
+  let switchSaving = true // 有selectedWorkSpaceId 就为true
+  // 航线飞行处于第几个点位
+  let currentWaypointIndex = 0
+  // 速度集合
+  let droneSpeedArr = []
+  let lastTime = null
+  let viewInfoFrustum = null
+
+  // 手机设备定位
+  let me_latitude = 0;
+  let me_longitude = 0;
+  let me_altitude = 0;
+  // 扫射定位
+  let measure_target_longitude = 0;
+  let measure_target_latitude = 0;
+  let measure_target_altitude = 0;
+
+
+  async function initDock(data:any, sn:any, dockSn:any, workspaceId:any, ssLinePath:any, viewDroneInfo:any) {
+    // 获取workspaceId
+    wId = workspaceId
+    // 给无人机参数赋值
+    deviceInfo = data.deviceInfo[`${sn}`]
+    // 机场信息
+    dockInfo = data.dockInfo[`${dockSn}`]
+    viewDroneInfo = viewDroneInfo
+    console.log('导致地图不显示原因1',viewDroneInfo.longitude)
+    // 当前飞行任务创建时间
+    if (data.currentType === EDeviceTypeName.Aircraft && deviceInfo) {
+      const droneLngLat = {
+        latitude: deviceInfo.latitude || 0,
+        longitude: deviceInfo.longitude || 0,
+      }
+      // 当飞机模型存在
+      if (droneEntity) {
+        //  且在空中飞行时,实时更新飞机模型的位置
+        if (deviceInfo.mode_code && [3, 4, 5, 9, 10, 16].includes(deviceInfo.mode_code)) {
+          if (store.currentAngle == 3) {
+            viewInfoFrustum?.clear()
+          } else {
+            initCreateFrustum(deviceInfo, viewDroneInfo)
+          }
+          addFlyGltf(
+            viewDroneInfo.longitude,
+            viewDroneInfo.latitude,
+            deviceInfo.height,
+            deviceInfo.payloads[0],
+            deviceInfo.attitude_head,
+            deviceInfo,
+            dockInfo,
+            ssLinePath
+          )
+          let domain = sessionStorage.getItem('domain')
+          if (domain !== '0') {
+            addFlyLaser(
+              deviceInfo.payloads[0]
+            )
+          }
+          setelCamera(
+            viewDroneInfo.longitude,
+            viewDroneInfo.latitude,
+            deviceInfo.height,
+            deviceInfo.payloads[0],
+            deviceInfo.attitude_head,
+          )
+        } else {
+          removeById('drone_fly')
+          droneEntity = null
+  
+          lastTime = null
+          viewInfoFrustum?.clear()
+          viewInfoFrustum = null
+  
+          window.cesiumViewer.camera.lookAtTransform(globalCesium.Matrix4.IDENTITY)
+          store.commit('SET_CURRENTANGLE', 1)
+        }
+      } else {
+        if (deviceInfo.mode_code && [3, 4, 5, 9, 10].includes(deviceInfo.mode_code)) {
+          initCreateFrustum(deviceInfo, viewDroneInfo)
+          addFlyGltf(
+            viewDroneInfo.longitude,
+            viewDroneInfo.latitude,
+            deviceInfo.height,
+            deviceInfo.payloads[0],
+            deviceInfo.attitude_head,
+            deviceInfo,
+            dockInfo,
+            ssLinePath
+          )
+          let domain = sessionStorage.getItem('domain')
+          if (domain !== '0') {
+            addFlyLaser(
+              deviceInfo.payloads[0]
+            )
+          }
+        }
+      }
+      const imgRightBlue = new URL('@/assets/images/arrow-right-pink.png', import.meta.url).href
+       // 无人机路线轨迹,判断是否存在drone_route_remove
+      if (getEntityById('drone_route_remove')) {
+        window.cesiumViewer.entities.add({
+          name: 'drone_route_remove',
+          id: 'drone_route_remove',
+          polyline: {
+            width: 7,
+            positions: previousPositions,
+            material: new ImageTrailMaterial({
+              color: globalCesium.Color.ORANGE,
+              speed: 10,
+              image: imgRightBlue,
+              repeat: { x: 1, y: 0 },
+            }),
+            clampToGround: false,
+          },
+        })
+      }
+      
+      if (data.deviceInfo[data.currentSn].mode_code && [3, 4, 5, 9, 10].includes(deviceInfo.mode_code)) {
+        if (switchSaving) return (switchSaving = false)
+          // console.log('5555', data.deviceInfo[data.currentSn].longitude)
+        const newPositions = globalCesium.Cartesian3.fromDegrees(
+          data.deviceInfo[data.currentSn].longitude,
+          data.deviceInfo[data.currentSn].latitude,
+          Math.floor(viewDroneInfo.elevation),
+        )
+        //若刷新,恢复无人机之前的路线轨迹
+        const dataIndexedDB = await IndexedDBService.getDataById(wId)
+        if (previousPositions.length == 0 && dataIndexedDB) {
+          previousPositions = previousPositions.concat(dataIndexedDB?.temporaryflightData)
+        } else {
+          previousPositions = previousPositions.concat(newPositions)
+        }
+        // 保存无人机当前执行的路线,防止刷新数据丢失
+        if (!dataIndexedDB) {
+          await IndexedDBService.addData({
+            id: wId,
+            temporaryflightData: previousPositions,
+          })
+        } else {
+          await IndexedDBService.updateData(wId, {temporaryflightData: previousPositions})
+        }
+        //  更新线段的位置
+        const drone_route_remove = getEntityById('drone_route_remove')
+        if (!drone_route_remove) return
+        drone_route_remove.polyline.positions = previousPositions
+        drone_route_remove.polyline._material._repeat._value.x = Math.floor(previousPositions.length / 7)
+      } else if ([0, 14].includes(deviceInfo.mode_code)) {
+        previousPositions = []
+        await IndexedDBService.deleteData(wId)
+        const drone_route_remove = getEntityById('drone_route_remove')
+        if (!drone_route_remove) return
+        drone_route_remove.polyline.positions = previousPositions
+        removeById('drone_route_remove')
+        viewInfoFrustum?.clear()
+        viewInfoFrustum = null
+      }
+    }
+    if (data.currentType === EDeviceTypeName.Dock && data.dockInfo[data.currentSn]) {
+      if (!deviceInfo?.basic_osd?.longitude || !deviceInfo?.basic_osd?.latitude) return
+      console.log('6666', deviceInfo?.basic_osd?.longitude)
+      if (snCode.includes(data.currentSn)) return
+      snCode.push(data.currentSn)
+    }
+  }
+
+  const imgLaser = new URL('@/assets/images/laser.png', import.meta.url).href
+  // 增加激光扫射点
+  function addFlyLaser(payloads:any) {
+    const startPosition = globalCesium.Cartesian3.fromDegrees(
+      me_longitude, me_latitude, 0
+    )
+    const position = globalCesium.Cartesian3.fromDegrees(
+      payloads.measure_target_longitude, payloads.measure_target_latitude, payloads.measure_target_altitude
+    )
+    measure_target_longitude = payloads.measure_target_longitude;
+    measure_target_latitude = payloads.measure_target_latitude;
+    measure_target_altitude = payloads.measure_target_altitude;
+
+    if (laserEntity && laserEntity != null) {
+      laserEntity.position = new globalCesium.CallbackProperty(function () {
+        return position
+      }, false)
+      // laserEntity.orientation = new globalCesium.CallbackProperty(function () {
+      //   return orientation
+      // }, false)
+  
+      laserEntity.show = true
+  
+      window.cesiumViewer.scene.requestRender()
+    } else {
+      laserEntity = window.cesiumViewer.entities.add({
+        position,
+        id: 'laser_coordinate',
+        billboard: {
+          image: imgLaser,
+          outlineWidth: 0,
+          width: 36,
+          height: 36,
+          scale: 1.0,
+        }
+      })
+    }
+    removeById('route_two_line')
+    twoLineEntity = window.cesiumViewer.entities.add({
+      id: 'route_two_line',
+      polyline: {
+        positions: new globalCesium.CallbackProperty(() => [startPosition, position], false),
+        width: 5,
+        material: new globalCesium.PolylineDashMaterialProperty({
+            color: globalCesium.Color.YELLOW, // 虚线颜色
+            dashLength: 6.0, // 虚线段的长度
+        }),
+        zIndex: 1,
+        clampToGround: false,
+      }
+    })
+    // 增加激光扫射信息
+    laserEntity.label = new globalCesium.LabelGraphics({
+      text: `目标海拔:${Math.ceil(payloads.measure_target_altitude)}m\n测距距离:${Math.round(
+        Math.ceil(payloads.measure_target_distance),
+      )}m`,
+      font: '13px monospace',
+      showBackground: true,
+      horizontalOrigin: globalCesium.HorizontalOrigin.CENTER,
+      verticalOrigin: globalCesium.VerticalOrigin.BOTTOM,
+      disableDepthTestDistance: Number.POSITIVE_INFINITY,
+      pixelOffset: new globalCesium.Cartesian2(0, -40),
+      show: true,
+    })
+  }
+
+  function addFlyGltf (lng:any, lat:any, alt:any, payloads:any, attitude_head:any, deviceInfo:any, dockInfo:any, ssLinePath:any) {
+    const { gimbal_pitch, gimbal_yaw } = payloads
+    const position = globalCesium.Cartesian3.fromDegrees(
+      lng, lat, alt
+    )
+    
+    const heading = globalCesium.Math.toRadians(Number(attitude_head)) //135度转弧度
+    const pitch = globalCesium.Math.toRadians(0)
+    const roll = 0
+    const hpr = new globalCesium.HeadingPitchRoll(heading, pitch, roll)
+    const orientation = globalCesium.Transforms.headingPitchRollQuaternion(
+      position,
+      hpr,
+    )
+  
+    if (droneEntity && droneEntity != null) {
+      droneEntity.position = new globalCesium.CallbackProperty(function () {
+        return position
+      }, false)
+  
+      droneEntity.orientation = new globalCesium.CallbackProperty(function () {
+        return orientation
+      }, false)
+  
+      droneEntity.show = true
+  
+      window.cesiumViewer.scene.requestRender()
+    } else {
+      droneEntity = window.cesiumViewer.entities.add({
+        show: true,
+        position,
+        id: 'drone_fly',
+        orientation: orientation,
+        model: {
+          uri: '/pilot-h5/gltf/dajiang-processed.gltf', //注意entitits.add方式加载gltf文件时,这里是uri,不是url,并且这种方式只能加载.glb格式的文件
+          scale: 1, //缩放比例
+          minimumPixelSize: 64, //最小像素大小,可以避免太小看不见
+          maximumScale: 128, //模型的最大比例尺大小。minimumPixelSize的上限
+          incrementallyLoadTextures: true, //加载模型后纹理是否可以继续流入
+          runAnimations: true, //是否启动模型中制定的gltf动画
+          clampAnimations: true, //制定gltf动画是否在没有关键帧的持续时间内保持最后一个姿势
+          shadows: globalCesium.ShadowMode.ENABLED,
+          heightReference: globalCesium.HeightReference.NONE,
+        },
+      })
+    }
+  
+    // 创建无人机信息
+    createDroneEntityLabel(droneEntity, deviceInfo, dockInfo, ssLinePath)
+  }
+  // 创建无人机信息
+  async function createDroneEntityLabel (entity:any, deviceInfo:any, dockInfo:any, ssLinePath:any) {
+    deviceInfo = deviceInfo
+    if (currentTaskCreateTime === null) return
+    if (!deviceInfo?.longitude && !deviceInfo?.latitude) return
+    if (deviceInfo.mode_code !== 5) {
+      currentTaskCreateTime = null
+      return
+    }
+    const executingWayline = store.executingWayline
+    if (!executingWayline?.id) return
+    if (waylinePoints.length === 0) {
+      // 改成获取航线地址
+      // const routeRes = await getRoutePlanningUrl(
+      //   wId,
+      //   executingWayline.id,
+      // )
+      // const routeData = routeRes.data
+      // if (routeData.code !== 0) return this.$message.error('获取航线信息失败!')
+      waylinePoints = await getWaylineFilePoints(ssLinePath)
+    }
+
+    const nextPoint = waylinePoints[currentWaypointIndex]
+    if (!nextPoint) return
+    // 两点之间的距离
+    console.log('8888', deviceInfo.longitude)
+    const devicePosition = globalCesium.Cartesian3.fromDegrees(
+      Number(deviceInfo.longitude),
+      Number(deviceInfo.latitude),
+      0,
+    )
+    console.log('9999', nextPoint.longitude)
+    const targetPosition = globalCesium.Cartesian3.fromDegrees(
+      Number(nextPoint.longitude),
+      Number(nextPoint.latitude),
+      0,
+    )
+    //   距离下个点位的距离
+    let distance = globalCesium.Cartesian3.distance(
+      devicePosition,
+      targetPosition,
+    )
+    const dockPosition = {
+      longitude: dockInfo?.basic_osd?.longitude,
+      latitude: dockInfo?.basic_osd?.latitude,
+    }
+
+    const distArr = waylinePoints.map((lnglat, index) => {
+      const { longitude, latitude } = lnglat
+      console.log('10000', longitude)
+      // 两点之间的距离
+      let devicePosition = null
+      if (index === 0) {
+        devicePosition = globalCesium.Cartesian3.fromDegrees(
+          Number(dockPosition.longitude),
+          Number(dockPosition.latitude),
+          0,
+        )
+      } else {
+        console.log('110', prevPoint.longitude)
+        const prevPoint = waylinePoints[index - 1]
+        devicePosition = globalCesium.Cartesian3.fromDegrees(
+          Number(prevPoint.longitude),
+          Number(prevPoint.latitude),
+          0,
+        )
+      }
+      const targetPosition = globalCesium.Cartesian3.fromDegrees(
+        Number(longitude),
+        Number(latitude),
+        0,
+      )
+      let distance = globalCesium.Cartesian3.distance(
+        devicePosition,
+        targetPosition,
+      )
+      return Math.round(distance)
+    })
+    // 计算到达点位和之前点位的总距离
+    let sum = null
+    if (distArr.length > 2) {
+      sum = distArr
+        .slice(0, currentWaypointIndex)
+        .reduce((accumulator, currentValue) => accumulator + currentValue, 0)
+    } else {
+      sum = distArr.reduce(
+        (accumulator, currentValue) => accumulator + currentValue,
+        0,
+      )
+    }
+
+    if (sum == 0) {
+      sum = distArr[0]
+    }
+
+    // 距离机场的位置
+    const homeDistance = Math.floor(deviceInfo.home_distance) || 0
+    // 速度
+    let horizontalSpeed = deviceInfo.horizontal_speed || 0
+    if (!droneSpeedArr.includes(horizontalSpeed) && horizontalSpeed > 1) {
+      droneSpeedArr.push(horizontalSpeed)
+    }
+    //  平均速度
+    const averageSpeed =
+      droneSpeedArr.reduce((sum, current) => sum + current, 0) /
+      droneSpeedArr.length
+    // 已用时间
+    let usedTime = Math.round((new Date().getTime() - currentTaskCreateTime) / 1000) - 30
+    let throughDistance = usedTime * averageSpeed
+
+    if (throughDistance < 0) {
+      throughDistance = 0
+      usedTime = 0
+    }
+    if (isNaN(throughDistance)) {
+      throughDistance = 0
+    }
+    if (isNaN(usedTime)) {
+      usedTime = 0
+    }
+    if (usedTime > 60) {
+      const minute = Math.floor(usedTime / 60)
+      const second = Math.round(usedTime % 60)
+      usedTime = `${minute}m${second}s`
+    } else {
+      usedTime = Math.round(usedTime) + 's'
+    }
+
+    if (horizontalSpeed < 5) {
+      horizontalSpeed = 10
+    }
+    // 预计到达下一个航点时间
+    let arrivalTime = distance / horizontalSpeed
+    if (arrivalTime === Infinity || isNaN(arrivalTime)) {
+      arrivalTime = 0
+    }
+    if (arrivalTime > 60) {
+      const minute = Math.floor(arrivalTime / 60)
+      const second = Math.round(arrivalTime % 60)
+      arrivalTime = `${minute}m${second}s`
+    } else {
+      arrivalTime = Math.round(arrivalTime) + 's'
+    }
+    entity.label = new globalCesium.LabelGraphics({
+      text: `距离机场水平距离:${homeDistance}m\n距离下一个航点:${Math.round(
+        distance,
+      )}m\n预计到达下一航点时间:${arrivalTime}\n本次飞行时间:${usedTime}\n本次航线平面里程:${Math.round(
+        throughDistance,
+      )}m`,
+      font: '13px monospace',
+      showBackground: true,
+      horizontalOrigin: globalCesium.HorizontalOrigin.CENTER,
+      verticalOrigin: globalCesium.VerticalOrigin.BOTTOM,
+      disableDepthTestDistance: Number.POSITIVE_INFINITY,
+      pixelOffset: new globalCesium.Cartesian2(0, -40),
+      show: true,
+    })
+  }
+  async function getWaylineFilePoints(fileUrl:any) {
+    const fileRes = await analyzeKmzFile(fileUrl);
+    const waylineContent = await fileRes['fileInfoObj']?.['wpmz/waylines.wpml'];
+    const xml = XMLToJSON(waylineContent);
+    const placemarkArr = xml?.Document?.Folder.Placemark;
+    const points = placemarkArr.map((placemark) => {
+      const lnglat = placemark.Point.coordinates?.['#text'].split(',');
+      return {
+        longitude: lnglat[0],
+        latitude: lnglat[1],
+      };
+    });
+    return points;
+  }
+
+  function setelCamera (lng, lat, alt, payloads, attitude_head) {
+    const { gimbal_pitch, gimbal_yaw } = payloads
+    let time = 0
+  
+    let current = store.currentAngle
+    var heading = globalCesium.Math.toRadians(Number(gimbal_yaw || attitude_head)) // 相机左右方向
+  
+    if (current == 1) {
+      lastTime = null
+      droneEntity.show = true
+      window.cesiumViewer.camera.lookAtTransform(globalCesium.Matrix4.IDENTITY)
+    } else if (current == 2) {
+      lastTime = null
+      droneEntity.show = true
+      window.cesiumViewer.camera.lookAtTransform(globalCesium.Matrix4.IDENTITY)
+  
+      let center = globalCesium.Cartesian3.fromDegrees(lng, lat)
+  
+      window.cesiumViewer.camera.lookAt(center, new globalCesium.Cartesian3(0.0, 0, 1500))
+    } else if (current == 3) {
+      droneEntity.show = false
+  
+      let curTime = Date.now()
+      if (lastTime && lastTime != null) {
+        time = (curTime - lastTime) / 1000
+      }
+  
+      window.cesiumViewer.camera.lookAtTransform(globalCesium.Matrix4.IDENTITY)
+      let center = globalCesium.Cartesian3.fromDegrees(lng, lat, alt)
+      var pitch = globalCesium.Math.toRadians(pitchAngle({ gimbal_pitch })) // 相机上下方向,负值表示向下看
+  
+      window.cesiumViewer.camera.flyTo({
+        destination: center,
+        orientation: {
+          heading,
+          pitch,
+          roll: 0
+        },
+        duration: time,
+        complete () {
+          window.cesiumViewer.camera.lookAt(center, new globalCesium.HeadingPitchRange(
+            heading,
+            pitch,
+            0.01
+          ))
+        }
+      })
+  
+      lastTime = Date.now()
+    }
+  }
+  // pitch 
+  function pitchAngle (options) {
+    const gimbal_pitch = Number(options?.gimbal_pitch) || 0
+    return gimbal_pitch
+  }
+  // 创建视锥
+  function initCreateFrustum (deviceInfo:any, test:any) {
+    
+    if (!deviceInfo || !deviceInfo.longitude || !deviceInfo.latitude) return
+    
+    const attitude_head = 180 + deviceInfo.attitude_head
+
+    const gimbal_pitch = 90 - pitchAngle({ gimbal_pitch: deviceInfo.payloads[0].gimbal_pitch })
+    
+    viewInfoFrustum?.clear()
+    viewInfoFrustum = new CreateFrustum(window.cesiumViewer, {
+      position: {
+        longitude: test.longitude,
+        latitude: test.latitude,
+        altitude: deviceInfo.height,
+      },
+      width: 30,
+      height: 30,
+      fov: 20.0,
+      near: 3.0,
+      far: 250.0,
+      roll: gimbal_pitch,
+      pitch: 0,
+      heading: attitude_head,
+    })
+  }
+
+  // 获取手机定位和激光发射定位的高度和距离
+  function getTwoHeightWidth(workspaceId:String) {
+    // 国内地图不会为0或者小于0
+    console.log('自身定位经纬度1', me_latitude)
+    console.log('自身定位经纬度2', me_longitude)
+    console.log('激光扫过定位1', measure_target_latitude)
+    console.log('激光扫过定位2', measure_target_longitude)
+    if (me_latitude <= 0 || me_longitude <= 0 || measure_target_latitude <= 0 || measure_target_longitude <= 0) return
+    getTwoPointInfo(workspaceId,me_latitude,me_longitude,measure_target_latitude,measure_target_longitude).then((res:any) => {
+      const heightDifference = res.data.heightDifference
+      const distance = res.data.distance
+      // 增加激光扫射信息
+      myAppEntity.label = new globalCesium.LabelGraphics({
+        text: `高度:${Math.ceil(heightDifference)}m\n距离:${Math.round(
+          Math.ceil(distance),
+        )}m`,
+        font: '13px monospace',
+        showBackground: true,
+        horizontalOrigin: globalCesium.HorizontalOrigin.CENTER,
+        verticalOrigin: globalCesium.VerticalOrigin.BOTTOM,
+        disableDepthTestDistance: Number.POSITIVE_INFINITY,
+        pixelOffset: new globalCesium.Cartesian2(0, -40),
+        show: true,
+      })
+    })
+  }
+
+  const meMapSrc = new URL('@/assets/images/me.png', import.meta.url).href
+  // 获取手机设备定位
+  function getPhoneLocation(value:Boolean, workspaceId:String) {
+    if (window.cesiumViewer == null) return
+    // 创建一个箭头实体
+    removeById('me_dw')
+    myAppEntity = window.cesiumViewer.entities.add({
+      id: 'me_dw',
+      position: globalCesium.Cartesian3.fromDegrees(0, 0, 0), // 初始位置
+      billboard: {
+        image: meMapSrc, // 箭头图片路径
+        width: 30,
+        height: 30,
+        alignedAxis: globalCesium.Cartesian3.UNIT_Z, // 对齐轴
+      },
+      // orientation: new globalCesium.CallbackProperty(() => {
+      //   return globalCesium.Transforms.headingPitchRollQuaternion(
+      //     myAppEntity.position.getValue(window.cesiumViewer.clock.currentTime),
+      //     new globalCesium.HeadingPitchRoll(heading, 0, 0) // 设置朝向
+      //   );
+      // }, false),
+    });
+
+    let heading = 0; // 初始朝向
+    // 获取设备朝向
+    // if (window.DeviceOrientationEvent) {
+    //   window.addEventListener('deviceorientation', (event) => {
+    //     if (event.alpha !== null) {
+    //       heading = globalCesium.Math.toRadians(event.alpha); // 将 alpha 转换为弧度
+    //     }
+    //   });
+    // } else {
+    //   console.log('手机不支持.');
+    // }
+
+    // 获取设备位置
+    if (navigator.geolocation) {
+      navigator.geolocation.watchPosition((position) => {
+        me_longitude = position.coords.longitude;
+        me_latitude = position.coords.latitude;
+        me_altitude = position.coords.altitude || 0;
+
+        // 更新箭头实体的位置
+        myAppEntity.position = globalCesium.Cartesian3.fromDegrees(me_longitude, me_latitude, me_altitude);
+        if (value) {
+          // 将相机定位到设备位置 只有点击图标才可以执行这里
+          window.cesiumViewer.camera.setView({
+            destination: globalCesium.Cartesian3.fromDegrees(me_longitude, me_latitude, me_altitude + 1000), // 相机高度
+            // orientation: {
+            //   heading: heading, // 相机朝向
+            //   pitch: globalCesium.Math.toRadians(-90), // 俯视角度
+            //   roll: 0,
+            // },
+          });
+        }
+        // 查看两条线直接距离和高度
+        getTwoHeightWidth(workspaceId)
+      }, (error) => {
+        console.error('定位有误:', error);
+      });
+    } else {
+      console.log('手机不支持.');
+    }
+  }
+
+
+  return {
+    initDock,
+    getPhoneLocation,
+  }
+}
\ No newline at end of file
diff --git a/src/views/hooks/droneFly.ts b/src/views/hooks/droneFly.ts
index 6fa5560..a42f788 100644
--- a/src/views/hooks/droneFly.ts
+++ b/src/views/hooks/droneFly.ts
@@ -36,16 +36,17 @@
   let viewInfoFrustum = null
 
   // 手机设备定位
-  let me_latitude = 0;
-  let me_longitude = 0;
+  let me_latitude = 0;// 28.624647955787974;
+  let me_longitude = 0;//115.85635808986208;
   let me_altitude = 0;
   // 扫射定位
-  let measure_target_longitude = 0;
-  let measure_target_latitude = 0;
+  let measure_target_longitude = 0;//115.85635872364763;
+  let measure_target_latitude = 0;//28.624648387113627;
   let measure_target_altitude = 0;
 
 
   async function initDock(data:any, sn:any, dockSn:any, workspaceId:any, ssLinePath:any, viewDroneInfo:any) {
+    // console.log('globalCesium查看是', globalCesium)
     // 获取workspaceId
     wId = workspaceId
     // 给无人机参数赋值
@@ -53,7 +54,6 @@
     // 机场信息
     dockInfo = data.dockInfo[`${dockSn}`]
     viewDroneInfo = viewDroneInfo
-    console.log('导致地图不显示原因1',viewDroneInfo.longitude)
     // 当前飞行任务创建时间
     if (data.currentType === EDeviceTypeName.Aircraft && deviceInfo) {
       const droneLngLat = {
@@ -67,6 +67,7 @@
           if (store.currentAngle == 3) {
             viewInfoFrustum?.clear()
           } else {
+            // 暂时把视锥代码注释掉
             initCreateFrustum(deviceInfo, viewDroneInfo)
           }
           addFlyGltf(
@@ -105,6 +106,7 @@
         }
       } else {
         if (deviceInfo.mode_code && [3, 4, 5, 9, 10].includes(deviceInfo.mode_code)) {
+          // 暂时把视锥代码注释掉
           initCreateFrustum(deviceInfo, viewDroneInfo)
           addFlyGltf(
             viewDroneInfo.longitude,
@@ -125,68 +127,68 @@
         }
       }
       const imgRightBlue = new URL('@/assets/images/arrow-right-pink.png', import.meta.url).href
-       // 无人机路线轨迹,判断是否存在drone_route_remove
-      if (getEntityById('drone_route_remove')) {
-        window.cesiumViewer.entities.add({
-          name: 'drone_route_remove',
-          id: 'drone_route_remove',
-          polyline: {
-            width: 7,
-            positions: previousPositions,
-            material: new ImageTrailMaterial({
-              color: globalCesium.Color.ORANGE,
-              speed: 10,
-              image: imgRightBlue,
-              repeat: { x: 1, y: 0 },
-            }),
-            clampToGround: false,
-          },
-        })
-      }
+      // 暂时把航线屏蔽
+      // 无人机路线轨迹,判断是否存在drone_route_remove
+      // if (getEntityById('drone_route_remove')) {
+      //   window.cesiumViewer.entities.add({
+      //     name: 'drone_route_remove',
+      //     id: 'drone_route_remove',
+      //     polyline: {
+      //       width: 7,
+      //       positions: previousPositions,
+      //       material: new ImageTrailMaterial({
+      //         color: globalCesium.Color.ORANGE,
+      //         speed: 10,
+      //         image: imgRightBlue,
+      //         repeat: { x: 1, y: 0 },
+      //       }),
+      //       clampToGround: false,
+      //     },
+      //   })
+      // }
       
-      if (data.deviceInfo[data.currentSn].mode_code && [3, 4, 5, 9, 10].includes(deviceInfo.mode_code)) {
-        if (switchSaving) return (switchSaving = false)
-          // console.log('5555', data.deviceInfo[data.currentSn].longitude)
-        const newPositions = globalCesium.Cartesian3.fromDegrees(
-          data.deviceInfo[data.currentSn].longitude,
-          data.deviceInfo[data.currentSn].latitude,
-          Math.floor(viewDroneInfo.elevation),
-        )
-        //若刷新,恢复无人机之前的路线轨迹
-        const dataIndexedDB = await IndexedDBService.getDataById(wId)
-        if (previousPositions.length == 0 && dataIndexedDB) {
-          previousPositions = previousPositions.concat(dataIndexedDB?.temporaryflightData)
-        } else {
-          previousPositions = previousPositions.concat(newPositions)
-        }
-        // 保存无人机当前执行的路线,防止刷新数据丢失
-        if (!dataIndexedDB) {
-          await IndexedDBService.addData({
-            id: wId,
-            temporaryflightData: previousPositions,
-          })
-        } else {
-          await IndexedDBService.updateData(wId, {temporaryflightData: previousPositions})
-        }
-        //  更新线段的位置
-        const drone_route_remove = getEntityById('drone_route_remove')
-        if (!drone_route_remove) return
-        drone_route_remove.polyline.positions = previousPositions
-        drone_route_remove.polyline._material._repeat._value.x = Math.floor(previousPositions.length / 7)
-      } else if ([0, 14].includes(deviceInfo.mode_code)) {
-        previousPositions = []
-        await IndexedDBService.deleteData(wId)
-        const drone_route_remove = getEntityById('drone_route_remove')
-        if (!drone_route_remove) return
-        drone_route_remove.polyline.positions = previousPositions
-        removeById('drone_route_remove')
-        viewInfoFrustum?.clear()
-        viewInfoFrustum = null
-      }
+      // if (data.deviceInfo[data.currentSn].mode_code && [3, 4, 5, 9, 10].includes(deviceInfo.mode_code)) {
+      //   if (switchSaving) return (switchSaving = false)
+      //     // console.log('5555', data.deviceInfo[data.currentSn].longitude)
+      //   const newPositions = globalCesium.Cartesian3.fromDegrees(
+      //     data.deviceInfo[data.currentSn].longitude,
+      //     data.deviceInfo[data.currentSn].latitude,
+      //     Math.floor(viewDroneInfo.elevation),
+      //   )
+      //   //若刷新,恢复无人机之前的路线轨迹
+      //   const dataIndexedDB = await IndexedDBService.getDataById(wId)
+      //   if (previousPositions.length == 0 && dataIndexedDB) {
+      //     previousPositions = previousPositions.concat(dataIndexedDB?.temporaryflightData)
+      //   } else {
+      //     previousPositions = previousPositions.concat(newPositions)
+      //   }
+      //   // 保存无人机当前执行的路线,防止刷新数据丢失
+      //   if (!dataIndexedDB) {
+      //     await IndexedDBService.addData({
+      //       id: wId,
+      //       temporaryflightData: previousPositions,
+      //     })
+      //   } else {
+      //     await IndexedDBService.updateData(wId, {temporaryflightData: previousPositions})
+      //   }
+      //   //  更新线段的位置
+      //   const drone_route_remove = getEntityById('drone_route_remove')
+      //   if (!drone_route_remove) return
+      //   drone_route_remove.polyline.positions = previousPositions
+      //   drone_route_remove.polyline._material._repeat._value.x = Math.floor(previousPositions.length / 7)
+      // } else if ([0, 14].includes(deviceInfo.mode_code)) {
+      //   previousPositions = []
+      //   await IndexedDBService.deleteData(wId)
+      //   const drone_route_remove = getEntityById('drone_route_remove')
+      //   if (!drone_route_remove) return
+      //   drone_route_remove.polyline.positions = previousPositions
+      //   removeById('drone_route_remove')
+      //   viewInfoFrustum?.clear()
+      //   viewInfoFrustum = null
+      // }
     }
     if (data.currentType === EDeviceTypeName.Dock && data.dockInfo[data.currentSn]) {
       if (!deviceInfo?.basic_osd?.longitude || !deviceInfo?.basic_osd?.latitude) return
-      console.log('6666', deviceInfo?.basic_osd?.longitude)
       if (snCode.includes(data.currentSn)) return
       snCode.push(data.currentSn)
     }
@@ -195,6 +197,8 @@
   const imgLaser = new URL('@/assets/images/laser.png', import.meta.url).href
   // 增加激光扫射点
   function addFlyLaser(payloads:any) {
+    console.log('激光扫射经度',payloads.measure_target_longitude)
+    console.log('激光扫射纬度',payloads.measure_target_latitude)
     const startPosition = globalCesium.Cartesian3.fromDegrees(
       me_longitude, me_latitude, 0
     )
@@ -205,57 +209,59 @@
     measure_target_latitude = payloads.measure_target_latitude;
     measure_target_altitude = payloads.measure_target_altitude;
 
-    if (laserEntity && laserEntity != null) {
-      laserEntity.position = new globalCesium.CallbackProperty(function () {
-        return position
-      }, false)
-      // laserEntity.orientation = new globalCesium.CallbackProperty(function () {
-      //   return orientation
-      // }, false)
+    // if (laserEntity && laserEntity != null) {
+    //   laserEntity.position = new globalCesium.CallbackProperty(function () {
+    //     return position
+    //   }, false)
+    //   // laserEntity.orientation = new globalCesium.CallbackProperty(function () {
+    //   //   return orientation
+    //   // }, false)
   
-      laserEntity.show = true
+    //   laserEntity.show = true
   
-      window.cesiumViewer.scene.requestRender()
-    } else {
+    //   window.cesiumViewer.scene.requestRender()
+    // } else {
+      removeById('laser_coordinate')
       laserEntity = window.cesiumViewer.entities.add({
-        position,
+        position: globalCesium.Cartesian3.fromDegrees(payloads.measure_target_longitude, payloads.measure_target_latitude, payloads.measure_target_altitude),
         id: 'laser_coordinate',
         billboard: {
           image: imgLaser,
-          outlineWidth: 0,
-          width: 36,
-          height: 36,
+          width: 30,
+          height: 30,
           scale: 1.0,
+          outlineWidth: 0,
         }
       })
-    }
-    removeById('route_two_line')
-    twoLineEntity = window.cesiumViewer.entities.add({
-      id: 'route_two_line',
-      polyline: {
-        positions: new globalCesium.CallbackProperty(() => [startPosition, position], false),
-        width: 5,
-        material: new globalCesium.PolylineDashMaterialProperty({
-            color: globalCesium.Color.YELLOW, // 虚线颜色
-            dashLength: 6.0, // 虚线段的长度
-        }),
-        zIndex: 1,
-        clampToGround: false,
-      }
-    })
+    // }
     // 增加激光扫射信息
     laserEntity.label = new globalCesium.LabelGraphics({
-      text: `目标海拔:${Math.ceil(payloads.measure_target_altitude)}m\n测距距离:${Math.round(
-        Math.ceil(payloads.measure_target_distance),
-      )}m`,
+      text: `H:${Math.ceil(payloads.measure_target_altitude)}m-L:${Math.round(Math.ceil(payloads.measure_target_distance),)}m`,
       font: '13px monospace',
+      fillColor: globalCesium.Color.fromCssColorString('red'), // 文字颜色
+      backgroundColor: globalCesium.Color.WHITE, // 背景颜色
       showBackground: true,
       horizontalOrigin: globalCesium.HorizontalOrigin.CENTER,
       verticalOrigin: globalCesium.VerticalOrigin.BOTTOM,
       disableDepthTestDistance: Number.POSITIVE_INFINITY,
-      pixelOffset: new globalCesium.Cartesian2(0, -40),
+      pixelOffset: new globalCesium.Cartesian2(0, -20),
       show: true,
     })
+    console.log('起点',startPosition)
+    console.log('终点',position)
+    if (startPosition && position) {
+      removeById('route_two_line')
+      twoLineEntity = window.cesiumViewer.entities.add({
+        id: 'route_two_line',
+        polyline: {
+          positions: new globalCesium.CallbackProperty(() => [startPosition, position], false),
+          width: 3,
+          material: globalCesium.Color.RED,
+          zIndex: -1,
+          clampToGround: false,
+        }
+      })
+    }
   }
 
   function addFlyGltf (lng:any, lat:any, alt:any, payloads:any, attitude_head:any, deviceInfo:any, dockInfo:any, ssLinePath:any) {
@@ -306,179 +312,7 @@
     }
   
     // 创建无人机信息
-    createDroneEntityLabel(droneEntity, deviceInfo, dockInfo, ssLinePath)
-  }
-  // 创建无人机信息
-  async function createDroneEntityLabel (entity:any, deviceInfo:any, dockInfo:any, ssLinePath:any) {
-    deviceInfo = deviceInfo
-    if (currentTaskCreateTime === null) return
-    if (!deviceInfo?.longitude && !deviceInfo?.latitude) return
-    if (deviceInfo.mode_code !== 5) {
-      currentTaskCreateTime = null
-      return
-    }
-    const executingWayline = store.executingWayline
-    if (!executingWayline?.id) return
-    if (waylinePoints.length === 0) {
-      // 改成获取航线地址
-      // const routeRes = await getRoutePlanningUrl(
-      //   wId,
-      //   executingWayline.id,
-      // )
-      // const routeData = routeRes.data
-      // if (routeData.code !== 0) return this.$message.error('获取航线信息失败!')
-      waylinePoints = await getWaylineFilePoints(ssLinePath)
-    }
-
-    const nextPoint = waylinePoints[currentWaypointIndex]
-    if (!nextPoint) return
-    // 两点之间的距离
-    console.log('8888', deviceInfo.longitude)
-    const devicePosition = globalCesium.Cartesian3.fromDegrees(
-      Number(deviceInfo.longitude),
-      Number(deviceInfo.latitude),
-      0,
-    )
-    console.log('9999', nextPoint.longitude)
-    const targetPosition = globalCesium.Cartesian3.fromDegrees(
-      Number(nextPoint.longitude),
-      Number(nextPoint.latitude),
-      0,
-    )
-    //   距离下个点位的距离
-    let distance = globalCesium.Cartesian3.distance(
-      devicePosition,
-      targetPosition,
-    )
-    const dockPosition = {
-      longitude: dockInfo?.basic_osd?.longitude,
-      latitude: dockInfo?.basic_osd?.latitude,
-    }
-
-    const distArr = waylinePoints.map((lnglat, index) => {
-      const { longitude, latitude } = lnglat
-      console.log('10000', longitude)
-      // 两点之间的距离
-      let devicePosition = null
-      if (index === 0) {
-        devicePosition = globalCesium.Cartesian3.fromDegrees(
-          Number(dockPosition.longitude),
-          Number(dockPosition.latitude),
-          0,
-        )
-      } else {
-        console.log('110', prevPoint.longitude)
-        const prevPoint = waylinePoints[index - 1]
-        devicePosition = globalCesium.Cartesian3.fromDegrees(
-          Number(prevPoint.longitude),
-          Number(prevPoint.latitude),
-          0,
-        )
-      }
-      const targetPosition = globalCesium.Cartesian3.fromDegrees(
-        Number(longitude),
-        Number(latitude),
-        0,
-      )
-      let distance = globalCesium.Cartesian3.distance(
-        devicePosition,
-        targetPosition,
-      )
-      return Math.round(distance)
-    })
-    // 计算到达点位和之前点位的总距离
-    let sum = null
-    if (distArr.length > 2) {
-      sum = distArr
-        .slice(0, currentWaypointIndex)
-        .reduce((accumulator, currentValue) => accumulator + currentValue, 0)
-    } else {
-      sum = distArr.reduce(
-        (accumulator, currentValue) => accumulator + currentValue,
-        0,
-      )
-    }
-
-    if (sum == 0) {
-      sum = distArr[0]
-    }
-
-    // 距离机场的位置
-    const homeDistance = Math.floor(deviceInfo.home_distance) || 0
-    // 速度
-    let horizontalSpeed = deviceInfo.horizontal_speed || 0
-    if (!droneSpeedArr.includes(horizontalSpeed) && horizontalSpeed > 1) {
-      droneSpeedArr.push(horizontalSpeed)
-    }
-    //  平均速度
-    const averageSpeed =
-      droneSpeedArr.reduce((sum, current) => sum + current, 0) /
-      droneSpeedArr.length
-    // 已用时间
-    let usedTime = Math.round((new Date().getTime() - currentTaskCreateTime) / 1000) - 30
-    let throughDistance = usedTime * averageSpeed
-
-    if (throughDistance < 0) {
-      throughDistance = 0
-      usedTime = 0
-    }
-    if (isNaN(throughDistance)) {
-      throughDistance = 0
-    }
-    if (isNaN(usedTime)) {
-      usedTime = 0
-    }
-    if (usedTime > 60) {
-      const minute = Math.floor(usedTime / 60)
-      const second = Math.round(usedTime % 60)
-      usedTime = `${minute}m${second}s`
-    } else {
-      usedTime = Math.round(usedTime) + 's'
-    }
-
-    if (horizontalSpeed < 5) {
-      horizontalSpeed = 10
-    }
-    // 预计到达下一个航点时间
-    let arrivalTime = distance / horizontalSpeed
-    if (arrivalTime === Infinity || isNaN(arrivalTime)) {
-      arrivalTime = 0
-    }
-    if (arrivalTime > 60) {
-      const minute = Math.floor(arrivalTime / 60)
-      const second = Math.round(arrivalTime % 60)
-      arrivalTime = `${minute}m${second}s`
-    } else {
-      arrivalTime = Math.round(arrivalTime) + 's'
-    }
-    entity.label = new globalCesium.LabelGraphics({
-      text: `距离机场水平距离:${homeDistance}m\n距离下一个航点:${Math.round(
-        distance,
-      )}m\n预计到达下一航点时间:${arrivalTime}\n本次飞行时间:${usedTime}\n本次航线平面里程:${Math.round(
-        throughDistance,
-      )}m`,
-      font: '13px monospace',
-      showBackground: true,
-      horizontalOrigin: globalCesium.HorizontalOrigin.CENTER,
-      verticalOrigin: globalCesium.VerticalOrigin.BOTTOM,
-      disableDepthTestDistance: Number.POSITIVE_INFINITY,
-      pixelOffset: new globalCesium.Cartesian2(0, -40),
-      show: true,
-    })
-  }
-  async function getWaylineFilePoints(fileUrl:any) {
-    const fileRes = await analyzeKmzFile(fileUrl);
-    const waylineContent = await fileRes['fileInfoObj']?.['wpmz/waylines.wpml'];
-    const xml = XMLToJSON(waylineContent);
-    const placemarkArr = xml?.Document?.Folder.Placemark;
-    const points = placemarkArr.map((placemark) => {
-      const lnglat = placemark.Point.coordinates?.['#text'].split(',');
-      return {
-        longitude: lnglat[0],
-        latitude: lnglat[1],
-      };
-    });
-    return points;
+    // createDroneEntityLabel(droneEntity, deviceInfo, dockInfo, ssLinePath)
   }
 
   function setelCamera (lng, lat, alt, payloads, attitude_head) {
@@ -539,8 +373,9 @@
   }
   // 创建视锥
   function initCreateFrustum (deviceInfo:any, test:any) {
-    
-    if (!deviceInfo || !deviceInfo.longitude || !deviceInfo.latitude) return
+    // console.log('视锥传参1',deviceInfo)
+    // console.log('视锥传参2',test)
+    if (!deviceInfo || !deviceInfo.longitude || !deviceInfo.latitude || !test.longitude || !test.latitude) return
     
     const attitude_head = 180 + deviceInfo.attitude_head
 
@@ -566,26 +401,21 @@
 
   // 获取手机定位和激光发射定位的高度和距离
   function getTwoHeightWidth(workspaceId:String) {
-    // 国内地图不会为0或者小于0
-    console.log('自身定位经纬度1', me_latitude)
-    console.log('自身定位经纬度2', me_longitude)
-    console.log('激光扫过定位1', measure_target_latitude)
-    console.log('激光扫过定位2', measure_target_longitude)
     if (me_latitude <= 0 || me_longitude <= 0 || measure_target_latitude <= 0 || measure_target_longitude <= 0) return
     getTwoPointInfo(workspaceId,me_latitude,me_longitude,measure_target_latitude,measure_target_longitude).then((res:any) => {
       const heightDifference = res.data.heightDifference
       const distance = res.data.distance
       // 增加激光扫射信息
       myAppEntity.label = new globalCesium.LabelGraphics({
-        text: `高度:${Math.ceil(heightDifference)}m\n距离:${Math.round(
-          Math.ceil(distance),
-        )}m`,
+        text: `H:${Math.ceil(heightDifference)}m-L:${Math.round(Math.ceil(distance),)}m`,
         font: '13px monospace',
+        fillColor: globalCesium.Color.fromCssColorString('red'), // 文字颜色
+        backgroundColor: globalCesium.Color.WHITE, // 背景颜色
         showBackground: true,
         horizontalOrigin: globalCesium.HorizontalOrigin.CENTER,
         verticalOrigin: globalCesium.VerticalOrigin.BOTTOM,
         disableDepthTestDistance: Number.POSITIVE_INFINITY,
-        pixelOffset: new globalCesium.Cartesian2(0, -40),
+        pixelOffset: new globalCesium.Cartesian2(0, -24),
         show: true,
       })
     })
@@ -597,6 +427,8 @@
     if (window.cesiumViewer == null) return
     if (navigator.geolocation) {
       navigator.geolocation.watchPosition((position) => {
+        console.log(me_longitude,position.coords.longitude)
+        console.log(me_latitude,position.coords.latitude)
         if (me_longitude > 0 && me_longitude == position.coords.longitude && me_latitude > 0 && me_latitude == position.coords.latitude) return 
         me_longitude = position.coords.longitude;
         me_latitude = position.coords.latitude;
@@ -611,6 +443,7 @@
             width: 30,
             height: 30,
             scale: 1.0,
+            outlineWidth: 0,
           }
         });
         // 查看两条线直接距离和高度

--
Gitblit v1.9.3