【类 型】: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,8 +123,17 @@ export default {
},
methods: {
onChange (val) {
this.$emit('input', val)
this.$emit('change', 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('change', val)
}
}
}
}

View File

@ -134,7 +134,7 @@ export default {
//
if (this.enableGuided) {
// longPress
// longPress
let pressTimer = null
let isLongPress = false //
let startPoint = null //
@ -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 飞机经纬高度数组
*/
createPathWithArray (coordinatesArray) {
@ -842,6 +981,7 @@ export default {
/**
* @description: 镜头跳转
* @param {obj} lonLat {lon:lon,lat:lat} 经纬度
* @param {Number} zoom 地图放大率
*/
goto (lonLat, zoom = 18) {
this.map.flyTo({

View File

@ -4,6 +4,7 @@
<div class="top-bar">
<DateRangePicker v-model="dateRange" class="m-r-20 m-b-20" />
<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>
@ -13,7 +14,7 @@
<div class="chart-area" v-if="flyDataList.length">
<div v-if="boxShow" id="main" class="chart-container"></div>
<map-box v-else ref="mapbox" @map-ready="onMapReady" :enableSaveToFile="true" :getData="() => flyDataList"/>
<map-box v-else ref="mapbox" @map-ready="onMapReady" :enableSaveToFile="true" :getData="() => flyDataList" />
</div>
<div v-else class="no-data-tip">暂无数据</div>
</div>
@ -39,7 +40,7 @@ export default {
flyDataList: [],
selectedPlaneIdArr: this.$store.state.app.toFlyDataIdArr,
dateRange: [start, end],
radioClass: '飞行时长',
radioClass: '作业架次',
boxShow: true
}
},
@ -88,6 +89,7 @@ export default {
const groupedData = {}
const keyMap = {
作业架次: () => 1,
飞行时长: (item) => {
if (!item.start_time || !item.end_time) return 0
return Math.round((item.end_time - item.start_time) / 60)
@ -199,41 +201,73 @@ export default {
methods: {
//
onMapReady () {
this.drawAllPathsOnMap()
this.drawAllHistoricalPaths()
},
//
drawAllPathsOnMap () {
//
drawAllHistoricalPaths () {
if (!this.$refs.mapbox) return
if (this.flyDataList.length === 0) return
//
this.$refs.mapbox.clearMapElements(['path'], ['path'])
// id
const lineLayerIds = []
const pointLayerIds = []
//
this.flyDataList.forEach(item => {
if (!item.gps_path) return
//
this.flyDataList.forEach((item, index) => {
let pathArray = item.gps_path
try {
const pathArray = JSON.parse(item.gps_path)
if (Array.isArray(pathArray) && pathArray.length > 0) {
this.$refs.mapbox.createPathWithArray(pathArray)
if (typeof pathArray === 'string') {
pathArray = JSON.parse(pathArray)
}
} 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) {
try {
const firstPath = JSON.parse(this.flyDataList[0].gps_path)
if (Array.isArray(firstPath) && firstPath.length > 0) {
const [lon, lat] = firstPath[0]
this.$refs.mapbox.goto({ lon, lat })
//
const firstPath = this.flyDataList[0]?.gps_path
let firstPoint = null
if (firstPath) {
if (typeof firstPath === 'string') {
try {
firstPoint = JSON.parse(firstPath)[0]
} catch {
firstPoint = null
}
} catch (e) {
//
} 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 })
}
},
//
async loadFlyData () {
if (this.selectedPlaneIdArr.length === 0) {
@ -280,7 +314,13 @@ export default {
xAxis: { type: 'category' },
yAxis: {
gridIndex: 0,
name: this.radioClass === '飞行时长' ? '分钟' : this.radioClass === '飞行距离' ? '米' : '毫安'
name: this.radioClass === '飞行时长'
? '分钟'
: this.radioClass === '飞行距离'
? '米'
: this.radioClass === '消耗电量'
? '毫安'
: '架次'
},
grid: { top: '55%' },
series: [