Mapbox GL基础(十一):地图下钻

为了丰富地图的展示形式,研究了地图下钻功能,类似于DataV.GeoAtlas实现的效果,下面将实现的过程进行说明。

数据的准备

要实现地图下钻功能,首先按要求准备需要的数据,使字段对应。此处仍然已DataV.GeoAtlas上的数据为例进行说明,下面是在此网站上下载的吉林省各个市与各个市对应区县的geojson数据,然后按照一定的规则进行字段的设置,下图为最终设置好的字段名称与数据。
在这里插入图片描述
在这里插入图片描述

初始化地图

初始化地图,加载底图服务,然后加载事先准备好的吉林省各个市的数据,代码如下:

mapBoxMap.on("load", () => {
  axios({url: cityUrl})
  .then(function (res) {
    //获取所有的city数据
    cityFeature = res.data.features
    mapBoxMap.addSource('my首页边界_200', {
      'type': 'geojson',
      'data': cityUrl
    })
    mapBoxMap.addLayer({
      'id': '首页边界',
      'type': 'fill',
      'source': 'my首页边界_200',
      'layout': {},
      'paint': {
        'fill-color': 'rgba(0,168,227,0)',
        'fill-outline-color':'#01B3E9',
      }
    });
  })
  axios({url: quUrl})
  .then(function (res) {
    //获取所有的区县数据
    quFeature = res.data.features
  })
});

此处说明:最开始获取所有市和区县feature的目的是为了减少滑动时请求过慢造成的卡顿情况发生。

鼠标的滑动

地图下钻功能,可以分为鼠标划入划出的高亮、鼠标点击时的下钻。
先介绍鼠标的滑动时触发的事件流程:

mapBoxMap.on("mousemove",function (e) {
  e.preventDefault()
  let xy = mapBoxMap.project([e.lngLat.lng, e.lngLat.lat])
  const features = mapBoxMap.queryRenderedFeatures(
    [xy.x,xy.y],
    {layers:["首页边界"]}
  )
  if(features.length > 0){
    //不存在区县  市级别
    if(!features[0].properties.name){
      //判断当前选中的城市是否为鼠标滑过的城市
      //不相同则进行新的数据加载
      if(!(nowCityMove == features[0].properties.city)){
        if (mapBoxMap.getSource('highLayerMouse')) {
          mapBoxMap.removeLayer('highLayerMouse')
          mapBoxMap.removeSource('highLayerMouse')
        }
        setTimeout(() => {
          if (!mapBoxMap.getSource('highLayerClick')) {
            mapBoxMap.getCanvas().style.cursor = 'pointer'
            nowCityMove = features[0].properties.city
            let featureNew = features[0].geometry
            for(let i=0;i<cityFeature.length;i++){
              if(features[0].properties.city == cityFeature[i].properties.city){
                featureNew = cityFeature[i].geometry
                break
              }
            }
            showHighLayerMouse(featureNew)
          }
        })
      }
    }
    else{
      if(!(nowQuMove == features[0].properties.name)){
        if (mapBoxMap.getSource('highLayerMouse')) {
          mapBoxMap.removeLayer('highLayerMouse')
          mapBoxMap.removeSource('highLayerMouse')
        }
        setTimeout(() => {
          if (!mapBoxMap.getSource('highLayerClick')) {
            mapBoxMap.getCanvas().style.cursor = 'pointer'
            nowCityMove = features[0].properties.city
            nowQuMove = features[0].properties.name
            let featureNew = features[0].geometry
            for(let i=0;i<quFeature.length;i++){
              if((nowQuMove == quFeature[i].properties.name) && (nowCityMove == quFeature[i].properties.city)){
                featureNew = quFeature[i].geometry
                break
              }
            }
            showHighLayerMouse(featureNew)
          }
        })
      }
    }
  }
  else{
    nowCityMove =''
    nowQuMove=''
    //地图上的指针变成自动的
    mapBoxMap.getCanvas().style.cursor = 'auto';
    if (mapBoxMap.getSource('highLayerMouse')) {
      mapBoxMap.removeLayer('highLayerMouse')
      mapBoxMap.removeSource('highLayerMouse')
    }
  }
})

