diff --git a/src/canvas_tile_layer.js b/src/canvas_tile_layer.js deleted file mode 100644 index bce1b82..0000000 --- a/src/canvas_tile_layer.js +++ /dev/null @@ -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]; -}; diff --git a/src/grid_layer.js b/src/grid_layer.js deleted file mode 100644 index 6e0f8ff..0000000 --- a/src/grid_layer.js +++ /dev/null @@ -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; - } - } - }; -}; diff --git a/src/torque.js b/src/torque.js deleted file mode 100644 index 3c8dc95..0000000 --- a/src/torque.js +++ /dev/null @@ -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('' + date_arry[0] + ' ' + date_arry[2] + ''); - - 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]; -}