美文网首页开源GIS加油站
mapboxGL中的底图切换

mapboxGL中的底图切换

作者: 牛老师讲webgis | 来源:发表于2023-11-12 19:14 被阅读0次

    概述

    底图切换,这么简单的功能还要写一篇文章?值得的,为什么这么说呢?因为mapboxGL的矢量底图有上百个,不同的底图用的样式、图层的名称、图层的内容、字体库、图标库都不一样,尤其是当地图上已经叠加了很多的图层之后。这时候你就会说它不是提供了map.setStyle的方法吗,是提供了,但你设置一下试试,一下让你回到解放前。好了,屁话说的有点多,本文就带你看看mapboxGL中矢量底图和栅格底图怎么实现切换。

    效果

    矢量暗黑 矢量白天 栅格底图

    实现思路

    1. 添加分割图层

    在地图加载完成后添加两个background类型的图层,设置其不显示,第一个用来区分矢量地图图层和栅格底图,第二个用来控制将所有的栅格底图添加到这两个中间;

    map.on('load', () => {
      map.addLayer({
        "id": "base-layer-split",
        "type": "background",
        "layout": {
            "visibility": "none"
        },
        "paint": {
            "background-color": "rgba(0, 0, 0, 0)"
        }
      })
      map.addLayer({
        "id": 'base-layer-last',
        "type": "background",
        "layout": {
          "visibility": "none"
        },
        "paint": {
          "background-color": "rgba(0, 0, 0, 0)"
        }
      })
    })
    

    2. 添加栅格底图

    完成了第一步,接下来将所有的栅格底图添加进去,并设置其不显示。

    // 添加栅格底图
    this.imageTiles.forEach(({ id, minzoom, maxzoom, url, scheme, tileSize }) => {
      this.map.addSource(`${BASE_IMAGE}-${id}`, {
        type: 'raster',
        tiles: url,
        tileSize: tileSize || 256,
        scheme: scheme || "xyz",
      });
      this.map.addLayer({
          id: `${BASE_IMAGE}-${id}`,
          type: 'raster',
          source: `${BASE_IMAGE}-${id}`,
          maxzoom: maxzoom || 18,
          minzoom: minzoom || 0,
          layout: {
            visibility: "none",
          },
        }, 'base-layer-last' );
    });
    

    3. 矢量切栅格

    矢量切换栅格的实现比较简单,通过map.setLayoutProperty设置矢量底图不可见,选中的栅格底图可见即可。

    const style = {
      ...this.map.getStyle()
    }
    const layers = [...style.layers]
    const vecIndex = layers.map(layer => layer.id).indexOf('base-layer-split')
    const beforeLayers = layers.splice(0, vecIndex)
    if(type === 'img') {
      // 隐藏矢量底图
      beforeLayers.forEach(layer => {
        map.setLayoutProperty(layer.id, 'visibility', 'none')
      })
      // 栅格底图处理
      this.imageTiles.forEach(img => {
        const visibility = img.id === val1.id ? 'visible' : 'none'
        map.setLayoutProperty(`${BASE_IMAGE}-${img.id}`, 'visibility', visibility)
      })
    }
    

    4. 切换到矢量

    不论是从栅格切换到矢量还是从矢量切换到矢量,都是一样的,在进行地图切换的时候要通过setStyle来实现,但是实现的时候需要注意:

    • 将栅格影像不可见
    • 需要将上一个状态地图的source保留,作为新的style的source;
    • 将分割图层后面的图层添加到新的style的layers后面;
      实现代码可如下:
    const style = {
      ...this.map.getStyle()
    }
    const sources = {
      ...style.sources
    }
    const layers = [...style.layers]
    const vecIndex = layers.map(layer => layer.id).indexOf(SKY_LAYER)
    const beforeLayers = layers.splice(0, vecIndex)
    if(type1 === 'vec')  {
      fetch(val1.url).then(res => res.json()).then(res => {
        // 设置栅格底图不可见
        layers.forEach(layer => {
          if(layer.id.indexOf(BASE_IMAGE) !== -1) layer.layout.visibility = 'none'
        })
        // 保留上一个状态地图的`source`
        res.sources = sources
        // 将分割图层后面的图层添加到新的style的layers后面
        res.layers = [
          ...res.layers,
          ...layers
        ]
        map.setStyle(res)
      })
    }
    

    相关文章

      网友评论

        本文标题:mapboxGL中的底图切换

        本文链接:https://www.haomeiwen.com/subject/yslrwdtx.html