概述
在前文中,有一篇文章讲述了Openlayers2结合Echart实现地图统计图,还以一篇文章讲述了结合heatmap.js实现Openlayers中热力图的展示。在本文,书接前文,讲述Openlayers如何结合Echart实现热力图。
效果
全图效果
放大效果
实现
1、关键点
echart实现heatmap的关键点在与屏幕坐标,所以,在地图中,应通过地理坐标到屏幕坐标的转换函数,将地理坐标转换为屏幕坐标。
2、实现代码
我将热力图扩展成为了一个openlayers的layer扩展,实现代码如下:
OpenLayers.Layer.EchartHeatmap = OpenLayers.Class(OpenLayers.Layer, { isBaseLayer : false, heatmap : null, mapLayer : null, heatdata : [], initialize : function (name, map, options) { var scope = this, heatdiv = document.createElement("div"), handler; OpenLayers.Layer.prototype.initialize.apply(this, [name, options]); heatdiv.style.cssText = "position:absolute;width:" + map.size.w + "px;height:" + map.size.h + "px;"; this.div.appendChild(heatdiv); this.map = map; this.heatdiv = heatdiv; this.heatdata = options.heatdata; this.opacity = options.opacity; handler = function (e) { if (scope.heatdata.length > 0) { scope.updateLayer(e); } }; handler(); map.events.register("zoomend", this, handler); map.events.register("moveend", this, handler); }, updateLayer : function (e) { var scope = this; require( [ 'echarts', 'echarts/chart/heatmap' ], function (ec) { var myChart = ec.init(scope.heatdiv); var heatD = []; var data = scope.heatdata; var orgXy, w, h; if(e){ orgXy = e.object.layerContainerOriginPx; } else{ orgXy={x:0,y:0}; } w = scope.map.size.w; h = scope.map.size.h; scope.heatdiv.style.cssText = "position:absolute;top:"+(-orgXy.y)+"px;left:"+(-orgXy.x)+ "px;width:" + w + "px;height:" + h + "px;"; for (var i = 0; i < data.length; ++i) { var d = data[i]; var scrPt = scope.map.getPixelFromLonLat(new OpenLayers.LonLat(d.lon, d.lat)); var x = scrPt.x, y = scrPt.y; heatD.push([ x, y, d.count ]); } var option = { series : [ { type : 'heatmap', data : heatD, opacity:scope.opacity, gradientColors : [ { offset : 0.4, color : 'green' }, { offset : 0.5, color : 'yellow' }, { offset : 0.8, color : 'orange' }, { offset : 1, color : 'red' } ], minAlpha : 0.2, valueScale : 2 } ] }; myChart.setOption(option); }); }, destroy : function () { OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments); }, CLASS_NAME : "OpenLayers.Layer.EchartHeatmap" } );前台调用的代码如下:
<html> <head> <meta charset="UTF-8"> <title>heatmap.js OpenLayers Heatmap Layer</title> <link rel="stylesheet" href="../../../plugin/OpenLayers-2.13.1/theme/default/style.css" type="text/css"> <style> html, body, #map,#chart{ padding:0; margin:0; height:100%; width:100%; overflow: hidden; } #chart{ position: absolute; top: 0px; left: 0px; z-index: 900; } </style> <script src="../../../plugin/OpenLayers-2.13.1/OpenLayers.js"></script> <script src="../../../plugin/jquery/jquery-1.8.3.js"></script> <script src="../../../plugin/echart/build/dist/echarts.js"></script> <script src="extend/echartheatlayer.js"></script> <script type="text/javascript"> require.config({ paths: { echarts: '../../../plugin/echart/build/dist' } }); var map; function init(){ var format = 'image/png'; var bounds = new OpenLayers.Bounds( 73.45100463562233, 18.16324718764174, 134.97679764650596, 53.531943152223576 ); var options = { controls: [], maxExtent: bounds, maxResolution: 0.2403351289487642, projection: "EPSG:4326", units: 'degrees' }; map = new OpenLayers.Map('map', options); var wms1 = new OpenLayers.Layer.WMS("base_map", "http://localhost:8088/geoserver/lzugis/wms", { layers: "province", transparent: true }, { isBaseLayer: true, singleTile: true }); map.addControl(new OpenLayers.Control.Zoom()); map.addControl(new OpenLayers.Control.Navigation()); var heatmap = new OpenLayers.Layer.EchartHeatmap("heatmap",map,{ heatdata:data, opacity:0.8 }); var wms2 = new OpenLayers.Layer.WMS("base_map", "http://localhost:8088/geoserver/lzugis/wms", { layers: "county", transparent: true }, { isBaseLayer: false, singleTile: true, opacity:0.2 }); map.addLayers([wms1,heatmap,wms2]); map.zoomToExtent(bounds); } </script> </head> <body onload="init()"> <div id="map"> </div> </body> </html>其中,变量data的数据格式如下:
[ {name:"东方市",lon:108.633357,lat:19.097025,count:30}, {name:"临高县",lon:109.686515,lat:19.91785,count:47}, {name:"儋州市",lon:109.575851,lat:19.518256,count:43}, {name:"昌江黎族自治县",lon:109.048657,lat:19.258351,count:71}, {name:"白沙黎族自治县",lon:109.448097,lat:19.235657,count:70}, …… ]
传播GIS知识 | 交流GIS经验 | 分享GIS价值 | 专注GIS发展
技术博客
http://blog.csdn.net/gisshixisheng
在线教程
http://edu.csdn.net/course/detail/799
Github
https://github.com/lzugis/
联系方式
q q:1004740957
e-mail:niujp08@qq.com
公众号:lzugis15
Q Q 群:452117357(webgis)
337469080(Android)