700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 在echarts中使用百度地图扩展 实现在地图上叠加显示栅格热力图

在echarts中使用百度地图扩展 实现在地图上叠加显示栅格热力图

时间:2020-02-23 06:04:14

相关推荐

在echarts中使用百度地图扩展 实现在地图上叠加显示栅格热力图

思路:

获得地图上的多边形覆盖物的点的数组中的最大的经度和纬度作为东北角的经纬度,最小的经度和纬度作为西南角的经纬度,这样的矩形将会完全包含多边形覆盖物,对这个矩形绘制栅格需;对西南角和东北角的经纬度进行处理,返回能够得到整数数量栅格需的西南角和东北角经纬度。一方面确保绘制出来的栅格需数量是整数,另一方面从西南角开始的网格的整数数量也会被作为位置使用来设置栅格需的id。根据西南角和东北角的经纬度能够得到四个角的经纬度,因此能够根据需求的网格的大小获得栅格需的数量,位置。判断每个栅格的中心点是否在多边形覆盖物内,在则给colorValue赋值为0,否则为-1。栅格根据id与接口返回的数据做匹配来获取要渲染的栅格及其value值; 判断每个栅格的中心点是否在多边形覆盖物内,在则给colorValue赋值为0,否则为-1。调用echarts渲染栅格需的方法,判断colorValue来确定是否在轮廓范围内,在则渲染,不在则不渲染,然后根据栅格的value值渲染栅格的热力。

