add device manager module
This commit is contained in:
parent
c6adcebf9a
commit
1fa0a4cb2b
3069
frontend/src/views/home/components/device-manage/index.js
Normal file
3069
frontend/src/views/home/components/device-manage/index.js
Normal file
File diff suppressed because it is too large
Load Diff
1479
frontend/src/views/home/components/device-manage/index.scss
Normal file
1479
frontend/src/views/home/components/device-manage/index.scss
Normal file
File diff suppressed because it is too large
Load Diff
433
frontend/src/views/home/components/device-manage/index.vue
Normal file
433
frontend/src/views/home/components/device-manage/index.vue
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
<template>
|
||||||
|
<div class="twin-situation" >
|
||||||
|
<!-- 资源列表 -->
|
||||||
|
<dt-card
|
||||||
|
:class="{
|
||||||
|
'resource-list': true,
|
||||||
|
'resource-list__large': isIconModeLarge
|
||||||
|
}"
|
||||||
|
icon="ri-send-plane-line"
|
||||||
|
title="可用资源"
|
||||||
|
:visible.sync="resourceList.visible"
|
||||||
|
:scroll="false"
|
||||||
|
:showClose="false"
|
||||||
|
:showDivider="false"
|
||||||
|
>
|
||||||
|
<template v-slot:header>
|
||||||
|
<span class="remote-header">
|
||||||
|
<i class="iconfont icon-left_icon_remote"></i>
|
||||||
|
可用资源
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<!-- <template v-slot:command>-->
|
||||||
|
<!-- <el-tooltip-->
|
||||||
|
<!-- effect="dark"-->
|
||||||
|
<!-- content="详情"-->
|
||||||
|
<!-- placement="bottom"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- <i class="ri-eye-2-line" @click="toggleRightShow"></i>-->
|
||||||
|
<!-- </el-tooltip>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
<div class="resource-list__content">
|
||||||
|
<div v-for="item in resourceList.data" :key="item.id" class="resource-item" @click.stop="resourceClick(item)">
|
||||||
|
<span class="device-status" :class="item.status ? 'device-status__online' : ''"></span>
|
||||||
|
<span class="icon"><i class="ri-dv-line"></i></span>
|
||||||
|
<span class="device-name">{{item.name}}</span>
|
||||||
|
<span class="battery" :class="getDeviceBatteryClass(item.battery)" style="opacity: 0;"><i class="ri-battery-saver-line"></i>{{item.battery}}%</span>
|
||||||
|
<span class="fly-height"><i class="ri-expand-vertical-line"></i>{{item.flyHeight}}m</span>
|
||||||
|
<span class="device-location"><i class="ri-map-pin-line"></i>{{item.lon}},{{item.lat}}</span>
|
||||||
|
<i class="iconfont icon-zhuizong device-lock" @click.stop="flyToTarget(item.lon, item.lat, item.flyHeight)"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dt-card>
|
||||||
|
|
||||||
|
<!-- 任务列表 -->
|
||||||
|
<!-- <dt-card
|
||||||
|
:class="{
|
||||||
|
'task-list': true,
|
||||||
|
'task-list__large': isIconModeLarge
|
||||||
|
}"
|
||||||
|
icon="ri-list-unordered"
|
||||||
|
title="任务列表"
|
||||||
|
:visible.sync="taskList.visible"
|
||||||
|
:scroll="false"
|
||||||
|
:showClose="false"
|
||||||
|
:showDivider="false"
|
||||||
|
>
|
||||||
|
<template v-slot:header>
|
||||||
|
<span class="remote-header">
|
||||||
|
<i class="iconfont icon-left_icon_remote"></i>
|
||||||
|
任务列表
|
||||||
|
</span>
|
||||||
|
</template> -->
|
||||||
|
<!-- <template v-slot:command>-->
|
||||||
|
<!-- <el-tooltip-->
|
||||||
|
<!-- effect="dark"-->
|
||||||
|
<!-- content="上传精处理图片"-->
|
||||||
|
<!-- placement="top"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- <i class="ri-upload-2-line" @click.stop="showUpload"></i>-->
|
||||||
|
<!-- </el-tooltip>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
<!--
|
||||||
|
<div class="task-list__content">
|
||||||
|
<div v-for="(item, index) in taskList.data" :key="item.id" class="task-item">
|
||||||
|
<div class="left-part">-->
|
||||||
|
<!-- <div class="task-progress-bar" :style="'width: ' + item.uavCompletion +'%;'"></div>-->
|
||||||
|
<!-- <div class="execute-info" @click="openTaskLineDetail(item)">
|
||||||
|
<span class="execute-type-icon" :class="'execute-state-' + item.status"><i class="ri-dv-line"></i></span>
|
||||||
|
<span class="task-execute">{{ item.name }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="task-info">
|
||||||
|
{{item.statusName}}
|
||||||
|
</div>
|
||||||
|
<div class="task-time">{{item.beginTime}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="right-part">
|
||||||
|
|
||||||
|
<el-tooltip
|
||||||
|
effect="dark"
|
||||||
|
:content="item.check ? '隐藏' : '显示'"
|
||||||
|
placement="right"
|
||||||
|
>
|
||||||
|
<i :class="item.check ? 'ri-eye-off-line' : 'ri-eye-line'" @click.stop="toggleTaskSceneShow(item, index)"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip
|
||||||
|
v-if="item.status === 0"
|
||||||
|
effect="dark"
|
||||||
|
content="执行"
|
||||||
|
placement="right"
|
||||||
|
>
|
||||||
|
<i class="ri-flight-takeoff-line" @click.stop="makeTaskUavFly(item, index)"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip
|
||||||
|
effect="dark"
|
||||||
|
content="结束任务"
|
||||||
|
placement="right"
|
||||||
|
v-if="item.status === 1"
|
||||||
|
>
|
||||||
|
<i class="ri-stop-circle-line" @click.stop="stopTask(item, index)"></i>
|
||||||
|
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip
|
||||||
|
effect="dark"
|
||||||
|
content="重新执行"
|
||||||
|
placement="right"
|
||||||
|
v-if="item.status === 2"
|
||||||
|
>
|
||||||
|
<i class="ri-repeat-line" @click.stop="reRunTask(item, index)"></i>
|
||||||
|
|
||||||
|
</el-tooltip>-->
|
||||||
|
<!-- <i class="el-icon-edit-outline edit-task" @click.stop="editTask(item)"></i>-->
|
||||||
|
<!-- <i class="el-icon-close delete-task" @click.stop="deleteTask(item)"></i>-->
|
||||||
|
<!-- </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dt-card>
|
||||||
|
-->
|
||||||
|
<!-- 图片上传 -->
|
||||||
|
<pictures-upload v-if="uploadPictureInfo.visible" :visible.sync="uploadPictureInfo.visible"></pictures-upload>
|
||||||
|
|
||||||
|
<!-- 气象预警 -->
|
||||||
|
<!--
|
||||||
|
<right-slide class="weather-info-wrap">
|
||||||
|
<dt-card
|
||||||
|
:class="{
|
||||||
|
'weather-info': true,
|
||||||
|
'weather-info__shrink': weatherInfo2.shrink,
|
||||||
|
'weather-info__large': isIconModeLarge
|
||||||
|
}"
|
||||||
|
icon="iconfont icon-target"
|
||||||
|
title="气象预警"
|
||||||
|
:visible.sync="rightShow"
|
||||||
|
:scroll="false"
|
||||||
|
:showClose="false"
|
||||||
|
:showDivider="false"
|
||||||
|
>
|
||||||
|
<div class="weather-info__content2">
|
||||||
|
<div class="base-info">
|
||||||
|
<div><span>温度:</span><span>{{weatherInfo2.wendu}}</span></div>
|
||||||
|
<div><span>湿度:</span><span>{{weatherInfo2.shidu}}</span></div>
|
||||||
|
<div><span>空气质量:</span><span>{{weatherInfo2.quality}}</span></div>
|
||||||
|
<div><span>pm25:</span><span>{{weatherInfo2.pm25}}</span></div>
|
||||||
|
<div><span>pm10:</span><span>{{weatherInfo2.pm10}}</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="week-info">
|
||||||
|
<div v-for="item in weatherInfo2.weekData" :key="item.ymd" class="week-info-item">
|
||||||
|
<div>{{item.week}}</div>
|
||||||
|
<div>{{item.type}}</div>
|
||||||
|
<div><span>{{item.temperatureRange[0]}}</span>~<span>{{item.temperatureRange[0]}}</span></div>
|
||||||
|
<div>{{item.fx}}</div>
|
||||||
|
<div>{{item.fl}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dt-card>
|
||||||
|
</right-slide>
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- 雷达图 -->
|
||||||
|
<!--
|
||||||
|
<right-slide class="radar-info-wrap">
|
||||||
|
<dt-card
|
||||||
|
:class="{
|
||||||
|
'radar-info': true,
|
||||||
|
'radar-info__large': isIconModeLarge
|
||||||
|
}"
|
||||||
|
icon="iconfont icon-target"
|
||||||
|
title="缩略图"
|
||||||
|
:visible.sync="rightShow"
|
||||||
|
:scroll="false"
|
||||||
|
:showClose="false"
|
||||||
|
:showDivider="false"
|
||||||
|
>
|
||||||
|
<template v-slot:command>
|
||||||
|
<el-tooltip
|
||||||
|
effect="dark"
|
||||||
|
content="重建"
|
||||||
|
placement="bottom"
|
||||||
|
>
|
||||||
|
<i class="el-icon-refresh" style="cursor: pointer;" @click.stop="refreshRadar"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<div class="radar-canvas" ref="radarCanvas"></div>
|
||||||
|
</dt-card>
|
||||||
|
</right-slide>
|
||||||
|
|
||||||
|
-->
|
||||||
|
<!-- 详情 -->
|
||||||
|
<right-slide class="detail-info-wrap" v-if="detailInfo.visible">
|
||||||
|
<dt-card
|
||||||
|
:class="{
|
||||||
|
'detail-info': true,
|
||||||
|
'detail-info__large': isIconModeLarge
|
||||||
|
}"
|
||||||
|
icon="iconfont icon-target"
|
||||||
|
title="详细信息"
|
||||||
|
v-if="detailInfo.visible"
|
||||||
|
:visible.sync="detailInfo.visible"
|
||||||
|
:scroll="false"
|
||||||
|
:showClose="true"
|
||||||
|
:showDivider="false"
|
||||||
|
>
|
||||||
|
<div class="detail-info__content">
|
||||||
|
<div class="base-info">
|
||||||
|
<!-- 无人机 -->
|
||||||
|
<div class="uav-item" >
|
||||||
|
<span class="device-status" :class="getDeviceSignalClass(detailInfo.baseInfo.signal)"></span>
|
||||||
|
<span class="icon"><i class="ri-dv-line"></i></span>
|
||||||
|
<span class="device-name">{{ detailInfo.baseInfo.name }}</span>
|
||||||
|
<span class="battery" :class="getDeviceBatteryClass(detailInfo.baseInfo.battery)" style="opacity: 0;"><i class="ri-battery-saver-line"></i>{{detailInfo.baseInfo.battery}}%</span>
|
||||||
|
<span class="fly-height"><i class="ri-expand-vertical-line"></i>{{detailInfo.baseInfo.flyHeight}}m</span>
|
||||||
|
<span class="device-location"><i class="ri-map-pin-line"></i>{{detailInfo.baseInfo.lon}},{{detailInfo.baseInfo.lat}}</span>
|
||||||
|
<i class="el-icon-info device-lock" @click="showUavMore"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="target-task-list">-->
|
||||||
|
<!-- <div class="target-task-item" v-for="item in detailInfo.taskList" :key="item.id">-->
|
||||||
|
<!-- <div class="execute-info">-->
|
||||||
|
<!-- <span class="execute-type-icon" :class="'execute-state-' + item.status"><i class="ri-dv-line"></i></span>-->
|
||||||
|
<!-- <span class="task-execute">{{ item.name }}</span>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- <div class="task-time">{{item.beginTime}}</div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<div class="picture-list">
|
||||||
|
<div>回传图像:</div>
|
||||||
|
<div v-for="item in detailInfo.pictureList" :key="item.createTime" class="picture-list-item">
|
||||||
|
<div class="picture-item-image">
|
||||||
|
<el-image
|
||||||
|
style="width: 40px; height: 40px"
|
||||||
|
:src="item.url"
|
||||||
|
:preview-src-list="[item.url]">
|
||||||
|
</el-image>
|
||||||
|
</div>
|
||||||
|
<div class="picture-item-info">
|
||||||
|
<div>拍摄任务:{{item.taskName}} | 拍摄载荷:{{item.loaderName}}</div>
|
||||||
|
<div>拍摄时间:{{item.createTime}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="picture-command">
|
||||||
|
<i class="iconfont icon-dt-icon-dingwei" @click="lockHistoryPicture(item)"></i>
|
||||||
|
<i class="iconfont icon-quanjushijiao-copy" @click="toggleHistoryPicture(item)"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dt-card>
|
||||||
|
</right-slide>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 详情 -->
|
||||||
|
<dt-card
|
||||||
|
:class="{
|
||||||
|
'detail-uav': true,
|
||||||
|
'detail-uav__large': isIconModeLarge
|
||||||
|
}"
|
||||||
|
icon="iconfont icon-target"
|
||||||
|
title="详细信息"
|
||||||
|
v-if="detailUav.visible"
|
||||||
|
:visible.sync="detailUav.visible"
|
||||||
|
:scroll="true"
|
||||||
|
:showClose="true"
|
||||||
|
:showDivider="false"
|
||||||
|
>
|
||||||
|
<div class="detail-uav__content">
|
||||||
|
<div class="image-info">
|
||||||
|
<img :src="detailUav.baseInfo.url" alt="">
|
||||||
|
<div class="status-info">
|
||||||
|
<div>
|
||||||
|
<span :class="detailUav.baseInfo.status ? 'uav-status-online' : 'uav-status-offline'"></span>
|
||||||
|
<span>{{detailUav.baseInfo.status ? '在线' : '离线'}}</span>
|
||||||
|
<!-- <span style="opacity: 0;"><i class="ri-battery-saver-line"></i>{{detailUav.baseInfo.battery}}%</span>-->
|
||||||
|
<span><i class="ri-expand-vertical-line"></i>{{detailUav.baseInfo.flyHeight}}m</span>
|
||||||
|
<!-- <span><i class="ri-expand-horizontal-line"></i>{{detailUav.baseInfo.flyWidth}}m</span>-->
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>{{detailUav.baseInfo.longitude}}</span>
|
||||||
|
<span>{{detailUav.baseInfo.latitude}}</span>
|
||||||
|
<i class="iconfont icon-zhuizong" @click.stop="flyToTarget(detailUav.baseInfo.longitude, detailUav.baseInfo.latitude, detailUav.baseInfo.flyHeight)"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="other-info">
|
||||||
|
<el-collapse v-model="detailUav.activeNames" @change="handleUavDetailCollapse">
|
||||||
|
<!-- <el-collapse-item title="基本信息" name="1">-->
|
||||||
|
<!-- <div class="uav-span-wrap"><span>名称:</span><span>{{detailUav.basicsInfo.name}}</span></div>-->
|
||||||
|
<!-- <div class="uav-span-wrap"><span>分组:</span><span>{{detailUav.basicsInfo.group}}</span></div>-->
|
||||||
|
<!-- </el-collapse-item>-->
|
||||||
|
<!-- <el-collapse-item title="任务信息" name="2">-->
|
||||||
|
<!-- <div class="target-task-item" v-for="item in detailUav.taskList" :key="item.id">-->
|
||||||
|
<!-- <div class="task-progress-bar" :style="'width: ' + item.uavCompletion +'%;'"></div>-->
|
||||||
|
<!-- <div class="task-info">-->
|
||||||
|
<!-- <i :class="item.typeIcon"></i>-->
|
||||||
|
<!-- <span class="task-name">{{ item.taskName }}</span>-->
|
||||||
|
<!-- <span :class="{ 'task-finish': item.isFinish }">{{-->
|
||||||
|
<!-- item.uavCompletionName-->
|
||||||
|
<!-- }}</span>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- <div class="task-time">{{item.taskTime}}</div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </el-collapse-item>-->
|
||||||
|
<el-collapse-item title="状态信息" name="3">
|
||||||
|
<el-tabs v-model="detailUav.activeTab">
|
||||||
|
<el-tab-pane label="DEV" name="DEV">
|
||||||
|
<div class="uav-span-wrap" v-for="item in detailUav.statusInfo.dev" :key="item.name">
|
||||||
|
<span>{{item.name}}:</span>
|
||||||
|
<span>{{item.value}}{{item.unit}}</span>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="GPS" name="GPS">
|
||||||
|
<div class="uav-span-wrap" v-for="item in detailUav.statusInfo.gps" :key="item.name">
|
||||||
|
<span>{{item.name}}:</span>
|
||||||
|
<span>{{item.value}}{{item.unit}}</span>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="IMU" name="IMU">
|
||||||
|
<div class="uav-span-wrap" v-for="item in detailUav.statusInfo.imu" :key="item.name">
|
||||||
|
<span>{{item.name}}:</span>
|
||||||
|
<span>{{item.value}}{{item.unit}}</span>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-collapse-item>
|
||||||
|
<el-collapse-item title="波形信息" name="4">
|
||||||
|
<div class="wave-chart">
|
||||||
|
<dt-multiple-analysis
|
||||||
|
ref="uavDetailChart"
|
||||||
|
:data="detailUav.chart.data"
|
||||||
|
:legend="detailUav.chart.legend"
|
||||||
|
:tooltip="detailUav.chart.tooltip"
|
||||||
|
:title="detailUav.chart.title"
|
||||||
|
:grid="detailUav.chart.grid"
|
||||||
|
:xAxis="detailUav.chart.xAxis"
|
||||||
|
:yAxis="detailUav.chart.yAxis"
|
||||||
|
></dt-multiple-analysis>
|
||||||
|
</div>
|
||||||
|
</el-collapse-item>
|
||||||
|
<el-collapse-item title="回传图像" name="5">
|
||||||
|
<div class="back-image">
|
||||||
|
<div v-for="item in detailInfo.pictureList" :key="item.time" class="picture-list-item">
|
||||||
|
<div class="picture-item-image">
|
||||||
|
<el-image
|
||||||
|
style="width: 40px; height: 40px"
|
||||||
|
:src="item.url"
|
||||||
|
:preview-src-list="[item.url]">
|
||||||
|
</el-image>
|
||||||
|
</div>
|
||||||
|
<div class="picture-item-info">
|
||||||
|
<div>拍摄任务:{{item.taskName}} | 拍摄载荷:{{item.loaderName}}</div>
|
||||||
|
<div>拍摄时间:{{item.time}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="picture-command">
|
||||||
|
<i class="iconfont icon-dt-icon-dingwei" @click="lockHistoryPicture(item)"></i>
|
||||||
|
<i class="iconfont icon-quanjushijiao-copy" @click="toggleHistoryPicture(item)"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-collapse-item>
|
||||||
|
</el-collapse>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dt-card>
|
||||||
|
|
||||||
|
|
||||||
|
<dt-dialog
|
||||||
|
:title="taskLineDetail.title"
|
||||||
|
top="20vh"
|
||||||
|
width="60vw"
|
||||||
|
:visible.sync="taskLineDetail.visible"
|
||||||
|
append-to-body
|
||||||
|
>
|
||||||
|
<div class="task-line-detail">
|
||||||
|
<el-table
|
||||||
|
:data="taskLineDetail.data"
|
||||||
|
height="100%"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
type="index"
|
||||||
|
width="50">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="startLon"
|
||||||
|
label="起点经度">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="startLat"
|
||||||
|
label="起点纬度">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="startHeight"
|
||||||
|
label="起点相对高度">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="startAlt"
|
||||||
|
label="起点海拔高度">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="endLon"
|
||||||
|
label="终点经度">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="endLat"
|
||||||
|
label="终点纬度">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="endHeight"
|
||||||
|
label="终点相对高度">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="endAlt"
|
||||||
|
label="终点海拔高度">
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</dt-dialog>
|
||||||
|
|
||||||
|
<dt-loading :visible="loadingCount > 0"></dt-loading>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script src="./index.js"></script>
|
||||||
|
<style src="./index.scss" lang="scss" scoped></style>
|
||||||
419
frontend/src/views/home/components/device-manage/uavTarget.js
Normal file
419
frontend/src/views/home/components/device-manage/uavTarget.js
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
import * as DT from 'dt-sdk'
|
||||||
|
import { viewer } from '@/components/dt-scene'
|
||||||
|
export default class UavTarget {
|
||||||
|
planLines = new DT.Cesium.AssociativeArray()
|
||||||
|
uavEntity = null
|
||||||
|
_options = {}
|
||||||
|
loaderPicture = {}
|
||||||
|
positions = []
|
||||||
|
startAltitude = 0
|
||||||
|
constructor(viewer, options) {
|
||||||
|
this.viewer = viewer
|
||||||
|
this._options = options
|
||||||
|
this.jobId = options.jobId
|
||||||
|
this.uavId = options.uavId
|
||||||
|
this.jobName = options.jobName
|
||||||
|
this.startAltitude = options.startAltitude
|
||||||
|
|
||||||
|
this.addPlanLine(options.airlineList)
|
||||||
|
this.addUav(options)
|
||||||
|
this.addUavLoader(options.payloadList)
|
||||||
|
}
|
||||||
|
addUav(info) {
|
||||||
|
let that = this
|
||||||
|
let position = DT.Cesium.Cartesian3.fromDegrees(info.startLon, info.startLat, info.startHeight)
|
||||||
|
if (info.trailList && info.trailList.length > 0) {
|
||||||
|
info.trailList.forEach(route => {
|
||||||
|
this.positions.push(DT.Cesium.Cartesian3.fromDegrees(route.lon, route.lat, route.height))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.positions.push(position.clone())
|
||||||
|
this.positions.push(position.clone())
|
||||||
|
}
|
||||||
|
let currentPosition = this.positions[this.positions.length - 1].clone()
|
||||||
|
let id = `${this.jobId}~${this.uavId}-uav`
|
||||||
|
this.uavEntity = this.viewer.entities.add({
|
||||||
|
id,
|
||||||
|
position: currentPosition,
|
||||||
|
// label: {
|
||||||
|
// text: info.uavName,
|
||||||
|
// font: '14px sans-serif',
|
||||||
|
// fillColor: DT.Cesium.Color.WHITE,
|
||||||
|
// horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT,
|
||||||
|
// verticalOrigin: DT.Cesium.VerticalOrigin.CENTER,
|
||||||
|
// disableDepthTestDistance: 10000,
|
||||||
|
// pixelOffset: new DT.Cesium.Cartesian2(10, 0),
|
||||||
|
// showBackground: true,
|
||||||
|
// scaleByDistance: new DT.Cesium.NearFarScalar(0, 1, 1, 0.8),
|
||||||
|
// distanceDisplayCondition: new DT.Cesium.DistanceDisplayCondition(0, 20000),
|
||||||
|
// backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'),
|
||||||
|
// style: DT.Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
// },
|
||||||
|
// model: {
|
||||||
|
// uri: process.env.BASE_URL + 'model/uav.gltf',
|
||||||
|
// // scale: 1,
|
||||||
|
// minimumPixelSize: 32,
|
||||||
|
// maximumScale: 128,
|
||||||
|
// },
|
||||||
|
polyline: {
|
||||||
|
positions: new DT.Cesium.CallbackProperty(function () {
|
||||||
|
return that.positions
|
||||||
|
}, false),
|
||||||
|
width: 2,
|
||||||
|
zIndex: 6,
|
||||||
|
material: DT.Cesium.Color.CYAN,
|
||||||
|
depthFailMaterial: DT.Cesium.Color.CYAN,
|
||||||
|
arcType: DT.Cesium.ArcType.NONE
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
updateCurrentPosition(position) {
|
||||||
|
this.uavEntity.position = position.clone()
|
||||||
|
this.positions.push(position.clone())
|
||||||
|
}
|
||||||
|
addUavLoader(data) {
|
||||||
|
let loaderPicture = {}
|
||||||
|
data.forEach(loader => {
|
||||||
|
loaderPicture[loader.payloadId] = []
|
||||||
|
let key = 'imageList'
|
||||||
|
if (loader.imageHighList && loader.imageHighList.length > 0) {
|
||||||
|
key = 'imageHighList'
|
||||||
|
}
|
||||||
|
if (loader[key] && loader[key].length > 0) {
|
||||||
|
console.log('这是哈222', loader.imageList)
|
||||||
|
loader[key].forEach((image, imageIndex) => {
|
||||||
|
let obj = {
|
||||||
|
picture: null,
|
||||||
|
fileId: image.fileId,
|
||||||
|
markArr: []
|
||||||
|
}
|
||||||
|
// let cby_bg_data=[
|
||||||
|
// image.left1Lon, image.left1Lat,
|
||||||
|
// image.left2Lon, image.left2Lat,
|
||||||
|
// image.right2Lon, image.right2Lat,
|
||||||
|
// image.right1Lon, image.right1Lat,
|
||||||
|
// ]
|
||||||
|
// obj.picture = this.viewer.entities.add({
|
||||||
|
// id: `${this.jobId}~${this.uavId}~${loader.payloadId}~${image.fileId}-picture`,
|
||||||
|
// name: '背景',
|
||||||
|
// polygon: {
|
||||||
|
// // hierarchy: DT.Cesium.Cartesian3.fromDegreesArrayHeights(cby_bg_data),
|
||||||
|
// hierarchy: DT.Cesium.Cartesian3.fromDegreesArray(cby_bg_data),
|
||||||
|
// perPositionHeight: true,
|
||||||
|
// material: new DT.Cesium.ImageMaterialProperty({
|
||||||
|
// image: window.config.imagePath + image.relativePath,
|
||||||
|
// // image: process.env.BASE_URL + 'static/img/ttt.tif',
|
||||||
|
// // image: process.env.BASE_URL + 'static/img/pic.png',
|
||||||
|
// }),//new Cesium.Color(0.29, 0.85, 0.89, 0.5), //Cesium.Color.PALETURQUOISE.withAlpha(0.5),
|
||||||
|
// outline: true,
|
||||||
|
// outlineColor: DT.Cesium.Color.WHITE,
|
||||||
|
// outlineWidth: 2, //很多电脑当宽度>1时,没用
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
let minLon = Math.min(image.left1Lon, image.left2Lon, image.right1Lon, image.right2Lon)
|
||||||
|
let maxLon = Math.max(image.left1Lon, image.left2Lon, image.right1Lon, image.right2Lon)
|
||||||
|
let minLat = Math.min(image.left1Lat, image.left2Lat, image.right1Lat, image.right2Lat)
|
||||||
|
let maxLat = Math.max(image.left1Lat, image.left2Lat, image.right1Lat, image.right2Lat)
|
||||||
|
if (maxLat - minLat > 0 && maxLon - minLon > 0) {
|
||||||
|
let rectangle = DT.Cesium.Rectangle.fromDegrees(minLon, minLat, maxLon, maxLat)
|
||||||
|
let layer = new DT.Cesium.SingleTileImageryProvider({
|
||||||
|
url: window.config.imagePath + image.relativePath,
|
||||||
|
rectangle
|
||||||
|
})
|
||||||
|
let addLayer = this.viewer.cesiumViewer.imageryLayers.addImageryProvider(layer)
|
||||||
|
// 设置分屏显示
|
||||||
|
addLayer.splitDirection = DT.Cesium.ImagerySplitDirection.LEFT
|
||||||
|
obj.picture = addLayer
|
||||||
|
if (image.itemList) {
|
||||||
|
image.itemList.forEach( (mark, markIndex) => {
|
||||||
|
let markId = `${this.jobId}~${this.uavId}~${loader.payloadId}~${image.fileId}~${mark.id}-mark${imageIndex}${markIndex}`
|
||||||
|
let markPosition = DT.Cesium.Cartesian3.fromDegrees(mark.left1Lon, mark.left1Lat, 1)
|
||||||
|
let markArr = [
|
||||||
|
mark.left1Lon, mark.left1Lat, 1,
|
||||||
|
mark.left2Lon, mark.left2Lat, 1,
|
||||||
|
mark.right2Lon, mark.right2Lat, 1,
|
||||||
|
mark.right1Lon, mark.right1Lat, 1,
|
||||||
|
mark.left1Lon, mark.left1Lat, 1,
|
||||||
|
]
|
||||||
|
let markLine = this.viewer.entities.add({
|
||||||
|
id: markId,
|
||||||
|
show: true,
|
||||||
|
position: markPosition,
|
||||||
|
label: {
|
||||||
|
text: window.detectType[mark.type],
|
||||||
|
font: '16px sans-serif',
|
||||||
|
fillColor: DT.Cesium.Color.RED,
|
||||||
|
horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT,
|
||||||
|
verticalOrigin: DT.Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: 10000,
|
||||||
|
showBackground: false,
|
||||||
|
backgroundColor: DT.Cesium.Color.BLACK,
|
||||||
|
style: DT.Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
},
|
||||||
|
polyline: {
|
||||||
|
positions: DT.Cesium.Cartesian3.fromDegreesArrayHeights(markArr),
|
||||||
|
// positions: DT.Cesium.Cartesian3.fromDegreesArray(markArr),
|
||||||
|
width: 1,
|
||||||
|
material: DT.Cesium.Color.RED,
|
||||||
|
depthFailMaterial: DT.Cesium.Color.RED,
|
||||||
|
zIndex: 3,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
obj.markArr.push(markLine)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
loaderPicture[loader.payloadId].push(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.loaderPicture = loaderPicture
|
||||||
|
}
|
||||||
|
appendLoaderPicture(image) {
|
||||||
|
// this.removePicture()
|
||||||
|
// this.removePictureItem(image.payloadId, image.airlineId)
|
||||||
|
if (!this.loaderPicture) {
|
||||||
|
this.loaderPicture = {}
|
||||||
|
}
|
||||||
|
if (!this.loaderPicture[image.payloadId]) {
|
||||||
|
this.loaderPicture[image.payloadId] = []
|
||||||
|
}
|
||||||
|
let obj = {
|
||||||
|
picture: null,
|
||||||
|
fileId: image.fileId,
|
||||||
|
airlineId: image.airlineId,
|
||||||
|
markArr: []
|
||||||
|
}
|
||||||
|
let length = this.loaderPicture[image.payloadId].length
|
||||||
|
// obj.picture = this.viewer.entities.add({
|
||||||
|
// id: `${this.jobId}~${this.uavId}~${image.payloadId}~${image.fileId}-picture`,
|
||||||
|
// name: '背景',
|
||||||
|
// polygon: {
|
||||||
|
// // hierarchy: DT.Cesium.Cartesian3.fromDegreesArrayHeights(cby_bg_data),
|
||||||
|
// hierarchy: DT.Cesium.Cartesian3.fromDegreesArray(cby_bg_data),
|
||||||
|
// perPositionHeight: true,
|
||||||
|
// material: new DT.Cesium.ImageMaterialProperty({
|
||||||
|
// image: window.config.imagePath + image.relativePath,
|
||||||
|
// // image: process.env.BASE_URL + 'static/img/ttt.tif',
|
||||||
|
// // image: process.env.BASE_URL + 'static/img/pic.png',
|
||||||
|
// }),//new Cesium.Color(0.29, 0.85, 0.89, 0.5), //Cesium.Color.PALETURQUOISE.withAlpha(0.5),
|
||||||
|
// outline: true,
|
||||||
|
// outlineColor: DT.Cesium.Color.WHITE,
|
||||||
|
// outlineWidth: 2, //很多电脑当宽度>1时,没用
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
let minLon = Math.min(image.left1Lon, image.left2Lon, image.right1Lon, image.right2Lon)
|
||||||
|
let maxLon = Math.max(image.left1Lon, image.left2Lon, image.right1Lon, image.right2Lon)
|
||||||
|
let minLat = Math.min(image.left1Lat, image.left2Lat, image.right1Lat, image.right2Lat)
|
||||||
|
let maxLat = Math.max(image.left1Lat, image.left2Lat, image.right1Lat, image.right2Lat)
|
||||||
|
if (maxLat - minLat > 0 && maxLon - minLon > 0) {
|
||||||
|
let rectangle = DT.Cesium.Rectangle.fromDegrees(minLon, minLat, maxLon, maxLat)
|
||||||
|
let layer = new DT.Cesium.SingleTileImageryProvider({
|
||||||
|
url: window.config.imagePath + image.relativePath,
|
||||||
|
rectangle
|
||||||
|
})
|
||||||
|
|
||||||
|
// console.log('添加的图片', obj.picture)
|
||||||
|
if (image.itemList) {
|
||||||
|
image.itemList.forEach( (mark, markIndex) => {
|
||||||
|
let markId = `${this.jobId}~${this.uavId}~${image.payloadId}~${image.fileId}~${mark.id}-mark${length}${markIndex}`
|
||||||
|
let markPosition = DT.Cesium.Cartesian3.fromDegrees(mark.left1Lon, mark.left1Lat, 1)
|
||||||
|
let markArr = [
|
||||||
|
mark.left1Lon, mark.left1Lat, 1,
|
||||||
|
mark.left2Lon, mark.left2Lat, 1,
|
||||||
|
mark.right2Lon, mark.right2Lat, 1,
|
||||||
|
mark.right1Lon, mark.right1Lat, 1,
|
||||||
|
mark.left1Lon, mark.left1Lat, 1,
|
||||||
|
]
|
||||||
|
let markLine = this.viewer.entities.add({
|
||||||
|
id: markId,
|
||||||
|
show: true,
|
||||||
|
position: markPosition,
|
||||||
|
label: {
|
||||||
|
text: window.detectType[mark.type],
|
||||||
|
font: '16px sans-serif',
|
||||||
|
fillColor: DT.Cesium.Color.RED,
|
||||||
|
horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT,
|
||||||
|
verticalOrigin: DT.Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: 10000,
|
||||||
|
showBackground: false,
|
||||||
|
backgroundColor: DT.Cesium.Color.BLACK,
|
||||||
|
style: DT.Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
scaleByDistance: new DT.Cesium.NearFarScalar(0, 1, 1, 0.8),
|
||||||
|
distanceDisplayCondition: new DT.Cesium.DistanceDisplayCondition(0, 10000),
|
||||||
|
},
|
||||||
|
polyline: {
|
||||||
|
positions: DT.Cesium.Cartesian3.fromDegreesArrayHeights(markArr),
|
||||||
|
// positions: DT.Cesium.Cartesian3.fromDegreesArray(markArr),
|
||||||
|
width: 1,
|
||||||
|
material: DT.Cesium.Color.RED,
|
||||||
|
depthFailMaterial: DT.Cesium.Color.RED,
|
||||||
|
zIndex: 3,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
obj.markArr.push(markLine)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
console.log('删除旧的')
|
||||||
|
layer.readyPromise.then(res => {
|
||||||
|
console.log('回调执行')
|
||||||
|
let addLayer = this.viewer.cesiumViewer.imageryLayers.addImageryProvider(layer)
|
||||||
|
// 设置分屏显示
|
||||||
|
addLayer.splitDirection = DT.Cesium.ImagerySplitDirection.LEFT
|
||||||
|
obj.picture = addLayer
|
||||||
|
setTimeout(() => {
|
||||||
|
this.removePictureItem(image.payloadId, image.airlineId)
|
||||||
|
this.loaderPicture[image.payloadId].push(obj)
|
||||||
|
}, 500)
|
||||||
|
|
||||||
|
})
|
||||||
|
// this.removePictureItem(image.payloadId, image.airlineId)
|
||||||
|
// this.loaderPicture[image.payloadId].push(obj)
|
||||||
|
console.log('push新的')
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
toggleAllLoaderVisible(visible) {
|
||||||
|
for (let key in this.loaderPicture) {
|
||||||
|
this.loaderPicture[key].forEach(item => {
|
||||||
|
item.picture.show = visible
|
||||||
|
item.markArr.forEach(item => {
|
||||||
|
item.show = visible
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toggleLoaderPictureVisible(payloadId,fileId) {
|
||||||
|
console.log('切换显隐', payloadId, fileId)
|
||||||
|
if (this.loaderPicture[payloadId]) {
|
||||||
|
let find = this.loaderPicture[payloadId].find(item => item.fileId + '' === fileId + '')
|
||||||
|
console.log('找到图片了吗', find)
|
||||||
|
if (find) {
|
||||||
|
let status = !find.picture.show
|
||||||
|
console.log('显示状态', status)
|
||||||
|
find.picture.show = status
|
||||||
|
find.markArr.forEach(mark => {
|
||||||
|
mark.show = status
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toggleLoaderPictureActive(payloadId,fileId, active, visible = true) {
|
||||||
|
if (this.loaderPicture[payloadId]) {
|
||||||
|
let find = this.loaderPicture[payloadId].find(item => item.fileId + '' === fileId + '')
|
||||||
|
if (find) {
|
||||||
|
if (active) {
|
||||||
|
find.picture.polygon.outlineColor = DT.Cesium.Color.RED
|
||||||
|
find.picture.show = true
|
||||||
|
find.markArr.forEach(mark => {
|
||||||
|
mark.show = true
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
find.picture.polygon.outlineColor = DT.Cesium.Color.WHITE
|
||||||
|
find.picture.show = visible
|
||||||
|
find.markArr.forEach(mark => {
|
||||||
|
mark.show = visible
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addPlanLine(data) {
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.forEach((item, index) => {
|
||||||
|
let height = Math.max(item.endHeight - 1, 1)
|
||||||
|
item.positions = [item.startLon, item.startLat, item.startHeight + this.startAltitude, item.endLon, item.endLat, item.endHeight + this.startAltitude]
|
||||||
|
let positions = DT.Cesium.Cartesian3.fromDegreesArrayHeights(item.positions)
|
||||||
|
let id = `${this.jobId}~${this.uavId}~${item.id}-planLine-${index}`
|
||||||
|
let line = this.viewer.entities.add({
|
||||||
|
id,
|
||||||
|
position: positions[0],
|
||||||
|
label: {
|
||||||
|
text: `规划航线${index + 1}起点`,
|
||||||
|
disableDepthTestDistance: 10000,
|
||||||
|
font: '14px sans-serif',
|
||||||
|
fillColor: DT.Cesium.Color.RED,
|
||||||
|
horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT,
|
||||||
|
pixelOffset: new DT.Cesium.Cartesian2(10, -15),
|
||||||
|
showBackground: true,
|
||||||
|
scaleByDistance: new DT.Cesium.NearFarScalar(0, 1, 1, 0.8),
|
||||||
|
distanceDisplayCondition: new DT.Cesium.DistanceDisplayCondition(0, 10000),
|
||||||
|
backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(255,255,255,0.6)')
|
||||||
|
},
|
||||||
|
polyline: {
|
||||||
|
show: true,
|
||||||
|
positions,
|
||||||
|
width: 2,
|
||||||
|
zIndex: 0,
|
||||||
|
material: DT.Cesium.Color.RED,
|
||||||
|
depthFailMaterial: DT.Cesium.Color.RED,
|
||||||
|
arcType: DT.Cesium.ArcType.NONE
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.planLines.set(id, line)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removePicture() {
|
||||||
|
for (let key in this.loaderPicture) {
|
||||||
|
this.loaderPicture[key].forEach((item, index) => {
|
||||||
|
if (item.picture) {
|
||||||
|
// this.viewer.entities.remove(item.picture)
|
||||||
|
this.viewer.cesiumViewer.imageryLayers.remove(item.picture)
|
||||||
|
}
|
||||||
|
item.markArr.forEach(mark => {
|
||||||
|
this.viewer.entities.remove(mark)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.loaderPicture = {}
|
||||||
|
}
|
||||||
|
removePictureItem(payloadId, airlineId) {
|
||||||
|
if (this.loaderPicture && this.loaderPicture[payloadId]) {
|
||||||
|
let findIndex = -1
|
||||||
|
this.loaderPicture[payloadId].forEach((item, index) => {
|
||||||
|
if (item.airlineId === airlineId) {
|
||||||
|
if (item.picture) {
|
||||||
|
this.viewer.cesiumViewer.imageryLayers.remove(item.picture)
|
||||||
|
item.markArr.forEach(mark => {
|
||||||
|
this.viewer.entities.remove(mark)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
findIndex = index
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (findIndex > -1) {
|
||||||
|
this.loaderPicture[payloadId].splice(findIndex, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
removeAll() {
|
||||||
|
if (this.uavEntity) {
|
||||||
|
this.viewer.entities.remove(this.uavEntity)
|
||||||
|
this.uavEntity = null
|
||||||
|
}
|
||||||
|
for (let key in this.loaderPicture) {
|
||||||
|
this.loaderPicture[key].forEach((item, index) => {
|
||||||
|
if (item.picture) {
|
||||||
|
// this.viewer.entities.remove(item.picture)
|
||||||
|
this.viewer.cesiumViewer.imageryLayers.remove(item.picture)
|
||||||
|
}
|
||||||
|
item.markArr.forEach(mark => {
|
||||||
|
this.viewer.entities.remove(mark)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.loaderPicture = null
|
||||||
|
this.planLines.values.forEach(item => {
|
||||||
|
this.viewer.entities.remove(item)
|
||||||
|
})
|
||||||
|
this.planLines.removeAll()
|
||||||
|
}
|
||||||
|
destroy() {
|
||||||
|
this.removeAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user