From b072965257d842d4f09ba1d775d7577fd1accb51 Mon Sep 17 00:00:00 2001 From: szdot Date: Thu, 25 Jul 2024 05:13:30 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E7=B1=BB=20=20=E5=9E=8B=E3=80=91?= =?UTF-8?q?=EF=BC=9Astyle=20=E6=A0=BC=E5=BC=8F=E5=8F=98=E5=8A=A8=20?= =?UTF-8?q?=E3=80=90=E5=8E=9F=20=20=E5=9B=A0=E3=80=91=EF=BC=9A=20=E3=80=90?= =?UTF-8?q?=E8=BF=87=20=20=E7=A8=8B=E3=80=91=EF=BC=9A=20=E3=80=90=E5=BD=B1?= =?UTF-8?q?=20=20=E5=93=8D=E3=80=91=EF=BC=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MapBox.vue | 263 +++++++++++------- src/styles/index.scss | 22 +- src/views/layout/components/headbar.vue | 177 ++++++++---- .../layout/components/main/planes/index.vue | 4 +- 4 files changed, 315 insertions(+), 151 deletions(-) diff --git a/src/components/MapBox.vue b/src/components/MapBox.vue index a4c6016..a44f453 100644 --- a/src/components/MapBox.vue +++ b/src/components/MapBox.vue @@ -17,8 +17,10 @@ export default { lngLats: [], // 航线 所有航点 wayLngLats: [], // 航线 不包括起点航点 takeoffLngLats: [], // 航线 第一个航点 起点 最后一个航点 + isflow: false, // 飞机经纬度变化时是否跟随飞机 // 地图样式 - GoogleRasterStyle: { // mapbox官方样式 卫星地图 + GoogleRasterStyle: { + // mapbox官方样式 卫星地图 name: 'Mapbox Streets', sprite: this.$store.state.settings.host + '/Public/map/sprite', glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf', @@ -34,7 +36,8 @@ export default { }, MapBoxglRasterStyle: 'mapbox://styles/mapbox/outdoors-v12', // mapbox官方样式 矢量街道 MapBoxglSatellite: 'mapbox://styles/mapbox/satellite-streets-v12', // mapbox官方样式 卫星街道 - GaodeVectorStyle: { // 第三方 高德矢量 + GaodeVectorStyle: { + // 第三方 高德矢量 name: 'Gaode Vector', sprite: this.$store.state.settings.host + '/Public/map/sprite', glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf', @@ -43,12 +46,15 @@ export default { gaode: { type: 'raster', tileSize: 256, // 瓦片大小 256 512像素 - tiles: ['http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'] + tiles: [ + 'http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}' + ] } }, layers: [{ id: 'GaodeVectorLayer', type: 'raster', source: 'gaode' }] }, - GaodeRasterStyle: { // 第三方 高德卫星 + GaodeRasterStyle: { + // 第三方 高德卫星 name: 'Gaode Raster', sprite: this.$store.state.settings.host + '/Public/map/sprite', glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf', @@ -57,7 +63,9 @@ export default { gaode: { type: 'raster', tileSize: 256, // 瓦片大小 256 512像素 - tiles: ['https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'] + tiles: [ + 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}' + ] } }, layers: [{ id: 'GaodeRasterLayer', type: 'raster', source: 'gaode' }] @@ -73,7 +81,8 @@ export default { } }, mounted () { - this.init().then(() => { // 地图初始化之后 + this.init().then(() => { + // 地图初始化之后 this.map.on('load', () => { /* 更新样式,添加自定义 sprite */ @@ -114,14 +123,16 @@ export default { // 长按事件 传longPress到组件外部调用 let pressTimer - this.map.on('mousedown', (event) => { // pc端点击事件 + this.map.on('mousedown', (event) => { + // pc端点击事件 pressTimer = setTimeout(() => { const lngLat = this.map.unproject(event.point) // 将经纬度信息传递到组件外部 this.$emit('longPress', lngLat) }, 1000) // 作为长按的时间阈值 }) - this.map.on('touchstart', (event) => { // 移动端点击事件 + this.map.on('touchstart', (event) => { + // 移动端点击事件 pressTimer = setTimeout(() => { const lngLat = this.map.unproject(event.point) // 将经纬度信息传递到组件外部 @@ -138,11 +149,12 @@ export default { }, methods: { /** - * @description: 地图初始化 - */ + * @description: 地图初始化 + */ async init () { // token - mapboxgl.accessToken = 'pk.eyJ1Ijoic3pkb3QiLCJhIjoiY2xhN2pkMWFoMHJ4eTN3cXp6bmlzaHZ0NCJ9.3hH-EAUr0wQCaLvIM2lBMQ' + mapboxgl.accessToken = + 'pk.eyJ1Ijoic3pkb3QiLCJhIjoiY2xhN2pkMWFoMHJ4eTN3cXp6bmlzaHZ0NCJ9.3hH-EAUr0wQCaLvIM2lBMQ' // 实例化map this.map = new mapboxgl.Map({ container: 'map', @@ -153,21 +165,31 @@ export default { bearing: 0, projection: 'globe' }) - // 地图控件 - this.map.addControl(new mapboxgl.NavigationControl(), 'top-right')// 移动旋转指南针 - // this.map.addControl(new mapboxgl.ScaleControl(), 'top-right')// 地图比例 - this.map.addControl(new mapboxgl.FullscreenControl(), 'top-right')// 全屏 - this.map.addControl( - new mapboxgl.GeolocateControl({ - positionOptions: { - enableHighAccuracy: true - }, - // When active the map will receive updates to the device's location as it changes. - trackUserLocation: true, - // Draw an arrow next to the location dot to indicate which direction the device is heading. - showUserHeading: true - }) - )// 跟随 + /* 地图控件 */ + // 移动旋转指南针 + this.map.addControl(new mapboxgl.NavigationControl(), 'top-right') + // 地图比例 + // this.map.addControl(new mapboxgl.ScaleControl(), 'top-right') + // 全屏 + this.map.addControl(new mapboxgl.FullscreenControl(), 'top-right') + // 跟随飞机 + // this.map.addControl( + // new mapboxgl.GeolocateControl({ + // positionOptions: { + // enableHighAccuracy: true + // }, + // trackUserLocation: true, + // showUserHeading: true + // }), 'top-right' + // ) + const customControl = new CustomControl({ + label: '点', + onClick: () => { + this.isflow = !this.isflow + this.goto({ lng: 20, lat: 30 })// 跳转到飞机位置 + } + }) + this.map.addControl(customControl, 'top-right') }, /** * @description: 清除地图上的航线 @@ -194,9 +216,9 @@ export default { } }, /** - * @description: 绘画航线 - * @param {*} routeObj 航点文件对象 - */ + * @description: 绘画航线 + * @param {*} routeObj 航点文件对象 + */ makeRoute (routeObj) { // 初始化清空航线 this.clearRoute() @@ -215,7 +237,9 @@ export default { this.takeoffLngLats.push(this.lngLats[2]) this.takeoffLngLats.push(this.lngLats[1]) this.takeoffLngLats.push(this.lngLats[this.lngLats.length - 2]) - } else if (routeObj.questAss.tasks[this.lngLats.length - 1].command === 21) { + } else if ( + routeObj.questAss.tasks[this.lngLats.length - 1].command === 21 + ) { this.takeoffLngLats.push(this.lngLats[2]) this.takeoffLngLats.push(this.lngLats[1]) } @@ -238,13 +262,13 @@ export default { source: 'takeoff_route', layout: { 'line-join': 'round', // 线连接处的样式 - 'line-cap': 'round'// 线结束处的样式 + 'line-cap': 'round' // 线结束处的样式 }, paint: { 'line-color': '#fff', // 线的颜色 'line-width': 2, // 线的宽度 'line-opacity': 1.0, // 线的透明度 - 'line-dasharray': [3, 2]// 虚线 + 'line-dasharray': [3, 2] // 虚线 } }) // 航线 叠加描边线 @@ -265,12 +289,12 @@ export default { source: 'way_route', layout: { 'line-join': 'round', // 线连接处的样式 - 'line-cap': 'round'// 线结束处的样式 + 'line-cap': 'round' // 线结束处的样式 }, paint: { 'line-color': '#fff', // 线的颜色 'line-width': 4, // 线的宽度 - 'line-opacity': 1.0// 线的透明度 + 'line-opacity': 1.0 // 线的透明度 } }) this.map.addLayer({ @@ -279,32 +303,35 @@ export default { source: 'way_route', layout: { 'line-join': 'round', // 线连接处的样式 - 'line-cap': 'round'// 线结束处的样式 + 'line-cap': 'round' // 线结束处的样式 }, paint: { 'line-color': '#f00', // 线的颜色 'line-width': 2, // 线的宽度 - 'line-opacity': 1.0// 线的透明度 + 'line-opacity': 1.0 // 线的透明度 } }) // 航点 图标 PS:home点 起飞点 航点 送餐点等 this.lngLats.forEach((item, index) => { // home点 - if (index === 0) { // 第一点home点 + if (index === 0) { + // 第一点home点 this.map.addSource('home_point', { type: 'geojson', data: { type: 'FeatureCollection', - features: [{ - type: 'Feature', - geometry: { - type: 'Point', - coordinates: item - }, - properties: { - 'marker-symbol': 'homePoint'// home点图标 + features: [ + { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: item + }, + properties: { + 'marker-symbol': 'homePoint' // home点图标 + } } - }] + ] } }) this.map.addLayer({ @@ -317,28 +344,33 @@ export default { 'icon-allow-overlap': true } }) - } else if (index === 1) { // 起飞点 + } else if (index === 1) { + // 起飞点 let takeoffPoint // 起点图标设定 根据最后一个航点为RETURN_TO_LAUNCH 20 返回起点降落 或者 最后一个航点为LAND 21 指定点降落 if (routeObj.questAss.tasks[this.lngLats.length - 1].command === 20) { takeoffPoint = 'takeoffLandPoint' - } else if (routeObj.questAss.tasks[this.lngLats.length - 1].command === 21) { + } else if ( + routeObj.questAss.tasks[this.lngLats.length - 1].command === 21 + ) { takeoffPoint = 'takeoffPoint' } this.map.addSource('takeoff_point', { type: 'geojson', data: { type: 'FeatureCollection', - features: [{ - type: 'Feature', - geometry: { - type: 'Point', - coordinates: item - }, - properties: { - 'marker-symbol': takeoffPoint// 起飞点图标 + features: [ + { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: item + }, + properties: { + 'marker-symbol': takeoffPoint // 起飞点图标 + } } - }] + ] } }) this.map.addLayer({ @@ -351,31 +383,39 @@ export default { 'icon-allow-overlap': true } }) - } else { // waypoint点 - if (index !== this.lngLats.length - 1) { // 最后一个点不显示 要不和最后一个点结合 要不和起点结合 + } else { + // waypoint点 + if (index !== this.lngLats.length - 1) { + // 最后一个点不显示 要不和最后一个点结合 要不和起点结合 let wayPoint = 'wayPoint' - if (index === this.lngLats.length - 2) { // 降落点 如果是LAND 21 和最后一个waypoint点结合 - if (routeObj.questAss.tasks[this.lngLats.length - 1].command === 21) { + if (index === this.lngLats.length - 2) { + // 降落点 如果是LAND 21 和最后一个waypoint点结合 + if ( + routeObj.questAss.tasks[this.lngLats.length - 1].command === 21 + ) { wayPoint = 'wayLandPoint' } } - if (routeObj.questAss.tasks[index].command === 94) { // command字段为94既然 投放放勾航点 放勾图标 + if (routeObj.questAss.tasks[index].command === 94) { + // command字段为94既然 投放放勾航点 放勾图标 wayPoint = 'hookPoint' } this.map.addSource('way_point' + index, { type: 'geojson', data: { type: 'FeatureCollection', - features: [{ - type: 'Feature', - geometry: { - type: 'Point', - coordinates: item - }, - properties: { - 'marker-symbol': wayPoint + features: [ + { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: item + }, + properties: { + 'marker-symbol': wayPoint + } } - }] + ] } }) this.map.addLayer({ @@ -403,13 +443,18 @@ export default { properties: {}, geometry: { type: 'LineString', - coordinates: coordinatesArray.map(coord => [coord[0], coord[1], coord[2]]) + coordinates: coordinatesArray.map((coord) => [ + coord[0], + coord[1], + coord[2] + ]) } } // 不是第一次 则改变路径图层里面得数据 if (this.map.getLayer('path')) { this.map.getSource('path').setData(geojson) - } else { // 第一次在地图里添加路径图层 + } else { + // 第一次在地图里添加路径图层 // 如果坐标数组不为空,创建新路径 if (coordinatesArray.length > 0) { // 添加3D图层 @@ -433,9 +478,9 @@ export default { } }, /** - * @description: 创建一个飞机 - * @param {*} plane 飞机对象 - */ + * @description: 创建一个飞机 + * @param {*} plane 飞机对象 + */ makePlane (plane, index = 0) { const customIcon = document.createElement('div') customIcon.className = 'custom-marker' // 添加自定义样式类名 @@ -445,14 +490,18 @@ export default { // 创建一个marker对象 this.planes[index] = new mapboxgl.Marker(customIcon) .setLngLat([plane.lng, plane.lat]) - .setPopup(new mapboxgl.Popup({ offset: 25 }).setHTML('

' + plane.name + '


macID:' + plane.macadd + '

')) // 添加弹出窗口 + .setPopup( + new mapboxgl.Popup({ offset: 25 }).setHTML( + '

' + plane.name + '


macID:' + plane.macadd + '

' + ) + ) // 添加弹出窗口 .addTo(this.map) }, /** - * @description: 移除页面上的所有飞机 - */ + * @description: 移除页面上的所有飞机 + */ removePlanes () { - this.planes.forEach(plane => { + this.planes.forEach((plane) => { plane.remove() }) this.planes = [] @@ -461,19 +510,19 @@ export default { * @description: 实时更新经纬度 * @param {obj} lnglat lng经度 lat纬度 * @param {*} index 飞机序号 - * @param {*} pathArr 是否创建轨迹 + * @param {*} pathArr 飞机轨迹 痕迹坐标数组 */ - setPlaneLngLat (lnglat, index, pathArr, isflow) { + setPlaneLngLat (lnglat, index, pathArr) { // 设置新的经纬度 const plane = this.planes[index] if (plane != null) { plane.setLngLat([lnglat.lng, lnglat.lat]) } // 创建轨迹 - this.createPathWithArray(pathArr)// 创建轨迹 + this.createPathWithArray(pathArr) // 创建轨迹 console.log(pathArr) // 镜头跟随飞机 - if (isflow) { + if (this.isflow) { this.map.flyTo({ center: lnglat, speed: 2, @@ -485,9 +534,9 @@ export default { } }, /** - * @description: 镜头跳转 - * @param {obj} lnglat {lng:lng,lat:lat} 经纬度 - */ + * @description: 镜头跳转 + * @param {obj} lnglat {lng:lng,lat:lat} 经纬度 + */ goto (lnglat) { this.map.flyTo({ center: lnglat, @@ -499,10 +548,10 @@ export default { }) }, /** - * @description: 屏幕横移 纵移 - * @param {*} x 正数向左移动 负数向右移动 - * @param {*} y 正数向上移动 负数向下移动 - */ + * @description: 屏幕横移 纵移 + * @param {*} x 正数向左移动 负数向右移动 + * @param {*} y 正数向上移动 负数向下移动 + */ mapXOffset (x, y) { this.map.panBy([x, y], { duration: 333 // 过渡持续时间,以毫秒为单位 @@ -519,13 +568,39 @@ export default { }, beforeDestroy () { if (this.map) { - this.$store.commit('app/setDefaultLngLat', this.map.getCenter())// 记录当前经纬度 缺省 - this.$store.commit('app/setDefaultZoom', this.map.getZoom())// 记录当前经纬度 缺省 - this.map.remove()// 清除地图资源 + this.$store.commit('app/setDefaultLngLat', this.map.getCenter()) // 记录当前经纬度 缺省 + this.$store.commit('app/setDefaultZoom', this.map.getZoom()) // 记录当前经纬度 缺省 + this.map.remove() // 清除地图资源 + } + }, + watch: { + isflow (val) { + console.log(val) } } } +class CustomControl { + constructor ({ label, onClick }) { + this._label = label + this._onClick = onClick + } + onAdd (map) { + this._map = map + this._container = document.createElement('div') + this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group' + this._button = document.createElement('button') + this._button.textContent = this._label + this._button.onclick = this._onClick + this._container.appendChild(this._button) + return this._container + } + + onRemove () { + this._container.parentNode.removeChild(this._container) + this._map = undefined + } +}