console
let map = null
const Main = {
data() {
return {
tree: [],
style: null,
defaultChecked: [],
styles: [
{
label: '标准',
url: 'https://openmap.tech/styles/streets.json'
},
{
label: '影像',
url: 'https://openmap.tech/styles/img.json'
},
{
label: '地形',
url: 'https://openmap.tech/styles/terrain.json'
}
]
}
},
mounted() {
map = new mapboxgl.Map({
container: 'map',
zoom: 7,
center: [119.3, 29.7],
pitch: 0,
bearing: 0,
hash: true
});
this.style = this.styles[0].url
},
watch: {
style() {
map.setStyle(this.style)
const loadSource = (event) => {
if (event.dataType === "style") {
this.setTree()
map.off("data", loadSource);
}
};
map.on("data", loadSource);
}
},
methods: {
async setTree() {
const styledata = await fetch(this.style).then(resp => resp.json())
const layers = styledata.layers
const tree = []
const defaultChecked = []
layers.forEach(layer => {
const path = layer['tree-path']
if (!path) {
return
}
const arr = path.split('-')
let temp = tree
for (let i = arr.length; i > 0; i--) {
const label = arr[i - 1]
const tt = temp.find(t => t.label === label)
if (tt) {
temp = tt.children
} else {
if (i === 1) {
temp.push({
label,
id: layer.id
})
} else {
temp.push({
label,
children: []
})
temp = temp[temp.length - 1].children
}
}
}
defaultChecked.push(layer.id)
})
this.tree = tree
this.defaultChecked = defaultChecked
},
checkChanged(d, flag) {
const layerId = d.id
const visible = flag ? 'visible' : 'none'
const layers = []
if (d.children) {
const find = dd => {
if (dd.children) {
dd.children.forEach(ddd => find(ddd))
} else {
layers.push(dd)
}
}
d.children.forEach(dd => find(dd))
}
layers.forEach(d => {
map.setLayoutProperty(d.id, 'visibility', visible)
})
}
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
<div id="app">
<div id="map"></div>
<el-select class="select" v-model="style" size="mini">
<el-option v-for="item in styles" :key="item.url" :label="item.label" :value="item.url">
</el-option>
</el-select>
<el-tree class="tree" :data="tree" :default-checked-keys="defaultChecked" show-checkbox node-key="id" check-on-click-node @check-change="checkChanged" >
</el-tree>
</div>
#map {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: hidden;
}
.select {
position: absolute;
right: 10px;
top: 10px;
}
.tree {
position: absolute;
z-index: 11;
left: 10px;
top: 10px;
max-height: calc(100% - 20px);
width: 300px;
background-color: white;
overflow: auto
}