mapbox地图切换踩坑

948 阅读1分钟

能看到这个文章,说明你已经踩坑了0.0

就是调用mapbox的setStyle后一些source和layer消失了

废话不多说!

如果只是用官方那几个地图 那用这个方式就能解决了github

我用的是浙江天地图直接cv就不行了


/**
 * 切换地图样式 [保留命中sourcesList、layersList的数据]
 */
interface ISwitchMapStyleParams {
  map: mapboxgl.Map; // 地图实例
  style: string | mapboxgl.Style; // 地图样式,支持外部解析完导入 和 mapbox自带地图
  layersList: string[]; // ["mapbox-gl-draw-", "ml-"]; // key 对应对比的位置 sources{[key]: obj}
  sourcesList: string[]; // ["gl-draw-", "ml-layerInfo-"]; // key 对应对比的位置 layers[{id: [key]}]
}
async function switchMapStyle({
  map,
  style,
  sourcesList,
  layersList,
}: ISwitchMapStyleParams) {
  let newStyle;
  if (typeof style !== "string") {
    newStyle = style;
  } else {
    const res = await axios.get(
      `https://api.mapbox.com/styles/v1/${style}?access_token=${mapboxgl.accessToken}`
    );
    newStyle = res.data;
  }
  const currentStyle = map.getStyle();
  const currentSources = Object.keys(currentStyle.sources).reduce(
    (obj, key) => {
      for (let i = 0; i < sourcesList.length; i++) {
        const sourcesKey = sourcesList[i];
        if (key.startsWith(sourcesKey)) {
          obj[key] = currentStyle.sources[key];
          break;
        }
      }
      return obj;
    },
    {}
  );
  // console.log("过滤出来 要保留的source ", currentSources);
  newStyle.sources = { ...newStyle.sources, ...currentSources };
  // console.log("合并完成的 newStyle.sources", newStyle.sources);
  const currentLayer = currentStyle.layers.filter((e) => {
    for (let i = 0; i < layersList.length; i++) {
      const layersKey = layersList[i];
      if (e.id.startsWith(layersKey)) {
        return true;
      }
    }
    return false;
  });
  // console.log("过滤出来 要保留的 layer ", currentLayer);
  newStyle.layers = [...newStyle.layers, ...currentLayer];
  // console.log("合并完成的 newStyle.layers", newStyle.layers);
  // console.log("======>  newStyle", newStyle);
  map.setStyle(newStyle);
}
// 调用方式
const styleUrl = 'https://zhejiang.tianditu.gov.cn/xxxxxxxxs_zw.json'
const res = await axios.get(styleUrl);
switchMapStyle({
    map: this.map,
    style: res.data,
    sourcesList: ["mapbox-gl-draw-", "ml-"],
    layersList: ["gl-draw-", "ml-layerInfo-"],
});
  • 再解释下这里的 sourcesList 和 layersList

  • "mapbox-gl-draw-"和"gl-draw-"是用来保留"@mapbox/mapbox-gl-draw"这个插件绘图出来的图层的,你没有的话就不用加

  • “ml-”和"ml-layerInfo-"是该项目的所有手动添加的source和layer都有各自的专有前缀,这也是我们switchMapStyle方法里用来过滤的关键

  • 【代码不规范,亲人两行泪,如果你的项目没有特别的专有前缀就去debugger看看currentStyle的内容吧...】

参考

mapbox的issue【github】

mapbox地图自定义主题切换踩坑指南【掘金】