removed old code \o/
This commit is contained in:
parent
983f6e5a54
commit
84b415b87e
@ -1,94 +0,0 @@
|
||||
/*
|
||||
====================
|
||||
canvas setup for drawing tiles
|
||||
====================
|
||||
*/
|
||||
|
||||
function CanvasTileLayer(canvas_setup, render) {
|
||||
this.tileSize = new google.maps.Size(256, 256);
|
||||
this.maxZoom = 19;
|
||||
this.name = "Tile #s";
|
||||
this.alt = "Canvas tile layer";
|
||||
this.tiles = {};
|
||||
this.canvas_setup = canvas_setup;
|
||||
this.render = render;
|
||||
if (!render) {
|
||||
this.render = canvas_setup;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// create a tile with a canvas element
|
||||
CanvasTileLayer.prototype.create_tile_canvas = function (coord, zoom, ownerDocument) {
|
||||
|
||||
// create canvas and reset style
|
||||
var canvas = ownerDocument.createElement('canvas');
|
||||
var hit_canvas = ownerDocument.createElement('canvas');
|
||||
canvas.style.border = hit_canvas.style.border = "none";
|
||||
canvas.style.margin = hit_canvas.style.margin = "0";
|
||||
canvas.style.padding = hit_canvas.style.padding = "0";
|
||||
|
||||
// prepare canvas and context sizes
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.width = canvas.width = this.tileSize.width;
|
||||
ctx.height = canvas.height = this.tileSize.height;
|
||||
|
||||
var hit_ctx = hit_canvas.getContext('2d');
|
||||
hit_canvas.width = hit_ctx.width = this.tileSize.width;
|
||||
hit_canvas.height = hit_ctx.height = this.tileSize.height;
|
||||
|
||||
//set unique id
|
||||
var tile_id = coord.x + '_' + coord.y + '_' + zoom;
|
||||
|
||||
canvas.setAttribute('id', tile_id);
|
||||
hit_canvas.setAttribute('id', tile_id);
|
||||
|
||||
if (tile_id in this.tiles)
|
||||
delete this.tiles[tile_id];
|
||||
|
||||
this.tiles[tile_id] = {canvas:canvas, ctx:ctx, hit_canvas:hit_canvas, hit_ctx:hit_ctx, coord:coord, zoom:zoom, primitives:null};
|
||||
|
||||
// custom setup
|
||||
//if (tile_id == '19295_24654_16'){
|
||||
if (this.canvas_setup)
|
||||
this.canvas_setup(this.tiles[tile_id], coord, zoom);
|
||||
//}
|
||||
return canvas;
|
||||
|
||||
}
|
||||
|
||||
|
||||
CanvasTileLayer.prototype.each = function (callback) {
|
||||
for (var t in this.tiles) {
|
||||
var tile = this.tiles[t];
|
||||
callback(tile);
|
||||
}
|
||||
}
|
||||
|
||||
CanvasTileLayer.prototype.recreate = function () {
|
||||
for (var t in this.tiles) {
|
||||
var tile = this.tiles[t];
|
||||
this.canvas_setup(tile, tile.coord, tile.zoom);
|
||||
}
|
||||
};
|
||||
|
||||
CanvasTileLayer.prototype.redraw_tile = function (tile) {
|
||||
this.render(tile, tile.coord, tile.zoom);
|
||||
};
|
||||
|
||||
CanvasTileLayer.prototype.redraw = function () {
|
||||
for (var t in this.tiles) {
|
||||
var tile = this.tiles[t];
|
||||
this.render(tile, tile.coord, tile.zoom);
|
||||
}
|
||||
};
|
||||
|
||||
// could be called directly...
|
||||
CanvasTileLayer.prototype.getTile = function (coord, zoom, ownerDocument) {
|
||||
return this.create_tile_canvas(coord, zoom, ownerDocument);
|
||||
};
|
||||
|
||||
CanvasTileLayer.prototype.releaseTile = function (tile) {
|
||||
var id = tile.getAttribute('id');
|
||||
delete this.tiles[id];
|
||||
};
|
@ -1,451 +0,0 @@
|
||||
/*
|
||||
====================
|
||||
this class renders tile data in a given time
|
||||
====================
|
||||
*/
|
||||
|
||||
|
||||
function TimePlayer(min_date, end, step, options) {
|
||||
this.time = 0;
|
||||
this.step = step;
|
||||
this.CAP_UNIT = end;
|
||||
this.MIN_DATE = min_date;
|
||||
this.MAX_UNITS = options.steps + 2;
|
||||
this.MAX_VALUE = 0;
|
||||
this.MAX_VALUE_LOG = 0;
|
||||
this.BASE_UNIT = 0;
|
||||
this.canvas_setup = this.get_time_data;
|
||||
this.render = this.render_time;
|
||||
this.cells = [];
|
||||
this.table = options.table;
|
||||
this.user = options.user;
|
||||
this.t_column = options.column;
|
||||
this.resolution = options.resolution;
|
||||
this.countby = options.countby
|
||||
this.base_url = 'http://' + this.user + '.cartodb.com/api/v2/sql';
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
TimePlayer.prototype = new CanvasTileLayer();
|
||||
|
||||
/**
|
||||
* change time, t is the month (integer)
|
||||
*/
|
||||
TimePlayer.prototype.set_time = function (t) {
|
||||
if (this.time != (t >> 0)) {
|
||||
this.time = t;
|
||||
this.redraw();
|
||||
}
|
||||
};
|
||||
TimePlayer.prototype.reset_max_value = function () {
|
||||
this.MAX_VALUE = 0;
|
||||
this.MAX_VALUE_LOG = 0;
|
||||
};
|
||||
/**
|
||||
* change table where the data is choosen
|
||||
*/
|
||||
TimePlayer.prototype.set_table = function (table, size) {
|
||||
if (this.table === table) {
|
||||
return; // nothing to do
|
||||
}
|
||||
this.table = table;
|
||||
this.pixel_size = size;
|
||||
this.recreate();
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
/**
|
||||
* private
|
||||
*/
|
||||
|
||||
// get data from cartodb
|
||||
TimePlayer.prototype.sql = function (sql, callback) {
|
||||
var self = this;
|
||||
var uri = this.base_url + "?q=" + encodeURIComponent(sql);
|
||||
//uri += '&t=' + Date.now() + Math.random();
|
||||
$.getJSON(uri, function (data) {
|
||||
callback(data);
|
||||
});
|
||||
};
|
||||
|
||||
var originShift = 2 * Math.PI * 6378137 / 2.0;
|
||||
var initialResolution = 2 * Math.PI * 6378137 / 256.0;
|
||||
function meterToPixels(mx, my, zoom) {
|
||||
var res = initialResolution / (1 << zoom);
|
||||
var px = (mx + originShift) / res;
|
||||
var py = (my + originShift) / res;
|
||||
return [px, py];
|
||||
}
|
||||
|
||||
// precache data to render fast
|
||||
TimePlayer.prototype.pre_cache_months = function (rows, coord, zoom) {
|
||||
var row;
|
||||
var xcoords;
|
||||
var ycoords;
|
||||
var values;
|
||||
if (typeof(ArrayBuffer) !== undefined) {
|
||||
xcoords = new Uint8Array(new ArrayBuffer(rows.length));
|
||||
ycoords = new Uint8Array(new ArrayBuffer(rows.length));
|
||||
values = new Uint8Array(new ArrayBuffer(rows.length * this.MAX_UNITS));// 256 months
|
||||
} else {
|
||||
// fallback
|
||||
xcoords = [];
|
||||
ycoords = [];
|
||||
values = [];
|
||||
// array buffer set by default to 0
|
||||
for (var i = 0; i < rows.length * this.MAX_UNITS; ++i) {
|
||||
values[i] = 0;
|
||||
}
|
||||
}
|
||||
// base tile x, y
|
||||
var tile_base_x = coord.x * 256;
|
||||
var tile_base_y = coord.y * 256;
|
||||
var total_pixels = 256 << zoom;
|
||||
for (var i in rows) {
|
||||
row = rows[i];
|
||||
pixels = meterToPixels(row.x, row.y, zoom);
|
||||
pixels[1] = total_pixels - pixels[1];
|
||||
xcoords[i] = pixels[0];
|
||||
ycoords[i] = pixels[1];
|
||||
var base_idx = i * this.MAX_UNITS;
|
||||
//def[row.sd[0]] = row.se[0];
|
||||
for (var j = 0; j < row.dates.length; ++j) {
|
||||
values[base_idx + row.dates[j]] = row.vals[j];
|
||||
if (row.vals[j] > this.MAX_VALUE) {
|
||||
this.MAX_VALUE = row.vals[j];
|
||||
this.MAX_VALUE_LOG = Math.log(this.MAX_VALUE);
|
||||
}
|
||||
|
||||
}
|
||||
;
|
||||
if (this.options.cumulative) {
|
||||
for (var j = 1; j < this.MAX_UNITS; ++j) {
|
||||
values[base_idx + j] += values[base_idx + j - 1];
|
||||
if (this.options.cumulative_expires) {
|
||||
for ( var u = 0; u < row.dates_end.length; ++u ) {
|
||||
if ( row.dates_end[u] != null && row.dates_end[u] < (j+1) ) {
|
||||
values[base_idx + j - 1 ] -= row.vals[u]
|
||||
}
|
||||
}
|
||||
}
|
||||
if (values[base_idx + j] > this.MAX_VALUE) {
|
||||
this.MAX_VALUE = values[base_idx + j];
|
||||
this.MAX_VALUE_LOG = Math.log(this.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
length:rows.length,
|
||||
xcoords:xcoords,
|
||||
ycoords:ycoords,
|
||||
values:values,
|
||||
size:1 << (this.resolution * 2)
|
||||
};
|
||||
};
|
||||
|
||||
// get time data in json format
|
||||
TimePlayer.prototype.get_time_data = function (tile, coord, zoom) {
|
||||
var self = this;
|
||||
|
||||
if (!self.table) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get x, y for cells and sd, se for deforestation changes
|
||||
// sd contains the months
|
||||
// se contains the deforestation for each entry in sd
|
||||
// take se and sd as a matrix [se|sd]
|
||||
var numTiles = 1 << zoom;
|
||||
var sql = ""
|
||||
var column_conv = "";
|
||||
var expir_conv = "";
|
||||
|
||||
if (this.options.istime == true){
|
||||
column_conv = "date_part('epoch',{0})".format(this.t_column);
|
||||
expir_conv = "date_part('epoch',{0})".format(this.options.expiration_column);
|
||||
} else {
|
||||
column_conv = this.t_column;
|
||||
expir_conv = this.options.expiration_column;
|
||||
}
|
||||
|
||||
var z_resolution = function(z) {
|
||||
var earth_circumference = 40075017;
|
||||
var tile_size = 256;
|
||||
var full_resolution = earth_circumference/tile_size;
|
||||
return full_resolution / (Math.pow(2,z));
|
||||
};
|
||||
|
||||
sql = "WITH cte AS ( " +
|
||||
"SELECT ST_SnapToGrid(i.the_geom_webmercator, " +
|
||||
"CDB_XYZ_Resolution({0})*{1}) g"
|
||||
. format(zoom, this.resolution) +
|
||||
", {0} c " .format(this.countby) +
|
||||
", floor(({0}- {1})/{2}) d" .format(column_conv, this.MIN_DATE, this.step);
|
||||
|
||||
if ( this.options.cumulative_expires ) {
|
||||
sql += ", floor(({0}- {1})/{2}) de".format(expir_conv, this.MIN_DATE, this.step);
|
||||
}
|
||||
|
||||
sql += " FROM {0} i\n".format(this.options.table) +
|
||||
"WHERE i.the_geom_webmercator && CDB_XYZ_Extent({0}, {1}, {2}) "
|
||||
.format(coord.x, coord.y, zoom) +
|
||||
" GROUP BY g, d";
|
||||
|
||||
if ( this.options.cumulative_expires ) {
|
||||
sql += ", de";
|
||||
}
|
||||
|
||||
sql += ") SELECT st_x(g) x, st_y(g) y, array_agg(c) vals, array_agg(d) dates ";
|
||||
|
||||
if ( this.options.cumulative_expires ) {
|
||||
sql += ", array_agg(de) dates_end";
|
||||
}
|
||||
|
||||
sql += " FROM cte GROUP BY x,y";
|
||||
|
||||
|
||||
var prof = Profiler.get('tile fetch');
|
||||
prof.start();
|
||||
this.sql(sql, function (data) {
|
||||
if (data.rows) {
|
||||
prof.end();
|
||||
var p = Profiler.get('tile data cache');
|
||||
p.start();
|
||||
tile.cells = self.pre_cache_months(data.rows, coord, zoom);
|
||||
p.end();
|
||||
p = Profiler.get('tile render');
|
||||
p.start();
|
||||
self.redraw_tile(tile);
|
||||
p.end();
|
||||
}
|
||||
});
|
||||
};
|
||||
YO = 1;
|
||||
TimePlayer.prototype.render_time = function (tile, coord, zoom) {
|
||||
var self = this;
|
||||
//var month = -this.BASE_UNIT + 1 + this.time>>0;
|
||||
//var month = Math.ceil(this.MAX_UNITS * (this.time - this.BASE_UNIT)/(this.CAP_UNIT-this.BASE_UNIT));
|
||||
var month = this.time;
|
||||
var w = tile.canvas.width;
|
||||
var h = tile.canvas.height;
|
||||
var ctx = tile.ctx;
|
||||
var i, x, y, cell, cells;
|
||||
cells = tile.cells;
|
||||
|
||||
if (!cells || cells.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var colors = [
|
||||
//"#FFFFE5",
|
||||
//"#FFF7BC",
|
||||
"#FEE391",
|
||||
"#FEC44F",
|
||||
"#FE9929",
|
||||
"#EC7014",
|
||||
"#CC4C02",
|
||||
"#993404",
|
||||
"#662506"
|
||||
];
|
||||
|
||||
var fillStyle;
|
||||
// clear canvas
|
||||
tile.canvas.width = w;
|
||||
|
||||
var ci = 0;
|
||||
var cu = 0;
|
||||
ctx.strokeStyle = ctx.fillStyle = colors[cu];
|
||||
ctx.globalCompositeOperation = this.options.blendmode;
|
||||
var xc = cells.xcoords;
|
||||
var yc = cells.ycoords;
|
||||
var vals = cells.values;
|
||||
var dz = 256 / Math.pow(2, zoom)
|
||||
|
||||
// render cells
|
||||
var len = cells.length;
|
||||
var pixel_size = this.resolution//*this.options.cellsize;
|
||||
var pixel_size_trail_circ = pixel_size * 2;
|
||||
var pixel_size_trail_squa = pixel_size * 1.5;
|
||||
var offset = Math.floor((pixel_size - 1) / 2);
|
||||
var tau = Math.PI * 2;
|
||||
|
||||
// memoize sprite canvases
|
||||
if (self.sprite_1 == undefined) {
|
||||
self.sprite_1 = [];
|
||||
$(colors).each(function () {
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.width = canvas.width = pixel_size * 2;
|
||||
ctx.height = canvas.height = pixel_size * 2;
|
||||
ctx.globalAlpha = 1;
|
||||
ctx.fillStyle = this.toString();
|
||||
ctx.beginPath();
|
||||
ctx.arc(pixel_size, pixel_size, pixel_size, 0, tau, true, true);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
self.sprite_1.push(canvas);
|
||||
});
|
||||
}
|
||||
|
||||
if (self.sprite_2 == undefined) {
|
||||
self.sprite_2 = [];
|
||||
$(colors).each(function () {
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.width = canvas.width = pixel_size_trail_circ * 2;
|
||||
ctx.height = canvas.height = pixel_size_trail_circ * 2;
|
||||
ctx.globalAlpha = 0.3;
|
||||
ctx.fillStyle = this.toString();
|
||||
ctx.beginPath();
|
||||
ctx.arc(pixel_size_trail_circ, pixel_size_trail_circ, pixel_size_trail_circ, 0, tau, true, true);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
self.sprite_2.push(canvas);
|
||||
});
|
||||
}
|
||||
|
||||
if (self.sprite_3 == undefined) {
|
||||
self.sprite_3 = [];
|
||||
$(colors).each(function () {
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.width = canvas.width = pixel_size * 2;
|
||||
ctx.height = canvas.height = pixel_size * 2;
|
||||
ctx.globalAlpha = 0.3;
|
||||
ctx.fillStyle = this.toString();
|
||||
ctx.beginPath();
|
||||
ctx.arc(pixel_size, pixel_size, pixel_size, 0, tau, true, true);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
self.sprite_3.push(canvas);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var numTiles = 1 << zoom;
|
||||
for (i = 0; i < len; ++i) {
|
||||
var cell = cells.values[this.MAX_UNITS * i + month];
|
||||
if (cell) {
|
||||
ci = cell == 0 ? 0 : Math.floor((colors.length - 1) * (Math.log(cell) / this.MAX_VALUE_LOG));
|
||||
if (ci != cu) {
|
||||
cu = ci < colors.length ? ci : cu;
|
||||
ctx.fillStyle = colors[cu];
|
||||
}
|
||||
if (this.options.point_type == 'circle') {
|
||||
ctx.drawImage(self.sprite_1[cu], xc[i] - pixel_size, yc[i] - pixel_size)
|
||||
} else if (this.options.point_type == 'square') {
|
||||
ctx.fillRect(xc[i] - offset, yc[i] - offset, pixel_size, pixel_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.trails == true) {
|
||||
|
||||
cell = cells.values[this.MAX_UNITS * i + month - 1];
|
||||
if (cell) {
|
||||
ci = cell == 0 ? 0 : Math.floor((colors.length - 1) * (Math.log(cell) / this.MAX_VALUE_LOG));
|
||||
if (ci != cu) {
|
||||
cu = ci < colors.length ? ci : cu;
|
||||
ctx.fillStyle = colors[cu];
|
||||
}
|
||||
if (this.options.point_type == 'circle') {
|
||||
//alignment hack - sorry to the gods of graphics
|
||||
ctx.drawImage(self.sprite_2[cu], xc[i] - pixel_size_trail_squa - 1, yc[i] - pixel_size_trail_squa - 1)
|
||||
} else if (this.options.point_type == 'square') {
|
||||
ctx.fillRect(xc[i] - offset, yc[i] - offset, pixel_size_trail_squa, pixel_size_trail_squa);
|
||||
}
|
||||
}
|
||||
|
||||
cell = cells.values[this.MAX_UNITS * i + month - 2];
|
||||
if (cell) {
|
||||
ci = cell == 0 ? 0 : Math.floor((colors.length - 1) * (Math.log(cell) / this.MAX_VALUE_LOG));
|
||||
if (ci != cu) {
|
||||
cu = ci < colors.length ? ci : cu;
|
||||
ctx.fillStyle = colors[cu];
|
||||
}
|
||||
if (this.options.point_type == 'circle') {
|
||||
ctx.drawImage(self.sprite_3[cu], xc[i] - pixel_size, yc[i] - pixel_size)
|
||||
} else if (this.options.point_type == 'square') {
|
||||
ctx.fillRect(xc[i] - offset, yc[i] - offset, pixel_size, pixel_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* String formatting for JavaScript.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* "{0} is {1}".format("CartoDB", "epic!");
|
||||
* // CartoDB is epic!
|
||||
*
|
||||
*/
|
||||
String.prototype.format = (function (i, safe, arg) {
|
||||
function format() {
|
||||
var str = this,
|
||||
len = arguments.length + 1;
|
||||
|
||||
for (i = 0; i < len; arg = arguments[i++]) {
|
||||
safe = typeof arg === 'object' ? JSON.stringify(arg) : arg;
|
||||
str = str.replace(RegExp('\\{' + (i - 1) + '\\}', 'g'), safe);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
//format.native = String.prototype.format;
|
||||
return format;
|
||||
})();
|
||||
|
||||
|
||||
// =================
|
||||
// profiler
|
||||
// =================
|
||||
|
||||
function Profiler() {
|
||||
}
|
||||
Profiler.times = {};
|
||||
Profiler.new_time = function (type, time) {
|
||||
var t = Profiler.times[type] = Profiler.times[type] || {
|
||||
max:0,
|
||||
min:10000000,
|
||||
avg:0,
|
||||
total:0,
|
||||
count:0
|
||||
};
|
||||
|
||||
t.max = Math.max(t.max, time);
|
||||
t.total += time;
|
||||
t.min = Math.min(t.min, time);
|
||||
++t.count;
|
||||
t.avg = t.total / t.count;
|
||||
};
|
||||
|
||||
Profiler.print_stats = function () {
|
||||
for (k in Profiler.times) {
|
||||
var t = Profiler.times[k];
|
||||
console.log(" === " + k + " === ");
|
||||
console.log(" max: " + t.max);
|
||||
console.log(" min: " + t.min);
|
||||
console.log(" avg: " + t.avg);
|
||||
console.log(" total: " + t.total);
|
||||
}
|
||||
};
|
||||
|
||||
Profiler.get = function (type) {
|
||||
return {
|
||||
t0:null,
|
||||
start:function () {
|
||||
this.t0 = new Date().getTime();
|
||||
},
|
||||
end:function () {
|
||||
if (this.t0 !== null) {
|
||||
Profiler.new_time(type, this.time = new Date().getTime() - this.t0);
|
||||
this.t0 = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
383
src/torque.js
383
src/torque.js
@ -1,383 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Torque library
|
||||
*
|
||||
* A tool for mapping temporal data from CartoDB
|
||||
* Still in development and being finalized for
|
||||
* CartoDB 2.0
|
||||
*
|
||||
* Authors: Andrew Hill, Simon Tokumine, Javier Santana
|
||||
*
|
||||
*/
|
||||
|
||||
// iOS fix
|
||||
if (Function.prototype.bind == undefined) {
|
||||
Function.prototype.bind = function (bind) {
|
||||
var self = this;
|
||||
return function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
return self.apply(bind || null, args);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function Torque() {
|
||||
var args = Array.prototype.slice.call(arguments),
|
||||
callback = args.pop(),
|
||||
modules = (args[0] && typeof args[0] === "string") ? args : args[0],
|
||||
config,
|
||||
i;
|
||||
|
||||
if (!(this instanceof Torque)) {
|
||||
return new Torque(modules, callback);
|
||||
}
|
||||
|
||||
if (!modules || modules === '*') {
|
||||
modules = [];
|
||||
for (i in Torque.modules) {
|
||||
if (Torque.modules.hasOwnProperty(i)) {
|
||||
modules.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < modules.length; i += 1) {
|
||||
Torque.modules[modules[i]](this);
|
||||
}
|
||||
|
||||
callback(this);
|
||||
return this;
|
||||
}
|
||||
;
|
||||
|
||||
Torque.modules = {};
|
||||
|
||||
Torque.modules.app = function (torque) {
|
||||
torque.app = {};
|
||||
torque.app.Instance = Class.extend(
|
||||
{
|
||||
init:function (logging) {
|
||||
this.layers = {};
|
||||
torque.log.enabled = logging ? logging : false;
|
||||
},
|
||||
addLayer:function (map, options) {
|
||||
var layer = new torque.layer.Engine(map, options);
|
||||
return layer
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
Torque.modules.layer = function (torque) {
|
||||
torque.layer = {};
|
||||
torque.layer.Engine = Class.extend({
|
||||
init:function (map, options) {
|
||||
this._defaults = {
|
||||
user:'viz2',
|
||||
table:'ny_bus',
|
||||
column:'timestamp',
|
||||
istime: true,
|
||||
steps:250,
|
||||
resolution:3,
|
||||
cumulative:false,
|
||||
fps:24,
|
||||
autoplay:true,
|
||||
clock:false,
|
||||
zindex:0,
|
||||
fitbounds:false,
|
||||
countby:'count(i.cartodb_id)',
|
||||
blendmode:'source-over',
|
||||
trails:false,
|
||||
point_type:'square',
|
||||
subtitles:false,
|
||||
scrub:false
|
||||
}
|
||||
this.options = _.defaults(options, this._defaults);
|
||||
|
||||
this._map = map;
|
||||
this._index = this.options.zindex;
|
||||
|
||||
while (this._map.overlayMapTypes.length < this.options.zindex) {
|
||||
this._map.overlayMapTypes.push(null);
|
||||
}
|
||||
|
||||
this._cartodb = new Backbone.CartoDB({user:this.options.user});
|
||||
this.bounds = new google.maps.LatLngBounds();
|
||||
|
||||
torque.clock.enabled = this.options.clock ? this.options.clock : false;
|
||||
torque.clock.set('loading...');
|
||||
|
||||
this.getDeltas();
|
||||
},
|
||||
pause:function () {
|
||||
if (this.running == true) {
|
||||
this.running = false;
|
||||
} else {
|
||||
this.running = true;
|
||||
this.play();
|
||||
}
|
||||
},
|
||||
setOptions:function (new_options) {
|
||||
|
||||
this.running = false;
|
||||
this.options = _.defaults(new_options, this._defaults);
|
||||
|
||||
torque.clock.enabled = this.options.clock ? this.options.clock : false;
|
||||
torque.clock.set('loading...');
|
||||
|
||||
this._cartodb = new Backbone.CartoDB({user:this.options.user});
|
||||
this.bounds = new google.maps.LatLngBounds();
|
||||
|
||||
this._map.overlayMapTypes.setAt(this._index, null);
|
||||
this.getDeltas();
|
||||
|
||||
},
|
||||
run:function () {
|
||||
this.start = new Date(this.options.start).getTime();
|
||||
this.end = new Date(this.options.end).getTime();
|
||||
|
||||
this._current = this.start;
|
||||
this._step = Math.floor((this.end - this.start) / this.options.steps);
|
||||
|
||||
this._setupListeners();
|
||||
|
||||
this._display = new TimePlayer(this.start, (this.start - this.end), this._step, this.options);
|
||||
|
||||
this._map.overlayMapTypes.setAt(this._index, this._display);
|
||||
|
||||
this.fitBounds(this.options.fitbounds);
|
||||
|
||||
this.running = false;
|
||||
torque.clock.clear();
|
||||
|
||||
// If scrubbable, override other options that may have been set
|
||||
if (this.options.scrub){
|
||||
this.options.scrub(this);
|
||||
// this.options.autoplay = false;
|
||||
// this.options.trails = false;
|
||||
}
|
||||
|
||||
if (this.options.autoplay) {
|
||||
this.running = true;
|
||||
this.play();
|
||||
}
|
||||
|
||||
|
||||
torque.log.info('Layer is now running!');
|
||||
},
|
||||
_setupListeners:function () {
|
||||
var that = this;
|
||||
google.maps.event.addListener(this._map, 'zoom_changed', function () {
|
||||
that._display.reset_max_value();
|
||||
});
|
||||
},
|
||||
getBounds:function () {
|
||||
return this.bounds;
|
||||
},
|
||||
fitBounds:function (f) {
|
||||
if (f !== false) {
|
||||
this._map.fitBounds(this.bounds);
|
||||
if (typeof f == 'number') {
|
||||
this._map.setZoom(this._map.getZoom() + f);
|
||||
} else {
|
||||
this._map.setZoom(this._map.getZoom());
|
||||
}
|
||||
}
|
||||
},
|
||||
getDeltas:function (options) {
|
||||
var that = this;
|
||||
if (this.options.istime == true){
|
||||
var max_col = "date_part('epoch',max({0}))".format(this.options.column);
|
||||
var min_col = "date_part('epoch',min({0}))".format(this.options.column);
|
||||
} else {
|
||||
var max_col = "max({0})".format(this.options.column);
|
||||
var min_col = "min({0})".format(this.options.column);
|
||||
}
|
||||
var sql = "SELECT st_xmax(st_envelope(st_collect(the_geom))) xmax,st_ymax(st_envelope(st_collect(the_geom))) ymax, st_xmin(st_envelope(st_collect(the_geom))) xmin, st_ymin(st_envelope(st_collect(the_geom))) ymin, {0} max, {1} min FROM {2}".format(max_col, min_col, this.options.table);
|
||||
|
||||
var timeExtents = this._cartodb.CartoDBCollection.extend({
|
||||
sql:sql
|
||||
});
|
||||
var times = new timeExtents();
|
||||
times.fetch();
|
||||
times.bind('reset', function () {
|
||||
times.each(function (p) {
|
||||
that.options.start = p.get('min');
|
||||
that.options.end = p.get('max');
|
||||
that.bounds.extend(new google.maps.LatLng(p.get('ymin'), p.get('xmax')));
|
||||
that.bounds.extend(new google.maps.LatLng(p.get('ymax'), p.get('xmin')));
|
||||
that.bounds.extend(new google.maps.LatLng((p.get('ymax') + p.get('ymin')) / 2, (p.get('xmax') + p.get('xmin')) / 2));
|
||||
});
|
||||
that.run();
|
||||
});
|
||||
},
|
||||
advance:function () {
|
||||
if (this._current + this._step < this.end) {
|
||||
this._current = this._current + this._step;
|
||||
// } else if (this._current < this.end) {
|
||||
// this._current = this.end;
|
||||
} else {
|
||||
this._current = this.start;
|
||||
}
|
||||
this._display.set_time((this._current - this.start) / this._step);
|
||||
},
|
||||
play:function () {
|
||||
var pause = 0;
|
||||
if (this._current < this.end) {
|
||||
this._current = this._current + this._step
|
||||
if (this.end < this._current) {
|
||||
pause = 500;
|
||||
}
|
||||
} else {
|
||||
this._current = this.start;
|
||||
}
|
||||
|
||||
var date = new Date(this._current * 1000);
|
||||
var date_arry = date.toString().substr(4).split(' ');
|
||||
torque.clock.set('<span id="month">' + date_arry[0] + '</span> <span id="year">' + date_arry[2] + '</span>');
|
||||
|
||||
if (this.options.subtitles) {
|
||||
torque.subtitles.set(date);
|
||||
}
|
||||
|
||||
this._display.set_time((this._current - this.start) / this._step);
|
||||
|
||||
if (this.options.scrub_move){
|
||||
this.options.scrub_move(this)
|
||||
}
|
||||
if (this.running) {
|
||||
if ( this.options.fps ) {
|
||||
var ms = pause + 1000 * 1 / this.options.fps;
|
||||
//console.log("play timeout: " + ms + " ms (pause:" + pause + ", fps:" + this.options.fps + ")");
|
||||
setTimeout(function () {
|
||||
this.play()
|
||||
}.bind(this), ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Torque.modules.clock = function (torque) {
|
||||
torque.clock = {};
|
||||
|
||||
torque.clock.clear = function () {
|
||||
$('.torque_time').html('');
|
||||
};
|
||||
torque.clock.set = function (msg) {
|
||||
torque.clock._hand(msg);
|
||||
};
|
||||
torque.clock._hand = function (msg) {
|
||||
var clockger = window.console;
|
||||
if (torque.clock.enabled) {
|
||||
$('.torque_time').html(msg);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Torque.modules.subtitles = function (torque) {
|
||||
torque.subtitles = {
|
||||
subs:[
|
||||
{
|
||||
from:new Date("March 01, 1913 00:00:00"),
|
||||
to:new Date("July 01, 1914 00:00:00"),
|
||||
sub:"Pre war"
|
||||
},
|
||||
{
|
||||
from:new Date("August 01, 1914 00:00:00"),
|
||||
to:new Date("February 01, 1915 00:00:00"),
|
||||
sub:"War begins with Germany"
|
||||
},
|
||||
{
|
||||
from:new Date("February 02, 1915 00:00:00"),
|
||||
to:new Date("October 01, 1916 00:00:00"),
|
||||
sub:"North Sea naval blockade"
|
||||
},
|
||||
{
|
||||
from:new Date("October 02, 1917 00:00:00"),
|
||||
to:new Date("April 01, 1917 00:00:00"),
|
||||
sub:"Atlantic U-boat warfare"
|
||||
},
|
||||
{
|
||||
from:new Date("April 02, 1917 00:00:00"),
|
||||
to:new Date("September 01, 1917 00:00:00"),
|
||||
sub:"USA enters war"
|
||||
},
|
||||
{
|
||||
from:new Date("September 02, 1917 00:00:00"),
|
||||
to:new Date("November 01, 1918 00:00:00"),
|
||||
sub:"Destroyers begin to escort convoys in Atlantic"
|
||||
},
|
||||
{
|
||||
from:new Date("November 02, 1918 00:00:00"),
|
||||
to:new Date("August 01, 1920 00:00:00"),
|
||||
sub:"End of WWI"
|
||||
},
|
||||
{
|
||||
from:new Date("August 02, 1920 00:00:00"),
|
||||
to:new Date("August 01, 1925 00:00:00"),
|
||||
sub:"Trade routes resume"
|
||||
}
|
||||
|
||||
]
|
||||
};
|
||||
|
||||
torque.subtitles.clear = function () {
|
||||
$('.torque_subs').html('');
|
||||
};
|
||||
torque.subtitles.set = function (date) {
|
||||
$.each(this.subs, function () {
|
||||
if (this.from < date && this.to > date) {
|
||||
torque.subtitles._update(this.sub);
|
||||
}
|
||||
});
|
||||
};
|
||||
torque.subtitles._update = function (msg) {
|
||||
$('.torque_subs').html(msg);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Logging module that torquetes log messages to the console and to the Speed
|
||||
* Tracer API. It contains convenience methods for info(), warn(), error(),
|
||||
* and todo().
|
||||
*
|
||||
*/
|
||||
Torque.modules.log = function (torque) {
|
||||
torque.log = {};
|
||||
|
||||
torque.log.info = function (msg) {
|
||||
torque.log._torquete('INFO: ' + msg);
|
||||
};
|
||||
|
||||
torque.log.warn = function (msg) {
|
||||
torque.log._torquete('WARN: ' + msg);
|
||||
};
|
||||
|
||||
torque.log.error = function (msg) {
|
||||
torque.log._torquete('ERROR: ' + msg);
|
||||
};
|
||||
|
||||
torque.log.todo = function (msg) {
|
||||
torque.log._torquete('TODO: ' + msg);
|
||||
};
|
||||
|
||||
torque.log._torquete = function (msg) {
|
||||
var logger = window.console;
|
||||
if (torque.log.enabled) {
|
||||
if (logger && logger.markTimeline) {
|
||||
logger.markTimeline(msg);
|
||||
}
|
||||
console.log(msg);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var originShift = 2 * Math.PI * 6378137 / 2.0;
|
||||
var initialResolution = 2 * Math.PI * 6378137 / 256.0;
|
||||
function meterToPixels(mx, my, zoom) {
|
||||
var res = initialResolution / (1 << zoom);
|
||||
var px = (mx + originShift) / res;
|
||||
var py = (my + originShift) / res;
|
||||
return [px, py];
|
||||
}
|
Loading…
Reference in New Issue
Block a user