Cesium热力图实现
转自原文 Cesium热力图实现
var _getColorPalette = function(config) {
var gradientConfig = config.gradient || config.defaultGradient;
var paletteCanvas = document.createElement('canvas');
var paletteCtx = paletteCanvas.getContext('2d'); paletteCanvas.width = 256;
paletteCanvas.height = 1; var gradient = paletteCtx.createLinearGradient(0, 0, 256, 1);
for (var key in gradientConfig) {
gradient.addColorStop(key, gradientConfig[key]);
} paletteCtx.fillStyle = gradient;
paletteCtx.fillRect(0, 0, 256, 1); return paletteCtx.getImageData(0, 0, 256, 1).data;
}; 对于输入的点数据,会根据点坐标生成一个黑色圆阴影效果。 //生成一个阴影模板
var _getPointTemplate = function(radius, blurFactor) {
var tplCanvas = document.createElement('canvas');
var tplCtx = tplCanvas.getContext('2d');
var x = radius;
var y = radius;
tplCanvas.width = tplCanvas.height = radius*2; if (blurFactor == 1) {
tplCtx.beginPath();
tplCtx.arc(x, y, radius, 0, 2 * Math.PI, false);
tplCtx.fillStyle = 'rgba(0,0,0,1)';
tplCtx.fill();
} else {
var gradient = tplCtx.createRadialGradient(x, y, radius*blurFactor, x, y, radius);
gradient.addColorStop(0, 'rgba(0,0,0,1)');
gradient.addColorStop(1, 'rgba(0,0,0,0)');
tplCtx.fillStyle = gradient;
tplCtx.fillRect(0, 0, 2*radius, 2*radius);
} var tpl;
if (!this._templates[radius]) {
this._templates[radius] = tpl = _getPointTemplate(radius, blur);
} else {
tpl = this._templates[radius];
}
// value from minimum / value range
// => [0, 1]
//根据value值设置阴影的alpha通道,后面可以通过alpha值获取value值
var templateAlpha = (value-min)/(max-min);
// this fixes #176: small values are not visible because globalAlpha < .01 cannot be read from imageData
shadowCtx.globalAlpha = templateAlpha < .01 ? .01 : templateAlpha; shadowCtx.drawImage(tpl, rectX, rectY); // update renderBoundaries
if (rectX < this._renderBoundaries[0]) {
this._renderBoundaries[0] = rectX;
}
if (rectY < this._renderBoundaries[1]) {
this._renderBoundaries[1] = rectY;
}
if (rectX + 2*radius > this._renderBoundaries[2]) {
this._renderBoundaries[2] = rectX + 2*radius;
}
if (rectY + 2*radius > this._renderBoundaries[3]) {
this._renderBoundaries[3] = rectY + 2*radius;
} }
首先呢,阴影是黑色的,所以接下来heatmap会进行一个像素点重新着色的过程,根据每个点的alpha值*4(rgba步长)得出一个offset,然后从调色板上取颜色。因为上面设置了阴影透明度效果是递减的,所以在获取颜色的时候,就能获得一个平滑的渐变效果。这样就得到了热力图。
_colorize: function() {
var x = this._renderBoundaries[0];
var y = this._renderBoundaries[1];
var width = this._renderBoundaries[2] - x;
var height = this._renderBoundaries[3] - y;
var maxWidth = this._width;
var maxHeight = this._height;
var opacity = this._opacity;
var maxOpacity = this._maxOpacity;
var minOpacity = this._minOpacity;
var useGradientOpacity = this._useGradientOpacity; if (x < 0) {
x = 0;
}
if (y < 0) {
y = 0;
}
if (x + width > maxWidth) {
width = maxWidth - x;
}
if (y + height > maxHeight) {
height = maxHeight - y;
} var img = this.shadowCtx.getImageData(x, y, width, height);
var imgData = img.data;
var len = imgData.length;
var palette = this._palette; for (var i = 3; i < len; i+= 4) {
var alpha = imgData[i];
var offset = alpha * 4; if (!offset) {
continue;
} var finalAlpha;
if (opacity > 0) {
finalAlpha = opacity;
} else {
if (alpha < maxOpacity) {
if (alpha < minOpacity) {
finalAlpha = minOpacity;
} else {
finalAlpha = alpha;
}
} else {
finalAlpha = maxOpacity;
}
} imgData[i-3] = palette[offset];
imgData[i-2] = palette[offset + 1];
imgData[i-1] = palette[offset + 2];
imgData[i] = useGradientOpacity ? palette[offset + 3] : finalAlpha; } img.data = imgData;
this.ctx.putImageData(img, x, y); this._renderBoundaries = [1000, 1000, 0, 0]; },
'if(heightValue.r<1.0/255.0) heightValue.a= 0.0; ' +
在Openlayer中实现热力图起始是很方便的。具体可参考下面的几篇文章。
进一步学习的参考资料
至于绘制的过程和原理、及完整代码,可以参考
http://www.wangshaoxing.com/blog/how-to-draw-a-heatmap.html
code
https://github.com/wshxbqq/WebGL-HeatMap
Cesium热力图实现的更多相关文章
- cesium 热力图
- Cesium专栏-热力图(附源码下载)
Cesium Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精 ...
- cesium 水面、淹没 效果
水面效果 参考: http://cesiumcn.org/topic/158.html http://api.rivermap.cn/cesium/rivermap/map.html https:// ...
- Cesium学习系列汇总
内容比较多,完整看完需要大概10分钟,废话不多说,撸起袖子,加油干!!! 1.前言 按照套路,先介绍一下什么是Cesium. Cesium ['siːzɪəm]是JavaScript开源库,通过Ces ...
- 将Cesium Tools用于更好的构建管理
Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ Cesium技术正在给建筑业带来革命性的变化.我们与 partn ...
- cesium自定义气泡窗口infoWindow
一.自定义气泡窗口与cesium默认窗口效果对比: 1.cesium点击弹出气泡窗口显示的位置固定在地图的右上角,默认效果: 2.对于习惯arcgis或者openlayer气泡窗口样式的giser来说 ...
- cesium核心类Viewer简介
1.简单描述Viewer Viewer类是cesium的核心类,是地图可视化展示的主窗口,cesium程序应用的切入口,扮演必不可少的核心角色. 官网的英文解析如下: A base widget fo ...
- Cesium简介以及离线部署运行
Cesium简介 cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎,一款开源3DGIS的js库.cesium支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区 ...
- 基于开源项目SharpMap的热力图(HeatLayer)实现。
当前公司需要一个用时较少的热力图呈现方案,在避免较底层的GDI开发和比较了多家GIS产品的实际效果之后,团队决定用sharpMap的API来实现,由于之前框架采用的是另外一个开源项目GMap.net, ...
随机推荐
- MediaStore类的使用
安卓系统会在每次开机之后扫描所有文件并分类整理存入数据库,记录在MediaStore这个类里,通过这个类就可以快速的获得相应类型的文件. 当然这个类只是给你一个uri,提取文件的操作还是要通过Curo ...
- 栈的push、pop序列 【微软面试100题 第二十九题】
题目要求: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1.2.3.4.5是某栈的压栈序列,序列4.5.3.2.1是该压栈 ...
- codeM预赛
[编程|1000分] 音乐研究 时间限制:1秒空间限制:32768K 题目描述 美团外卖的品牌代言人袋鼠先生最近正在进行音乐研究.他有两段音频,每段音频是一个表示音高的序列.现在袋鼠先生想要在第二段音 ...
- 九度oj 题目1470:调整方阵
题目描述: 输入一个N(N<=10)阶方阵,按照如下方式调整方阵:1.将第一列中最大数所在的行与第一行对调.2.将第二列中从第二行到第N行最大数所在的行与第二行对调. 依此类推...N-1.将第 ...
- 高并发下的HashMap,ConcurrentHashMap
参照: http://mp.weixin.qq.com/s/dzNq50zBQ4iDrOAhM4a70A http://mp.weixin.qq.com/s/1yWSfdz0j-PprGkDgOomh ...
- ubuntu 安装tomcat<服务器>
一.下载tomcat 可以先下载到本地,然后ftp到服务器 官方 Apache Tomcat 的下载页面(下面的链接是apache自己的镜像服务器的地址,不同网络连接的话,apache会给出不同的镜像 ...
- BZOJ 4584 [Apio2016]赛艇 ——动态规划
Subtask 1 直接$N^2$ $DP$,就可以了 Subtask 2 用$f[i][j]$表示当前位置为$i$,结束元素为$j$的方案数. Subtask 3 看下面 Subtask 4 首先可 ...
- RSA签名
RSA签名: /** * RSA签名 * @param content 待签名数据 * @param privateKey 商户私钥 * @return 签名值 */public static ...
- C# 模拟windows文件名称排序(使用windows自带dll)
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] private static extern int StrCmpLogi ...
- 【前端学习笔记】2015-09-09~~~~nodejs中的require()和module.exports
nodejs中一个js文件就可以看做是一个模块 在node环境中,可以直接var a=require('模块路径以及不带扩展名的模块名') exports---module.exports 其中nod ...