From ccc871a2c3686b2152ec1f814c54f695e652b1fa Mon Sep 17 00:00:00 2001 From: Stuart Lynn Date: Tue, 27 Oct 2015 15:41:38 -0400 Subject: [PATCH 1/2] Updating tileJson provider to use webworkers to process tiles when they are available. This is probably still not as efficient as it could be as we are not recycling workers. --- lib/torque/provider/tilejson.js | 56 +++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/lib/torque/provider/tilejson.js b/lib/torque/provider/tilejson.js index 93c3467b..46f315d7 100644 --- a/lib/torque/provider/tilejson.js +++ b/lib/torque/provider/tilejson.js @@ -48,10 +48,39 @@ * Index: Array index to the properties * } */ - proccessTile: function(rows, coord, zoom) { + createProccessTileWorker:function(){ + var workerFunction = "var proccessTile ="+ this.proccessTileSerial.toString() + var wrapper = "; self.onmessage = function(e){var data = JSON.parse(e.data); JSON.stringify(self.postMessage(proccessTile(data.rows,data.coord, data.zoom, data.options)))}" + var script = workerFunction + wrapper; + var blob = new Blob([script], {type: "text/javascript"}) + var worker = new Worker(window.URL.createObjectURL(blob)) + return worker + }, + proccessTile:function(rows,coord,zoom,callback){ + if(typeof(Worker) === "undefined"){ + callback(this.proccessTileSerial(rows,coord,zoom, this.options)) + } + else{ + var worker = this.createProccessTileWorker() + worker.onmessage = function(e){ + callback(e.data) + worker.terminate() + } + + var workerSafeOptions= { + x : new this.options.coordinates_data_type(rows.length), + y : new this.options.coordinates_data_type(rows.length), + cumulative: this.options.cumulative, + valueDataType: this.options.valueDataType, + resolution: this.options.resolution, + } + worker.postMessage(JSON.stringify({rows: rows, coord: {x:coord.x,y:coord.y}, zoom:zoom, options: workerSafeOptions})) + } + }, + proccessTileSerial: function(rows, coord, zoom,options) { var r; - var x = new this.options.coordinates_data_type(rows.length); - var y = new this.options.coordinates_data_type(rows.length); + var x = options.x || new options.coordinates_data_type(rows.length); + var y = options.y || new options.coordinates_data_type(rows.length); // count number of dates var dates = 0; @@ -64,16 +93,16 @@ } } - if(this.options.cumulative) { + if(options.cumulative) { dates = (1 + maxDateSlots) * rows.length; } - var type = this.options.cumulative ? Uint32Array: Uint8ClampedArray; + var type = options.cumulative ? Uint32Array: Uint8ClampedArray; // 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 renderData = new (options.valueDataType || type)(dates); var renderDataPos = new Uint32Array(dates); var rowsPerSlot = {}; @@ -81,15 +110,15 @@ // precache pixel positions for (var r = 0; r < rows.length; ++r) { var row = rows[r]; - x[r] = row.x__uint8 * this.options.resolution; - y[r] = row.y__uint8 * this.options.resolution; + x[r] = row.x__uint8 * options.resolution; + y[r] = row.y__uint8 * options.resolution; var dates = row.dates__uint16; var vals = row.vals__uint8; - if (!this.options.cumulative) { + if (!options.cumulative) { for (var j = 0, len = dates.length; j < len; ++j) { var rr = rowsPerSlot[dates[j]] || (rowsPerSlot[dates[j]] = []); - if(this.options.cumulative) { + if(options.cumulative) { vals[j] += prev_val; } prev_val = vals[j]; @@ -152,7 +181,7 @@ }; }, - setSteps: function(steps, opt) { + setSteps: function(steps, opt) { opt = opt || {}; if (this.options.steps !== steps) { this.options.steps = steps; @@ -257,7 +286,7 @@ torque.net.get( url , function (data) { if (data && data.responseText) { var rows = JSON.parse(data.responseText); - callback(self.proccessTile(rows, coord, zoom)); + self.proccessTile(rows, coord, zoom,callback.bind(self)); } else { callback(null); } @@ -314,6 +343,7 @@ _fetchMap: function(callback) { var self = this; + torque.net.get(this.options.tileJSON, function (data) { data = JSON.parse(data.response); if (data) { @@ -334,4 +364,4 @@ } }; - module.exports = tileJSON; \ No newline at end of file + module.exports = tileJSON; From fe8958d12ae096808a960808c85b168742192f1a Mon Sep 17 00:00:00 2001 From: Stuart Lynn Date: Tue, 27 Oct 2015 15:42:33 -0400 Subject: [PATCH 2/2] Updating point renderer to support the new callback style for proccessTile. Not sure this is used any more but just to be safe. --- test/support/point_renderer.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/test/support/point_renderer.js b/test/support/point_renderer.js index d5af2a5e..dcc4fdd1 100644 --- a/test/support/point_renderer.js +++ b/test/support/point_renderer.js @@ -44,14 +44,16 @@ function getTile(jsonRelPath, cartocss, z, x, y, step, callback) { var canvas = new Canvas(256, 256); var pointRenderer = new torque.renderer.Point(canvas, rendererOptions); + provider.proccessTile(rows, {x: x, y: y}, z, function(tile){ + pointRenderer.renderTile(tile, step, function(err) { + if (err) { + return callback(err, null); + } + pointRenderer.applyFilters(); + return callback(null, canvas); + }); + }.bind(this)); - pointRenderer.renderTile(provider.proccessTile(rows, {x: x, y: y}, z), step, function(err) { - if (err) { - return callback(err, null); - } - pointRenderer.applyFilters(); - return callback(null, canvas); - }); } module.exports = {