【类 型】:factor
【原 因】:完善 飞行数据统计的1.架次统计 2.飞行轨迹的bug修复 【过 程】: 【影 响】: # 类型 包含: # feat:新功能(feature) # fix:修补bug # docs:文档(documentation) # style: 格式(不影响代码运行的变动) # refactor:重构(即不是新增功能,也不是修改bug的代码变动) # test:增加测试 # chore:构建过程或辅助工具的变动
This commit is contained in:
parent
bc6bf29da2
commit
6126b9d137
@ -123,8 +123,17 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onChange (val) {
|
onChange (val) {
|
||||||
this.$emit('input', val)
|
if (Array.isArray(val) && val.length === 2) {
|
||||||
this.$emit('change', val)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ export default {
|
|||||||
|
|
||||||
// 判断地图开启了点飞功能
|
// 判断地图开启了点飞功能
|
||||||
if (this.enableGuided) {
|
if (this.enableGuided) {
|
||||||
// 长按事件 传longPress到组件外部调用
|
// 长按事件 传longPress到组件外部调用
|
||||||
let pressTimer = null
|
let pressTimer = null
|
||||||
let isLongPress = false // 标记是否为长按
|
let isLongPress = false // 标记是否为长按
|
||||||
let startPoint = null // 记录按下时的位置
|
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 飞机经纬高度数组
|
* @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({
|
||||||
|
@ -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>
|
||||||
@ -13,7 +14,7 @@
|
|||||||
|
|
||||||
<div class="chart-area" v-if="flyDataList.length">
|
<div class="chart-area" v-if="flyDataList.length">
|
||||||
<div v-if="boxShow" id="main" class="chart-container"></div>
|
<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>
|
||||||
<div v-else class="no-data-tip">暂无数据</div>
|
<div v-else class="no-data-tip">暂无数据</div>
|
||||||
</div>
|
</div>
|
||||||
@ -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
|
||||||
try {
|
let firstPoint = null
|
||||||
const firstPath = JSON.parse(this.flyDataList[0].gps_path)
|
if (firstPath) {
|
||||||
if (Array.isArray(firstPath) && firstPath.length > 0) {
|
if (typeof firstPath === 'string') {
|
||||||
const [lon, lat] = firstPath[0]
|
try {
|
||||||
this.$refs.mapbox.goto({ lon, lat })
|
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 () {
|
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: [
|
||||||
|
Loading…
Reference in New Issue
Block a user