Vue使用高德地图api实现热力图动态缩放
前言
项目需要,根据积水数据的多少,在页面中进行展示,选用高德热力图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>
参考: