Browse Source

1、修改VCEarthViewer3D绘图插件的图形数据输出格式(key)

2、添加2D视频绘图插件canvas-select,完善相应功能
3、新增rtsp+2d绘图测试页面用于调试
master
Fuyuu 1 year ago
parent
commit
887b1f7da2
  1. 1
      package.json
  2. 24
      src/router/routes/index.ts
  3. 17
      src/views/military/modules/ai/monitorArea/components/VCEarthViewer.vue
  4. 2
      src/views/military/modules/ops/maintain/MsMaintainList.vue
  5. 2
      src/views/military/modules/ops/maintain/MsMaintainPlan.vue
  6. 2
      src/views/military/modules/ops/maintain/MsMaintainRecord.vue
  7. 2
      src/views/military/modules/ops/repair/audit/MsFaultAudit.vue
  8. 2
      src/views/military/modules/ops/repair/record/MsFaultRecord.vue
  9. 2
      src/views/military/modules/ops/repair/repair/MsFaultList.vue
  10. 2
      src/views/military/modules/ops/repair/report/MsFaultReport.vue
  11. 283
      src/views/system/loginmini/CanvasVideoPage.vue
  12. BIN
      src/views/system/loginmini/assets/big_buck_bunny.mp4
  13. BIN
      src/views/system/loginmini/assets/hide.png
  14. 12
      vite.config.ts

1
package.json

@ -85,6 +85,7 @@
"ant-design-vue": "^3.2.12",
"autofit.js": "^3.0.4",
"axios": "^0.26.1",
"canvas-select": "^2.18.1-beta.1",
"china-area-data": "^5.0.1",
"clipboard": "^2.0.8",
"codemirror": "^5.65.3",

24
src/router/routes/index.ts

