【类 型】:feat 写地图选择控件
【原 因】:切换地图 【过 程】:调用控件 【影 响】:留好缓存地图设置
This commit is contained in:
parent
9667b718b5
commit
6a80d87ddd
@ -19,58 +19,59 @@ export default {
|
|||||||
wayLngLats: [], // 航线 不包括起点航点
|
wayLngLats: [], // 航线 不包括起点航点
|
||||||
takeoffLngLats: [], // 航线 第一个航点 起点 最后一个航点
|
takeoffLngLats: [], // 航线 第一个航点 起点 最后一个航点
|
||||||
isflow: false, // 飞机经纬度变化时是否跟随飞机
|
isflow: false, // 飞机经纬度变化时是否跟随飞机
|
||||||
|
currentStyleIndex: 0, // 当前选中的地图样式索引
|
||||||
// 地图样式
|
// 地图样式
|
||||||
GoogleRasterStyle: {
|
mapStyles: [
|
||||||
// mapbox官方样式 卫星地图
|
// mapbox官方样式 卫星地图
|
||||||
name: 'Mapbox Streets',
|
{
|
||||||
sprite: this.$store.state.settings.host + '/Public/map/sprite',
|
name: '谷歌卫星',
|
||||||
glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
|
sprite: this.$store.state.settings.host + '/Public/map/sprite',
|
||||||
version: 8,
|
glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
|
||||||
sources: {
|
version: 8,
|
||||||
google: {
|
sources: {
|
||||||
type: 'raster',
|
google: {
|
||||||
tileSize: 256,
|
type: 'raster',
|
||||||
tiles: ['https://sb.im/google-maps/vt?lyrs=s&x={x}&y={y}&z={z}']
|
tileSize: 256,
|
||||||
}
|
tiles: ['https://sb.im/google-maps/vt?lyrs=s&x={x}&y={y}&z={z}']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
layers: [{ id: 'GoogleRasterLayer', type: 'raster', source: 'google' }]
|
||||||
},
|
},
|
||||||
layers: [{ id: 'GoogleRasterLayer', type: 'raster', source: 'google' }]
|
|
||||||
},
|
|
||||||
MapBoxglRasterStyle: 'mapbox://styles/mapbox/outdoors-v12', // mapbox官方样式 矢量街道
|
|
||||||
MapBoxglSatellite: 'mapbox://styles/mapbox/satellite-streets-v12', // mapbox官方样式 卫星街道
|
|
||||||
GaodeVectorStyle: {
|
|
||||||
// 第三方 高德矢量
|
// 第三方 高德矢量
|
||||||
name: 'Gaode Vector',
|
{
|
||||||
sprite: this.$store.state.settings.host + '/Public/map/sprite',
|
name: '高德矢量',
|
||||||
glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
|
sprite: this.$store.state.settings.host + '/Public/map/sprite',
|
||||||
version: 8,
|
glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
|
||||||
sources: {
|
version: 8,
|
||||||
gaode: {
|
sources: {
|
||||||
type: 'raster',
|
gaode: {
|
||||||
tileSize: 256, // 瓦片大小 256 512像素
|
type: 'raster',
|
||||||
tiles: [
|
tileSize: 256, // 瓦片大小 256 512像素
|
||||||
'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' }]
|
||||||
},
|
},
|
||||||
layers: [{ id: 'GaodeVectorLayer', type: 'raster', source: 'gaode' }]
|
|
||||||
},
|
|
||||||
GaodeRasterStyle: {
|
|
||||||
// 第三方 高德卫星
|
// 第三方 高德卫星
|
||||||
name: 'Gaode Raster',
|
{
|
||||||
sprite: this.$store.state.settings.host + '/Public/map/sprite',
|
name: '高德卫星',
|
||||||
glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
|
sprite: this.$store.state.settings.host + '/Public/map/sprite',
|
||||||
version: 8,
|
glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
|
||||||
sources: {
|
version: 8,
|
||||||
gaode: {
|
sources: {
|
||||||
type: 'raster',
|
gaode: {
|
||||||
tileSize: 256, // 瓦片大小 256 512像素
|
type: 'raster',
|
||||||
tiles: [
|
tileSize: 256, // 瓦片大小 256 512像素
|
||||||
'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' }]
|
},
|
||||||
}
|
layers: [{ id: 'GaodeRasterLayer', type: 'raster', source: 'gaode' }]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -159,7 +160,7 @@ export default {
|
|||||||
// 实例化map
|
// 实例化map
|
||||||
this.map = new mapboxgl.Map({
|
this.map = new mapboxgl.Map({
|
||||||
container: 'map',
|
container: 'map',
|
||||||
style: this.GoogleRasterStyle,
|
style: this.mapStyles[0],
|
||||||
center: this.defaultLnglat,
|
center: this.defaultLnglat,
|
||||||
zoom: this.defaultZoom,
|
zoom: this.defaultZoom,
|
||||||
pitch: 0,
|
pitch: 0,
|
||||||
@ -174,15 +175,9 @@ export default {
|
|||||||
// 全屏 并再之后 刷新地图
|
// 全屏 并再之后 刷新地图
|
||||||
this.map.addControl(new CustomFullscreenControl(this.handleResize), 'top-right')
|
this.map.addControl(new CustomFullscreenControl(this.handleResize), 'top-right')
|
||||||
|
|
||||||
// 地图样式选择
|
|
||||||
// 默认样式(可以根据需要修改或添加更多样式)
|
|
||||||
MapboxStyleSwitcherControl.DEFAULT_STYLES = [
|
|
||||||
{ title: '谷歌卫星', uri: 'mapbox://styles/mapbox/streets-v11' },
|
|
||||||
{ title: '高德卫星', uri: 'mapbox://styles/mapbox/satellite-v9' }
|
|
||||||
// 你可以添加更多样式
|
|
||||||
]
|
|
||||||
// 地图样式选择控件
|
// 地图样式选择控件
|
||||||
const styleSwitcherControl = new MapboxStyleSwitcherControl([], 'iconfont icon-duozhang f-s-20')
|
// 自定义地图样式列表
|
||||||
|
const styleSwitcherControl = new MapboxStyleSwitcherControl(this.mapStyles, 'iconfont icon-duozhang f-s-20', this.currentStyleIndex)
|
||||||
this.map.addControl(styleSwitcherControl, 'top-right')
|
this.map.addControl(styleSwitcherControl, 'top-right')
|
||||||
|
|
||||||
// 飞机跟随
|
// 飞机跟随
|
||||||
@ -597,5 +592,4 @@ export default {
|
|||||||
background-size: cover;
|
background-size: cover;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,58 +1,142 @@
|
|||||||
import mapboxgl from 'mapbox-gl'
|
import mapboxgl from 'mapbox-gl'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义地图样式切换控件
|
||||||
|
* 用于在 Mapbox 地图上添加一个控件,允许用户选择不同的地图样式
|
||||||
|
*/
|
||||||
export class MapboxStyleSwitcherControl {
|
export class MapboxStyleSwitcherControl {
|
||||||
constructor (styles = [], defaultIconClass = '') {
|
/**
|
||||||
this.styles = styles.length ? styles : MapboxStyleSwitcherControl.DEFAULT_STYLES
|
* 构造函数
|
||||||
this.defaultIconClass = defaultIconClass // 用于设置自定义图标的类名
|
* @param {Array} styles - 可选的样式列表,每个样式包含 name 和 URI。默认为空数组。
|
||||||
this.controlContainer = null
|
* @param {String} defaultIconClass - 自定义图标的 CSS 类名。默认为空字符串。
|
||||||
this.map = null
|
* @param {Number} currentStyleIndex - 当前选中的样式索引。默认为 0。
|
||||||
this.styleButton = null
|
*/
|
||||||
this.styleDropdown = null
|
constructor (styles = [], defaultIconClass = '', currentStyleIndex = 0) {
|
||||||
|
this.styles = styles
|
||||||
|
this.defaultIconClass = defaultIconClass
|
||||||
|
this.currentStyleIndex = currentStyleIndex // 当前样式索引
|
||||||
|
this.controlContainer = null // 控件容器
|
||||||
|
this.map = null // 地图实例
|
||||||
|
this.styleButton = null // 切换样式的按钮
|
||||||
|
this.styleDropdown = null // 样式选择的下拉菜单
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加控件到地图上
|
||||||
|
* @param {MapboxMap} map - Mapbox 地图实例
|
||||||
|
* @returns {HTMLElement} 控件的容器元素
|
||||||
|
*/
|
||||||
onAdd (map) {
|
onAdd (map) {
|
||||||
this.map = map
|
this.map = map
|
||||||
|
|
||||||
|
// 创建控件的容器元素
|
||||||
this.controlContainer = document.createElement('div')
|
this.controlContainer = document.createElement('div')
|
||||||
this.controlContainer.className = 'mapboxgl-ctrl mapboxgl-ctrl-group'
|
this.controlContainer.className = 'mapboxgl-ctrl mapboxgl-ctrl-group'
|
||||||
|
this.controlContainer.style.display = 'flex'
|
||||||
|
this.controlContainer.style.flexDirection = 'column'
|
||||||
|
this.controlContainer.style.alignItems = 'center'
|
||||||
|
this.controlContainer.style.justifyContent = 'center'
|
||||||
|
this.controlContainer.style.overflow = 'hidden'
|
||||||
|
|
||||||
|
// 创建切换样式的按钮
|
||||||
this.styleButton = document.createElement('button')
|
this.styleButton = document.createElement('button')
|
||||||
this.styleButton.className = this.defaultIconClass || 'style-switcher-button' // 如果提供了自定义类名,则使用它
|
this.styleButton.className = this.defaultIconClass || 'style-switcher-button' // 如果提供了自定义类名,则使用它
|
||||||
this.styleButton.onclick = this._toggleDropdown.bind(this)
|
this.styleButton.onclick = this._toggleDropdown.bind(this) // 绑定按钮点击事件
|
||||||
|
|
||||||
|
// 让按钮内容(图标)居中
|
||||||
|
this.styleButton.style.display = 'flex'
|
||||||
|
this.styleButton.style.alignItems = 'center'
|
||||||
|
this.styleButton.style.justifyContent = 'center'
|
||||||
|
this.styleButton.style.width = '29px' // 可以根据需要调整
|
||||||
|
this.styleButton.style.height = '29px' // 可以根据需要调整
|
||||||
|
|
||||||
|
// 创建样式选择的下拉菜单
|
||||||
this.styleDropdown = document.createElement('div')
|
this.styleDropdown = document.createElement('div')
|
||||||
this.styleDropdown.className = 'style-dropdown'
|
this.styleDropdown.className = 'style-dropdown'
|
||||||
this.styleDropdown.style.display = 'none'
|
this.styleDropdown.style.display = 'none' // 初始状态为隐藏
|
||||||
this.styles.forEach(style => {
|
this.styleDropdown.style.cursor = 'pointer' // 鼠标样式
|
||||||
|
|
||||||
|
// 为每个样式创建选择项并添加到下拉菜单中
|
||||||
|
this.styles.forEach((style, index) => {
|
||||||
const styleOption = document.createElement('div')
|
const styleOption = document.createElement('div')
|
||||||
styleOption.className = 'style-option'
|
styleOption.className = 'style-option'
|
||||||
styleOption.innerHTML = style.title
|
styleOption.innerHTML = style.name // 使用 name 作为显示内容
|
||||||
styleOption.onclick = () => this._changeStyle(style.uri)
|
styleOption.style.padding = '5px 5px'
|
||||||
|
styleOption.style.borderTop = '1px solid #ddd'
|
||||||
|
styleOption.style.overflow = 'hidden'
|
||||||
|
// 如果当前样式索引与选中样式索引匹配,添加高亮样式
|
||||||
|
if (this.currentStyleIndex === index) {
|
||||||
|
styleOption.style.color = '#409EFF' // 设置选中项字体颜色
|
||||||
|
} else {
|
||||||
|
styleOption.style.color = 'black' // 设置默认字体颜色
|
||||||
|
}
|
||||||
|
styleOption.onclick = () => this._changeStyle(style, index) // 绑定样式选择事件
|
||||||
|
|
||||||
|
// 添加鼠标经过效果
|
||||||
|
styleOption.addEventListener('mouseover', () => {
|
||||||
|
styleOption.style.backgroundColor = '#f0f0f0' // 鼠标经过时的背景颜色
|
||||||
|
})
|
||||||
|
|
||||||
|
styleOption.addEventListener('mouseout', () => {
|
||||||
|
styleOption.style.backgroundColor = 'transparent' // 鼠标移开时的背景颜色
|
||||||
|
})
|
||||||
|
|
||||||
this.styleDropdown.appendChild(styleOption)
|
this.styleDropdown.appendChild(styleOption)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 将按钮和下拉菜单添加到控件容器中
|
||||||
this.controlContainer.appendChild(this.styleButton)
|
this.controlContainer.appendChild(this.styleButton)
|
||||||
this.controlContainer.appendChild(this.styleDropdown)
|
this.controlContainer.appendChild(this.styleDropdown)
|
||||||
|
|
||||||
return this.controlContainer
|
return this.controlContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从地图上移除控件
|
||||||
|
*/
|
||||||
onRemove () {
|
onRemove () {
|
||||||
this.controlContainer.parentNode.removeChild(this.controlContainer)
|
this.controlContainer.parentNode.removeChild(this.controlContainer)
|
||||||
this.map = null
|
this.map = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换下拉菜单的显示状态
|
||||||
|
*/
|
||||||
_toggleDropdown () {
|
_toggleDropdown () {
|
||||||
if (this.styleDropdown.style.display === 'none') {
|
if (this.styleDropdown.style.display === 'none') {
|
||||||
this.styleDropdown.style.display = 'block'
|
this.styleDropdown.style.display = 'block' // 显示下拉菜单
|
||||||
|
this.styleButton.style.width = '100%' // 可以根据需要调整
|
||||||
} else {
|
} else {
|
||||||
this.styleDropdown.style.display = 'none'
|
this.styleDropdown.style.display = 'none' // 隐藏下拉菜单
|
||||||
|
this.styleButton.style.width = '29px' // 可以根据需要调整
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_changeStyle (styleURI) {
|
/**
|
||||||
this.map.setStyle(styleURI)
|
* 切换地图样式
|
||||||
this.styleDropdown.style.display = 'none'
|
* @param {Object} style - 要切换到的样式对象
|
||||||
|
* @param {Number} index - 要切换到的样式索引
|
||||||
|
*/
|
||||||
|
_changeStyle (style, index) {
|
||||||
|
this.map.setStyle(style) // 设置地图样式
|
||||||
|
this.styleDropdown.style.display = 'none' // 隐藏下拉菜单
|
||||||
|
this.styleButton.style.width = '29px' // 可以根据需要调整
|
||||||
|
this.currentStyleIndex = index // 更新当前选中的样式索引
|
||||||
|
this._updateStyleOptions() // 更新下拉菜单中的样式选项
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新下拉菜单中的样式选项
|
||||||
|
*/
|
||||||
|
_updateStyleOptions () {
|
||||||
|
const styleOptions = this.styleDropdown.querySelectorAll('.style-option')
|
||||||
|
styleOptions.forEach((option, index) => {
|
||||||
|
if (this.currentStyleIndex === index) {
|
||||||
|
option.style.color = '#409EFF' // 高亮选中项
|
||||||
|
} else {
|
||||||
|
option.style.color = 'black' // 默认字体颜色
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user