updating code to use the new tile format

This commit is contained in:
Stuart Lynn 2015-11-06 17:06:21 +00:00
parent 71fc89a8d8
commit dea2f1f27f
2 changed files with 51 additions and 93 deletions

View File

@ -91,23 +91,21 @@ var Profiler = require('../profiler');
var maxDateSlots = -1;
for (r = 0; r < rows.length; ++r) {
var row = rows[r];
dates += row.dates__uint16.length;
for(var d = 0; d < row.dates__uint16.length; ++d) {
maxDateSlots = Math.max(maxDateSlots, row.dates__uint16[d]);
dates += row.steps.length;
for(var d = 0; d < row.steps.length; ++d) {
maxDateSlots = Math.max(maxDateSlots, row.steps[d]);
}
}
if(this.options.cumulative) {
dates = (1 + maxDateSlots) * rows.length;
}
var type = this.options.cumulative ? Uint32Array: Uint8Array;
// var type = Uint8Array;
// reserve memory for all the dates
var timeIndex = new Int32Array(maxDateSlots + 1); //index-size
var timeCount = new Int32Array(maxDateSlots + 1);
var renderData = new (this.options.valueDataType || type)(dates);
var renderDataPos = new Uint32Array(dates);
// var timeIndex = new Int32Array(maxDateSlots + 1); //index-size
// var timeCount = new Int32Array(maxDateSlots + 1);
var renderData = new Array()
// var renderDataPos = new Uint32Array(dates);
prof_mem.inc(
4 * maxDateSlots + // timeIndex
@ -123,73 +121,29 @@ var Profiler = require('../profiler');
// precache pixel positions
for (var r = 0; r < rows.length; ++r) {
var row = rows[r];
x[r] = row.x__uint8 * this.options.resolution;
x[r] = row.x //* this.options.resolution;
// fix value when it's in the tile EDGE
// TODO: this should be fixed in SQL query
if (row.y__uint8 === -1) {
if (row.y === -1) {
y[r] = 0;
} else {
y[r] = row.y__uint8 * this.options.resolution;
y[r] = row.y //* this.options.resolution;
}
var dates = row.dates__uint16;
var vals = row.vals__uint8;
if (!this.options.cumulative) {
for (var j = 0, len = dates.length; j < len; ++j) {
var rr = rowsPerSlot[dates[j]] || (rowsPerSlot[dates[j]] = []);
if(this.options.cumulative) {
vals[j] += prev_val;
}
prev_val = vals[j];
rr.push([r, vals[j]]);
}
} else {
var valByDate = {}
for (var j = 0, len = dates.length; j < len; ++j) {
valByDate[dates[j]] = vals[j];
}
var accum = 0;
// extend the latest to the end
for (var j = dates[0]; j <= maxDateSlots; ++j) {
var rr = rowsPerSlot[j] || (rowsPerSlot[j] = []);
var v = valByDate[j];
if (v) {
accum += v;
}
rr.push([r, accum]);
}
for(var i=0; i < row.steps.length; i++){
renderData[r*row.steps.length + i] = row.vals[i]
}
/*var lastDateSlot = dates[dates.length - 1];
for (var j = lastDateSlot + 1; j <= maxDateSlots; ++j) {
var rr = rowsPerSlot[j] || (rowsPerSlot[j] = []);
rr.push([r, prev_val]);
}
*/
}
}
// for each timeslot search active buckets
var renderDataIndex = 0;
var timeSlotIndex = 0;
var i = 0;
for(var i = 0; i <= maxDateSlots; ++i) {
var c = 0;
var slotRows = rowsPerSlot[i]
if(slotRows) {
for (var r = 0; r < slotRows.length; ++r) {
var rr = slotRows[r];
++c;
renderDataPos[renderDataIndex] = rr[0]
renderData[renderDataIndex] = rr[1];
++renderDataIndex;
}
}
timeIndex[i] = timeSlotIndex;
timeCount[i] = c;
timeSlotIndex += c;
}
prof_process_time.end();
@ -202,11 +156,11 @@ var Profiler = require('../profiler');
y: coord.y,
z: zoom
},
timeCount: timeCount,
timeIndex: timeIndex,
renderDataPos: renderDataPos,
// timeCount: timeCount,
// timeIndex: timeIndex,
// renderDataPos: renderDataPos,
renderData: renderData,
maxDate: maxDateSlots
// maxDate: maxDateSlots
};
},
_generateFilterSQLForCat:function(name,categories){
@ -225,7 +179,7 @@ var Profiler = require('../profiler');
_setFilters:function(filters){
this.filters = filters
},
_generateFiltersSQL:function(){
_generateFiltersSQL:function(){
return Object.keys(this._filters).map(function(filterName){
var filter = this._filters[filterName]
if(filter){
@ -242,7 +196,7 @@ var Profiler = require('../profiler');
else{
return ""
}
})
}).join(" and ")
},
_host: function() {
var opts = this.options;
@ -358,30 +312,31 @@ var Profiler = require('../profiler');
column_conv = format("date_part('epoch', {column})", this.options);
}
var sql = "" +
"WITH " +
"par AS (" +
" SELECT CDB_XYZ_Resolution({zoom})*{resolution} as res" +
", 256/{resolution} as tile_size" +
", CDB_XYZ_Extent({x}, {y}, {zoom}) as ext " +
")," +
"cte AS ( "+
" SELECT ST_SnapToGrid(i.the_geom_webmercator, p.res) g" +
", avg(passenger_count) c1, avg(tip_amount) c2, sum( case when payment_type=1 then 1 else 0 end) c3, sum(case when payment_type=2 then 1 else 0 end ) c4, sum(case when payment_type=3 then 1 else 0 end ) c5,sum(case when payment_type=4 then 1 else 0 end ) c6, count(cartodb_id) c7 " +
" FROM ({_sql}) i, par p " +
" WHERE i.the_geom_webmercator && p.ext " +
" GROUP BY g" +
") " +
"" +
"SELECT (st_x(g)-st_xmin(p.ext))/p.res x__uint8, " +
" (st_y(g)-st_ymin(p.ext))/p.res y__uint8," +
" Array[c1,c2,c3,c4,c5,c6,c7] vals__uint8," +
" Array[0,1,2,3,4,5,6] dates__uint16" +
// the tile_size where are needed because the overlaps query in cte subquery includes the points
// in the left and bottom borders of the tile
" FROM cte, par p where (st_y(g)-st_ymin(p.ext))/p.res < tile_size and (st_x(g)-st_xmin(p.ext))/p.res < tile_size ";
// var sql = "" +
// "WITH " +
// "par AS (" +
// " SELECT CDB_XYZ_Resolution({zoom})*{resolution} as res" +
// ", 256/{resolution} as tile_size" +
// ", CDB_XYZ_Extent({x}, {y}, {zoom}) as ext " +
// ")," +
// "cte AS ( "+
// " SELECT ST_SnapToGrid(i.the_geom_webmercator, p.res) g" +
// ", avg(passenger_count) c1, avg(tip_amount) c2, sum( case when payment_type=1 then 1 else 0 end) c3, sum(case when payment_type=2 then 1 else 0 end ) c4, sum(case when payment_type=3 then 1 else 0 end ) c5,sum(case when payment_type=4 then 1 else 0 end ) c6, count(cartodb_id) c7 " +
// " FROM ({_sql}) i, par p " +
// " WHERE i.the_geom_webmercator && p.ext " +
// " GROUP BY g" +
// ") " +
// "" +
// "SELECT (st_x(g)-st_xmin(p.ext))/p.res x__uint8, " +
// " (st_y(g)-st_ymin(p.ext))/p.res y__uint8," +
// " Array[c1,c2,c3,c4,c5,c6,c7] vals__uint8," +
// " Array[0,1,2,3,4,5,6] dates__uint16" +
// // the tile_size where are needed because the overlaps query in cte subquery includes the points
// // in the left and bottom borders of the tile
// " FROM cte, par p where (st_y(g)-st_ymin(p.ext))/p.res < tile_size and (st_x(g)-st_xmin(p.ext))/p.res < tile_size ";
this.options.filters = this._generateFiltersSQL()
var sql = ""+
"SELECT * FROM torque_tile(x:={x}, y:={y}, z:={zoom}, aggr:=ARRAY['{columns}'], table_name:='{table}', where_clause:='{filters}');"
var query = format(sql, this.options, {
zoom: zoom,
x: coord.x,
@ -392,7 +347,9 @@ var Profiler = require('../profiler');
var self = this;
console.log("query is ", query)
this.sql(query, function (data) {
if (data) {
var rows = JSON.parse(data.responseText).rows;
callback(self.proccessTile(rows, coord, zoom));

View File

@ -241,6 +241,7 @@ var Filters = require('./torque_filters');
// the torque tile
//
_renderTile: function(tile, key, frame_offset, sprites, shader, shaderVars) {
if (!this._canvas) return;
var prof = Profiler.metric('torque.renderer.point.renderTile').start();
var ctx = this._ctx;
@ -259,7 +260,7 @@ var Filters = require('./torque_filters');
var pixelIndex = 0;//tile.timeIndex[key];
for(var p = 0; p < activePixels; ++p) {
if(tile.renderFlags[p]){
var posIdx = tile.renderDataPos[pixelIndex + p];
var posIdx = p// tile.renderDataPos[pixelIndex + p];
var c = tile.renderData[pixelIndex + p];
if (c) {
var sp = sprites[c];