浏览代码

Merge branch 'yufei' of gitadmin/tuoheng_lc_web into develop

tags/v1.0.0^2
yufei111 2 年前
父节点
当前提交
df995fcf6d
共有 4 个文件被更改,包括 473 次插入13 次删除
  1. +1
    -0
      src/components/PositionMsg/OverLay.vue
  2. +328
    -5
      src/views/task-manage/all-task/components/DemandDrawer.vue
  3. +143
    -7
      src/views/task-manage/all-task/components/LiveDrawer.vue
  4. +1
    -1
      src/views/task-manage/all-task/index.vue

+ 1
- 0
src/components/PositionMsg/OverLay.vue 查看文件

@@ -14,6 +14,7 @@
<n-form-item label="问题类型:">
<n-select
v-model:value="form.type"
:disabled="positionType === 'look'"
:options="typeList"
placeholder="请选择问题类型"
/>

+ 328
- 5
src/views/task-manage/all-task/components/DemandDrawer.vue 查看文件

@@ -1,18 +1,67 @@
<template>
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse">
<n-drawer-content closable title="轨迹回放">
<BaseMap />
<div class="main_container">
<div id="history-map" />
<!-- 视频播放 -->
<div class="videobox">
<!-- 视频开关 -->
<div
class="flagbox"
:class="videoShow == 'back' ? 'flagbox_open' : 'flaxbox_back'"
>
<span class="videotitle">巡检视频</span>
<img
v-if="videoShow == 'back'"
src="@/assets/img/back.png"
alt=""
class="closedetail imageicon"
@click="showVideo('open')"
>
<img
v-else
src="@/assets/img/open.png"
alt=""
class="closedetail imageicon"
@click="showVideo('back')"
>
</div>
<!-- 直播视频 -->
<!-- <div
class="video_content"
:class="videoShow == 'back' ? 'video_show' : 'video_hidden'"
>
<VideoPlayer :ref="videoRef" :options="getVideoOptions" @time-update="handleOriginTime" @video-status="handleOriginStatus" />
<VideoPlayer :ref="aiVideoRef" :options="getVideoAiOptions" @time-update="handleAiTime" @video-status="(data)=>videoStatus.aiStatus = data.status" />

</div> -->
</div>
</div>
</n-drawer-content>
</n-drawer>
</template>

<script>
import BaseMap from './BaseMap.vue'
import { defineComponent, computed, reactive, toRefs } from 'vue'
import { defineComponent, computed, reactive, toRefs, onMounted, ref, watch } from 'vue'
import { Map, View, Feature } from 'ol'
import 'ol/ol.css'
import { Tile, Vector as VectorLayer } from 'ol/layer'
import LineString from 'ol/geom/LineString'
import Point from 'ol/geom/Point'
import { XYZ, Vector as VectorSource } from 'ol/source'
import { transform, fromLonLat } from 'ol/proj'
import { getVectorContext } from 'ol/render'
import VectorContext from 'ol/render/VectorContext'
import { Draw } from 'ol/interaction'
import { toRaw } from '@vue/reactivity'
import * as control from 'ol/control'
import { styleList } from '../tools/style.js'

