贴个群号
WebGIS学习交流群461555818,欢迎大家。
前言
一般的popup是针对于单个图层的,添加单个图层的时候,就给这个图层绑定上一个popup事件
那么这样的话其实就暴露出来了一个问题,如果鼠标点所在的地方,有很多图层呢?
每个图层都绑定一个鼠标滑过展示popup的事件,那么鼠标点移动到上面的时候,下面的每个图层都会触发这个事件,就会展示出来很多popup,那么我们该怎么解决这个问题呢,只显示点击到的最上层的要素的popup。
方法一 每个图层绑定popup
为每个图层绑定一个popup,但是需要判断features的第一个要素,或者再有空间过滤图层挡着的时候的第二个要素,是不是这个图层的,如果是,那么就显示他的popup,不是的话,就不显示
addPopup(layerID){
const self = this
const popup = new mapboxgl.Popup()
let layerId = ''
this.map.on('mousemove',layerID,function (e){
e.preventDefault()
const features = self.map.queryRenderedFeatures(e.point)
// console.log(features)
//鼠标点有要素
if(features.length>0){
let properties = features[0].properties
layerId = features[0].layer.id
//如果被空间过滤图层盖住了,那就选鼠标点所在的第二个图层
if(layerId == 'filterGeoJSON'){
if(features[1]){
properties = features[1].properties
layerId = features[1].layer.id
}
}
// console.log(properties)
//鼠标点的要素需要展示popup,在popup配置里面有这个图层的配置信息的话
if(layerId ==layerID&&layerPopupName[layerId]){
//改变鼠标状态
self.map.getCanvas().style.cursor = 'pointer'
const name = properties[layerPopupName[layerId].name]
let contentData = ''
//配置信息里面如果有lable,就把lable啥的选上,没有就直接显示一个name就可以了
if(layerPopupName[layerId].label){
contentData =layerPopupName[layerId].label+':'+name+layerPopupName[layerId].units
} else{
contentData =name
}
const content = `
<div style="background: #ffffff;
border-radius: 10px;
padding: 10px;">
${contentData}
</div>
`
popup.setLngLat(e.lngLat)
.setHTML(content)
.addTo(self.map)
}
}else{
popup.remove()
//改变鼠标状态
self.map.getCanvas().style.cursor = 'grab'
}
})
}
方法二,不为单个图层绑定popup,而是为整个地图绑定popup
不再监听单个图层,而是直接监听地图,移动的鼠标点,有没有要素,如果第一层是空间过滤图层,那么需要选择第二个要素,然后判断我们的popup配置文件里面有没有配这个图层的popup信息,不是所有逇图层都需要一个popup,有要加popup的图层,咱就写到配置里面,然后展示出来
addPopup(){
const self = this
const popup = new mapboxgl.Popup()
let layerId = ''
this.map.on('mousemove',function (e){
e.preventDefault()
const features = self.map.queryRenderedFeatures(e.point)
// console.log(features)
//鼠标点有要素
if(features.length>0){
let properties = features[0].properties
layerId = features[0].layer.id
//如果被空间过滤图层盖住了,那就选鼠标点所在的第二个图层
if(layerId == 'filterGeoJSON'){
if(features[1]){
properties = features[1].properties
layerId = features[1].layer.id
}
}
// console.log(properties)
//鼠标点的要素需要展示popup,在popup配置里面有这个图层的配置信息的话
if(layerPopupName[layerId]){
//改变鼠标状态
self.map.getCanvas().style.cursor = 'pointer'
const name = properties[layerPopupName[layerId].name]
let contentData = ''
//配置信息里面如果有lable,就把lable啥的选上,没有就直接显示一个name就可以了
if(layerPopupName[layerId].label){
contentData =layerPopupName[layerId].label+':'+name+layerPopupName[layerId].units
} else{
contentData =name
}
const content = `
<div style="background: #ffffff;
border-radius: 10px;
padding: 10px;">
${contentData}
</div>
`
popup.setLngLat(e.lngLat)
.setHTML(content)
.addTo(self.map)
}else{
popup.remove()
//改变鼠标状态
self.map.getCanvas().style.cursor = 'grab'
}
}
})
}
附 popup配置文件格式,这个你自己的有什么需求,自己定制着写就好了,为了大家阅读方便,我就写一下我的上面的简单popup的配置
//简单的所有要素popup
export const layerPopupName={
//最大水深
MaxWDepth:{
name:'MaxWDepth',
units:'(m)',
label:'水深'
}
//河网
river:{
name:'河名',
units:'',
label:''
}
}