HeatMap.JS+ArcGISAPI结合显示热力图
一、热力图数据获取和处理
- 通过接口获取对应的数据
- 针对获取的数据进行数据的处理
- 通过Turf.js计算点和点之间的距离
- 设定默认的距离和默认最大权重,并根据上面计算的距离重新计算当前点位的权重
- 当该点位的权重超过默认最大权重,更新最大权重
- 将点位信息按照[经度,纬度,权重]的格式进行暂存
- 设置heatmap的config,获取当前地图的视图view
- 创建热力图图层,并刷新视图
// 绘制热力图
drawHeatMap() {
var caseList = this.heatMapList.rows;
var that = this;
var points = [];
var distance;
var defaultDistance = 3;
var defaultCount = 10;
var maxCount = defaultCount;
require([ "esri/geometry/Point"], function (Point) {
Robin.Map.MapView.when(function () {
// 遍历获取的地图事件点位,根据点位之间的距离确定每个点位的权重信息
for (var i = 0; i < caseList.length; i++) {
var count = defaultCount;
for (var j = 0; j < caseList.length - 1; j++) {
//通过turf.js计算每个相邻点的点位距离,生成不同的权重
var from = turf.point([caseList[j].COORDX, caseList[j].COORDY]);
var to = turf.point([caseList[j + 1].COORDX, caseList[j + 1].COORDY]);
distance = turf.distance(from, to);
if (distance < defaultDistance) {
count += (defaultDistance - distance) / defaultDistance;
}
}
if (maxCount < count) {
maxCount = count;
}
// [经度,纬度,权重]
var point = [caseList[i].COORDX, caseList[i].COORDY,count];
points.push(point);
}
var config = {
container: null,
radius: 30,
maxOpacity: .7,
minOpacity: 0,
blur: .85,
gradient: {
0.25: "rgb(000,000,255)",
0.55: "rgb(000,255,255)",
0.65: "rgb(000,255,000)",
0.98: "rgb(255,255,000)",
1.00: "rgb(255,000,000)"
}
};
// 需要传递的参数
// view:地图视图
// config:配置参数
// points:地图点位 可以只传递经纬度,此时默认权重为1
if (that.heatmap != null) {
that.heatmap.setData(points);
} else {
that.heatmap = new HeatMapLayer(
Robin.Map.MapView,
config,
points
);
}
// 设置显隐后需要立即刷新热力图层,防止热力图与当前视图不匹配
that.heatmap.setVisible(that.heatMapShow);
that.heatmap.freshenLayer();
});
});
}
二、根据heatMap.JS和ArcGISAPI相关的方法进行HeatMapLayer组件的封装
-
构建热力图并与ArcGIS结合主要需要以下几点:
- view:当前地图的视图
- box:显示热力图的container
- heatmap:通过h337创建的热力图,可以看成heatmap.js根据传入的config创建的热力图层
- data:绘制热力图需要的数据。由于heatmap是根据屏幕坐标来绘制,所以需要针对经纬度坐标进行一次转换
-
具体实现方法
-
承接并设定当前地图视图
setBaseMap: function (view) { this.view = view; },
-
创建DIV来承接热力图
- with和height与view一致
- DOM父节点时"esri-view-surface[0]"
/*创建HeatMaplayer的容器,添加到map的layers下面*/ createDIV: function () { this.box = document.createElement("div"); this.box.setAttribute("id", "testData"); this.box.style.width = this.view.width + 'px'; this.box.style.height = this.view.height + 'px'; this.box.style.position = "absolute"; this.box.style.top = 0; this.box.style.left = 0; let parent = document.getElementsByClassName("esri-view-surface")[0]; parent.appendChild(this.box); },
-
更新热力图的config
setConfig: function (config) { this.config = { container: this.box, //图像容器 radius: config.radius, //半径 maxOpacity: config.maxOpacity, //最大透明度 minOpacity: config.minOpacity, //最小透明度 debug: false, visible: true, useLocalMaximum: false, gradient: config.gradient //渐变度 }; },
-
创建热力图图层
/*创建HeatMaplayer的容器,添加到map的layers下面*/ createLayer: function () { this.heatmap = h337.create(this.config); },
-
数据转换
/*转换数据*/ convertHeatmapData: function (data) { var heatPluginData = { max: this.MaxValue(data), data: [] //空数据 }; if (data == null || data.length == 0) { return heatPluginData; } if (data[0].length == 2) { for (var i = 0; i < data.length; i++) { var screenpoint = this.view.toScreen(new Point({ longitude: data[i][0], latitude: data[i][1], })); heatPluginData.data.push( { x: Math.round(screenpoint.x), y: Math.round(screenpoint.y), value: 1 } ) } } else { for (var i = 0; i < data.length; i++) { var screenpoint = this.view.toScreen(new Point({ longitude: data[i][0], latitude: data[i][1], })); heatPluginData.data.push( { x: Math.round(screenpoint.x), y: Math.round(screenpoint.y), value: data[i][2] } ) } } return heatPluginData; },
-
添加地图事件的监听,判断是否需要重新绘制
/*监听地图事件,根据图层是否显示,判断是否重绘热力图*/ startMapEventListeners: function () { let view = this.view; view.watch("extent", lang.hitch(this, function () { if (!this.visible) return; this.freshenLayer(); this.box.hidden = false; })); view.watch("camera", lang.hitch(this, function () { if (!this.visible) return; this.freshenLayer(); this.box.hidden = false; })); }
-
需要用到的ArcGISAPI的 “dojo/_base/declare”, “dojo/_base/lang”, “esri/geometry/Point”, "esri/geometry/SpatialReference"
-
还有热力图setData,清除渲染和刷新、销毁等方法,比较简单,不再赘述。