此处说明:首先判断划入时是否存在feature,不存在就都清空;如果存在,再判断划入时处于市级别还是区县级别,同时要判断划入处的城市名称是否为当前显示高亮的名称,避免抖动的情况;滑动最终效果如下:
在这里插入图片描述

鼠标的点击

接下来介绍鼠标点击时触发的事件流程:

mapBoxMap.on("click",function (e) {
  let xy = mapBoxMap.project([e.lngLat.lng, e.lngLat.lat])
  const features = mapBoxMap.queryRenderedFeatures(
    [xy.x,xy.y],
    {layers:["首页边界"]}
  )
  if(features.length > 0){
    //不存在区县  市级别
    if(!features[0].properties.name){
      nowCityClick = features[0].properties.city
      let allSources = mapBoxMap.getStyle().sources;
      for (const key in allSources) {
        if (allSources.hasOwnProperty(key) && /首页边界/.test(key)) {
          if (mapBoxMap.getSource('my首页边界_200')) {
            mapBoxMap.removeLayer('首页边界')
            mapBoxMap.removeSource('my首页边界_200')
          }
          setTimeout(()=>{
            mapBoxMap.addSource('my首页边界_200', {
              'type': 'geojson',
              'data': quUrl
            });
            mapBoxMap.addLayer({
              'id': '首页边界',
              'type': 'fill',
              'source': 'my首页边界_200',
              'layout': {},
              'filter':['==', 'city', features[0].properties.city],
              'paint': {
                'fill-color': 'rgba(0,168,227,0)',
                'fill-outline-color':'#01B3E9',
                'fill-antialias':true
              }
            });
          })
        }
      }
    }
    else{
      if (mapBoxMap.getSource('highLayerPoint')) {
        return
      }else{
        nowQuClick = features[0].properties.name
        mapBoxMap.setFilter('首页边界',['all',['==','city',features[0].properties.city],['==','name',features[0].properties.name]]);
        let featureNew = features[0].geometry
        let bbox = turf.bbox(featureNew);
        mapBoxMap.fitBounds([[bbox[0]-0.01, bbox[1]-0.01], [bbox[2]+0.01, bbox[3]+0.01]],{
          linear: false,
          animate: true,
        })
        showHighLayer(featureNew)
      }
    }
  }
  else{
    if (mapBoxMap.getSource('highLayerClick')) {
      mapBoxMap.removeLayer('highLayerClick')
      mapBoxMap.removeSource('highLayerClick')
    }
    //地图上的指针变成自动的
    mapBoxMap.getCanvas().style.cursor = 'auto';
    if(nowQuClick == ''){
      let allSources = mapBoxMap.getStyle().sources;
      if(!(allSources['my首页边界_200'].data == cityUrl)){
        if (mapBoxMap.getSource('my首页边界_200')) {
          mapBoxMap.removeLayer('首页边界')
          mapBoxMap.removeSource('my首页边界_200')
        }
        setTimeout(()=>{
          mapBoxMap.addSource('my首页边界_200', {
            'type': 'geojson',
            'data': cityUrl
          });
          mapBoxMap.addLayer({
            'id': '首页边界',
            'type': 'fill',
            'source': 'my首页边界_200',
            'layout': {},
            'paint': {
              'fill-color': 'rgba(0,168,227,0)',
              'fill-outline-color':'#01B3E9',
              'fill-antialias':true
            }
          });
        })
      } 
    }
    else{
      nowQuClick = ''
      mapBoxMap.setFilter('首页边界',['==','city',nowCityClick]);
    }
  }
})

此处说明:首先判断点击时是否存在feature,不存在判断处于哪一级别,进而来决定返回上一级别是什么;如果存在,再判断划入时处于市级别还是区县级别,同时要判断划入处的城市名称是否为当前显示高亮的名称,避免抖动的情况;点击最终效果如下:
在这里插入图片描述

总结

本文针对地图下钻功能的实现进行了说明,以后如果遇到新的功能再进行补充,接下来的章节将继续探索Mapbox。
欢迎关注星林社区,文章将同步更新在星林社区中!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值