前言

在公司项目中,之前使用的是vue-baidu-map库,功能上使用暂无太大问题。最近需要在项目基础上添加一个大屏数据页面,并涉及到换肤功能,就是在换肤这里遇到了一些坑,使用个性化主题之后,出现,地图加载卡顿、白色方块,图层缩放最大等级问题等。

查了一些资料,因为vue-baidu-map中使用的是v2版本,而在给地图设置个性化主题时,使用的是setMapStyleV2方法,这个方法要V3版本才有。所以、跟着教程把vue-baidu-map修改成了V3版本,但事与愿违,并没有生效,反而在切换主题时,出现奇怪的效果、 2个主题同时出现在地图上。

最后看了一下百度地图官方上面的一些DEMO实例,决定使用webgl,除了3D视角,在其它方面上、如地图的加载、点与点的切换,缩放等功能,都有过渡动画和一些细节上的优化,和V2相比、给人的体验好太多。

一、百度webgl地图引入和初始化

webgl可自行到vue项目中的index.html中引入

<template>
  <div :id="el" style="width:100%;height:100%;z-index:0;"></div>
</template>
<script>
export default {
  props: {
    el: {
      type: String,
      default: "alarm-big-map"
    }
  },
  data() {
    return {
      zoom: 3,
      mapObj: null,
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    // 地图初始化
    initMap() {
      if (!this.mapObj) {
        this.mapObj = new window.BMapGL.Map(this.el);
      }
      var point = new BMapGL.Point(116.404, 39.915); // 初始化中心点坐标
      this.mapObj.centerAndZoom(point, this.zoom); // 初始化地图,设置中心点坐标和地图级别
      this.mapObj.enableScrollWheelZoom(true);
    }
  }
};
</script>
<style lang="less" scoped>
</style>

二、设置个性化主题setMapStyleV2()

<template>
  <div :id="el" style="width:100%;height:100%;z-index:0;"></div>
</template>
<script>
import mapTheme from "@/assets/newbig/themeJson/default.json";
export default {
  props: {
    el: {
      type: String,
      default: "alarm-big-map"
    }
  },
  data() {
    return {
      zoom: 3,
      mapObj: null
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    // 地图初始化
    initMap() {
      if (!this.mapObj) {
        this.mapObj = new window.BMapGL.Map(this.el);
      }
      this.setTheme(mapTheme);
      var point = new BMapGL.Point(116.404, 39.915); // 初始化中心点坐标
      this.mapObj.centerAndZoom(point, this.zoom); // 初始化地图,设置中心点坐标和地图级别
      this.mapObj.enableScrollWheelZoom(true);
    },
    // 设置/切换 主题
    setTheme(styleJson) {
      this.mapObj.setMapStyleV2({
        styleJson
      });
    }
  }
};
</script>
<style lang="less" scoped>
</style>

三、添加自定义覆盖物

1、Marker
如果是一些简单的自定义图片、形状点等,使用Marker就可以了。

let myIcon = new BMapGL.Icon(
    this.renderIcon(item),
    new BMapGL.Size(25, 25)
);
let mk = new BMapGL.Marker(
   new BMapGL.Point(item.longitude, item.latitude),
   { icon: myIcon }
);
mk.setTitle(item.equipmentName); // 设置鼠标悬浮展示标题

添加点击事件

 mk.addEventListener("click", () => {})

2、自定义覆盖物
有两个自定义覆盖类,CustomOverlay和CustomHtmlLayer,经过测试和使用,CustomOverlay类的MinZoom和MaxZoom属性设置后不生效(官方的DEMO上其实也不生效),这两个属性主要是控制、在不同的缩放等级中是否展示或隐藏。所以选用CustomHtmlLayer

// 渲染 项目点
    renderItemPoint(list) {
      function createItemEle(config) {
        const box = document.createElement("div");
        box.setAttribute("class", "big-map-item-box");
        const span = document.createElement("span");
        span.innerText = config.count;

        let title = document.createElement("div");
        title.setAttribute("class", "big-map-item-box-title");
        title.innerText = config.workName;
        box.appendChild(span);
        box.appendChild(title);
        return box;
      }

      let _that = this;

      const customOverlay = new BMapGL.CustomHtmlLayer(createItemEle, {
        maxZoom: 13
      });

      let features = list.reduce((prev, next) => {
        prev.push({
          type: "Feature",
          geometry: {
            type: "Point",
            coordinates: [next.longitude, next.latitude]
          },
          properties: { // 这里的数据,点击事件中可以获取
            width: 50,
            height: 50,
            radius: 50,
            lineWidth: 20,
            bgBase: "#add",
            bgFill: "#9d55ef",
            data: 0.5,
            ...next
          }
        });

        return prev;
      }, []);

      var data = {
        type: "FeatureCollection",
        features
      };

      customOverlay.setData(data);
      // 添加自定义图层到地图上
      this.mapObj.addCustomHtmlLayer(customOverlay);
      // 点击事件
      customOverlay.addEventListener("click", function(e) {
        console.log(e.target.properties.data);
        let { longitude, latitude } = e.target.properties;
        _that.mapObj.setZoom(21);
        _that.mapObj.centerAndZoom(new BMapGL.Point(longitude, latitude), 21);
        setTimeout(() => {
          _that.zoom = 21;
        }, 1000);
      });
    },

四、清除所有覆盖物clearOverlays()

this.mapObj.clearOverlays();
Logo

前往低代码交流专区

更多推荐