mapboxGL中的底圖切換

概述

底圖切換,這么簡單的功能還要寫一篇文章?值得的,為什么這么說呢?因為mapboxGL的矢量底圖有上百個,不同的底圖用的樣式、圖層的名稱、圖層的內(nèi)容、字體庫、圖標庫都不一樣,尤其是當?shù)貓D上已經(jīng)疊加了很多的圖層之后。這時候你就會說它不是提供了map.setStyle的方法嗎,是提供了,但你設(shè)置一下試試,一下讓你回到解放前。好了,屁話說的有點多,本文就帶你看看mapboxGL中矢量底圖和柵格底圖怎么實現(xiàn)切換。

效果

矢量暗黑
矢量白天
柵格底圖

實現(xiàn)思路

1. 添加分割圖層

在地圖加載完成后添加兩個background類型的圖層,設(shè)置其不顯示,第一個用來區(qū)分矢量地圖圖層和柵格底圖,第二個用來控制將所有的柵格底圖添加到這兩個中間;

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. 添加柵格底圖

完成了第一步,接下來將所有的柵格底圖添加進去,并設(shè)置其不顯示。

// 添加柵格底圖
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. 矢量切柵格

矢量切換柵格的實現(xiàn)比較簡單,通過map.setLayoutProperty設(shè)置矢量底圖不可見,選中的柵格底圖可見即可。

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來實現(xiàn),但是實現(xiàn)的時候需要注意:

  • 將柵格影像不可見
  • 需要將上一個狀態(tài)地圖的source保留,作為新的style的source;
  • 將分割圖層后面的圖層添加到新的style的layers后面;
    實現(xiàn)代碼可如下:
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 => {
    // 設(shè)置柵格底圖不可見
    layers.forEach(layer => {
      if(layer.id.indexOf(BASE_IMAGE) !== -1) layer.layout.visibility = 'none'
    })
    // 保留上一個狀態(tài)地圖的`source`
    res.sources = sources
    // 將分割圖層后面的圖層添加到新的style的layers后面
    res.layers = [
      ...res.layers,
      ...layers
    ]
    map.setStyle(res)
  })
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容