【类 型】:feat

【原  因】:地图组件显示飞机图标 实时根据在线状态 重量状态 实时更新图标
【过  程】:mapbox加一个更新updatePlaneIcon函数  概况 飞机操作界面 监测飞机状态 调用更图标函数
【影  响】:

# 类型 包含:
# feat:新功能(feature)
# fix:修补bug
# docs:文档(documentation)
# style: 格式(不影响代码运行的变动)
# refactor:重构(即不是新增功能,也不是修改bug的代码变动)
# test:增加测试
# chore:构建过程或辅助工具的变动
This commit is contained in:
air 2025-09-18 16:24:51 +08:00
parent 2ce3e8c27e
commit 2f991d8934
5 changed files with 978 additions and 2816 deletions

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 30 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -8,7 +8,8 @@
import mapboxgl from 'mapbox-gl'
import { MapboxStyleSwitcherControl, FollowControl, CustomFullscreenControl, NoFlyControl, RestrictflyControl, SaveToFileControl, PolygonToggleControl } from '@/utils/mapboxgl_plugs'
import planeIcon from '@/assets/svg/plane.svg'
// import unlineIcon from '@/assets/svg/plane_unline.svg'
import planeRunIcon from '@/assets/svg/plane_run.svg'
import unlineIcon from '@/assets/svg/plane_unline.svg'
import civilIcon from '@/assets/svg/civil.svg'
export default {
@ -87,22 +88,6 @@ export default {
}
},
watch: {
/** 动态开关地图样式切换控件 */
enableSwitch (val) {
if (!this.map) return
if (val) {
if (!this.styleSwitcherControlRef) {
const control = new MapboxStyleSwitcherControl(this.mapStyleList, 'iconfont icon-duozhang f-s-20', this.currentStyleIndex)
this.map.addControl(control, 'top-right')
this.styleSwitcherControlRef = control
}
} else {
if (this.styleSwitcherControlRef) {
try { this.map.removeControl(this.styleSwitcherControlRef) } catch (e) { /* noop */ }
this.styleSwitcherControlRef = null
}
}
},
/** 动态开关全屏控件enableZoom */
enableZoom (val) {
if (!this.map) return
@ -118,6 +103,22 @@ export default {
this.fullscreenControlRef = null
}
}
},
/** 动态开关地图样式切换控件 */
enableSwitch (val) {
if (!this.map) return
if (val) {
if (!this.styleSwitcherControlRef) {
const control = new MapboxStyleSwitcherControl(this.mapStyleList, 'iconfont icon-duozhang f-s-20', this.currentStyleIndex)
this.map.addControl(control, 'top-right')
this.styleSwitcherControlRef = control
}
} else {
if (this.styleSwitcherControlRef) {
try { this.map.removeControl(this.styleSwitcherControlRef) } catch (e) { /* noop */ }
this.styleSwitcherControlRef = null
}
}
}
},
async mounted () {
@ -253,13 +254,6 @@ export default {
this.map.addControl(this.fullscreenControlRef, 'top-right')
}
//
//
if (this.enableSwitch) {
this.styleSwitcherControlRef = new MapboxStyleSwitcherControl(this.mapStyleList, 'iconfont icon-duozhang f-s-20', this.currentStyleIndex)
this.map.addControl(this.styleSwitcherControlRef, 'top-right')
}
//
if (this.enableFollow) {
this.map.addControl(new FollowControl({
@ -349,6 +343,13 @@ export default {
}
}), 'top-right')
}
//
//
if (this.enableSwitch) {
this.styleSwitcherControlRef = new MapboxStyleSwitcherControl(this.mapStyleList, 'iconfont icon-duozhang f-s-20', this.currentStyleIndex)
this.map.addControl(this.styleSwitcherControlRef, 'top-right')
}
},
/**
* @description 通用地图图层和数据源清除方法
@ -917,7 +918,17 @@ export default {
makePlane (plane, index = 0) {
const customIcon = document.createElement('div')
customIcon.className = 'custom-marker'
customIcon.style.backgroundImage = `url(${planeIcon})`
// 线
// : online === false 线( undefined/null) 线
const isOnline = !((plane && plane.planeState && plane.planeState.online) === false)
const lwRaw0 = plane && plane.planeState ? plane.planeState.loadweight : 0
const lwNum0 = Number(lwRaw0)
const loadWeight = Number.isFinite(lwNum0) ? lwNum0 : 0
const iconToUse = !isOnline ? unlineIcon : (loadWeight > 300 ? planeRunIcon : planeIcon)
// 使 important
customIcon.style.setProperty('background-image', `url(${iconToUse})`, 'important')
customIcon.style.setProperty('background-repeat', 'no-repeat', 'important')
customIcon.style.setProperty('background-size', 'contain', 'important')
customIcon.style.width = '64px'
customIcon.style.height = '64px'
@ -1088,6 +1099,32 @@ export default {
popup.setHTML(popupContent)
}
},
/**
* @description 实时根据在线状态与载重更新指定飞机的图标
* @param {Object} stateObj 飞机状态对象需包含 online, loadweight
* @param {number} index 对应的飞机索引
*/
updatePlaneIcon (stateObj, index = 0) {
const marker = this.planes[index]
if (!marker) return
const el = marker.getElement()
if (!el) return
// : online === false 线( undefined/null) 线
const isOnline = !((stateObj && stateObj.online) === false)
const lwRaw = stateObj ? stateObj.loadweight : 0
const lwNum = Number(lwRaw)
const loadWeight = Number.isFinite(lwNum) ? lwNum : 0
const iconToUse = !isOnline ? unlineIcon : (loadWeight > 300 ? planeRunIcon : planeIcon)
// 使 important
el.style.setProperty('background-image', `url(${iconToUse})`, 'important')
el.style.setProperty('background-repeat', 'no-repeat', 'important')
el.style.setProperty('background-size', 'contain', 'important')
//
try {
el.dataset.icon = !isOnline ? 'unline' : (loadWeight > 300 ? 'run' : 'normal')
console.debug('[updatePlaneIcon]', { index, online: stateObj && stateObj.online, loadweight: lwRaw, parsedLoad: loadWeight, chosen: el.dataset.icon })
} catch (e) { /* noop */ }
},
/**
* @description: 镜头跳转
* @param {obj} lonLat {lon:lon,lat:lat} 经纬度

View File

@ -43,6 +43,20 @@ export default {
return Array.isArray(posArr) ? posArr : []
})
},
/**
* @description: 派生出与图标选择强相关的轻量状态供独立 watcher 监控
* offline: 是否离线run: 载重是否超过阈值>300
*/
planeIconStates () {
return this.planeList.map(plane => {
const s = plane.planeState || {}
const n = Number(s.loadweight)
return {
offline: s.online === false,
run: Number.isFinite(n) && n > 300
}
})
},
/**
* @description: 侧边栏显隐
*/
@ -129,6 +143,21 @@ export default {
},
deep: true
},
// DOM
planeIconStates: {
handler (val, oldVal) {
val.forEach((iconState, index) => {
const prev = Array.isArray(oldVal) ? oldVal[index] : undefined
const changed = !prev || prev.offline !== iconState.offline || prev.run !== iconState.run
if (changed) {
// 使 planeState
const stateObj = this.planeList[index].planeState || {}
this.$refs.mapbox.updatePlaneIcon(stateObj, index)
}
})
},
deep: true
},
/**
* @description: 侧边栏缩进有变化时 地图重新自适应
*/

View File

@ -175,8 +175,20 @@ export default {
*/
isCollapse () {
return this.$store.state.app.isCollapse
},
/**
* @description: 与图标选择强相关的轻量状态仅当前选中飞机
*/
planeIconState () {
const s = this.planeState || {}
const n = Number(s.loadweight)
return {
offline: s.online === false,
run: Number.isFinite(n) && n > 300
}
}
},
methods: {
/** 切换主视图 */
toggleMainView () {
@ -336,6 +348,18 @@ export default {
},
deep: true
},
// 线/
planeIconState: {
handler (val, oldVal) {
const changed = !oldVal || oldVal.offline !== val.offline || oldVal.run !== val.run
if (changed) {
const stateObj = this.planeState || {}
// MapBox 0
this.$refs.mapbox.updatePlaneIcon(stateObj, 0)
}
},
deep: false
},
/**
* @description: 更新飞机位置 并画出轨迹 跟随飞机
*/