data:function(){return {//多边形覆盖物plateOverlays:[],//栅格默认的参数blockDefaultParams:{southWest: { lng: 112.963588, lat: 22.515978 },northEast: { lng: 114.075063, lat: 23.945013 },dataBlockSize: 5000,},//接口返回的栅格的数组blockData:[]}},methods:{//根据地图上的多边形覆盖物轮廓获得最大的经度纬度作为东北角,最小的经度纬度作为西南角updateBlockDefaultParams:function(){var _this = this;var points = [];var plateOverlays = _this.plateOverlays;for (var i in plateOverlays) {var polygon = plateOverlays[i];points = points.concat(polygon.getPath());//返回多边形覆盖物的点数组}//取多边形覆盖物各点中的最大的经度纬度作为东北角,最小的经度纬度作为西南角//所绘的矩形完全包括了多边形覆盖物var lngArr = [],latArr = [];points.map(function(item){lngArr.push(item.lng);latArr.push(item.lat);})var maxLng = lngArr.reduce(function(a , b){return b > a ? b : a;});var maxLat = latArr.reduce(function(a , b){return b > a ? b : a;});var minLng = lngArr.reduce(function(a , b){return b < a ? b : a;});var minLat = latArr.reduce(function(a , b){return b < a ? b : a;});var southWest = {lng: minLng,lat: minLat}var northEast = {lng: maxLng,lat: maxLat}_this.blockDefaultParams.southWest = southWest;_this.blockDefaultParams.northEast = northEast;_this.$nextTick(function(){_this.getBlock();})},getNearestPoint :function (tp, lngLatInterval, max) {var _this = this;var nearestPoint = {};//分别获得经纬度上栅格的数量var xLengthVal = tp.lng / lngLatInterval[0];var yLengthVal = tp.lat / lngLatInterval[1];//对栅格数量进行取整var xLength = '',yLength = '';if (max) {xLength = parseInt(Math.ceil(xLengthVal));yLength = parseInt(Math.ceil(yLengthVal));}else{xLength = parseInt(Math.floor(xLengthVal));yLength = parseInt(Math.floor(yLengthVal));}//获得能够使栅格数量为整数的西南角和东北角的经纬度坐标nearestPoint.lng = lngLatInterval[0] * xLength;nearestPoint.lat = lngLatInterval[1] * yLength;return nearestPoint;},//栅格尺寸大小转化为经纬度距离distanceToLngLat : function (distance) {var _this = this;var values = new Array(2);values[0] = distance * 0.00000978;values[1] = distance * 0.00000899;return values;},//渲染网格getBlock:function(){var _this = this;var dp = _this.blockDefaultParams;// 网格的格子大小var blockSize = dp.dataBlockSize;//将网格大小转换为经纬度上的距离var lngLatInterval = _this.distanceToLngLat(blockSize);//对西南角和东北角的经纬度进行处理,返回能够得到整数数量网格的西南角和东北角经纬度var defaultSouthWest = _this.getNearestPoint(dp.southWest, lngLatInterval, false);var defaultNorthEast = _this.getNearestPoint(dp.northEast, lngLatInterval, true);//网格数量var colLength = parseInt((defaultNorthEast.lng - defaultSouthWest.lng) / lngLatInterval[0]) ;var rowLength = parseInt((defaultNorthEast.lat - defaultSouthWest.lat) / lngLatInterval[1]) ;var data = [];//最终渲染的网格的数据var blockData = _this.blockData;//接口返回的网格数组//获得(0,0)到西南角的网格数量,作为网格的位置var colStart = defaultSouthWest.lng / lngLatInterval[0];var rowStart = defaultSouthWest.lat / lngLatInterval[1];var polygons = _this.plateOverlays;for (var col = 0; col < colLength; col++) {for (var row = 0; row < rowLength; row++) {//相当于网格idvar uCode = "col" + (col + colStart) + "-row" + (row + rowStart);//遍历接口返回的数组,判断是否有匹配的网格var block = null;blockData.map(function(item){if(item.blockId == uCode){block = item;}})//获得网格的中心点var lng = defaultSouthWest.lng + col * lngLatInterval[0] + lngLatInterval[0] * 0.5;var lat = defaultSouthWest.lat + row * lngLatInterval[1] + lngLatInterval[1] * 0.5;var point = new BMap.Point(lng, lat);//判断栅格的中心点是否在多边形覆盖物内var inside = false;if (polygons != null && polygons.length > 0) {for (var i in polygons) {var polygon = polygons[i];if (BMapLib.GeoUtils.isPointInPolygon(point, polygon)) {inside = true;break;}}}var colorVal = -1;//colorValue用来判断是否要绘制,在多边形覆盖物区域内则绘制,在多边形覆盖物区域外则不绘制var value = 0;//color是热力的值if (inside) {colorVal = 0;if (block != null) {value = block.val;}}data.push({value:[col, row,colorVal,value, uCode, point]});}}//渲染每个网格function renderItem(params, api) {var context = params.context;var lngIndex = api.value(0);var latIndex = api.value(1);var pointLeftTop = getCoord(params, api, lngIndex, latIndex);var pointRightBottom = getCoord(params, api, lngIndex + 1, latIndex + 1);//如果是-1,即在区域外,则不绘制var colorVal = api.value(2);if (colorVal == -1) {context = '';lngIndex = '';latIndex = '';pointLeftTop = '';pointRightBottom = '';}return {type: 'rect',shape: {x: pointLeftTop[0],y: pointLeftTop[1],width: pointRightBottom[0] - pointLeftTop[0],height: pointRightBottom[1] - pointLeftTop[1]},style: api.style({stroke: 'rgba(73,208,180,0.9)',//网格的边线颜色}),styleEmphasis: api.styleEmphasis()};}//经度和纬度方向var lngExtent = [defaultSouthWest.lat, defaultNorthEast.lat];var latExtent = [defaultSouthWest.lng, defaultNorthEast.lng];var cellSizeCoord = [lngLatInterval[0],lngLatInterval[1]];function getCoord(params, api, lngIndex, latIndex) {var coords = params.context.coords || (params.context.coords = []);var key = lngIndex + '-' + latIndex;return coords[key] || (coords[key] = api.coord([+(latExtent[0] + lngIndex * cellSizeCoord[0]).toFixed(6),+(lngExtent[0] + latIndex * cellSizeCoord[1]).toFixed(6)]));}var option = {visualMap:{type: 'piecewise',show: false,pieces:[{min:35000,max:40000,color:'#435DFF',opacity:0.8},{min:40000,color:'#503EFF',opacity:0.8}]},series:[{type: 'custom',coordinateSystem: 'bmap',renderItem: renderItem,animation: false,encode: {tooltip: 2},data: data}]}_this.echartsModel.setOption(option);}}

这种实现方式,首先需要根据轮廓来绘制出一个矩形的全部栅格;然后再调用方法判断栅格是否在轮廓范围内,在则渲染,否则不渲染。这两步都非常耗时。

优化之后的方法:数据分析师那边算出需要渲染的栅格通过后台传到前端,返回什么渲染什么即可。(不再需要绘制全部的栅格和去判断是否在边界范围内,这些步骤交给数据分析师去做)

可以想象,由于知道了所渲染区域的最大最小经纬度,现在地图上有一个矩形,把它划分成一行行一列列;根据返回的栅格数据可以知道栅格的行和列,以此来排列渲染。

methdos:{//渲染栅格//需要的参数:所渲染区域的最大最小经纬度(数值类型)、所画栅格的经纬度大小(数值类型)、栅格数据(data=[[col,row,id,value],[col,row,id,value]])renderGrid:function(result){//所渲染区域的最大最小经纬度var lngExtent = [result.city.minlat, result.city.maxlat];var latExtent = [result.city.minlng, result.city.maxlng];//所画栅格的经纬度大小var cellSizeCoord = [result.city.lnggap,result.city.latgap];//栅格数据var data = result.block;//渲染每个网格function renderItem(params, api) {var context = params.context;var lngIndex = api.value(0);var latIndex = api.value(1);var pointLeftTop = getCoord(params, api, lngIndex, latIndex);var pointRightBottom = getCoord(params, api, lngIndex + 1, latIndex + 1);return {type: 'rect',shape: {x: pointLeftTop[0],y: pointLeftTop[1],width: pointRightBottom[0] - pointLeftTop[0],height: pointRightBottom[1] - pointLeftTop[1]},style: api.style({stroke: 'white',//网格的边线颜色}),styleEmphasis: api.styleEmphasis()};}function getCoord(params, api, lngIndex, latIndex) {var coords = params.context.coords || (params.context.coords = []);var key = lngIndex + '-' + latIndex;return coords[key] || (coords[key] = api.coord([+(latExtent[0] + lngIndex * cellSizeCoord[0]).toFixed(6),+(lngExtent[0] + latIndex * cellSizeCoord[1]).toFixed(6)]));}var option = {visualMap:{type: 'piecewise',show:false,inRange: {color: ["#FEEFAC", "#FEE199",'#FEC77F','#FEAD72','#FC8068','#EA5C5C','#D14D65','#A94A62'],opacity: 0.8,},splitNumber:8,min:0,max:100},series:[{type: 'custom',coordinateSystem: 'bmap',renderItem: renderItem,animation: false,encode: {tooltip: 2},data: data}]}this.echartsModel.setOption(option);}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。