Echart在Openlayers的应用-热力图

概述

在前文中,有一篇文章讲述了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},
  ……
]

查看示例

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员的诗和远方

在React Native中优雅的使用iconfont

React Native大火大热,其中为了解决图标,易于修改,换颜色,高清等需求,iconfont的应用更是必不可少。 React Native中的ic...

67340
来自专栏学海无涯

Python爬虫之BeautifulSoup

上一篇博文中提到用正则表达式来匹配数据项,但是写起来容易出错,如果有过DOM开发经验或者使用过jQuery的朋友看到BeautifulSoup就像是见到了老朋友...

436100
来自专栏GIS讲堂

Openlayers中Google地图的加载

在实现的时候,参考了mygisforum的文章http://blog.csdn.net/mygisforum/article/details/7582449的内...

45450
来自专栏Golang语言社区

go语言实现通过FTP库自动上传web日志

因为平时管理的web服务器都是VM服务器,为节省硬盘空间,一般给虚拟机分配的硬盘空间都比较小,只有8G,因为,保存不了多少日志,所以每天都需要把每台WEB日志转...

50530
来自专栏程序员维他命

MJRefresh 源码解析

MJRefresh是李明杰老师的作品,到现在已经有1w+颗star了,是一个简单实用,功能强大的iOS下拉刷新(也支持上拉加载更多)控件。它的可定制性很高,几乎...

21420
来自专栏Google Dart

Flutter 构建完整应用手册-设计基础知识 顶

这本食谱包含演示如何在写Flutter应用程序时解决常见问题的食谱。 每个配方都是独立的,可以作为参考帮助您构建应用程序。

14510
来自专栏张高兴的博客

张高兴的 UWP 开发笔记:汉堡菜单进阶

46860
来自专栏张善友的专栏

初探ReactJS.NET 开发

ReactJS通常也被称为"React",是一个刚刚在这场游戏中登场的新手。它由Facebook创建,并在2013年首次发布。Facebook认为React在处...

26750
来自专栏张高兴的博客

张高兴的 UWP 开发笔记:手机状态栏 StatusBar

36450
来自专栏GIS讲堂

OL3+中链家地图找房功能实现

看看链家的地图找房功能,其实比较简单,主要包涵: 1)基于行政区划的统计展示; 2)分级别展示,逐级钻取。

26730

扫码关注云+社区

领取腾讯云代金券