// 视频组件
import VideoPlayer from '@/components/VideoPlayer/index.vue'
export default defineComponent({
name: 'LiveDrawer',
components: { BaseMap },
components: { VideoPlayer },
props: {
/* 可见 */
visible: {
@@ -30,7 +79,39 @@ export default defineComponent({
},
setup(props, { emit }) {
const data = reactive({

mapData: null,
view: null,
trackLayer: null,
trackInfo: null,
// 轨迹数据
trackList: [
{ lng: '118.765591', lat: '32.050993' },
{ lng: '118.665591', lat: '32.150993' },
{ lng: '118.565591', lat: '32.070993' },
{ lng: '118.465591', lat: '32.020993' },
{ lng: '118.365591', lat: '32.110993' },
{ lng: '118.265591', lat: '32.080993' },
{ lng: '118.165591', lat: '32.150993' }
],
disdance: null,
animating: null,
detailData: {
videoUrl: '',
aiVideoUrl: ''
},
videoShow: 'back', // 视频展示开关
videoInfo: {
currentTime: 0,
duration: 100
},
aiVideoInfo: {
currentTime: 0,
duration: 100
},
videoStatus: {
status: 'init',
aiStatus: 'init'
}
})

/* 获取抽屉的信息 */
@@ -41,13 +122,173 @@ export default defineComponent({
placement: 'right'
}
})
/* 获取原视频地址 */
const getVideoOptions = computed(() => {
return {
id: 'palyer-on',
width: '400px',
height: '324px',
autoplay: false,
source: data.detailData.videoUrl
}
})
/* 获取AI视频地址 */
const getVideoLiveOptions = computed(() => {
return {
id: 'palyer-ai-on',
width: '400px',
height: '324px',
autoplay: false,
source: data.detailData.aiVideoUrl
}
})
const handleOriginStatus = function(data) {
data.videoStatus.status = data.status
data.videoInfo = {
...data
}
}
const videoRef = ref(null)
const aiVideoRef = ref(null)
const handleOriginTime = function(data) {
data.videoInfo = {
...data
}
const len = Math.abs(data.currentTime - data.aiVideoInfo.currentTime)
if (data.status === 'skip' || len > 3) {
aiVideoRef.value.seekTime(data.currentTime)
}
}
const handleAiTime = function(data) {
data.aiVideoInfo = {
...data
}
const len = Math.abs(data.currentTime - data.videoInfo.currentTime)
if (data.status === 'skip' || len > 3) {
videoRef.value.seekTime(data.currentTime)
}
}
/* 播放视频 */
const startAllVideo = function() {
videoRef.value.playVideo()
aiVideoRef.value.playVideo()
}

watch(() => data.videoStatus, (value) => {
if (value.status === 'ready' && value.aiStatus === 'ready') {
startAllVideo()
}
})

onMounted(() => {
initMap()
// 加载航线
initTrack(formatTradeList(data.trackList), 'trackLayer', 'route')
})

/* 初始化地图 */
const initMap = function() {
const layers = [
new Tile({
visible: true,
source: new XYZ({
url: 'https://tianditu.t-aaron.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=f82bb2fd8115c7fb576a8b2fcf738523'
})
})
]

data.view = new View({
maxZoom: 18,
zoom: 5,
center: transform([118.837886, 32.057175], 'EPSG:4326', 'EPSG:3857')
})
data.mapData = new Map({
layers: layers,
target: 'history-map',
view: data.view,
controls: control.defaults({
attribution: false,
rotate: false,
zoom: false
})
})
data.mapData.render()
}

/* 处理轨迹列表 */
const formatTradeList = function(trackList) {
return trackList.map((item) =>
fromLonLat([parseFloat(item.lng), parseFloat(item.lat)])
)
}

/* 初始化轨迹 */
const initTrack = function(coordinate, layer, routeType) {
let vectorLayer = null
const route = new LineString(coordinate)
const routeFeature = new Feature({
type: routeType,
geometry: route
})
const startMarker = new Feature({
type: 'icon',
geometry: new Point(route.getFirstCoordinate())
})
const position = startMarker.getGeometry().clone()
const geoMarker = new Feature({
type: 'geoMarker',
geometry: position
})
geoMarker.setProperties({ type: 'geoMarker' }, false)
if (data.trackLayer) {
data.trackLayer.setSource(
new VectorSource({
features: [geoMarker, routeFeature]
})
)
vectorLayer = data.trackLayer
} else {
vectorLayer = new VectorLayer({
source: new VectorSource({
features: [geoMarker, routeFeature]
}),
style: function(feature) {
return styleList[feature.get('type')]
}
})
}
data[layer] = vectorLayer
data.mapData.addLayer(data[layer])
data.view.fit(route, { padding: [50, 50, 50, 50] })
data[layer].on('postrender', moveFeature.bind())

function moveFeature(event) {
/* 计算飞行的百分比 */
var distance = data.videoInfo.currentTime / data.videoInfo.duration
const currentCoordinate = route.getCoordinateAt(distance)
position.setCoordinates(currentCoordinate)
geoMarker.setGeometry(null)
const vectorContext = getVectorContext(event)
vectorContext.setStyle(styleList['geoMarker'])
vectorContext.drawGeometry(position)
data.mapData.render()
}
}

function handleDrawerColse() {
emit('update:visible', false)
}

return {
...toRefs(data),
videoRef,
aiVideoRef,
getDrawerOptions,
handleOriginStatus,
handleOriginTime,
handleAiTime,
getVideoOptions,
getVideoLiveOptions,
handleDrawerColse
}
}
@@ -58,4 +299,86 @@ export default defineComponent({
.n-button+.n-button{
margin-left: 30px;
}
.main_container {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
}
#history-map {
width: 100%;
height: 100%;
}
/* 视频 */
.videobox {
width: 800px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-end;
position: absolute;
top: 10px;
right: 10px;
}
.flagbox {
width: 800px;
height: 27px;
background: #fff;
padding: 0 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.flagbox_open {
width: 800px;
animation: openbox 1s;
}
.flaxbox_back {
width: 116px;
animation: backbox 1s;
}
@keyframes backbox {
from {
width: 800px;
}
to {
width: 116px;
}
}
@keyframes openbox {
from {
width: 116px;
}
to {
width: 800px;
}
}
.video_content {
width: 800px;
display: flex;
}
.video_show {
opacity: 1;
animation: showIt 1s;
}
@keyframes showIt {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.video_hidden {
opacity: 0;
animation: hiddenIt 1s;
}
@keyframes hiddenIt {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
</style>

+ 143
- 7
src/views/task-manage/all-task/components/LiveDrawer.vue 查看文件

@@ -3,6 +3,40 @@
<n-drawer-content closable title="飞行直播">
<div class="main_container">
<div id="live-map" />
<!-- 视频播放 -->
<div v-if="detailData?.name" class="videobox">
<!-- 视频开关 -->
<div
class="flagbox"
:class="videoShow == 'back' ? 'flagbox_open' : 'flaxbox_back'"
>
<span class="videotitle">巡检视频</span>
<img
v-if="videoShow == 'back'"
src="@/assets/img/back.png"
alt=""
class="closedetail imageicon"
@click="showVideo('open')"
>
<img
v-else
src="@/assets/img/open.png"
alt=""
class="closedetail imageicon"
@click="showVideo('back')"
>
</div>
<!-- 直播视频 -->
<div
controls
class="video_content"
:class="videoShow == 'back' ? 'video_show' : 'video_hidden'"
>
<VideoPlayer :options="getVideoOptions" />
<div class="flagbox">AI识别视频</div>
<VideoPlayer :options="getVideoLiveOptions" />
</div>
</div>
</div>
</n-drawer-content>
</n-drawer>
@@ -24,8 +58,11 @@ import { toRaw } from '@vue/reactivity'
import * as control from 'ol/control'
import { styleList } from '../tools/style.js'

// 视频组件
import VideoPlayer from '@/components/VideoPlayer/index.vue'
export default defineComponent({
name: 'LiveDrawer',
components: { VideoPlayer },
props: {
/* 可见 */
visible: {
@@ -60,14 +97,14 @@ export default defineComponent({
{ lng: '118.165591', lat: '32.150993' },
{ lng: '118.765591', lat: '32.150993' },
{ lng: '118.665591', lat: '32.050993' },
{ lng: '118.565591', lat: '32.170993' },
{ lng: '118.465591', lat: '32.010993' },
{ lng: '118.365591', lat: '32.060993' },
{ lng: '118.265591', lat: '32.180993' },
{ lng: '118.165591', lat: '32.050993' }
],
// 轨迹数据
trackList: [
trackList: [],
// 历史轨迹坐标数据
trajectoryList: [
{ lng: '118.765591', lat: '32.050993' },
{ lng: '118.665591', lat: '32.150993' },
{ lng: '118.565591', lat: '32.070993' },
@@ -76,9 +113,11 @@ export default defineComponent({
{ lng: '118.265591', lat: '32.080993' },
{ lng: '118.165591', lat: '32.150993' }
],
trajectoryList: [], // 历史轨迹坐标数据
disdance: null,
animating: null
animating: null,
detailData: {},
videoShow: 'back' // 视频展示开关

})
/* 获取抽屉的信息 */
const getDrawerOptions = computed(() => {
@@ -88,6 +127,27 @@ export default defineComponent({
placement: 'right'
}
})
/* 获取原视频地址 */
const getVideoOptions = computed(() => {
return {
id: 'video-live',
width: '378px',
height: '212px',
source: data.detailData.pullUrl,
isLive: true
}
})
/* 获取AI视频地址 */
const getVideoLiveOptions = computed(() => {
return {
id: 'video-live',
width: '378px',
height: '212px',
source: data.detailData.pullUrl,
isLive: true
}
})

function handleDrawerColse() {
emit('update:visible', false)
}
@@ -97,7 +157,7 @@ export default defineComponent({
// 加载航线
initTrack(formatTradeList(data.lineTrajectoryList), 'lineTrackLayer', 'lineRoute')
// 加载历史轨迹和实时轨迹
setLiveTrack(formatTradeList(data.trackList))
setLiveTrack(formatTradeList(data.trajectoryList))
})

/* 初始化地图 */
@@ -263,7 +323,9 @@ export default defineComponent({
return {
...toRefs(data),
getDrawerOptions,
handleDrawerColse
handleDrawerColse,
getVideoOptions,
getVideoLiveOptions
}
}
})
@@ -283,5 +345,79 @@ export default defineComponent({
width: 100%;
height: 100%;
}
/* 视频 */
.videobox {
width: 378px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-end;
position: absolute;
top: 10px;
right: 10px;
}
.flagbox {
width: 378px;
height: 27px;
background: #fff;
padding: 0 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.flagbox_open {
width: 378px;
animation: openbox 1s;
}
.flaxbox_back {
width: 116px;
animation: backbox 1s;
}
@keyframes backbox {
from {
width: 378px;
}
to {
width: 116px;
}
}
@keyframes openbox {
from {
width: 116px;
}
to {
width: 378px;
}
}
.video_content {
width: 378px;
height: 220px;
position: relative;
}

.video_show {
opacity: 1;
animation: showIt 1s;
}
@keyframes showIt {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.video_hidden {
opacity: 0;
animation: hiddenIt 1s;
}
@keyframes hiddenIt {
from {
opacity: 1;
}
to {
opacity: 0;
}
}

</style>

+ 1
- 1
src/views/task-manage/all-task/index.vue 查看文件

@@ -31,7 +31,7 @@
<!-- 直播抽屉 -->
<LiveDrawer v-if="liveDrawer" v-model:visible="liveDrawer" :data="rowData" />
<!-- 轨迹回放 -->
<DemandDrawer v-model:visible="demandDrawer" :data="rowData" />
<DemandDrawer v-if="demandDrawer" v-model:visible="demandDrawer" :data="rowData" />
<!-- 问题核实 -->
<VerifyDrawer v-model:visible="verifyDrawer" :data="rowData" />


正在加载...
取消
保存