@ -36,7 +36,7 @@ export const ElectronicMapRoute: AppRouteRecordRaw = {
meta: {
title: t('routes.basic.login'),
},
children:[
children: [
{
path: 'show',
name: 'show',
@ -55,10 +55,9 @@ export const ElectronicMapRoute: AppRouteRecordRaw = {
},
component: () => import('/@/views/earthMap/edit/ElectronicMap.vue'),
},
]
],
};
export const VideoMonitorRoute: AppRouteRecordRaw = {
path: '/videoIndex',
name: 'VideoIndex',
@ -67,7 +66,7 @@ export const VideoMonitorRoute: AppRouteRecordRaw = {
meta: {
title: t('routes.basic.login'),
},
children:[
children: [
{
path: 'videoMonitor',
name: 'VideoMonitor',
@ -101,10 +100,9 @@ export const VideoMonitorRoute: AppRouteRecordRaw = {
// currentActiveMenu: '/error-log',
},
},
]
],
};
export const LoginRoute: AppRouteRecordRaw = {
path: '/login',
name: 'Login',
@ -112,6 +110,8 @@ export const LoginRoute: AppRouteRecordRaw = {
// component: () => import('/@/views/sys/login/Login.vue'),
// component: () => import('/@/views/system/loginmini/MiniLogin.vue'),
component: () => import('/@/views/system/loginmini/ZGXLogin.vue'),
// 测试登录页 - rtsp + 视频绘图标注
// component: () => import('/@/views/system/loginmini/CanvasVideoPage.vue'),
meta: {
title: t('routes.basic.login'),
},
@ -144,4 +144,14 @@ export const TokenLoginRoute: AppRouteRecordRaw = {
};
// Basic routing without permission
export const basicRoutes = [LoginRoute, RootRoute, ...mainOutRoutes, REDIRECT_ROUTE, PAGE_NOT_FOUND_ROUTE, TokenLoginRoute, Oauth2LoginRoute, ElectronicMapRoute, VideoMonitorRoute];
export const basicRoutes = [
LoginRoute,
RootRoute,
...mainOutRoutes,
REDIRECT_ROUTE,
PAGE_NOT_FOUND_ROUTE,
TokenLoginRoute,
Oauth2LoginRoute,
ElectronicMapRoute,
VideoMonitorRoute,
];

17
src/views/military/modules/ai/monitorArea/components/VCEarthViewer.vue

@ -260,19 +260,19 @@
function getDrawingActionInstances(viewer: any) {
//
let areaData: any = [];
let k = 1;
let k = 0;
//
proxy.$refs.drawingsRef.getDrawingActionInstances().forEach((item) => {
//
let source = item.cmpRef._value.renderDatas._rawValue;
console.log(item.cmpRef._value);
//
let obj_list: any = [];
// console.log('item.name', item.name);
if (item.name == 'pin' || item.name == 'point') {
//
source.forEach((ele) => {
k++;
//
let result: any = cartesian3ToCartographic(ele.position, viewer);
let result_area = {
@ -280,7 +280,7 @@
lat: result[1],
key: k,
};
k++;
obj_list.push(result);
areaData.push(result_area);
});
@ -299,7 +299,9 @@
//
// :,
let source_area = item.cmpRef._value.computedRenderDatas._value;
source_area.forEach((ele) => {
k++;
for (let i = 0; i < ele.polygonPositions.length - 1; i++) {
let result: any = cartesian3ToCartographic(ele.polygonPositions[i], viewer);
let result_area = {
@ -307,7 +309,6 @@
lat: result[1],
key: k,
};
k++;
areaData.push(result_area);
}
});
@ -327,6 +328,7 @@
// :,
let source_area = item.cmpRef._value.computedRenderDatas._value;
source_area.forEach((ele) => {
k++;
for (let i = 0; i < ele.polygonPositions.length; i++) {
let result: any = cartesian3ToCartographic(ele.polygonPositions[i], viewer);
let result_area = {
@ -334,7 +336,6 @@
lat: result[1],
key: k,
};
k++;
areaData.push(result_area);
}
});
@ -354,6 +355,7 @@
// :,
let source_area = item.cmpRef._value.computedRenderDatas._value;
source_area.forEach((ele) => {
k++;
//
let result: any = cartesian3ToCartographic(ele.positions[0], viewer);
let result_area = {
@ -362,12 +364,12 @@
distance: ele.distance,
key: k,
};
k++;
areaData.push(result_area);
});
} else {
//
source.forEach((ele) => {
k++;
//
let point_list: any = [];
ele.positions.forEach((point) => {
@ -378,7 +380,6 @@
lat: result[1],
key: k,
};
k++;
areaData.push(result_area);
point_list.push(result);
});

2
src/views/military/modules/ops/maintain/MsMaintainList.vue

@ -1,7 +1,7 @@
<!--
保养检查及进度
目录位置运维保障 -> 保养检查及进度
目录位置运维保障 -> 日常保养 -> 保养检查及进度
功能概述用于展示并管理保养进度等信息
-->
<template>

2
src/views/military/modules/ops/maintain/MsMaintainPlan.vue

@ -1,7 +1,7 @@
<!--
保养计划
目录位置运维保障 -> 保养计划
目录位置运维保障 -> 日常保养 -> 保养计划
功能概述用于管理保养计划信息包括编辑查询等操作
-->
<template>

2
src/views/military/modules/ops/maintain/MsMaintainRecord.vue

@ -1,7 +1,7 @@
<!--
保养记录
目录位置运维保障 -> 保养记录
目录位置运维保障 -> 日常保养 -> 保养记录
功能概述用于管理保养记录数据包括记录的录入编辑等可以进行多条件查询
-->
<template>

2
src/views/military/modules/ops/repair/audit/MsFaultAudit.vue

@ -1,7 +1,7 @@
<!--
故障报单审核及计划 审批及计划
目录位置运维保障 -> 故障报单审核及计划 审批及计划
目录位置运维保障 -> 故障管理 -> 故障报单审核及计划 审批及计划
功能概述用于管理故障保单计划并进行审核等操作可以多条件查询
-->
<template>

2
src/views/military/modules/ops/repair/record/MsFaultRecord.vue

@ -1,7 +1,7 @@
<!--
维修记录库
目录位置运维保障 -> 维修记录库
目录位置运维保障 -> 故障管理 -> 维修记录库
功能概述用于管理维修记录数据包括记录的录入编辑等可以进行多条件查询
-->
<template>

2
src/views/military/modules/ops/repair/repair/MsFaultList.vue

@ -1,7 +1,7 @@
<!--
维修进度
目录位置运维保障 -> 维修进度
目录位置运维保障 -> 故障管理 -> 维修进度
功能概述用于管理维修进度包括维修单号状态故障码基础信息可进行多条件查询
-->
<template>

2
src/views/military/modules/ops/repair/report/MsFaultReport.vue

@ -1,7 +1,7 @@
<!--
故障上报
目录位置运维保障 -> 故障上报
目录位置运维保障 -> 故障管理 -> 故障上报
功能概述用于管理故障保单数据包括故障的基础信息编辑以及故障发生时间的筛选
-->
<template>

283
src/views/system/loginmini/CanvasVideoPage.vue

@ -0,0 +1,283 @@
<!--
测试页面
目录位置
功能概述用于测试2d数据标注插件canvas-select的相关功能,包括基础图形绘制.编辑,数据保存.回显
同时结合rtsp视频播放功能,完成基于视频资源的图形标注
-->
<template>
<div class="box">
<div class="left">
<div>
<canvas ref="canvas" class="container" @mouseup="handleMouseUp" @mousedown="handleMouseDown" @mousemove="handleMouseMove"></canvas>
<!-- <video width="500" height="280" autoplay muted loop>
<source src="./assets/big_buck_bunny.mp4" type="video/mp4" />
</video> -->
<div class="mpegPlayer" ref="mpegPlayer"></div>
</div>
<div>
<div class="flexBox">
<label>rtsp流地址</label>
<a-input type="text" v-model:value="rtspUrl"></a-input>
<a-button @click="open">打开rtsp</a-button>
<a-button @click="close">关闭rtsp</a-button>
</div>
<div v-if="msg">消息rtsp流{{ msg }}</div>
<a-button type="primary" @click="change(0)"><ApiOutlined />关闭创建</a-button>
<a-button type="primary" @click="change(1)">创建矩形</a-button>
<a-button type="primary" @click="change(2)">创建多边形</a-button>
<a-button type="primary" @click="change(3)">创建标记点</a-button>
<a-button type="primary" @click="change(4)">创建线</a-button>
<a-button type="primary" @click="change(5)">创建圆</a-button>
<!-- <a-button type="primary" @click="toggleLineType()">切换线型-测试</a-button> -->
<br />
<br />
<a-button type="primary" @click="zoom(true)"><PlusOutlined />放大</a-button>
<a-button type="primary" @click="zoom(false)"><MinusOutlined />缩小</a-button>
<!-- <a-button type="primary" @click="fitting()">最佳适配比</a-button> -->
<a-button type="primary" @click="onFocus()"><AimOutlined />专注模式</a-button>
<br />
<br />
<a-button type="primary" danger @click="clear()"><FormatPainterOutlined />清除绘制</a-button>
<a-button type="primary" danger @click="lock()"><LinkOutlined />锁定/解锁</a-button>
<br />
<br />
<a-button type="primary" @click="save()"><FileDoneOutlined />保存</a-button>
</div>
</div>
<div class="right">
<pre>
1.设置 instance.createType 指定需要创建形状类型
2.创建矩形时按住鼠标左键拖动完成创建
3.创建多边形时鼠标左键单击添加点双击闭合完成创建Backspace退出创建Escape退一步删除选择点
4.创建折线时鼠标左键单击添加点双击完成创建Backspace退出创建Escape退一步删除选择点
5.按住鼠标右键拖动画布
6.鼠标滚轮缩放画布
7.选中形状Backspace删除
</pre
>
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import {
FileDoneOutlined,
FormatPainterOutlined,
LinkOutlined,
PlusOutlined,
MinusOutlined,
ApiOutlined,
AimOutlined,
} from '@ant-design/icons-vue';
//
import CanvasSelect from 'canvas-select';
// rtsp
import MpegPlayer from 'jsmpeg-player';
const { ipcRenderer } = require('electron');
// rtsp
const rtspUrl = ref('rtsp://admin:hk123456@192.168.1.71:554/');
const mpegPlayer = ref();
//
const msg = ref('');
//
let player: any = null;
//canvas
const canvas = ref(null);
//
const mouseX = ref(0);
const mouseY = ref(0);
const isRightMouseDown = ref(false);
//
// rtsp
const open = () => {
const res = ipcRenderer.sendSync('openRtsp', rtspUrl.value);
if (res.code === 200) {
player = new MpegPlayer.VideoElement(mpegPlayer.value, res.ws);
}
msg.value = res.msg;
};
// rtsp
const close = () => {
const res = ipcRenderer.sendSync('closeRtsp', rtspUrl.value);
msg.value = res.msg;
};
//
const hideUrl = new URL('./assets/hide.png', import.meta.url).href;
//
let instance: any = ref(null);
//
const option: any = ref([]);
onMounted(() => {
//
option.value = JSON.parse(localStorage.getItem('canvasData')!);
//
instance = new CanvasSelect('.container', hideUrl);
//
instance.labelMaxLen = 10;
//
instance.scrollZoom = false;
//
instance.setData(option.value);
// 线
instance.lineWidth = 2;
//
instance.labelFont = '12px Arial';
//
instance.labelFillStyle = '#fa4545';
//
instance.textFillStyle = '#fff';
//
instance.ctrlRadius = 4;
//
instance.on('load', (src: any) => {
console.log('image load', src);
});
//
instance.on('add', (info: any) => {
//
switch (instance.createType) {
case 1:
info.label = '矩形防区';
break;
case 2:
info.label = '多边形防区';
break;
case 3:
info.label = '标记点位';
break;
case 4:
info.label = '报警界线';
break;
case 5:
info.label = '圆形防区';
break;
default:
info.label = '未定义';
}
//
instance.update();
});
//
instance.on('delete', (info: any) => {
console.log('delete', info);
});
//
instance.on('select', (shape: any) => {
console.log('select', shape);
});
//
instance.on('updated', (result: any) => {
// console.log('', result);
});
});
//
function handleMouseMove(e) {
const rect = canvas.value.getBoundingClientRect();
mouseX.value = e.clientX - rect.left;
mouseY.value = e.clientY - rect.top;
if (isRightMouseDown.value) {
//
// console.log('');
//
console.log(instance);
}
}
//
function handleMouseUp(e) {
if (e.button === 2) {
isRightMouseDown.value = false;
}
}
//
function handleMouseDown(e) {
if (e.button === 2) {
isRightMouseDown.value = true;
}
}
//
function change(num: any) {
instance.createType = num;
}
//
function zoom(type: any) {
instance.setScale(type);
}
//
// function fitting() {
// instance.fitZoom();
// }
//
function onFocus() {
instance.setFocusMode(!instance.focusMode);
}
//
function clear() {
instance.setData([]);
}
// /
function lock() {
instance.lock = !instance.lock;
}
//
function save() {
//
//
instance.dataset.forEach((item) => {
item.active = false;
});
console.log(JSON.stringify(instance.dataset));
//
localStorage.setItem('canvasData', JSON.stringify(instance.dataset));
}
</script>
<style scoped>
.box {
display: flex;
margin: 10px;
position: relative;
}
.container {
width: 800px;
height: 480px;
position: absolute;
z-index: 999;
left: 0;
top: 0;
}
button {
margin-right: 3px;
}
.flexBox {
display: flex;
height: 50px;
margin-top: 20px;
}
.flexBox input {
height: 30px;
width: 400px;
box-sizing: border-box;
padding-left: 8px;
}
.flexBox button {
height: 30px;
padding: 0 12px;
}
.mpegPlayer {
width: 800px;
height: 480px;
background: #000;
}
</style>

BIN
src/views/system/loginmini/assets/big_buck_bunny.mp4

Binary file not shown.

BIN
src/views/system/loginmini/assets/hide.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

12
vite.config.ts

@ -8,7 +8,7 @@ import { createProxy } from './build/vite/proxy';
import { wrapperEnv } from './build/utils';
import { createVitePlugins } from './build/vite/plugin';
import { OUTPUT_DIR } from './build/constant';
const path = require('path');
function pathResolve(dir: string) {
return resolve(process.cwd(), '.', dir);
}
@ -74,7 +74,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
minify: 'esbuild',
target: 'es2015',
cssTarget: 'chrome80',
outDir: OUTPUT_DIR,
outDir: OUTPUT_DIR,
terserOptions: {
compress: {
keep_infinity: true,
@ -110,13 +110,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
target: 'es2020',
},
// @iconify/iconify: The dependency is dynamically and virtually loaded by @purge-icons/generated, so it needs to be specified explicitly
include: [
'@vue/runtime-core',
'@vue/shared',
'@iconify/iconify',
'ant-design-vue/es/locale/zh_CN',
'ant-design-vue/es/locale/en_US',
],
include: ['@vue/runtime-core', '@vue/shared', '@iconify/iconify', 'ant-design-vue/es/locale/zh_CN', 'ant-design-vue/es/locale/en_US'],
},
};
};

Loading…
Cancel
Save