}) | }) | ||||
} | } | ||||
// 定点飞行 | |||||
export function pointflight(params) { | |||||
return request({ | |||||
url: `/airport/pointflight`, | |||||
method: 'POST', | |||||
params | |||||
}) | |||||
} | |||||
// 预警已确认 | // 预警已确认 | ||||
export function emergencyList(params = { airportFlyType: 2, statusList: 2 }) { | export function emergencyList(params = { airportFlyType: 2, statusList: 2 }) { | ||||
return request({ | return request({ |
import { Style, Icon, Stroke } from 'ol/style' | |||||
import imgGeo from '@/assets/point/geo.png' | |||||
export const styleList = { | |||||
route: new Style({ | |||||
stroke: new Stroke({ | |||||
width: 2, | |||||
color: 'red' | |||||
}) | |||||
}), | |||||
geoMarker: new Style({ | |||||
image: new Icon({ | |||||
anchor: [0.5, 0.5], | |||||
src: imgGeo, | |||||
crossOrigin: '', | |||||
scale: [1, 1], | |||||
rotateWithView: true | |||||
}) | |||||
}), | |||||
lineRoute: new Style({ | |||||
stroke: new Stroke({ | |||||
width: 2, | |||||
color: 'yellow', | |||||
lineDash: [5] | |||||
}) | |||||
}) | |||||
} | |||||
align-items: center; | align-items: center; | ||||
justify-content: space-around; | justify-content: space-around; | ||||
overflow: hidden; | overflow: hidden; | ||||
margin: 0 5px 0 0; | |||||
.crcle__panel{ | .crcle__panel{ | ||||
width: 180px; | width: 180px; | ||||
height: 180px; | height: 180px; |
<template> | |||||
<div class="content" id="myChart"> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import * as echarts from 'echarts' | |||||
import { ref, reactive, toRefs, watch, onMounted } from 'vue' | |||||
export default { | |||||
name: 'Echarts', | |||||
setup(props) { | |||||
const initMyChart = () => { | |||||
const chartDom = document.getElementById('myChart'); | |||||
const myChart = echarts.init(chartDom); | |||||
var option; | |||||
option = { | |||||
legend: { | |||||
top: '12', | |||||
data: ['速度', '高度'], | |||||
icon: 'roundRect', | |||||
itemHeight: 1, | |||||
itemWidth: 31, | |||||
textStyle: { | |||||
color: '#ffffff' | |||||
} | |||||
}, | |||||
grid: { | |||||
top: '60', | |||||
bottom: '23', | |||||
left: '50', | |||||
right: '60' | |||||
}, | |||||
xAxis: { | |||||
type: 'category', | |||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | |||||
show: false | |||||
}, | |||||
yAxis: [ | |||||
{ | |||||
type: 'value', | |||||
name: '速度(m/s)', | |||||
nameTextStyle: { | |||||
color: "rgba(255,255,255,1)" | |||||
}, | |||||
axisLabel: { | |||||
show: true, | |||||
textStyle: { | |||||
color: 'rgba(255,255,255,1)' | |||||
} | |||||
} | |||||
}, | |||||
{ | |||||
type: 'value', | |||||
name: '高度(s)', | |||||
position: "right", | |||||
nameTextStyle: { | |||||
color: "rgba(255,255,255,1)" | |||||
}, | |||||
axisLabel: { | |||||
textStyle: { | |||||
color: "rgba(255,255,255,1)", | |||||
}, | |||||
formatter: "{value}", | |||||
}, | |||||
} | |||||
], | |||||
series: [ | |||||
{ | |||||
name: '速度', | |||||
data: [150, 230, 224, 218, 135, 147, 260], | |||||
type: 'line', | |||||
symbol: 'none', | |||||
smooth: true, | |||||
itemStyle: { | |||||
normal: { | |||||
color: 'rgba(255,141,26,1)', | |||||
width: 2 | |||||
} | |||||
}, | |||||
yAxisIndex: 0, | |||||
}, | |||||
{ | |||||
name: '高度', | |||||
data: [500, 2000, 3000, 1000, 1200, 1300, 2310], | |||||
type: 'line', | |||||
smooth: true, | |||||
symbol: 'none', | |||||
yAxisIndex: 1, | |||||
itemStyle: { | |||||
normal: { | |||||
color: 'rgba(165, 214, 63, 1)', | |||||
width: 2 | |||||
} | |||||
} | |||||
} | |||||
] | |||||
}; | |||||
option && myChart.setOption(option); | |||||
} | |||||
onMounted( | |||||
() => { | |||||
initMyChart() | |||||
}) | |||||
} | |||||
} | |||||
</script> | |||||
<style> | |||||
.content { | |||||
position: absolute; | |||||
bottom: 16px; | |||||
left: 24px; | |||||
background-color: rgba(0, 0, 0, 1); | |||||
width: 734px; | |||||
height: 216px; | |||||
font-size: 16px; | |||||
font-weight: 400; | |||||
color: rgba(255, 255, 255, 1) | |||||
} | |||||
</style> |
<span>{{ statusList[item.status] }}</span> | <span>{{ statusList[item.status] }}</span> | ||||
<n-popconfirm | <n-popconfirm | ||||
v-if="item.status == 1" | v-if="item.status == 1" | ||||
@positive-click="handlePositiveClick(item)" | |||||
@negative-click="handleNegativeClick" | |||||
> | > | ||||
<template #trigger> | <template #trigger> | ||||
<span class="table__operate">执行</span> | <span class="table__operate">执行</span> | ||||
</template> | </template> | ||||
是否立即开始执行任务? | 是否立即开始执行任务? | ||||
</n-popconfirm> | </n-popconfirm> | ||||
<span v-else class="table__operate live">直播</span> | |||||
<span | |||||
v-else | |||||
class="table__operate live" | |||||
@click="liveShow(item)" | |||||
>直播</span> | |||||
</li> | </li> | ||||
</ul> | </ul> | ||||
</div> | </div> | ||||
<script> | <script> | ||||
import { onMounted, reactive, toRefs } from 'vue' | import { onMounted, reactive, toRefs } from 'vue' | ||||
import { useRouter } from 'vue-router' | |||||
import { startOfDay } from 'date-fns/esm' | import { startOfDay } from 'date-fns/esm' | ||||
import { getMissionList, getQuestionList } from '@/api/dashboard/index.js' | import { getMissionList, getQuestionList } from '@/api/dashboard/index.js' | ||||
import { cameraList } from '@/api/basic/monitor.js' | import { cameraList } from '@/api/basic/monitor.js' | ||||
import camera from '@/assets/icon/camera.png' | import camera from '@/assets/icon/camera.png' | ||||
import materials from '@/assets/icon/materials.png' | import materials from '@/assets/icon/materials.png' | ||||
import personnel from '@/assets/icon/personnel.png' | import personnel from '@/assets/icon/personnel.png' | ||||
import { implement } from '@/api/task/index.js' | |||||
const ICON_LIST = { | const ICON_LIST = { | ||||
'002000': problemSpot_icon, | '002000': problemSpot_icon, | ||||
'002001': deadTree_icon, | '002001': deadTree_icon, | ||||
name: 'MapExtend', | name: 'MapExtend', | ||||
emits: ['send'], | emits: ['send'], | ||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
const router = useRouter() | |||||
const data = reactive({ | const data = reactive({ | ||||
selectedTab: 0, | selectedTab: 0, | ||||
extendList: [ | extendList: [ | ||||
emit('send', { tabs: data.selectedTab, data: ques.message, type: value, ops: 'select' }) | emit('send', { tabs: data.selectedTab, data: ques.message, type: value, ops: 'select' }) | ||||
} | } | ||||
/** | |||||
* 展示直播视频 | |||||
*/ | |||||
const liveShow = (rowInfo) => { | |||||
rowInfo = JSON.stringify(rowInfo) | |||||
router.push({ | |||||
path: '/taskManage/all', | |||||
query: { rowInfo: rowInfo } | |||||
}) | |||||
} | |||||
return { | return { | ||||
...toRefs(data), | ...toRefs(data), | ||||
...toRefs(warn), | ...toRefs(warn), | ||||
handlePageChange, | handlePageChange, | ||||
handleDateChange, | handleDateChange, | ||||
handleWarnChange, | handleWarnChange, | ||||
handleQuesChange | |||||
handleQuesChange, | |||||
handlePositiveClick(row) { | |||||
$message.info('机场设备开始自检,请稍等') | |||||
implement(row.id).then((res) => { | |||||
if (res.code === 0) { | |||||
$message.info('操作成功') | |||||
} | |||||
}) | |||||
}, | |||||
handleNegativeClick() {}, | |||||
liveShow | |||||
} | } | ||||
} | } | ||||
} | } |
<p class="alarm-title">机场调度</p> | <p class="alarm-title">机场调度</p> | ||||
<p class="dispatch-detail"> | <p class="dispatch-detail"> | ||||
<span>选择机场:</span> | <span>选择机场:</span> | ||||
<n-select v-model:value="airValue" placeholder="请选择机场" :options="airpotOptions" /> | |||||
<n-select v-model:value="airportId" placeholder="请选择机场" :options="airpotOptions" /> | |||||
<a @click="checkAirport">可用机场列表</a> | <a @click="checkAirport">可用机场列表</a> | ||||
</p> | </p> | ||||
<p class="dispatch-detail"> | <p class="dispatch-detail"> | ||||
<li v-for="(item, index) in recoedList" :key="index"> | <li v-for="(item, index) in recoedList" :key="index"> | ||||
<span class="task-time">{{ item.time }}</span> | <span class="task-time">{{ item.time }}</span> | ||||
<span class="task-name">{{ item.name }}</span> | <span class="task-name">{{ item.name }}</span> | ||||
<span v-if="item.statusNum === 1" class="task-status on-fly">{{ item.status }}</span> | |||||
<span v-if="item.statusNum === 2" class="task-status on-fly" @click="handleExecute(item.emergencyMissionId)">{{ item.status }}</span> | |||||
<span v-else class="task-status">{{ item.status }}</span> | <span v-else class="task-status">{{ item.status }}</span> | ||||
</li> | </li> | ||||
</ul> | </ul> | ||||
import { reactive, toRefs, watch } from 'vue' | import { reactive, toRefs, watch } from 'vue' | ||||
import { EARLY_SOURCE, TASK_STATUS } from '@/utils/dictionary.js' | import { EARLY_SOURCE, TASK_STATUS } from '@/utils/dictionary.js' | ||||
import { getWarningRecord, getWarningInfo, ignoreWarning, confirmWarning } from '@/api/dashboard/index.js' | |||||
import { getWarningRecord, getWarningInfo, ignoreWarning, confirmWarning, pointflight } from '@/api/dashboard/index.js' | |||||
// turf 用于简单的空间计算 | // turf 用于简单的空间计算 | ||||
import * as turf from '@turf/turf' | import * as turf from '@turf/turf' | ||||
export default { | export default { | ||||
airportShow: false, | airportShow: false, | ||||
warningInfo: {}, | warningInfo: {}, | ||||
airportSelect: '', | airportSelect: '', | ||||
airValue: 0, | |||||
airportId: null, | |||||
warningPic: null, | warningPic: null, | ||||
recoedList: [], | recoedList: [], | ||||
warningShow: false, | warningShow: false, | ||||
}) | }) | ||||
data.fireDetail.time = value?.createTime | data.fireDetail.time = value?.createTime | ||||
Promise.all([await getWarningInfo(value.id), await getWarningRecord({ warningId: value.id })]) | |||||
.then(([info, record]) => { | |||||
// 分析后的图片 | |||||
data.warningPic = info?.data?.fileMarkerUrl || null | |||||
// 任务id | |||||
data.missionId = info?.data?.missionId || null | |||||
showUsableAirport(info) | |||||
showWarningRecord(record) | |||||
}) | |||||
.catch(err => { | |||||
console.log(err) | |||||
}) | |||||
getRecord(value.id) | |||||
getAirport(value.id) | |||||
} | |||||
// 获取记录 | |||||
const getAirport = async(id) => { | |||||
const info = await getWarningInfo(id) | |||||
if (info.code === 0) { | |||||
// 分析后的图片 | |||||
data.warningPic = info?.data?.fileMarkerUrl || null | |||||
// 任务id | |||||
data.missionId = info?.data?.missionId | |||||
showUsableAirport(info) | |||||
} | |||||
} | |||||
// 获取记录 | |||||
const getRecord = async(id) => { | |||||
const record = await getWarningRecord({ warningId: id }) | |||||
if (record.code === 0) { | |||||
showWarningRecord(record) | |||||
} | |||||
} | } | ||||
// 预警记录列表 | // 预警记录列表 | ||||
const showWarningRecord = (record) => { | const showWarningRecord = (record) => { | ||||
// 清空原来的应急任务列表 | |||||
data.recoedList.length = 0 | data.recoedList.length = 0 | ||||
var status = '' | var status = '' | ||||
var statusNum = 0 | var statusNum = 0 | ||||
} | } | ||||
}) | }) | ||||
data.recoedList.push({ | data.recoedList.push({ | ||||
// 应急任务创建时间 | |||||
time: item.createTime, | time: item.createTime, | ||||
// 应急任务名称 | |||||
name: item.name, | name: item.name, | ||||
// 状态 | |||||
status: status, | status: status, | ||||
statusNum: statusNum | |||||
// 状态编号 | |||||
statusNum: statusNum, | |||||
// 应急任务id | |||||
emergencyMissionId: item.emergencyMissionId | |||||
}) | }) | ||||
}) | }) | ||||
} | } | ||||
label: item.name | label: item.name | ||||
}) | }) | ||||
}) | }) | ||||
data.airValue = data.airpotOptions[0]?.value || null | |||||
data.airportId = data.airpotOptions[0]?.value || null | |||||
} | } | ||||
const checkAirport = () => { | const checkAirport = () => { | ||||
data.warningShow = false | data.warningShow = false | ||||
} | } | ||||
const test = () => { | |||||
handleExecute() | |||||
console.log(data.warningInfo) | |||||
const test = async() => { | |||||
var airportName = '' | |||||
data.airpotOptions?.map((item) => { | |||||
if (item.value === data.airportId) { | |||||
airportName = item.label | |||||
} | |||||
}) | |||||
const res = await pointflight({ | |||||
airportId: parseInt(data.airportId), | |||||
airportName: airportName, | |||||
warningId: parseInt(data.warningInfo?.id), | |||||
missionId: parseInt(data.missionId), | |||||
alt: String(data.flyHeight), | |||||
lon: String(data.warningInfo.lng), | |||||
lat: String(data.warningInfo.lat) | |||||
}) | |||||
if (res.code === 0) { | |||||
getRecord(parseInt(data.warningInfo?.id)) | |||||
handleExecute(parseInt(data.missionId)) | |||||
} | |||||
} | } | ||||
// 忽略预警 | // 忽略预警 | ||||
return value + 'm' | return value + 'm' | ||||
} | } | ||||
const handleExecute = () => { | |||||
emit('start') | |||||
const handleExecute = (id) => { | |||||
// console.log(id) | |||||
emit('start', id) | |||||
} | } | ||||
return { | return { |
<fire-alarm ref="Warning" :data="warningDetail" :airport="airportsAll" @start="handleExecute" /> | <fire-alarm ref="Warning" :data="warningDetail" :airport="airportsAll" @start="handleExecute" /> | ||||
<WarningDrawer v-model:visible="drawerShow" /> | <WarningDrawer v-model:visible="drawerShow" /> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import * as control from 'ol/control' | import * as control from 'ol/control' | ||||
import uav_icon from '@/assets/images/airport.png' | import uav_icon from '@/assets/images/airport.png' | ||||
import warningIcon from '@/assets/gis/images/fire.png' | import warningIcon from '@/assets/gis/images/fire.png' | ||||
import { reactive, toRefs, onMounted, computed, ref, watch, onBeforeUnmount } from 'vue' | |||||
import { reactive, toRefs, onMounted, computed, ref, watch, onBeforeUnmount, provide } from 'vue' | |||||
import { Point } from 'ol/geom' | import { Point } from 'ol/geom' | ||||
import { | import { | ||||
airportList, getWarning | airportList, getWarning | ||||
warningList: [], | warningList: [], | ||||
warningLayers: [], | warningLayers: [], | ||||
warningDetail: {}, | warningDetail: {}, | ||||
drawerShow: false | |||||
drawerShow: false, | |||||
missionId: 0 | |||||
}) | }) | ||||
const getMapOptions = computed(() => { | const getMapOptions = computed(() => { | ||||
monitorVideo.value?.disposeVideo() | monitorVideo.value?.disposeVideo() | ||||
} | } | ||||
const handleExecute = () => { | |||||
let abc = ref() | |||||
const handleExecute = (id) => { | |||||
data.drawerShow = true | data.drawerShow = true | ||||
abc = id | |||||
provide('test', abc) | |||||
} | } | ||||
onMounted(() => { | onMounted(() => { | ||||
hideProblemInfo, | hideProblemInfo, | ||||
getMaxZOverlay, | getMaxZOverlay, | ||||
Warning, | Warning, | ||||
handleExecute | |||||
handleExecute, | |||||
abc | |||||
} | } | ||||
} | } | ||||
} | } |
<template> | |||||
<div id="myChart" class="my-chart" /> | |||||
</template> | |||||
<script> | |||||
import * as echarts from 'echarts' | |||||
import { onMounted, reactive, toRefs, watch } from 'vue' | |||||
export default { | |||||
name: 'SpeedChart', | |||||
props: { | |||||
data: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
setup(props) { | |||||
const data = reactive({ | |||||
myChart: null, | |||||
chartOption: {}, | |||||
chartDom: null, | |||||
chartData: {} | |||||
}) | |||||
watch(() => props.data, (value) => { | |||||
if (JSON.stringify(value) !== '{}') { | |||||
data.chartData = value | |||||
data.myChart.dispose() | |||||
initChart() | |||||
} | |||||
}) | |||||
const initChart = () => { | |||||
data.chartDom = document.getElementById('myChart') | |||||
data.myChart = echarts.init(data.chartDom) | |||||
data.chartOption = { | |||||
legend: { | |||||
top: '12', | |||||
data: ['速度', '高度'], | |||||
icon: 'roundRect', | |||||
itemHeight: 1, | |||||
itemWidth: 31, | |||||
textStyle: { | |||||
color: '#ffffff' | |||||
} | |||||
}, | |||||
grid: { | |||||
top: '60', | |||||
bottom: '23', | |||||
left: '50', | |||||
right: '60' | |||||
}, | |||||
xAxis: { | |||||
type: 'category', | |||||
data: [0, 1], | |||||
show: false | |||||
}, | |||||
yAxis: [ | |||||
{ | |||||
type: 'value', | |||||
name: '速度(m/s)', | |||||
nameTextStyle: { | |||||
color: 'rgba(255,255,255,1)' | |||||
}, | |||||
axisLabel: { | |||||
show: true, | |||||
textStyle: { | |||||
color: 'rgba(255,255,255,1)' | |||||
} | |||||
} | |||||
}, | |||||
{ | |||||
type: 'value', | |||||
name: '高度(s)', | |||||
position: 'right', | |||||
nameTextStyle: { | |||||
color: 'rgba(255,255,255,1)' | |||||
}, | |||||
axisLabel: { | |||||
textStyle: { | |||||
color: 'rgba(255,255,255,1)' | |||||
}, | |||||
formatter: '{value}' | |||||
} | |||||
} | |||||
], | |||||
series: [ | |||||
{ | |||||
name: '速度', | |||||
data: data.chartData?.speed, | |||||
type: 'line', | |||||
symbol: 'none', | |||||
smooth: true, | |||||
itemStyle: { | |||||
normal: { | |||||
color: 'rgba(255,141,26,1)', | |||||
width: 2 | |||||
} | |||||
}, | |||||
yAxisIndex: 0 | |||||
}, | |||||
{ | |||||
name: '高度', | |||||
data: data.chartData?.alt, | |||||
type: 'line', | |||||
smooth: true, | |||||
symbol: 'none', | |||||
yAxisIndex: 1, | |||||
itemStyle: { | |||||
normal: { | |||||
color: 'rgba(165, 214, 63, 1)', | |||||
width: 2 | |||||
} | |||||
} | |||||
} | |||||
] | |||||
} | |||||
data.myChart.setOption(data.chartOption) | |||||
} | |||||
onMounted( | |||||
() => { | |||||
initChart() | |||||
}) | |||||
return { | |||||
...toRefs(data) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style> | |||||
.my-chart { | |||||
position: relative; | |||||
z-index: 99; | |||||
background-color: rgba(0, 0, 0, 1); | |||||
width: 734px; | |||||
height: 220px; | |||||
font-size: 16px; | |||||
font-weight: 400; | |||||
color: rgba(255, 255, 255, 1); | |||||
margin: 0 5px 0 0; | |||||
} | |||||
</style> |
</template> | </template> | ||||
<script> | <script> | ||||
import { Map, View } from 'ol' | |||||
import { XYZ } from 'ol/source' | |||||
import { reactive, toRefs, onMounted, computed, watch, onBeforeUnmount, inject, ref } from 'vue' | |||||
import { Map, View, Feature } from 'ol' | |||||
import 'ol/ol.css' | |||||
import { Tile, Vector as VectorLayer } from 'ol/layer' | |||||
import TileWMS from 'ol/source/TileWMS.js' | import TileWMS from 'ol/source/TileWMS.js' | ||||
import { Tile } from 'ol/layer' | |||||
import { transform } from 'ol/proj' | |||||
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 * as control from 'ol/control' | import * as control from 'ol/control' | ||||
import { reactive, toRefs, onMounted, computed, ref, onBeforeUnmount } from 'vue' | |||||
import { styleList } from '@/utils/style.js' | |||||
import { getTrackList } from '@/api/task/index.js' | |||||
export default { | export default { | ||||
name: 'OneMap', | |||||
name: 'UnderLay', | |||||
props: { | props: { | ||||
id: { | id: { | ||||
type: String, | type: String, | ||||
default: 'underlay' | default: 'underlay' | ||||
}, | |||||
data: { | |||||
type: Number, | |||||
default: 0 | |||||
} | } | ||||
}, | }, | ||||
setup(props) { | setup(props) { | ||||
const monitorVideo = ref() | |||||
const data = reactive({ | const data = reactive({ | ||||
map: null, | map: null, | ||||
drawerShow: false | |||||
drawerShow: false, | |||||
trackLayer: null, | |||||
trackInfo: null, | |||||
// 轨迹数据 | |||||
trackList: [], | |||||
id: 0 | |||||
}) | }) | ||||
const getMapOptions = computed(() => { | const getMapOptions = computed(() => { | ||||
} | } | ||||
}) | }) | ||||
let abc = ref() | |||||
abc = inject('test') | |||||
watch(() => abc, (value) => { | |||||
if (value) { | |||||
console.log('hhh', value) | |||||
} else { | |||||
console.log('hhh', value) | |||||
} | |||||
// getTrackData(id).then(res => { | |||||
// if (res.trackList.length > 0) { | |||||
// initTrack(formatTradeList(res.trackList), 'route') | |||||
// } | |||||
// }) | |||||
}) | |||||
/** | /** | ||||
* 初始化地图 | * 初始化地图 | ||||
*/ | */ | ||||
wmsSource.setOpacity(0.3) | wmsSource.setOpacity(0.3) | ||||
} | } | ||||
/* 获取轨迹数据 */ | |||||
const getTrackData = async function(id) { | |||||
const res = await getTrackList(id) | |||||
const trackList = res.data | |||||
data.trackList = trackList | |||||
// const trackList = data.trackList | |||||
return Promise.resolve({ | |||||
trackList | |||||
}) | |||||
} | |||||
/* 处理轨迹列表 */ | |||||
const formatTradeList = function(trackList) { | |||||
return trackList.map((item) => | |||||
fromLonLat([parseFloat(item.lng), parseFloat(item.lat)]) | |||||
) | |||||
} | |||||
/* 初始化轨迹 */ | |||||
const initTrack = function(coordinate, 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.mapData.addLayer(vectorLayer) | |||||
data.mapView.fit(route, { padding: [50, 50, 50, 50] }) | |||||
vectorLayer.on('postrender', moveFeature.bind()) | |||||
function moveFeature(event) { | |||||
/* 计算飞行的百分比 */ | |||||
const percent = data.videoInfo.currentTime / data.videoInfo.duration | |||||
const currentCoordinate = route.getCoordinateAt(percent) | |||||
position.setCoordinates(currentCoordinate) | |||||
geoMarker.setGeometry(null) | |||||
const vectorContext = getVectorContext(event) | |||||
vectorContext.setStyle(styleList['geoMarker']) | |||||
vectorContext.drawGeometry(position) | |||||
data.mapData?.render() | |||||
} | |||||
} | |||||
onMounted(() => { | onMounted(() => { | ||||
initMap() | initMap() | ||||
}) | }) | ||||
onBeforeUnmount(() => { | onBeforeUnmount(() => { | ||||
monitorVideo.value?.disposeVideo() | |||||
}) | }) | ||||
return { | return { |
<p class="side__title">操作</p> | <p class="side__title">操作</p> | ||||
<div class="side__control"> | <div class="side__control"> | ||||
<n-button>抛投</n-button> | <n-button>抛投</n-button> | ||||
<n-button>喊话</n-button> | |||||
<n-button @click="fanhang">喊话</n-button> | |||||
<n-button @click="handleOperate">{{ operate }}</n-button> | <n-button @click="handleOperate">{{ operate }}</n-button> | ||||
<n-button @click="handleControl">{{ control }}</n-button> | <n-button @click="handleControl">{{ control }}</n-button> | ||||
<n-button class="control__special" round @click="handleBack">返航</n-button> | <n-button class="control__special" round @click="handleBack">返航</n-button> | ||||
</div> | </div> | ||||
<div class="control__panel"> | <div class="control__panel"> | ||||
<ControlPanel v-if="showControl" mode="camera" /> | |||||
<ControlPanel v-if="showControl" mode="locus" /> | |||||
<SpeedChart :data="chartData" /> | |||||
<ControlPanel v-if="showControl" mode="camera" @start="startOrder" @reset="endOrder" /> | |||||
<ControlPanel v-if="showControl" mode="locus" @start="startOrder" @reset="endOrder" /> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div ref="mapRef" class="warn__back"> | <div ref="mapRef" class="warn__back"> | ||||
<Underlay /> | <Underlay /> | ||||
<div ref="videoRef" class="inner"> | <div ref="videoRef" class="inner"> | ||||
111111111111 | 111111111111 | ||||
</div> | </div> | ||||
<Echarts/> | |||||
</n-drawer-content> | </n-drawer-content> | ||||
</n-drawer> | </n-drawer> | ||||
</template> | </template> | ||||
import { defineComponent, ref, reactive, toRefs, computed, watch, nextTick } from 'vue' | import { defineComponent, ref, reactive, toRefs, computed, watch, nextTick } from 'vue' | ||||
import Underlay from './Underlay.vue' | import Underlay from './Underlay.vue' | ||||
import ControlPanel from './ControlPanel.vue' | import ControlPanel from './ControlPanel.vue' | ||||
import Echarts from './Echarts.vue' | |||||
import SpeedChart from './SpeedChart.vue' | |||||
export default defineComponent({ | export default defineComponent({ | ||||
name: 'WarningDrawer', | name: 'WarningDrawer', | ||||
components: { Underlay, ControlPanel,Echarts }, | |||||
components: { Underlay, ControlPanel, SpeedChart }, | |||||
props: { | props: { | ||||
/* 可见 */ | /* 可见 */ | ||||
visible: { | visible: { | ||||
data: { | data: { | ||||
type: Object, | type: Object, | ||||
default: () => {} | default: () => {} | ||||
}, | |||||
id: { | |||||
type: Number, | |||||
default: 0 | |||||
} | } | ||||
}, | }, | ||||
emits: { | emits: { | ||||
const sideRef = ref() | const sideRef = ref() | ||||
const mapRef = ref() | const mapRef = ref() | ||||
const videoRef = ref() | const videoRef = ref() | ||||
const data = reactive({ | const data = reactive({ | ||||
hasChanged: false, | hasChanged: false, | ||||
showControl: false, | showControl: false, | ||||
operate: '悬停', | operate: '悬停', | ||||
control: '手动控制' | |||||
control: '手动控制', | |||||
chartData: {}, | |||||
missionId: 0 | |||||
}) | }) | ||||
/* 获取抽屉的信息 */ | /* 获取抽屉的信息 */ | ||||
window.dispatchEvent(new Event('resize')) | window.dispatchEvent(new Event('resize')) | ||||
} | } | ||||
const fanhang = () => { | |||||
data.chartData = { | |||||
speed: [300, 200], | |||||
alt: [500, 510] | |||||
} | |||||
} | |||||
const startOrder = (params) => { | |||||
console.log(params) | |||||
} | |||||
const endOrder = (params) => { | |||||
console.log(params) | |||||
} | |||||
watch(() => props.visible, (value) => { | watch(() => props.visible, (value) => { | ||||
if (value) { | if (value) { | ||||
nextTick(() => { | nextTick(() => { | ||||
} | } | ||||
}) | }) | ||||
watch(() => props.id, (id) => { | |||||
if (id) { | |||||
data.missionId = id | |||||
console.log(data.missionId) | |||||
} | |||||
}) | |||||
const handleOperate = () => { | const handleOperate = () => { | ||||
data.operate = data.operate === '悬停' ? '继续飞行' : '悬停' | data.operate = data.operate === '悬停' ? '继续飞行' : '悬停' | ||||
} | } | ||||
handleChange, | handleChange, | ||||
handleOperate, | handleOperate, | ||||
handleControl, | handleControl, | ||||
handleBack | |||||
handleBack, | |||||
fanhang, | |||||
startOrder, | |||||
endOrder | |||||
} | } | ||||
} | } | ||||
}) | }) | ||||
} | } | ||||
} | } | ||||
.control__panel{ | |||||
.control__panel { | |||||
position: absolute; | position: absolute; | ||||
bottom: 0; | bottom: 0; | ||||
display: flex; | display: flex; |