test heat
This commit is contained in:
parent
20b88a72ff
commit
306afd8b92
@ -226,10 +226,11 @@ L.TorqueLayer = L.CanvasLayer.extend({
|
|||||||
// all the points
|
// all the points
|
||||||
this.renderer._ctx.drawImage(tile._tileCache, 0, 0);
|
this.renderer._ctx.drawImage(tile._tileCache, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
this.renderer.renderTile(tile, this.key);
|
this.renderer.renderTile(tile, this.key, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.renderer.flush();
|
||||||
|
|
||||||
// prepare caches if the animation is not running
|
// prepare caches if the animation is not running
|
||||||
// don't cache if the key has just changed, this avoids to cache
|
// don't cache if the key has just changed, this avoids to cache
|
||||||
|
@ -2,6 +2,7 @@ var torque = require('../');
|
|||||||
var cartocss = require('./cartocss_render');
|
var cartocss = require('./cartocss_render');
|
||||||
var Profiler = require('../profiler');
|
var Profiler = require('../profiler');
|
||||||
var carto = global.carto || require('carto');
|
var carto = global.carto || require('carto');
|
||||||
|
var heat = require('./simpleheat');
|
||||||
|
|
||||||
var TAU = Math.PI * 2;
|
var TAU = Math.PI * 2;
|
||||||
var DEFAULT_CARTOCSS = [
|
var DEFAULT_CARTOCSS = [
|
||||||
@ -47,6 +48,8 @@ var carto = global.carto || require('carto');
|
|||||||
this.options = options;
|
this.options = options;
|
||||||
this._canvas = canvas;
|
this._canvas = canvas;
|
||||||
this._ctx = canvas.getContext('2d');
|
this._ctx = canvas.getContext('2d');
|
||||||
|
this._heat = heat(this._canvas);
|
||||||
|
this._heat.max(255);
|
||||||
this._sprites = []; // sprites per layer
|
this._sprites = []; // sprites per layer
|
||||||
this._shader = null;
|
this._shader = null;
|
||||||
this.setCartoCSS(this.options.cartocss || DEFAULT_CARTOCSS);
|
this.setCartoCSS(this.options.cartocss || DEFAULT_CARTOCSS);
|
||||||
@ -144,7 +147,8 @@ var carto = global.carto || require('carto');
|
|||||||
// renders all the layers (and frames for each layer) from cartocss
|
// renders all the layers (and frames for each layer) from cartocss
|
||||||
//
|
//
|
||||||
renderTile: function(tile, key) {
|
renderTile: function(tile, key) {
|
||||||
var prof = Profiler.metric('torque.renderer.point.renderLayers').start();
|
this._renderTile(tile, 0, 0, null, null);
|
||||||
|
/*var prof = Profiler.metric('torque.renderer.point.renderLayers').start();
|
||||||
var layers = this._shader.getLayers();
|
var layers = this._shader.getLayers();
|
||||||
for(var i = 0, n = layers.length; i < n; ++i ) {
|
for(var i = 0, n = layers.length; i < n; ++i ) {
|
||||||
var layer = layers[i];
|
var layer = layers[i];
|
||||||
@ -159,6 +163,7 @@ var carto = global.carto || require('carto');
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
prof.end(true);
|
prof.end(true);
|
||||||
|
*/
|
||||||
},
|
},
|
||||||
|
|
||||||
_createCanvas: function() {
|
_createCanvas: function() {
|
||||||
@ -178,41 +183,35 @@ var carto = global.carto || require('carto');
|
|||||||
// the torque tile
|
// the torque tile
|
||||||
//
|
//
|
||||||
_renderTile: function(tile, key, frame_offset, sprites, shader, shaderVars) {
|
_renderTile: function(tile, key, frame_offset, sprites, shader, shaderVars) {
|
||||||
if(!this._canvas) return;
|
if(!this._canvas || !this._heat) return;
|
||||||
|
|
||||||
var prof = Profiler.metric('torque.renderer.point.renderTile').start();
|
var prof = Profiler.metric('torque.renderer.point.renderTile').start();
|
||||||
var ctx = this._ctx;
|
var ctx = this._ctx;
|
||||||
var blendMode = compop2canvas(shader.eval('comp-op')) || this.options.blendmode;
|
|
||||||
if(blendMode) {
|
|
||||||
ctx.globalCompositeOperation = blendMode;
|
|
||||||
}
|
|
||||||
if (this.options.cumulative && key > tile.maxDate) {
|
|
||||||
//TODO: precache because this tile is not going to change
|
|
||||||
key = tile.maxDate;
|
|
||||||
}
|
|
||||||
var tileMax = this.options.resolution * (this.TILE_SIZE/this.options.resolution - 1)
|
var tileMax = this.options.resolution * (this.TILE_SIZE/this.options.resolution - 1)
|
||||||
var activePixels = tile.timeCount[key];
|
var activePixels = tile.timeCount[key];
|
||||||
if(activePixels) {
|
if (activePixels) {
|
||||||
var pixelIndex = tile.timeIndex[key];
|
var pixelIndex = tile.timeIndex[key];
|
||||||
for(var p = 0; p < activePixels; ++p) {
|
for(var p = 0; p < activePixels; ++p) {
|
||||||
var posIdx = tile.renderDataPos[pixelIndex + p];
|
var posIdx = tile.renderDataPos[pixelIndex + p];
|
||||||
var c = tile.renderData[pixelIndex + p];
|
var c = tile.renderData[pixelIndex + p];
|
||||||
if(c) {
|
if(c) {
|
||||||
var sp = sprites[c];
|
var x = tile.x[posIdx];
|
||||||
if(sp === undefined) {
|
|
||||||
sp = sprites[c] = this.generateSprite(shader, c, torque.extend({ zoom: tile.z, 'frame-offset': frame_offset }, shaderVars));
|
|
||||||
}
|
|
||||||
if (sp) {
|
|
||||||
var x = tile.x[posIdx]- (sp.width >> 1);
|
|
||||||
var y = tileMax - tile.y[posIdx]; // flip mercator
|
var y = tileMax - tile.y[posIdx]; // flip mercator
|
||||||
ctx.drawImage(sp, x, y - (sp.height >> 1));
|
this._heat.add([x, y, c]);
|
||||||
}
|
this._ctx.fillRect(x, y, 2, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prof.end(true);
|
prof.end(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
flush: function() {
|
||||||
|
if(!this._heat) return;
|
||||||
|
this._heat.draw();
|
||||||
|
this._heat.clear();
|
||||||
|
},
|
||||||
|
|
||||||
setBlendMode: function(b) {
|
setBlendMode: function(b) {
|
||||||
this.options.blendmode = b;
|
this.options.blendmode = b;
|
||||||
},
|
},
|
||||||
|
139
lib/torque/renderer/simpleheat.js
Normal file
139
lib/torque/renderer/simpleheat.js
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
(c) 2014, Vladimir Agafonkin
|
||||||
|
simpleheat, a tiny JavaScript library for drawing heatmaps with Canvas
|
||||||
|
https://github.com/mourner/simpleheat
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function simpleheat(canvas) {
|
||||||
|
// jshint newcap: false, validthis: true
|
||||||
|
if (!(this instanceof simpleheat)) { return new simpleheat(canvas); }
|
||||||
|
|
||||||
|
this._canvas = canvas = typeof canvas === 'string' ? document.getElementById(canvas) : canvas;
|
||||||
|
|
||||||
|
this._ctx = canvas.getContext('2d');
|
||||||
|
this._width = canvas.width;
|
||||||
|
this._height = canvas.height;
|
||||||
|
|
||||||
|
this._max = 1;
|
||||||
|
this._data = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
simpleheat.prototype = {
|
||||||
|
|
||||||
|
defaultRadius: 25,
|
||||||
|
|
||||||
|
defaultGradient: {
|
||||||
|
0.4: 'blue',
|
||||||
|
0.6: 'cyan',
|
||||||
|
0.7: 'lime',
|
||||||
|
0.8: 'yellow',
|
||||||
|
1.0: 'red'
|
||||||
|
},
|
||||||
|
|
||||||
|
data: function (data) {
|
||||||
|
this._data = data;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
max: function (max) {
|
||||||
|
this._max = max;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
add: function (point) {
|
||||||
|
this._data.push(point);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
clear: function () {
|
||||||
|
this._data = [];
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
radius: function (r, blur) {
|
||||||
|
blur = blur || 15;
|
||||||
|
|
||||||
|
// create a grayscale blurred circle image that we'll use for drawing points
|
||||||
|
var circle = this._circle = document.createElement('canvas'),
|
||||||
|
ctx = circle.getContext('2d'),
|
||||||
|
r2 = this._r = r + blur;
|
||||||
|
|
||||||
|
circle.width = circle.height = r2 * 2;
|
||||||
|
|
||||||
|
ctx.shadowOffsetX = ctx.shadowOffsetY = 200;
|
||||||
|
ctx.shadowBlur = blur;
|
||||||
|
ctx.shadowColor = 'black';
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(r2 - 200, r2 - 200, r, 0, Math.PI * 2, true);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
gradient: function (grad) {
|
||||||
|
// create a 256x1 gradient that we'll use to turn a grayscale heatmap into a colored one
|
||||||
|
var canvas = document.createElement('canvas'),
|
||||||
|
ctx = canvas.getContext('2d'),
|
||||||
|
gradient = ctx.createLinearGradient(0, 0, 0, 256);
|
||||||
|
|
||||||
|
canvas.width = 1;
|
||||||
|
canvas.height = 256;
|
||||||
|
|
||||||
|
for (var i in grad) {
|
||||||
|
gradient.addColorStop(i, grad[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.fillStyle = gradient;
|
||||||
|
ctx.fillRect(0, 0, 1, 256);
|
||||||
|
|
||||||
|
this._grad = ctx.getImageData(0, 0, 1, 256).data;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
draw: function (minOpacity) {
|
||||||
|
if (!this._circle) {
|
||||||
|
this.radius(this.defaultRadius);
|
||||||
|
}
|
||||||
|
if (!this._grad) {
|
||||||
|
this.gradient(this.defaultGradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctx = this._ctx;
|
||||||
|
|
||||||
|
//ctx.clearRect(0, 0, this._width, this._height);
|
||||||
|
|
||||||
|
// draw a grayscale heatmap by putting a blurred circle at each data point
|
||||||
|
for (var i = 0, len = this._data.length, p; i < len; i++) {
|
||||||
|
p = this._data[i];
|
||||||
|
|
||||||
|
ctx.globalAlpha = Math.max(p[2] / this._max, minOpacity === undefined ? 0.05 : minOpacity);
|
||||||
|
ctx.drawImage(this._circle, p[0] - this._r, p[1] - this._r);
|
||||||
|
}
|
||||||
|
|
||||||
|
// colorize the heatmap, using opacity value of each pixel to get the right color from our gradient
|
||||||
|
//var colored = ctx.getImageData(0, 0, this._width, this._height);
|
||||||
|
//this._colorize(colored.data, this._grad);
|
||||||
|
//ctx.putImageData(colored, 0, 0);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
_colorize: function (pixels, gradient) {
|
||||||
|
for (var i = 3, len = pixels.length, j; i < len; i += 4) {
|
||||||
|
j = pixels[i] * 4; // get gradient color from opacity value
|
||||||
|
|
||||||
|
if (j) {
|
||||||
|
pixels[i - 3] = gradient[j];
|
||||||
|
pixels[i - 2] = gradient[j + 1];
|
||||||
|
pixels[i - 1] = gradient[j + 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = simpleheat;
|
Loading…
Reference in New Issue
Block a user