【类 型】:factor

【原  因】:完善 飞行数据统计的1.架次统计  2.飞行轨迹的bug修复
【过  程】:
【影  响】:

# 类型 包含:
# feat:新功能(feature)
# fix:修补bug
# docs:文档(documentation)
# style: 格式(不影响代码运行的变动)
# refactor:重构(即不是新增功能,也不是修改bug的代码变动)
# test:增加测试
# chore:构建过程或辅助工具的变动
This commit is contained in:
szdot 2025-06-22 15:05:06 +08:00
parent bc6bf29da2
commit 6126b9d137
3 changed files with 217 additions and 28 deletions

View File

@ -123,9 +123,18 @@ export default {
}, },
methods: { methods: {
onChange (val) { onChange (val) {
if (Array.isArray(val) && val.length === 2) {
const start = val[0]
const end = new Date(val[1])
end.setHours(23, 59, 59, 999) //
this.internalValue = [start, end]
this.$emit('input', [start, end])
this.$emit('change', [start, end])
} else {
this.$emit('input', val) this.$emit('input', val)
this.$emit('change', val) this.$emit('change', val)
} }
} }
} }
}
</script> </script>

View File

@ -605,7 +605,146 @@ export default {
} }
}, },
/** /**
* @description: 创建飞机轨迹 ps:原理删除之前的轨迹 重新绘制 * @description 清除历史轨迹所有轨迹线和轨迹点的图层与数据源
* @param {Array<string>} lineLayerIds - 轨迹线图层ID数组
* @param {Array<string>} pointLayerIds - 轨迹点图层ID数组
*/
clearHistoryPaths (lineLayerIds = [], pointLayerIds = []) {
if (!this.map) return
// 线
lineLayerIds.forEach(id => {
if (this.map.getLayer(id)) {
this.map.removeLayer(id)
}
if (this.map.getSource(id)) {
this.map.removeSource(id)
}
})
//
pointLayerIds.forEach(id => {
if (this.map.getLayer(id)) {
this.map.removeLayer(id)
}
if (this.map.getSource(id)) {
this.map.removeSource(id)
}
})
},
/**
* @description 根据索引绘制一条历史轨迹的轨迹线和起点圆点
* @param {Array<Array<number>>} pathArray - GPS坐标数组格式为 [[lon, lat, ...], ...]
* @param {number} index - 用于生成图层ID的索引确保每条轨迹ID唯一
*/
drawHistoryPathByIndex (pathArray, index) {
if (!this.map) return
if (!pathArray || pathArray.length === 0) return
const zoomThreshold = 12 // 线
const pointRadius = 6 //
// 线GeoJSON
const lineGeojson = {
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: pathArray
}
}
// GeoJSON
const pointGeojson = {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: pathArray[0]
}
}
// ID
const lineLayerId = `path${index}`
const pointLayerId = `path${index}-point`
// 线
const drawLine = () => {
if (this.map.getSource(lineLayerId)) return
this.map.addSource(lineLayerId, {
type: 'geojson',
data: lineGeojson
})
this.map.addLayer({
id: lineLayerId,
type: 'line',
source: lineLayerId,
layout: {
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': '#3388ff',
'line-width': 3
}
})
}
//
const drawPoint = () => {
if (this.map.getSource(pointLayerId)) return
this.map.addSource(pointLayerId, {
type: 'geojson',
data: pointGeojson
})
this.map.addLayer({
id: pointLayerId,
type: 'circle',
source: pointLayerId,
paint: {
'circle-radius': pointRadius,
'circle-color': '#3388ff',
'circle-stroke-color': '#fff',
'circle-stroke-width': 2
}
})
}
// 线
const updateDisplay = () => {
const zoom = this.map.getZoom()
//
if (!this.map.getSource(pointLayerId)) {
drawPoint()
}
// 线
if (zoom >= zoomThreshold) {
// 线
if (!this.map.getSource(lineLayerId)) {
drawLine()
}
} else {
// 线
if (this.map.getLayer(lineLayerId)) {
this.map.removeLayer(lineLayerId)
}
if (this.map.getSource(lineLayerId)) {
this.map.removeSource(lineLayerId)
}
}
}
//
updateDisplay()
//
this.map.on('zoom', () => {
updateDisplay()
})
},
/**
* @description: 创建飞机轨迹 ps:原理删除之前的轨迹 重新绘制 用于实时轨迹
* @param {arr} coordinatesArray 飞机经纬高度数组 * @param {arr} coordinatesArray 飞机经纬高度数组
*/ */
createPathWithArray (coordinatesArray) { createPathWithArray (coordinatesArray) {
@ -842,6 +981,7 @@ export default {
/** /**
* @description: 镜头跳转 * @description: 镜头跳转
* @param {obj} lonLat {lon:lon,lat:lat} 经纬度 * @param {obj} lonLat {lon:lon,lat:lat} 经纬度
* @param {Number} zoom 地图放大率
*/ */
goto (lonLat, zoom = 18) { goto (lonLat, zoom = 18) {
this.map.flyTo({ this.map.flyTo({

View File

@ -4,6 +4,7 @@
<div class="top-bar"> <div class="top-bar">
<DateRangePicker v-model="dateRange" class="m-r-20 m-b-20" /> <DateRangePicker v-model="dateRange" class="m-r-20 m-b-20" />
<el-radio-group v-model="radioClass"> <el-radio-group v-model="radioClass">
<el-radio-button label="作业架次"></el-radio-button>
<el-radio-button label="飞行时长"></el-radio-button> <el-radio-button label="飞行时长"></el-radio-button>
<el-radio-button label="飞行距离"></el-radio-button> <el-radio-button label="飞行距离"></el-radio-button>
<el-radio-button label="消耗电量"></el-radio-button> <el-radio-button label="消耗电量"></el-radio-button>
@ -39,7 +40,7 @@ export default {
flyDataList: [], flyDataList: [],
selectedPlaneIdArr: this.$store.state.app.toFlyDataIdArr, selectedPlaneIdArr: this.$store.state.app.toFlyDataIdArr,
dateRange: [start, end], dateRange: [start, end],
radioClass: '飞行时长', radioClass: '作业架次',
boxShow: true boxShow: true
} }
}, },
@ -88,6 +89,7 @@ export default {
const groupedData = {} const groupedData = {}
const keyMap = { const keyMap = {
作业架次: () => 1,
飞行时长: (item) => { 飞行时长: (item) => {
if (!item.start_time || !item.end_time) return 0 if (!item.start_time || !item.end_time) return 0
return Math.round((item.end_time - item.start_time) / 60) return Math.round((item.end_time - item.start_time) / 60)
@ -199,41 +201,73 @@ export default {
methods: { methods: {
// //
onMapReady () { onMapReady () {
this.drawAllPathsOnMap() this.drawAllHistoricalPaths()
}, },
// //
drawAllPathsOnMap () { drawAllHistoricalPaths () {
if (!this.$refs.mapbox) return if (!this.$refs.mapbox) return
if (this.flyDataList.length === 0) return
// // id
this.$refs.mapbox.clearMapElements(['path'], ['path']) const lineLayerIds = []
const pointLayerIds = []
// //
this.flyDataList.forEach(item => { this.flyDataList.forEach((item, index) => {
if (!item.gps_path) return let pathArray = item.gps_path
try { try {
const pathArray = JSON.parse(item.gps_path) if (typeof pathArray === 'string') {
if (Array.isArray(pathArray) && pathArray.length > 0) { pathArray = JSON.parse(pathArray)
this.$refs.mapbox.createPathWithArray(pathArray)
} }
} catch (e) { } catch (e) {
console.warn('gps_path 解析失败', item.gps_path) console.warn(`${index + 1}条轨迹 gps_path 解析失败`, e)
return
}
// id
lineLayerIds.push(`path${index}`)
pointLayerIds.push(`path${index}-point`)
})
//
this.$refs.mapbox.clearHistoryPaths(lineLayerIds, pointLayerIds)
//
this.flyDataList.forEach((item, index) => {
let pathArray = item.gps_path
if (typeof pathArray === 'string') {
try {
pathArray = JSON.parse(pathArray)
} catch (e) {
console.warn(`${index + 1}条轨迹 gps_path 解析失败`, e)
return
}
}
if (Array.isArray(pathArray) && pathArray.length > 0) {
this.$refs.mapbox.drawHistoryPathByIndex(pathArray, index)
} }
}) })
// //
if (this.flyDataList.length > 0 && this.flyDataList[0].gps_path) { const firstPath = this.flyDataList[0]?.gps_path
let firstPoint = null
if (firstPath) {
if (typeof firstPath === 'string') {
try { try {
const firstPath = JSON.parse(this.flyDataList[0].gps_path) firstPoint = JSON.parse(firstPath)[0]
if (Array.isArray(firstPath) && firstPath.length > 0) { } catch {
const [lon, lat] = firstPath[0] firstPoint = null
}
} else if (Array.isArray(firstPath)) {
firstPoint = firstPath[0]
}
}
if (firstPoint && Array.isArray(firstPoint) && firstPoint.length >= 2) {
const [lon, lat] = firstPoint
this.$refs.mapbox.goto({ lon, lat }) this.$refs.mapbox.goto({ lon, lat })
} }
} catch (e) {
//
}
}
}, },
// //
async loadFlyData () { async loadFlyData () {
if (this.selectedPlaneIdArr.length === 0) { if (this.selectedPlaneIdArr.length === 0) {
@ -280,7 +314,13 @@ export default {
xAxis: { type: 'category' }, xAxis: { type: 'category' },
yAxis: { yAxis: {
gridIndex: 0, gridIndex: 0,
name: this.radioClass === '飞行时长' ? '分钟' : this.radioClass === '飞行距离' ? '米' : '毫安' name: this.radioClass === '飞行时长'
? '分钟'
: this.radioClass === '飞行距离'
? '米'
: this.radioClass === '消耗电量'
? '毫安'
: '架次'
}, },
grid: { top: '55%' }, grid: { top: '55%' },
series: [ series: [