Jelajahi Sumber

森防 操作功能

Hwf 3 bulan lalu
induk
melakukan
12f62942c2

+ 0 - 9
index.html

@@ -6,16 +6,7 @@
     <meta name="renderer" content="webkit" />
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
 <!--    <link rel="icon" href="/favicon.ico" />-->
-    <link rel="stylesheet" href="/lib/mapbox/css/mapbox-gl.css" />
-    <link rel="stylesheet" href="/lib/mapbox/css/mapbox-gl-draw.css" />
-    <script src="/lib/mapbox/js/mapbox-gl.js"></script>
-    <script src="/lib/mapbox/js/mapbox-gl-draw.js"></script>
-    <script src="/lib/GeoGlobeSDK/GeoGlobeJS.min.js"></script>
-    <script src="/lib/GeoGlobeSDK/GeoGlobeJS.visuals.min.js"></script>
-    <script src="/lib/GeoGlobeSDK/GeoGlobeJS.extends.min.js"></script>
-    <script src="/lib/GeoGlobeSDK/GeoLevel.js"></script>
     <script src="/h5player.min.js"></script>
-    <script src="/Decoder.js"></script>
     <script src="/ol-plot.js"></script>
 
     <title>茂名智慧应急一张图</title>

+ 19 - 0
src/api/globalMap/forestDefenseVideo.ts

@@ -1,5 +1,6 @@
 import request from '@/utils/request';
 
