restores point renderer
This commit is contained in:
parent
1b0f79b92f
commit
9ad0ce8582
@ -3,9 +3,6 @@ var cartocss = require('./cartocss_render');
|
||||
var Profiler = require('../profiler');
|
||||
var carto = global.carto || require('carto');
|
||||
var Filters = require('./torque_filters');
|
||||
var d3 = require('d3');
|
||||
var contour = require('./contour');
|
||||
var cSpline = require('cardinal-spline');
|
||||
|
||||
var TAU = Math.PI * 2;
|
||||
var DEFAULT_CARTOCSS = [
|
||||
@ -62,7 +59,6 @@ var cSpline = require('cardinal-spline');
|
||||
this._gradients = {};
|
||||
|
||||
this._forcePoints = false;
|
||||
this.globalGrid = [];
|
||||
}
|
||||
|
||||
torque.extend(PointRenderer.prototype, torque.Event, {
|
||||
@ -109,10 +105,74 @@ var cSpline = require('cardinal-spline');
|
||||
this._sprites = [];
|
||||
},
|
||||
|
||||
|
||||
//
|
||||
// generate sprite based on cartocss style
|
||||
//
|
||||
generateSprite: function(shader, value, shaderVars) {
|
||||
var self = this;
|
||||
var prof = Profiler.metric('torque.renderer.point.generateSprite').start();
|
||||
var st = shader.getStyle({
|
||||
value: value
|
||||
}, shaderVars);
|
||||
if(this._style === null || this._style !== st){
|
||||
this._style = st;
|
||||
}
|
||||
|
||||
var pointSize = st['marker-width'];
|
||||
if (!pointSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (st['marker-opacity'] === 0 && !st['marker-line-opacity']) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var canvas = this._createCanvas();
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
var markerFile = st["marker-file"] || st["point-file"];
|
||||
var qualifiedUrl = markerFile && this._qualifyURL(markerFile);
|
||||
|
||||
if (qualifiedUrl && this._iconsToLoad <= 0 && this._icons[qualifiedUrl]) {
|
||||
var img = this._icons[qualifiedUrl];
|
||||
|
||||
var dWidth = Math.min(st['marker-width'] * 2 || img.width, cartocss.MAX_SPRITE_RADIUS * 2);
|
||||
var dHeight = Math.min((st['marker-height'] || dWidth) * (img.width / img.height), cartocss.MAX_SPRITE_RADIUS * 2);
|
||||
|
||||
canvas.width = ctx.width = dWidth;
|
||||
canvas.height = ctx.height = dHeight;
|
||||
|
||||
ctx.scale(dWidth/img.width, dHeight/img.height);
|
||||
|
||||
cartocss.renderSprite(ctx, img, st);
|
||||
} else {
|
||||
// take into account the exterior ring to calculate the size
|
||||
var canvasSize = (st['marker-line-width'] || 0) + pointSize*2;
|
||||
var w = ctx.width = canvas.width = ctx.height = canvas.height = Math.ceil(canvasSize);
|
||||
ctx.translate(w/2, w/2);
|
||||
|
||||
var mt = st['marker-type'];
|
||||
if (mt && mt === 'rectangle') {
|
||||
cartocss.renderRectangle(ctx, st);
|
||||
} else {
|
||||
cartocss.renderPoint(ctx, st);
|
||||
}
|
||||
}
|
||||
prof.end(true);
|
||||
if (torque.flags.sprites_to_images) {
|
||||
var i = this._createImage();
|
||||
i.src = canvas.toDataURL();
|
||||
return i;
|
||||
}
|
||||
|
||||
return canvas;
|
||||
},
|
||||
|
||||
//
|
||||
// renders all the layers (and frames for each layer) from cartocss
|
||||
//
|
||||
renderTile: function(tile, key, pos) {
|
||||
renderTile: function(tile, key, callback) {
|
||||
if (this._iconsToLoad > 0) {
|
||||
this.on('allIconsLoaded', function() {
|
||||
this.renderTile.apply(this, [tile, key, callback]);
|
||||
@ -129,12 +189,14 @@ var cSpline = require('cardinal-spline');
|
||||
for(var fr = 0; fr < layer.frames().length; ++fr) {
|
||||
var frame = layer.frames()[fr];
|
||||
var fr_sprites = sprites[frame] || (sprites[frame] = []);
|
||||
this._renderTile(tile, key - frame, frame, fr_sprites, layer, pos);
|
||||
this._renderTile(tile, key - frame, frame, fr_sprites, layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prof.end(true);
|
||||
|
||||
return callback && callback(null);
|
||||
},
|
||||
|
||||
_createCanvas: function() {
|
||||
@ -178,7 +240,7 @@ var cSpline = require('cardinal-spline');
|
||||
// renders a tile in the canvas for key defined in
|
||||
// the torque tile
|
||||
//
|
||||
_renderTile: function(tile, key, frame_offset, sprites, shader, pos) {
|
||||
_renderTile: function(tile, key, frame_offset, sprites, shader, shaderVars) {
|
||||
if (!this._canvas) return;
|
||||
|
||||
var prof = Profiler.metric('torque.renderer.point.renderTile').start();
|
||||
@ -194,61 +256,27 @@ var cSpline = require('cardinal-spline');
|
||||
var tileMax = this.options.resolution * (this.TILE_SIZE/this.options.resolution - 1)
|
||||
var activePixels = tile.timeCount[key];
|
||||
var anchor = this.options.resolution/2;
|
||||
|
||||
/*
|
||||
Torque Isolines
|
||||
To be moved somewhere else (ideally something link isolines.js within /renderer/)
|
||||
*/
|
||||
var isolines = true;
|
||||
if (isolines) {
|
||||
this._gridData(tile);
|
||||
}
|
||||
prof.end(true);
|
||||
},
|
||||
|
||||
_gridData: function(tile){
|
||||
var valsPerTile = this.TILE_SIZE/this.options.resolution;
|
||||
var difX = tile.coord.x - this.firstTileCoords.coord.x;
|
||||
var difY = tile.coord.y - this.firstTileCoords.coord.y;
|
||||
if (difX < 0 || difY < 0) return;
|
||||
// baseIndex is the distance to the upper left corner of the grid, in cells
|
||||
var baseIndex = {
|
||||
x: (difX) * valsPerTile,
|
||||
y: (difY) * valsPerTile
|
||||
}
|
||||
|
||||
for(var i = 0; i < tile.renderData.length; i++){
|
||||
var x = tile.x[i], y = tile.y[i];
|
||||
this.globalGrid[baseIndex.y + (256 - y) / this.options.resolution -1][baseIndex.x + x/this.options.resolution] = tile.renderData[i];
|
||||
}
|
||||
},
|
||||
|
||||
_getPipe: function(cell, contour){
|
||||
var parsedCell = cell.map(function(cornerValue){
|
||||
if (cornerValue >= contour){
|
||||
return "1";
|
||||
if (activePixels) {
|
||||
var pixelIndex = tile.timeIndex[key];
|
||||
for(var p = 0; p < activePixels; ++p) {
|
||||
var posIdx = tile.renderDataPos[pixelIndex + p];
|
||||
var c = tile.renderData[pixelIndex + p];
|
||||
if (c) {
|
||||
var sp = sprites[c];
|
||||
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) + anchor;
|
||||
var y = tileMax - tile.y[posIdx] + anchor; // flip mercator
|
||||
ctx.drawImage(sp, x, y - (sp.height >> 1));
|
||||
}
|
||||
}
|
||||
return "0";
|
||||
}).join("");
|
||||
var type = parseInt(parsedCell, 2);
|
||||
var interpolated = true;
|
||||
var N = interpolated? [this._lerp(cell[1], cell[0], contour), 0]: [0.5,0],
|
||||
S = interpolated? [this._lerp(cell[2], cell[3], contour), 1]: [0.5,1],
|
||||
E = interpolated? [1, this._lerp(cell[2], cell[1], contour)]: [1,0.5],
|
||||
W = interpolated? [0, this._lerp(cell[3], cell[0], contour)]: [0,0.5]
|
||||
if (type === 0 || type === 15) return null;
|
||||
if (type === 1 || type === 14) return [W, S]
|
||||
if (type === 2 || type === 13) return [S, E]
|
||||
if (type === 3 || type === 12) return [W, E]
|
||||
if (type === 4 || type === 11) return [N, E]
|
||||
if (type === 6 || type === 9) return [N, S]
|
||||
if (type === 7 || type === 8) return [W, N]
|
||||
if (type === 5) return [W, N, S, E]
|
||||
if (type === 10) return [W, S, N, E]
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_lerp: function(valueA, valueB, contourValue){
|
||||
return 1 + (-0.5) * (contourValue - valueA) / (valueB - valueA);
|
||||
prof.end(true);
|
||||
},
|
||||
|
||||
setBlendMode: function(b) {
|
||||
@ -374,85 +402,44 @@ var cSpline = require('cardinal-spline');
|
||||
}
|
||||
},
|
||||
|
||||
drawIsolines: function(){
|
||||
if (this.globalGrid.length > 0) {
|
||||
var style = this._shader.getLayers()[1].getStyle({}, {zoom: 2});
|
||||
var cellsY = this.globalGrid.length-1;
|
||||
var contourValues = [0, 4, 8, 16, 32, 64, 128];
|
||||
var ctx = this._ctx;
|
||||
var res = this.options.resolution;
|
||||
var startPos = this.firstTileCoords.pos;
|
||||
ctx.strokeStyle = style["-isoline-line-color"] || "black";
|
||||
ctx.lineWidth = style["-isoline-line-width"] || 2;
|
||||
ctx.globalAlpha = style["-isoline-line-opacity"] || 0.8;
|
||||
var grad = style["-isoline-line-ramp"] && this._generateGradient(style["-isoline-line-ramp"].args);
|
||||
for (var c = 0; c < contourValues.length; c++) {
|
||||
if(style["-isoline-line-decay"]){
|
||||
var max = contourValues[contourValues.length - 1];
|
||||
ctx.globalAlpha = (contourValues[c]/max)*(style["-isoline-line-opacity"] || 0.8);
|
||||
}
|
||||
if(grad){
|
||||
ctx.strokeStyle = "rgb("+grad[4*contourValues[c]+1]+","+grad[4*contourValues[c]+2]+","+grad[4*contourValues[c]+3]+")";
|
||||
}
|
||||
for (var y = 0; y < cellsY; y++) {
|
||||
for (var x = 0; x < this.globalGrid[y].length-1; x++){
|
||||
var currentCell = [
|
||||
this.globalGrid[y][x],
|
||||
this.globalGrid[y][x+1],
|
||||
this.globalGrid[y+1][x+1],
|
||||
this.globalGrid[y+1][x]
|
||||
];
|
||||
var pipe = this._getPipe(currentCell, contourValues[c]);
|
||||
if (pipe){
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(res * (x + 0.5 + pipe[0][0]), res * (y + 0.5 + pipe[0][1]));
|
||||
ctx.lineTo(res * (x + 0.5 + pipe[1][0]), res * (y + 0.5 + pipe[1][1]));
|
||||
ctx.stroke();
|
||||
if (pipe.length === 4){
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(res * (x + 0.5 + pipe[2][0]), res * (y + 0.5 + pipe[2][1]));
|
||||
ctx.lineTo(res * (x + 0.5 + pipe[3][0]), res * (y + 0.5 + pipe[3][1]));
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.globalAlpha = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_generateGradient: function(ramp){
|
||||
var gradientCanvas = this._createCanvas(),
|
||||
gctx = gradientCanvas.getContext('2d'),
|
||||
gradient = gctx.createLinearGradient(0, 0, 0, 256);
|
||||
gradientCanvas.width = 1;
|
||||
gradientCanvas.height = 256;
|
||||
|
||||
for (var i = 0; i < ramp.length; i++) {
|
||||
var color = "rgb("+ramp[i].rgb[0]+","+ramp[i].rgb[1]+","+ramp[i].rgb[2]+")";
|
||||
gradient.addColorStop(i/(ramp.length-1), color);
|
||||
}
|
||||
gctx.fillStyle = gradient;
|
||||
gctx.fillRect(0, 0, 1, 256);
|
||||
|
||||
return gctx.getImageData(0, 0, 1, 256).data;
|
||||
},
|
||||
|
||||
applyFilters: function(){
|
||||
this.drawIsolines();
|
||||
// for (var y = 0; y < this.globalGrid.length; y++){
|
||||
// for (var x = 0; x < this.globalGrid[0].length; x++){
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(res/2 + x*res, res/2 + y*res, 1, 0, 2 * Math.PI, false);
|
||||
// var value = this.globalGrid[y][x];
|
||||
// ctx.fillStyle = "rgb("+0+", "+value * 50+", "+value * 50+")";
|
||||
// if(value === 0) ctx.fillStyle = "red";
|
||||
// ctx.fill();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
if(this._style){
|
||||
if(this._style['image-filters']){
|
||||
function gradientKey(imf){
|
||||
var hash = ""
|
||||
for(var i = 0; i < imf.args.length; i++){
|
||||
var rgb = imf.args[i].rgb;
|
||||
hash += rgb[0] + ":" + rgb[1] + ":" + rgb[2];
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
var gradient = this._gradients[gradientKey(this._style['image-filters'])];
|
||||
if(!gradient){
|
||||
function componentToHex(c) {
|
||||
var hex = c.toString(16);
|
||||
return hex.length == 1 ? "0" + hex : hex;
|
||||
}
|
||||
|
||||
function rgbToHex(r, g, b) {
|
||||
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
|
||||
}
|
||||
gradient = {};
|
||||
var colorize = this._style['image-filters'].args;
|
||||
|
||||
var increment = 1/colorize.length;
|
||||
for (var i = 0; i < colorize.length; i++){
|
||||
var key = increment * i + increment;
|
||||
var rgb = colorize[i].rgb;
|
||||
var formattedColor = rgbToHex(rgb[0], rgb[1], rgb[2]);
|
||||
gradient[key] = formattedColor;
|
||||
}
|
||||
this._gradients[gradientKey(this._style['image-filters'])] = gradient;
|
||||
}
|
||||
this._filters.gradient(gradient);
|
||||
this._filters.draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user