【类 型】:fix
【原 因】:1修正 地图组件载入 内部函数调用过早 导致报错 2.完善地图源地址 从 后端数据库拿数据 【过 程】: 【影 响】: # 类型 包含: # feat:新功能(feature) # fix:修补bug # docs:文档(documentation) # style: 格式(不影响代码运行的变动) # refactor:重构(即不是新增功能,也不是修改bug的代码变动) # test:增加测试 # chore:构建过程或辅助工具的变动
This commit is contained in:
parent
03ee669804
commit
bc6bf29da2
@ -23,8 +23,7 @@ export default {
|
||||
takeoffLonLats: [], // 航线 第一个航点 起点 最后一个航点
|
||||
isflow: false, // 飞机经纬度变化时是否跟随飞机
|
||||
currentStyleIndex: 0, // 当前选中的地图样式索引
|
||||
guidedMarker: null, // 指点飞行地图标记
|
||||
mapStyles: this.$store.state.mapStyleList// 地图样式
|
||||
guidedMarker: null // 指点飞行地图标记
|
||||
}
|
||||
},
|
||||
props: {
|
||||
@ -79,53 +78,63 @@ export default {
|
||||
},
|
||||
defaultZoom () {
|
||||
return this.$store.getters['app/getDefaultZoom']
|
||||
},
|
||||
mapStyleList () {
|
||||
return this.$store.state.mapStyleList
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.init().then(() => {
|
||||
// 地图初始化之后
|
||||
this.map.on('load', () => {
|
||||
this.$emit('map-ready') // 外部组件回调 触发地图加载完成事件 传到外部组件调用 以确保执行时地图已经加载完成
|
||||
/* 更新样式,添加自定义 sprite */
|
||||
watch: {
|
||||
},
|
||||
async mounted () {
|
||||
// 等待 异步 加载 后端地图源 地址
|
||||
await this.$store.dispatch('fetchMapStyleList', this.$store.state.settings.host)
|
||||
// 等待 异步 地图初始化
|
||||
await this.init()
|
||||
|
||||
// 星空背景 大气层
|
||||
this.map.setFog({
|
||||
range: [1.0, 8.0],
|
||||
color: 'white',
|
||||
'horizon-blend': 0.01
|
||||
})
|
||||
// // 添加等高线图层
|
||||
// this.map.addSource('contours', {
|
||||
// type: 'vector',
|
||||
// url: 'mapbox://mapbox.mapbox-terrain-v2'
|
||||
// })
|
||||
// this.map.addLayer({
|
||||
// id: 'contours',
|
||||
// type: 'line',
|
||||
// source: 'contours',
|
||||
// 'source-layer': 'contour',
|
||||
// layout: {
|
||||
// 'line-join': 'round',
|
||||
// 'line-cap': 'round'
|
||||
// },
|
||||
// paint: {
|
||||
// 'line-color': '#ff69b4',// 设置等高线颜色
|
||||
// 'line-width': 1 // 设置等高线宽度
|
||||
// }
|
||||
// })
|
||||
// // 3D地图
|
||||
// this.map.addSource('mapbox-dem', {
|
||||
// type: 'raster-dem',
|
||||
// url: 'mapbox://mapbox.mapbox-terrain-dem-v1',
|
||||
// tileSize: 512,
|
||||
// maxzoom: 14
|
||||
// })
|
||||
// this.map.setTerrain({ source: 'mapbox-dem', exaggeration: 1.5 })
|
||||
// 地图初始化之后
|
||||
this.map.on('load', () => {
|
||||
/* 更新样式,添加自定义 sprite */
|
||||
|
||||
// 星空背景 大气层
|
||||
this.map.setFog({
|
||||
range: [1.0, 8.0],
|
||||
color: 'white',
|
||||
'horizon-blend': 0.01
|
||||
})
|
||||
// // 添加等高线图层
|
||||
// this.map.addSource('contours', {
|
||||
// type: 'vector',
|
||||
// url: 'mapbox://mapbox.mapbox-terrain-v2'
|
||||
// })
|
||||
// this.map.addLayer({
|
||||
// id: 'contours',
|
||||
// type: 'line',
|
||||
// source: 'contours',
|
||||
// 'source-layer': 'contour',
|
||||
// layout: {
|
||||
// 'line-join': 'round',
|
||||
// 'line-cap': 'round'
|
||||
// },
|
||||
// paint: {
|
||||
// 'line-color': '#ff69b4',// 设置等高线颜色
|
||||
// 'line-width': 1 // 设置等高线宽度
|
||||
// }
|
||||
// })
|
||||
// // 3D地图
|
||||
// this.map.addSource('mapbox-dem', {
|
||||
// type: 'raster-dem',
|
||||
// url: 'mapbox://mapbox.mapbox-terrain-dem-v1',
|
||||
// tileSize: 512,
|
||||
// maxzoom: 14
|
||||
// })
|
||||
// this.map.setTerrain({ source: 'mapbox-dem', exaggeration: 1.5 })
|
||||
|
||||
// 外部组件回调 触发地图加载完成事件(on 'load') 传到外部组件调用 以确保执行时地图已经加载完成
|
||||
this.$emit('map-ready')
|
||||
|
||||
// 判断地图开启了点飞功能
|
||||
if (this.enableGuided) {
|
||||
// 长按事件 传longPress到组件外部调用
|
||||
// 长按事件 传longPress到组件外部调用
|
||||
let pressTimer = null
|
||||
let isLongPress = false // 标记是否为长按
|
||||
let startPoint = null // 记录按下时的位置
|
||||
@ -186,7 +195,7 @@ export default {
|
||||
// 实例化map
|
||||
this.map = new mapboxgl.Map({
|
||||
container: 'map',
|
||||
style: this.mapStyles[0],
|
||||
style: this.mapStyleList[0],
|
||||
center: this.defaultLonlat,
|
||||
zoom: this.defaultZoom,
|
||||
pitch: 0,
|
||||
@ -211,7 +220,7 @@ export default {
|
||||
// 地图样式选择控件
|
||||
// 自定义地图样式列表
|
||||
if (this.enableSwitch) {
|
||||
const styleSwitcherControl = new MapboxStyleSwitcherControl(this.mapStyles, 'iconfont icon-duozhang f-s-20', this.currentStyleIndex)
|
||||
const styleSwitcherControl = new MapboxStyleSwitcherControl(this.mapStyleList, 'iconfont icon-duozhang f-s-20', this.currentStyleIndex)
|
||||
this.map.addControl(styleSwitcherControl, 'top-right')
|
||||
}
|
||||
|
||||
@ -871,8 +880,6 @@ export default {
|
||||
this.$store.commit('app/setDefaultLonLat', this.map.getCenter())
|
||||
this.$store.commit('app/setDefaultZoom', this.map.getZoom())
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
}
|
||||
}
|
||||
|
||||
@ -899,5 +906,4 @@ export default {
|
||||
.adsb-icon {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -26,7 +26,6 @@ const store = new Vuex.Store({
|
||||
logList: [], // 操作日志列表
|
||||
messageList: [], // 管理员公告列表
|
||||
mapStyleList: [], // 地图样式列表
|
||||
mapIsStyleReady: false, // 地图样式是否加载完成 在全局入口判断设置 子页面调用地图组件时直接判断该值
|
||||
crosFrequency: null, // 对频macadd
|
||||
ADSBList: [] // 存放当前活跃的 ADSB 飞机数据
|
||||
},
|
||||
@ -155,13 +154,6 @@ const store = new Vuex.Store({
|
||||
setMapStyleList (state, list) {
|
||||
state.mapStyleList = list
|
||||
},
|
||||
/**
|
||||
* @description: 确认地图源地址 加载完成
|
||||
* @param {bool} status 是否完成
|
||||
*/
|
||||
setMapIsStyleReady (state, status) {
|
||||
state.mapIsStyleReady = status
|
||||
},
|
||||
/**
|
||||
* @description: 清除过期的 ADSB 数据
|
||||
*/
|
||||
@ -1209,7 +1201,6 @@ const store = new Vuex.Store({
|
||||
}
|
||||
})
|
||||
commit('setMapStyleList', list)
|
||||
commit('setMapIsStyleReady', true)
|
||||
} else {
|
||||
commit('setMapStyleList', [])
|
||||
Message.error(res.data.msg || '地图样式获取失败')
|
||||
|
@ -158,3 +158,37 @@ export function formatPrice (value) {
|
||||
}
|
||||
return formattedPrice
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待 Mapbox 地图的画布容器(Canvas Container)准备就绪。
|
||||
* 因为 Mapbox 初始化是异步的,某些操作需要等待画布容器加载完成才能执行。
|
||||
*
|
||||
* @param {Object} map - Mapbox GL JS 地图实例对象
|
||||
* @param {number} maxRetry - 最大重试次数,防止无限等待,默认5次
|
||||
* @returns {Promise<HTMLElement>} 返回一个 Promise,成功时返回画布容器元素,失败时抛出错误
|
||||
*/
|
||||
export function waitForMapCanvasReady (map, maxRetry = 5) {
|
||||
return new Promise((resolve, reject) => {
|
||||
/**
|
||||
* 递归检查函数,使用 requestAnimationFrame 尽可能快地检测画布容器是否可用
|
||||
* @param {number} retry 剩余重试次数
|
||||
*/
|
||||
const check = (retry) => {
|
||||
// 尝试获取画布容器元素
|
||||
const container = map?.getCanvasContainer?.()
|
||||
|
||||
// 如果获取成功,表示地图画布已准备好
|
||||
if (container) {
|
||||
resolve(container) // Promise 成功返回画布容器
|
||||
} else if (retry > 0) { // 如果还没准备好且重试次数未用尽,继续异步下一帧检测
|
||||
// requestAnimationFrame 在浏览器每一帧时执行回调,比 setTimeout 更高效和精准
|
||||
requestAnimationFrame(() => check(retry - 1))
|
||||
} else { // 超过最大重试次数,拒绝 Promise,避免无限等待
|
||||
reject(new Error('Map canvas container is not ready after multiple retries'))
|
||||
}
|
||||
}
|
||||
|
||||
// 启动首次检测,带上最大重试次数参数
|
||||
check(maxRetry)
|
||||
})
|
||||
}
|
||||
|
@ -1,21 +1,25 @@
|
||||
<template>
|
||||
<div class="h-100">
|
||||
<map-box ref="mapbox" v-if="$store.state.mapIsStyleReady">
|
||||
<!-- <template #content>
|
||||
<Statistics :plane="plane" />
|
||||
</template> -->
|
||||
<map-box ref="mapbox" @map-ready="onMapReady">
|
||||
<template #content>
|
||||
<div v-show="mapReady">
|
||||
<!-- <Statistics :plane="plane" /> -->
|
||||
</div>
|
||||
</template>
|
||||
</map-box>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MapBox from '@/components/MapBox'
|
||||
import { waitForMapCanvasReady } from '@/utils'
|
||||
// import Statistics from '@/components/Statistics'
|
||||
|
||||
export default {
|
||||
name: 'Home',
|
||||
data () {
|
||||
return {
|
||||
mapReady: false// 地图加载完成后 回调时 设置此值 让地图组件插槽内容 滞后显示
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@ -34,6 +38,11 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 地图组件回调地图加载完成后 执行
|
||||
onMapReady () {
|
||||
this.mapReady = true // 标记地图加载完成
|
||||
this.makePlanes(this.airList)
|
||||
},
|
||||
/**
|
||||
* @description: 创建飞机图标
|
||||
*/
|
||||
@ -46,8 +55,9 @@ export default {
|
||||
plane.lon = planeDefaultLonLat.lon
|
||||
plane.lat = planeDefaultLonLat.lat
|
||||
} else {
|
||||
plane.lon = 0
|
||||
plane.lat = 0
|
||||
// 缺省 给经纬度 小数点后随机第五位 即有个10米左右的随机距离
|
||||
plane.lon = 100 + Number((Math.random() * 0.01).toFixed(5))
|
||||
plane.lat = 40 + Number((Math.random() * 0.01).toFixed(5))
|
||||
}
|
||||
this.$refs.mapbox.makePlane(plane, index)
|
||||
})
|
||||
@ -56,13 +66,21 @@ export default {
|
||||
mounted () {
|
||||
},
|
||||
watch: {
|
||||
/**
|
||||
* @description: 飞机列表更新时候 更新地图
|
||||
*/
|
||||
airList: {
|
||||
handler (val) {
|
||||
if (val && val.length > 0) {
|
||||
this.makePlanes(val)
|
||||
async handler () {
|
||||
try {
|
||||
// 等待地图画布准备好
|
||||
await waitForMapCanvasReady(this.map)
|
||||
// 画布准备好后执行你自己的逻辑
|
||||
this.onMapReady()
|
||||
} catch (err) {
|
||||
console.debug('等待地图画布准备超时', err)
|
||||
}
|
||||
},
|
||||
immediate: true // 页面加载先触发一次
|
||||
immediate: true
|
||||
},
|
||||
/**
|
||||
* @description: 侧边栏显隐
|
||||
|
@ -1,12 +1,14 @@
|
||||
<template>
|
||||
<div class="h-100">
|
||||
<!-- 地图组件 -->
|
||||
<map-box ref="mapbox" :enableShowNofly="true" :enableGuided="true" :enableFollow="true" :enblueScale="!$store.state.app.isWideScreen"
|
||||
@longPress="handleLongPress">
|
||||
<map-box ref="mapbox" :enableShowNofly="true" :enableGuided="true" :enableFollow="true"
|
||||
:enblueScale="!$store.state.app.isWideScreen" @longPress="handleLongPress" @map-ready="onMapReady">
|
||||
<template #content>
|
||||
<BatteryStatus :plane="plane" />
|
||||
<PlaneStatus :plane="plane" />
|
||||
<ControllerTabs :plane="plane" @mapXOffset="mapXOffset" @makeRoute="makeRoute" @clearRoute="clearRoute" />
|
||||
<div v-show="mapReady">
|
||||
<BatteryStatus :plane="plane" />
|
||||
<PlaneStatus :plane="plane" />
|
||||
<ControllerTabs :plane="plane" @mapXOffset="mapXOffset" @makeRoute="makeRoute" @clearRoute="clearRoute" />
|
||||
</div>
|
||||
</template>
|
||||
</map-box>
|
||||
<!-- 弹出框 -->
|
||||
@ -42,6 +44,7 @@ import ControllerTabs from '@/components/ControllerTabs'
|
||||
import BatteryStatus from '@/components/BatteryStatus'
|
||||
import PlaneStatus from '@/components/PlaneStatus'
|
||||
import mqtt from '@/utils/mqtt'
|
||||
import { waitForMapCanvasReady } from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'Planes',
|
||||
@ -54,7 +57,8 @@ export default {
|
||||
guidedAlt: '', // 点飞的高度
|
||||
isReserveGuidedMaker: false, // 关闭指点飞行操作窗口时 标记是否删除图标
|
||||
planesId: this.$route.params.id,
|
||||
localCount: 0 // 本地存储计数器
|
||||
localCount: 0, // 本地存储计数器
|
||||
mapReady: false// 地图加载完成后 回调时 设置此值 让地图组件插槽内容 滞后显示
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@ -116,6 +120,11 @@ export default {
|
||||
const posLen = this.plane.planeState.position.length
|
||||
this.guidedAlt = this.plane.planeState.position[posLen - 1][2]// 取出 点击时飞机的高度
|
||||
},
|
||||
// 地图组件回调地图加载完成后 执行
|
||||
onMapReady () {
|
||||
this.mapReady = true// 标记地图加载完成
|
||||
this.makePlane(this.plane)
|
||||
},
|
||||
/**
|
||||
* @description: 创建飞机图标
|
||||
*/
|
||||
@ -126,8 +135,9 @@ export default {
|
||||
plane.lon = planeDefaultLonLat.lon
|
||||
plane.lat = planeDefaultLonLat.lat
|
||||
} else {
|
||||
plane.lon = 100
|
||||
plane.lat = 40
|
||||
// 缺省 给经纬度 小数点后随机第五位 即有个10米左右的随机距离
|
||||
plane.lon = 100 + Number((Math.random() * 0.01).toFixed(5))
|
||||
plane.lat = 40 + Number((Math.random() * 0.01).toFixed(5))
|
||||
}
|
||||
this.$refs.mapbox.removePlanes()// 先清除画布上现有的飞机
|
||||
this.$refs.mapbox.makePlane(plane)// 创建飞机
|
||||
@ -166,13 +176,20 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
if (this.plane) {
|
||||
this.makePlane(this.plane) // 创建飞机图标
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
plane (val) {
|
||||
if (val) this.makePlane(val)// 有飞机数据之后 在地图上创建飞机
|
||||
plane: {
|
||||
async handler () {
|
||||
try {
|
||||
// 等待地图画布准备好
|
||||
await waitForMapCanvasReady(this.map)
|
||||
// 画布准备好后执行你自己的逻辑
|
||||
this.onMapReady()
|
||||
} catch (err) {
|
||||
console.debug('等待地图画布准备超时', err)
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
/**
|
||||
* @description: 更新飞机位置 并画出轨迹 跟随飞机
|
||||
|
@ -122,13 +122,13 @@ export default {
|
||||
this.$store.dispatch('fetchSpuList'),
|
||||
this.$store.dispatch('fetchSkuList'),
|
||||
this.$store.dispatch('fetchPaidOrderList'),
|
||||
this.$store.dispatch('fetchMessageList'),
|
||||
this.$store.dispatch('fetchMapStyleList', this.$store.state.settings.host)
|
||||
this.$store.dispatch('fetchMessageList')
|
||||
]).then(() => {
|
||||
return this.$store.dispatch('fetchNoflyData', this.shop_id)
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
|
||||
/**
|
||||
* @description: 异步拿到飞机列表之后 再进行一些初始化操作
|
||||
* @param {*} res 飞机列表
|
||||
|
Loading…
Reference in New Issue
Block a user