+// 获取视频通道PTZ信息
 export const getPtzInfo = (params) => {
   return request({
     url: '/api/videoResource/hkvideo/get_ptz_info',
@@ -7,3 +8,21 @@ export const getPtzInfo = (params) => {
     params: params
   });
 };
+
+// 根据设备编号获取编码设备详细信息
+export const getDeviceByIndexCode = (params) => {
+  return request({
+    url: '/api/videoResource/hkvideo/getDeviceByIndexCode',
+    method: 'get',
+    params: params
+  });
+};
+
+// 根据设备编号获取编码设备详细信息
+export const setHkVideoControlling = (data: VideoControlParams) => {
+  return request({
+    url: '/api/videoResource/hkvideo/controlling',
+    method: 'post',
+    data: data
+  });
+};

+ 1 - 3
src/components/HKVideo/index.vue

@@ -39,9 +39,7 @@ const play = () => {
 
 const refresh_data = () => {
   console.log('refresh_data');
-  // get_video_item(props.dot_data.code).then((res) => {
-  //   props.dot_data.favor = res.favor;
-  // });
+  play_now();
 };
 
 const emits = defineEmits(['propClick', 'videoPreviewClick', 'favorClick']);

+ 1 - 0
src/types/components.d.ts

@@ -81,6 +81,7 @@ declare module 'vue' {
     ImagePreview: typeof import('./../components/ImagePreview/index.vue')['default']
     ImageUpload: typeof import('./../components/ImageUpload/index.vue')['default']
     Index2: typeof import('./../components/Dialog/index2.vue')['default']
+    InfoDialog: typeof import('./../components/InfoDialog/index.vue')['default']
     LangSelect: typeof import('./../components/LangSelect/index.vue')['default']
     LineWidthSelect: typeof import('./../components/LineWidthSelect/index.vue')['default']
     Map: typeof import('./../components/Map/index.vue')['default']

+ 19 - 0
src/types/globalMap.d.ts

@@ -0,0 +1,19 @@
+interface VideoControlParams {
+  // 监控点编号
+  cameraIndexCode: string;
+  // 开始或停止操作(0 开始  1 停止)
+  action: string;
+  // 控制命令(不区分大小写)
+  // 说明:
+  // 左转LEFT 右转RIGHT 上转UP 下转DOWN
+  // 焦距变大ZOOM_IN 焦距变小ZOOM_OUT
+  // 左上LEFT_UP 左下LEFT_DOWN 右上RIGHT_UP 右下RIGHT_DOWN
+  // 焦点前移FOCUS_NEAR 焦点后移FOCUS_FAR
+  // 光圈扩大IRIS_ENLARGE 光圈缩小IRIS_REDUCE
+  // 以下命令presetIndex不可为空:到预置点GOTO_PRESET
+  command: string;
+  // 云台速度(取值范围1-100,默认40)
+  speed?: number;
+  // 预置点编号(取值范围为1-128)
+  presetIndex?: number;
+}

+ 1 - 5
src/utils/notification.ts

@@ -59,13 +59,9 @@ const createNotificationElement = (type: string, msg: string) => {
 
 // 移除提示元素
 const removeNotificationElement = (duration: number) => {
-  if (!!timerId) {
-    toastElement.remove();
-    toastElement = null;
-  }
   timerId = setTimeout(
     () => {
-      toastElement.remove();
+      toastElement?.remove();
       toastElement = null;
     },
     duration ? duration : commonDuration

+ 126 - 30
src/views/globalMap/RightMenu/ForestDefenseVideo/DetailDialog.vue

@@ -28,7 +28,7 @@
         </div>
       </div>
       <div class="video-box">
-        <HKVideo ref="videoRef" :dot_data="detailData" autoplay style="height: 100%" />
+        <HKVideo ref="videoRef" :dot_data="data" autoplay style="height: 100%" />
       </div>
       <div class="control-container">
         <div class="common-title-box">操作台</div>
@@ -43,14 +43,14 @@
           </div>
           <div class="control-box2">
             <div class="control">
-              <div class="up-btn" />
-              <div class="up-left-btn" />
-              <div class="up-right-btn" />
-              <div class="down-btn" />
-              <div class="down-left-btn" />
-              <div class="down-right-btn" />
-              <div class="left-btn" @click="handleControl('left')" />
-              <div class="right-btn" @click="handleControl('right')" />
+              <div class="up-btn" @click="handleControl('UP')" />
+              <div class="up-left-btn" @click="handleControl('LEFT_UP')" />
+              <div class="up-right-btn" @click="handleControl('RIGHT_UP')" />
+              <div class="down-btn" @click="handleControl('DOWN')" />
+              <div class="down-left-btn" @click="handleControl('LEFT_DOWN')" />
+              <div class="down-right-btn" @click="handleControl('RIGHT_DOWN')" />
+              <div class="left-btn" @click="handleControl('LEFT')" />
+              <div class="right-btn" @click="handleControl('RIGHT')" />
               <div :class="!!isRefresh ? 'refresh-btn rotate-box' : 'refresh-btn'" @click="handleRefresh" />
             </div>
           </div>
@@ -64,7 +64,7 @@
         </div>
       </div>
       <div class="operate-box">
-        <div class="common-btn-primary5">开始巡航</div>
+        <div class="common-btn-primary5" @click="handleCruise">{{ !cruise ? '开始巡航' : '结束巡航' }}</div>
         <div class="common-btn-primary5" @click="handleScreenshot">截图</div>
         <div class="common-btn-primary5" @click="handleRecording">{{ !!recording ? '结束录像' : '录像' }}</div>
       </div>
@@ -86,13 +86,16 @@ import videoImg from '@/assets/images/dotIcon/33_forest_defense_video.png';
 import VectorLayer from 'ol/layer/Vector';
 import VectorSource from 'ol/source/Vector';
 import Polygon from 'ol/geom/Polygon';
-import { getPtzInfo } from '@/api/globalMap/forestDefenseVideo';
+import { getDeviceByIndexCode, getPtzInfo, setHkVideoControlling } from '@/api/globalMap/forestDefenseVideo';
 import { showErrorMsg, showSuccessMsg } from '@/utils/notification';
 
 const props = defineProps({
   id: String,
   activeMap: String
 });
+const data = ref({
+  'video_code': props.id
+});
 const mapUtils = inject('getMapUtils');
 let map, AMap, marker, circle, sector, vectorLayer;
 const AMapType = ['vectorgraph', 'satellite'];
@@ -111,10 +114,10 @@ let visibleRange = ref(false);
 let detailData = ref({
   title: '',
   address: '',
-  lng: 0,
-  lat: 0,
+  lng: undefined,
+  lat: undefined,
   type: '',
-  speed: 0,
+  speed: 1,
   video_code: ''
 });
 let ptzInfo = ref({
@@ -122,22 +125,32 @@ let ptzInfo = ref({
   AngelH: 0,
   AzimuthH: 0
 });
-
-const getData = () => {
+const handleGetPtzInfo = () => {
   getPtzInfo({ code: props.id }).then((res) => {
     ptzInfo.value = res.data;
+    if (visibleRange.value) {
+      createSector();
+    }
   });
+};
+const getData = (refresh) => {
+  handleGetPtzInfo();
+  // getDeviceByIndexCode({ code: props.id }).then((res) => {
+  //   detailData.value = res.data;
+  // });
   detailData.value = {
     title: '高州市根子镇上炕村委会',
     address: '茂名市高州市坡心东南约400米',
     lng: 110.819207,
     lat: 21.711887,
     type: '云台',
-    speed: 246,
-    // video_code: '44090000001321000033',
-    video_code: '44092251001320000009',
+    speed: 1,
+    video_code: '44090000001321000033'
+    // video_code: '44092251001320000009'
   };
-  initDot();
+  if (!refresh) {
+    initDot();
+  }
 };
 // 加载地图标点
 const initDot = () => {
@@ -198,25 +211,49 @@ const handleSpeed = (type) => {
   } else {
     detailData.value.speed -= 1;
   }
+  if (cruise.value) {
+    handleCruise();
+  }
 };
 
 // 焦距控制
 const handleFocusControl = (type) => {
+  const params = {
+    cameraIndexCode: props.id,
+    action: '0',
+    command: type,
+    speed: detailData.value.speed,
+    presetIndex: 20
+  };
   if (type === 'add') {
+    params.command = 'ZOOM_IN';
   } else {
+    params.command = 'ZOOM_OUT';
   }
+  setHkVideoControlling(params).then(() => {
+    params.action = '1';
+    setHkVideoControlling(params);
+  });
 };
 
 // 控制视角移动
 const handleControl = (type) => {
-  if (type === 'left') {
-    ptzInfo.value.AzimuthH -= 10;
-  } else if (type === 'right') {
-    ptzInfo.value.AzimuthH += 10;
-  }
-  if (visibleRange.value) {
-    createSector();
+  if (cruise.value) {
+    return showErrorMsg('请先关闭巡航再操作');
   }
+  const params = {
+    cameraIndexCode: props.id,
+    action: '0',
+    command: type,
+    speed: detailData.value.speed,
+    presetIndex: 20
+  };
+  setHkVideoControlling(params).then(() => {
+    params.action = '1';
+    setHkVideoControlling(params).then(() => {
+      handleGetPtzInfo();
+    });
+  });
 };
 // 新增扇形
 const createSector = () => {
@@ -257,9 +294,10 @@ let isRefresh = ref(false);
 const handleRefresh = () => {
   if (isRefresh.value) return;
   isRefresh.value = true;
+  videoRef.value.refresh_data();
   setTimeout(() => {
     isRefresh.value = false;
-  }, 3000);
+  }, 1000);
 };
 
 watch(visibleRange, () => {
@@ -389,10 +427,31 @@ const calculateAngle = (azimuthH, angelH) => {
   const endAngle_deg = endAngle_deci / 10;
 
   return {
-    startAngle: startAngle_deg,
-    endAngle: endAngle_deg
+    startAngle: convertToClockwiseAngle(endAngle_deg),
+    endAngle: convertToClockwiseAngle(startAngle_deg)
   };
 };
+const convertToClockwiseAngle = (counterClockwiseAngle) => {
+  // 由于角度具有周期性,我们可以对360取模来标准化角度
+  let standardAngle = counterClockwiseAngle % 360;
+
+  // 如果角度是0或360的倍数,它既是逆时针也是顺时针
+  if (standardAngle === 0) {
+    return 0;
+  }
+
+  // 将逆时针角度转换为等效的顺时针角度
+  // 注意:这里我们仍然返回正数,但在解释时视为顺时针
+  // 例如,300度逆时针相当于60度顺时针
+  let clockwiseAngle = (360 - standardAngle) % 360;
+
+  // 处理模运算后的特殊情况,确保结果为正数
+  if (clockwiseAngle === 0) {
+    clockwiseAngle = 360; // 或者你可以选择返回其他表示,比如继续用0
+  }
+
+  return clockwiseAngle;
+};
 // 截图
 let videoRef = ref(null);
 const handleScreenshot = () => {
@@ -423,6 +482,7 @@ const handleRecording = () => {
     // 结束录像
     player.JS_StopSave(0).then(
       () => {
+        showSuccessMsg('录像结束');
         recording.value = false;
       },
       (err) => {
@@ -431,6 +491,42 @@ const handleRecording = () => {
     );
   }
 };
+// 巡航
+let cruise = ref(false);
+let timer;
+const handleCruise = (event?: MouseEvent) => {
+  if (!cruise.value || !event) {
+    // 开始巡航
+    setHkVideoControlling({
+      cameraIndexCode: props.id,
+      action: '0',
+      command: 'RIGHT',
+      speed: detailData.value.speed,
+      presetIndex: 20
+    }).then(() => {
+      showSuccessMsg('巡航开始');
+      cruise.value = true;
+      if (!!timer) {
+        clearInterval(timer);
+      }
+      timer = setInterval(handleGetPtzInfo, 1000);
+    });
+  } else {
+    setHkVideoControlling({
+      cameraIndexCode: props.id,
+      action: '1',
+      command: 'RIGHT',
+      speed: detailData.value.speed,
+      presetIndex: 20
+    }).then(() => {
+      clearInterval(timer);
+      timer = null;
+      showSuccessMsg('巡航结束');
+      cruise.value = false;
+      handleGetPtzInfo();
+    });
+  }
+};
 watch(
   () => props.id,
   () => {