diff --git a/examples/navy_leaflet.html b/examples/navy_leaflet.html index 3f2561e..55da2e9 100644 --- a/examples/navy_leaflet.html +++ b/examples/navy_leaflet.html @@ -21,7 +21,7 @@ 'Map {', '-torque-time-attribute: "date";', '-torque-aggregation-function: "count(cartodb_id)";', - '-torque-frame-count: 760;', + '-torque-frame-count: 512;', '-torque-animation-duration: 15;', '-torque-resolution: 2', '}', @@ -52,13 +52,22 @@ attribution: 'CartoDB' }).addTo(map); + var limit = 10000; + var offset = 10000; var torqueLayer = new L.TorqueLayer({ user : 'viz2', table : 'ow', - cartocss: CARTOCSS + sql: 'select * from ow order by cartodb_id limit ' + limit, + cartocss: CARTOCSS, + streaming: true }); torqueLayer.addTo(map); torqueLayer.play() + setInterval(function() { + offset += limit; + torqueLayer.setSQL("select * from ow order by cartodb_id offset " + offset + " limit " + limit ); + //torqueLayer._reloadTiles(); + }, 10000); diff --git a/lib/torque/animator.js b/lib/torque/animator.js index 6634a5b..9781831 100644 --- a/lib/torque/animator.js +++ b/lib/torque/animator.js @@ -65,10 +65,13 @@ }, rescale: function() { - this.domainInv = torque.math.linear(this.options.animationDelay, this.options.animationDelay + this.options.animationDuration); - this.domain = this.domainInv.invert(); - this.range = torque.math.linear(0, this.options.steps); - this.rangeInv = this.range.invert(); + var opts = { + extrapolate: this.options.streaming + }; + this.domainInv = torque.math.linear(this.options.animationDelay, this.options.animationDelay + this.options.animationDuration, opts); + this.domain = this.domainInv.invert(opts); + this.range = torque.math.linear(0, this.options.steps, opts); + this.rangeInv = this.range.invert(opts); this.time(this._time); return this; }, @@ -108,7 +111,9 @@ this._time += delta; this.time(this._time); if(this.step() >= this.options.steps) { - this._time = 0; + if (!this.options.streaming) { + this._time = 0; + } } if(this.running) { requestAnimationFrame(this._tick); diff --git a/lib/torque/leaflet/torque.js b/lib/torque/leaflet/torque.js index 14edaec..df24c67 100644 --- a/lib/torque/leaflet/torque.js +++ b/lib/torque/leaflet/torque.js @@ -20,6 +20,7 @@ L.TorqueLayer = L.CanvasLayer.extend({ if (!torque.isBrowserSupported()) { throw new Error("browser is not supported by torque"); } + this._tileStream = {} options.tileLoader = true; this.key = 0; if (options.cartocss) { @@ -72,7 +73,25 @@ L.TorqueLayer = L.CanvasLayer.extend({ var tileData = this.provider.getTileData(t, t.zoom, function(tileData) { // don't load tiles that are not being shown if (t.zoom !== self._map.getZoom()) return; + tileData.steps = self.provider.getSteps(); self._tileLoaded(t, tileData); + if (self.options.streaming) { + var k = self._tileKey(t); + var stream = self._tileStream[k]; + if (!stream) { + console.log("creating stream ", k); + stream = self._tileStream[k] = []; + } + if (stream.length) { + var last = stream[stream.length - 1]; + tileData.startKey = last.startKey + last.steps; + } else { + tileData.startKey = 0; + } + console.log(" - start", tileData.startKey); + console.log(" - steps", tileData.steps); + stream.push(tileData); + } if (tileData) { self.redraw(); } @@ -183,12 +202,29 @@ L.TorqueLayer = L.CanvasLayer.extend({ canvas.width = canvas.width; var ctx = canvas.getContext('2d'); - for(t in this._tiles) { - tile = this._tiles[t]; + var tiles = this._tiles; + + if (this.options.streaming) { + tiles = this._tileStream + } + + var key = this.key; + + for(t in tiles) { + tile = tiles[t]; + // search for the stream index for this.key + if (this.options.streaming) { + var c = 0; + while(c < tile.length && this.key >= (tile[c].startKey + tile[c].steps)) { + ++c; + } + tile = tile[c]; + } if (tile) { + key = this.key - tile.startKey; pos = this.getTilePos(tile.coord); ctx.setTransform(1, 0, 0, 1, pos.x, pos.y); - this.renderer.renderTile(tile, this.key, pos.x, pos.y); + this.renderer.renderTile(tile, key, pos.x, pos.y); } } diff --git a/lib/torque/math.js b/lib/torque/math.js index 4e1676d..a5ee907 100644 --- a/lib/torque/math.js +++ b/lib/torque/math.js @@ -8,21 +8,31 @@ }; } - function invLinear(a, b) { - var c = clamp(0, 1.0); + function invLinear(a, b, options) { + var c; + if (options && options.extrapolate) { + c = function(t) { return t; }; + } else { + c = clamp(0, 1.0); + } return function(t) { return c((t - a)/(b - a)); }; } - function linear(a, b) { - var c = clamp(a, b); + function linear(a, b, options) { + var c ; + if (options && options.extrapolate) { + c = function(t) { return t; }; + } else { + c = clamp(a, b); + } function _linear(t) { return c(a*(1.0 - t) + t*b); } - _linear.invert = function() { - return invLinear(a, b); + _linear.invert = function(options) { + return invLinear(a, b, options); }; return _linear;