前言

项目需要,根据积水数据的多少,在页面中进行展示,选用高德热力图api。实现后发现地图的缩放会导致热力图自动更改渲染的颜色,导致预期的效果发生变化,研究文档后实现了动态调整热力图的渲染,保证在不同缩放等级的地图下都能展示预期效果

使用vue ui命令构建项目,vue版本为2.x,使用axios读取本地积水数据,
axios安装命令为npm install axios --save
完整代码先看最后

1.引入高德js

在public目录下的index.html页面中引用脚本和css样式

<script src="https://webapi.amap.com/maps?v=1.4.15&key=你申请的key值"></script>
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />

2.显示基本的热力图

显示底图:

loadMap() {
 this.map = new AMap.Map("container", {
   resizeEnable: true,
   center: [108.909759, 34.412745],
   zoom: 12,
 });
}

这里有个小地方需要注意,如果不指定宽高,那么地图无法显示
我的做法是先指定父级节点的宽高,再指定本页面的宽高
父级节点在App.vue中
在这里插入图片描述

添加热力图:

createHeatMap2() {
let _this = this; //保存vue实例,保证this作用域一致
let api = "/js/result_half.json";
axios.get(api).then((res) => {
  let data = res.data;
  console.log(tempdata);

  _this.map.plugin(["AMap.Heatmap"], function () {
    //初始化heatmap对象
    _this.heatmap = new AMap.Heatmap(_this.map, {
      radius: 0.9, //每个热力点的大小
      opacity: [0.2, 0.8], //最小透明度和最大透明度,最小透明度越小,数值小的点就越不明显;最大透明度越大,数值大的点就越明显
      blur: 0.5, //一个点外圈和内圈的大小比例,值越大,内圈占的比例就越大;值越小,外圈占的比例就越大
      gradient: {
        //同 min参数以及 max参数一起生效,比如积水数值在[0.02,0.4]之间时,
        //gradient定义了某一个积水数值在这个区间的不同位置时显示什么颜色,如果计算出来不相等,就取两者之间的颜色
        0.25: _this.level1,
        0.5: _this.level2,
        0.75: _this.level3,
        0.8: _this.level4,
        1: _this.level5,
      },
    });
    //设置数据集
    _this.heatmap.setDataSet({
      data: data,
      max: 0.5,
      min: 0.1,
    });
  });
});
},

其中,result_half.json文件存在于本地,为了符合高德api,格式需要如下

[
	{
		"lng":xxx,
		"lat":xxx,
		"count":xxx
	},
	{
		"lng":xxx,
		"lat":xxx,
		"count":xxx
	},
]

效果:
在这里插入图片描述此处存在问题,上图的地图缩放等级为12,当放大后原本应该为红色区域(积水数值较大)的地方效果会淡化,如下:
在这里插入图片描述
这里是由于heatmap.js本身的计算导致,因此需要一个方法来解决

3.显示优化

热力图的radius属性可以指定热力点的半径大小,根据高德api文档,只需要绑定一个地图缩放事件,当地图放大缩小时,调整热力点的大小,保证显示效果的一致

addHeatMapEvent() {
  let _this=this;
  _this.map.on("zoomchange", function (e) {
    let newRadius;
    let zoomLevel = _this.map.getZoom();
    if (zoomLevel <= 12) {
      newRadius = 0.9;
    } else if (zoomLevel == 13) {
      newRadius = 1;
    } else if (zoomLevel == 14) {
      newRadius = 2;
    } else if (zoomLevel == 15) {
      newRadius = 3.5;
    } else if (zoomLevel == 16) {
      newRadius = 7;
    } else {
      newRadius = 15;
    }
    _this.heatmap.setOptions({
      radius: newRadius,
    });
  });
},

由于高德的地图缩放等级并不多,这里一般用到的是12-17级,所以可以直接写死,热力点具体的半径大小需要根据显示效果慢慢调整,地图放得越大,半径就调整得越大。加入该方法后,显示效果如下:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
问题解决

4.Vue页面完整代码

<template>
  <div id="container"></div>
</template>

<script>
export default {
  mounted() {
    this.loadMap();
    this.createHeatMap2();
    this.addHeatMapEvent();
  },

  data() {
    return {
      map: null,
      heatmap: null,
      level1: "#BFEFFF",
      level2: "#00BFFF",
      level3: "yellow",
      level4: "#FFA500",
      level5: "red",
    };
  },

  methods: {
    //加载地图
    loadMap() {
      this.map = new AMap.Map("container", {
        resizeEnable: true,
        center: [108.909759, 34.412745],
        zoom: 12,
      });
    },

    //添加热力图
    createHeatMap2() {
      let _this = this; //保存vue实例,保证this作用域一致
      let api = "/js/result_half.json";
      axios.get(api).then((res) => {
        let data = res.data;
        // console.log(tempdata);

        _this.map.plugin(["AMap.Heatmap"], function () {
          //初始化heatmap对象
          _this.heatmap = new AMap.Heatmap(_this.map, {
            radius: 0.9, //每个热力点的大小
            opacity: [0.2, 0.8], //最小透明度和最大透明度,最小透明度越小,数值小的点就越不明显;最大透明度越大,数值大的点就越明显
            blur: 0.5, //一个点外圈和内圈的大小比例,值越大,内圈占的比例就越大;值越小,外圈占的比例就越大
            gradient: {
              //同 min参数以及 max参数一起生效,比如积水数值在[0.02,0.4]之间时,
              //gradient定义了某一个积水数值在这个区间的不同位置时显示什么颜色,如果计算出来不相等,就取两者之间的颜色
              0.25: _this.level1,
              0.5: _this.level2,
              0.75: _this.level3,
              0.8: _this.level4,
              1: _this.level5,
            },
          });
          //设置数据集
          _this.heatmap.setDataSet({
            data: data,
            max: 0.5,
            min: 0.1,
          });
        });
      });
    },

    //根据缩放等级调整热力点大小
    addHeatMapEvent() {
      let _this=this;
      _this.map.on("zoomchange", function (e) {
        // var oldRadius = heatmap.getOptions()['radius'];
        let newRadius;
        let zoomLevel = _this.map.getZoom();
        if (zoomLevel <= 12) {
          newRadius = 0.9;
        } else if (zoomLevel == 13) {
          newRadius = 1;
        } else if (zoomLevel == 14) {
          newRadius = 2;
        } else if (zoomLevel == 15) {
          newRadius = 3.5;
        } else if (zoomLevel == 16) {
          newRadius = 7;
        } else {
          newRadius = 15;
        }
        _this.heatmap.setOptions({
          radius: newRadius,
        });
      });
    },
  },
};
</script>

<style scoped>
html,
body,
#container {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
}
</style>

参考:

Logo

前往低代码交流专区

更多推荐