Mapbox 永远只显示鼠标点最上方的要素popup

贴个群号

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:''
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值