cdb
This commit is contained in:
@@ -0,0 +1,556 @@
|
||||
(function() {
|
||||
|
||||
Queue = function() {
|
||||
|
||||
// callback storage
|
||||
this._methods = [];
|
||||
|
||||
// reference to the response
|
||||
this._response = null;
|
||||
|
||||
// all queues start off unflushed
|
||||
this._flushed = false;
|
||||
|
||||
};
|
||||
|
||||
Queue.prototype = {
|
||||
|
||||
// adds callbacks to the queue
|
||||
add: function(fn) {
|
||||
|
||||
// if the queue had been flushed, return immediately
|
||||
if (this._flushed) {
|
||||
|
||||
// otherwise push it on the queue
|
||||
fn(this._response);
|
||||
|
||||
} else {
|
||||
this._methods.push(fn);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
flush: function(resp) {
|
||||
|
||||
// flush only ever happens once
|
||||
if (this._flushed) {
|
||||
return;
|
||||
}
|
||||
|
||||
// store the response for subsequent calls after flush()
|
||||
this._response = resp;
|
||||
|
||||
// mark that it's been flushed
|
||||
this._flushed = true;
|
||||
|
||||
// shift 'em out and call 'em back
|
||||
while (this._methods[0]) {
|
||||
this._methods.shift()(resp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
StaticImage = function() {
|
||||
|
||||
MapBase.call(this, this);
|
||||
|
||||
this.imageOptions = {};
|
||||
|
||||
this.error = null;
|
||||
|
||||
this.supported_formats = ["png", "jpg"];
|
||||
|
||||
this.defaults = {
|
||||
basemap_url_template: "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
|
||||
basemap_subdomains: ["a", "b", "c"],
|
||||
format: "png",
|
||||
zoom: 10,
|
||||
center: [0, 0],
|
||||
size: [320, 240],
|
||||
tiler_port: 80,
|
||||
tiler_domain: "carto.com"
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
StaticImage.prototype = _.extend({}, MapBase.prototype, {
|
||||
|
||||
load: function(vizjson, options) {
|
||||
|
||||
_.bindAll(this, "_onVisLoaded");
|
||||
|
||||
this.queue = new Queue;
|
||||
|
||||
this.no_cdn = options.no_cdn;
|
||||
|
||||
this.auth_tokens = options.auth_tokens;
|
||||
|
||||
this.userOptions = options;
|
||||
|
||||
options = _.defaults({ vizjson: vizjson, temp_id: "s" + this._getUUID() }, this.defaults);
|
||||
|
||||
this.imageOptions = options;
|
||||
|
||||
cdb.core.Loader.get(vizjson, this._onVisLoaded);
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
loadLayerDefinition: function(layerDefinition, options) {
|
||||
|
||||
var self = this;
|
||||
|
||||
this.queue = new Queue;
|
||||
|
||||
if (!layerDefinition.user_name) {
|
||||
cartodb.log.error("Please, specify the username");
|
||||
return;
|
||||
}
|
||||
|
||||
this.userOptions = options;
|
||||
|
||||
this.options.api_key = layerDefinition.api_key;
|
||||
this.options.user_name = layerDefinition.user_name;
|
||||
this.options.tiler_protocol = layerDefinition.tiler_protocol;
|
||||
this.options.tiler_domain = layerDefinition.tiler_domain;
|
||||
this.options.tiler_port = layerDefinition.tiler_port;
|
||||
this.options.maps_api_template = layerDefinition.maps_api_template;
|
||||
this.endPoint = "/api/v1/map";
|
||||
|
||||
if (!this.options.maps_api_template) {
|
||||
this._buildMapsApiTemplate(this.options);
|
||||
}
|
||||
|
||||
this.options.layers = layerDefinition;
|
||||
|
||||
this._requestLayerGroupID();
|
||||
|
||||
},
|
||||
|
||||
_onVisLoaded: function(data) {
|
||||
|
||||
if (data) {
|
||||
|
||||
var layerDefinition;
|
||||
var baseLayer = data.layers[0];
|
||||
var dataLayer = this._getDataLayer(data.layers);
|
||||
|
||||
if (dataLayer.options) {
|
||||
this.options.user_name = dataLayer.options.user_name;
|
||||
}
|
||||
|
||||
// keep this for backward compatibility with tiler_* variables
|
||||
if (!dataLayer.options.maps_api_template) {
|
||||
this._setupTilerConfiguration(dataLayer.options.tiler_protocol, dataLayer.options.tiler_domain, dataLayer.options.tiler_port);
|
||||
} else {
|
||||
this.options.maps_api_template = dataLayer.options.maps_api_template;
|
||||
}
|
||||
|
||||
this.endPoint = "/api/v1/map";
|
||||
|
||||
var bbox = [];
|
||||
var bounds = data.bounds;
|
||||
|
||||
if (bounds) {
|
||||
bbox.push([bounds[0][1], bounds[0][0]]);
|
||||
bbox.push([bounds[1][1], bounds[1][0]]);
|
||||
}
|
||||
|
||||
this.imageOptions.zoom = data.zoom;
|
||||
this.imageOptions.center = JSON.parse(data.center);
|
||||
this.imageOptions.bbox = bbox;
|
||||
this.imageOptions.bounds = data.bounds;
|
||||
|
||||
if (baseLayer && baseLayer.options) {
|
||||
this.imageOptions.basemap = baseLayer;
|
||||
}
|
||||
|
||||
/* If the vizjson contains a named map and a torque layer with a named map,
|
||||
ignore the torque layer */
|
||||
var ignoreTorqueLayer = false;
|
||||
var namedMap = this._getLayerByType(data.layers, "namedmap");
|
||||
|
||||
if (namedMap) {
|
||||
var torque = this._getLayerByType(data.layers, "torque");
|
||||
|
||||
if (torque && torque.options && torque.options.named_map) {
|
||||
|
||||
if (torque.options.named_map.name === namedMap.options.named_map.name) {
|
||||
ignoreTorqueLayer = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var layers = [];
|
||||
var basemap = this._getBasemapLayer();
|
||||
|
||||
if (basemap) {
|
||||
layers.push(basemap);
|
||||
}
|
||||
|
||||
var labelsLayer;
|
||||
for (var i = 1; i < data.layers.length; i++) {
|
||||
var layer = data.layers[i];
|
||||
|
||||
if (layer.type === "torque" && !ignoreTorqueLayer) {
|
||||
layers.push(this._getTorqueLayerDefinition(layer));
|
||||
} else if (layer.type === "namedmap") {
|
||||
layers.push(this._getNamedmapLayerDefinition(layer));
|
||||
} else if (layer.type === "tiled") {
|
||||
labelsLayer = this._getHTTPLayer(layer);
|
||||
} else if (layer.type !== "torque" && layer.type !== "namedmap") {
|
||||
var ll = this._getLayergroupLayerDefinition(layer);
|
||||
|
||||
for (var j = 0; j < ll.length; j++) {
|
||||
layers.push(ll[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there's a second `tiled` layer, it's a layer with labels and
|
||||
// it needs to be on top of all other layers
|
||||
if (labelsLayer) {
|
||||
layers.push(labelsLayer);
|
||||
}
|
||||
|
||||
this.options.layers = { layers: layers };
|
||||
this._requestLayerGroupID();
|
||||
}
|
||||
},
|
||||
|
||||
_getDataLayer: function(layers) {
|
||||
return this._getLayerByType(layers, "namedmap") ||
|
||||
this._getLayerByType(layers, "layergroup") ||
|
||||
this._getLayerByType(layers, "torque");
|
||||
},
|
||||
|
||||
visibleLayers: function() {
|
||||
// Overwrites the layer_definition method.
|
||||
// We return all the layers, since we have filtered them before
|
||||
return this.options.layers.layers;
|
||||
},
|
||||
|
||||
_getLayerByType: function(layers, type) {
|
||||
return _.find(layers, function(layer) { return layer.type === type; });
|
||||
},
|
||||
|
||||
_setupTilerConfiguration: function(protocol, domain, port) {
|
||||
|
||||
this.options.tiler_domain = domain;
|
||||
this.options.tiler_protocol = protocol;
|
||||
this.options.tiler_port = port;
|
||||
|
||||
this._buildMapsApiTemplate(this.options);
|
||||
|
||||
},
|
||||
|
||||
toJSON: function(){
|
||||
return this.options.layers;
|
||||
},
|
||||
|
||||
_requestLayerGroupID: function() {
|
||||
|
||||
var self = this;
|
||||
|
||||
this.createMap(function(data, error) {
|
||||
|
||||
if (error) {
|
||||
self.error = error;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
self.imageOptions.layergroupid = data.layergroupid;
|
||||
self.cdn_url = data.cdn_url;
|
||||
}
|
||||
|
||||
self.queue.flush(this);
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
_getDefaultBasemapLayer: function() {
|
||||
|
||||
return {
|
||||
type: "http",
|
||||
options: {
|
||||
urlTemplate: this.defaults.basemap_url_template,
|
||||
subdomains: this.defaults.basemap_subdomains
|
||||
}
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
_getHTTPLayer: function(basemap) {
|
||||
|
||||
var urlTemplate = basemap.options.urlTemplate;
|
||||
|
||||
if (!urlTemplate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
type: "http",
|
||||
options: {
|
||||
urlTemplate: urlTemplate,
|
||||
subdomains: basemap.options.subdomains || this.defaults.basemap_subdomains
|
||||
}
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
_getPlainBasemapLayer: function(color) {
|
||||
|
||||
return {
|
||||
type: "plain",
|
||||
options: {
|
||||
color: color
|
||||
}
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
_getBasemapLayer: function() {
|
||||
|
||||
var basemap = this.userOptions.basemap || this.imageOptions.basemap;
|
||||
|
||||
if (basemap) {
|
||||
|
||||
// TODO: refactor this
|
||||
var type = basemap.type.toLowerCase();
|
||||
|
||||
if (basemap.options && basemap.options.type) {
|
||||
type = basemap.options.type.toLowerCase();
|
||||
}
|
||||
|
||||
if (type === "plain") {
|
||||
return this._getPlainBasemapLayer(basemap.options.color);
|
||||
} else {
|
||||
return this._getHTTPLayer(basemap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this._getDefaultBasemapLayer();
|
||||
|
||||
},
|
||||
|
||||
_getTorqueLayerDefinition: function(layer_definition) {
|
||||
|
||||
if (layer_definition.options.named_map) { // If the layer contains a named map inside, use it instead
|
||||
return this._getNamedmapLayerDefinition(layer_definition);
|
||||
}
|
||||
|
||||
var layerDefinition = new LayerDefinition(layer_definition, layer_definition.options);
|
||||
|
||||
var query = layerDefinition.options.query || "SELECT * FROM " + layerDefinition.options.table_name;
|
||||
var cartocss = layer_definition.options.tile_style;
|
||||
|
||||
return {
|
||||
type: "torque",
|
||||
options: {
|
||||
step: this.userOptions.step || 0,
|
||||
sql: query,
|
||||
cartocss: cartocss
|
||||
}
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
_getLayergroupLayerDefinition: function(layer) {
|
||||
|
||||
var options = layer.options;
|
||||
|
||||
options.layer_definition.layers = this._getVisibleLayers(options.layer_definition.layers);
|
||||
|
||||
var layerDefinition = new LayerDefinition(options.layer_definition, options);
|
||||
|
||||
return layerDefinition.toJSON().layers;
|
||||
|
||||
},
|
||||
|
||||
_getNamedmapLayerDefinition: function(layer) {
|
||||
|
||||
var options = layer.options;
|
||||
|
||||
var layerDefinition = new NamedMap(options.named_map, options);
|
||||
|
||||
var options = {
|
||||
name: layerDefinition.named_map.name
|
||||
};
|
||||
|
||||
if (this.auth_tokens && this.auth_tokens.length > 0) {
|
||||
options.auth_tokens = this.auth_tokens;
|
||||
}
|
||||
|
||||
return {
|
||||
type: "named",
|
||||
options: options
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_getVisibleLayers: function(layers) {
|
||||
return _.filter(layers, function(layer) { return layer.visible; });
|
||||
},
|
||||
|
||||
_getUrl: function() {
|
||||
|
||||
var username = this.options.user_name;
|
||||
var bbox = this.imageOptions.bbox;
|
||||
var layergroupid = this.imageOptions.layergroupid;
|
||||
var zoom = this.imageOptions.zoom || this.defaults.zoom;
|
||||
var center = this.imageOptions.center || this.defaults.center;
|
||||
var size = this.imageOptions.size || this.defaults.size;
|
||||
var format = this.imageOptions.format || this.defaults.format;
|
||||
|
||||
var lat = center[0];
|
||||
var lon = center[1];
|
||||
|
||||
var width = size[0];
|
||||
var height = size[1];
|
||||
|
||||
var subhost = this.isHttps() ? null : "a";
|
||||
|
||||
var url = this._host(subhost) + this.endPoint;
|
||||
|
||||
if (bbox && bbox.length && !this.userOptions.override_bbox) {
|
||||
return [url, "static/bbox" , layergroupid, bbox.join(","), width, height + "." + format].join("/");
|
||||
} else {
|
||||
return [url, "static/center" , layergroupid, zoom, lat, lon, width, height + "." + format].join("/");
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
// Generates a random string
|
||||
_getUUID: function() {
|
||||
var S4 = function() {
|
||||
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
|
||||
};
|
||||
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
|
||||
},
|
||||
|
||||
/* Setters */
|
||||
_set: function(name, value) {
|
||||
|
||||
var self = this;
|
||||
|
||||
this.queue.add(function() {
|
||||
self.imageOptions[name] = value;
|
||||
});
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
zoom: function(zoom) {
|
||||
return this._set("zoom", zoom);
|
||||
},
|
||||
|
||||
bbox: function(bbox) {
|
||||
return this._set("bbox", bbox);
|
||||
},
|
||||
|
||||
center: function(center) {
|
||||
this._set("bbox", null);
|
||||
return this._set("center", center);
|
||||
},
|
||||
|
||||
format: function(format) {
|
||||
return this._set("format", _.include(this.supported_formats, format) ? format : this.defaults.format);
|
||||
},
|
||||
|
||||
size: function(width, height) {
|
||||
return this._set("size", [width, height === undefined ? width : height]);
|
||||
},
|
||||
|
||||
/* Methods */
|
||||
|
||||
/* Image.into(HTMLImageElement)
|
||||
inserts the image in the HTMLImageElement specified */
|
||||
into: function(img) {
|
||||
|
||||
var self = this;
|
||||
|
||||
if (!(img instanceof HTMLImageElement)) {
|
||||
cartodb.log.error("img should be an image");
|
||||
return;
|
||||
}
|
||||
|
||||
this.imageOptions.size = [img.width, img.height];
|
||||
|
||||
this.queue.add(function(response) {
|
||||
img.src = self._getUrl();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/* Image.getUrl(callback(err, url))
|
||||
gets the url for the image, err is null is there was no error */
|
||||
|
||||
getUrl: function(callback) {
|
||||
|
||||
var self = this;
|
||||
|
||||
this.queue.add(function() {
|
||||
if (callback) {
|
||||
callback(self.error, self._getUrl());
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/* Image.write(attributes)
|
||||
adds a img tag in the same place script is executed */
|
||||
|
||||
write: function(attributes) {
|
||||
|
||||
var self = this;
|
||||
|
||||
this.imageOptions.attributes = attributes;
|
||||
|
||||
if (attributes && attributes.src) {
|
||||
document.write('<img id="' + this.imageOptions.temp_id + '" src="' + attributes.src + '" />');
|
||||
} else {
|
||||
document.write('<img id="' + this.imageOptions.temp_id + '" />');
|
||||
}
|
||||
|
||||
this.queue.add(function() {
|
||||
|
||||
var element = document.getElementById(self.imageOptions.temp_id);
|
||||
|
||||
element.src = self._getUrl();
|
||||
element.removeAttribute("temp_id");
|
||||
|
||||
var attributes = self.imageOptions.attributes;
|
||||
|
||||
if (attributes && attributes.class) { element.setAttribute("class", attributes.class); }
|
||||
if (attributes && attributes.id) { element.setAttribute("id", attributes.id); }
|
||||
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
cdb.Image = function(data, options) {
|
||||
|
||||
if (!options) options = {};
|
||||
|
||||
var image = new StaticImage();
|
||||
|
||||
if (typeof data === 'string') {
|
||||
image.load(data, options);
|
||||
} else {
|
||||
image.loadLayerDefinition(data, options);
|
||||
}
|
||||
|
||||
return image;
|
||||
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,141 @@
|
||||
|
||||
(function() {
|
||||
|
||||
var Layers = cdb.vis.Layers;
|
||||
|
||||
/*
|
||||
* if we are using http and the tiles of base map need to be fetched from
|
||||
* https try to fix it
|
||||
*/
|
||||
|
||||
var HTTPS_TO_HTTP = {
|
||||
'https://dnv9my2eseobd.cloudfront.net/': 'http://a.tiles.mapbox.com/',
|
||||
'https://maps.nlp.nokia.com/': 'http://maps.nlp.nokia.com/',
|
||||
'https://tile.stamen.com/': 'http://tile.stamen.com/',
|
||||
"https://{s}.maps.nlp.nokia.com/": "http://{s}.maps.nlp.nokia.com/",
|
||||
"https://cartocdn_{s}.global.ssl.fastly.net/": "http://{s}.api.cartocdn.com/",
|
||||
"https://cartodb-basemaps-{s}.global.ssl.fastly.net/": "http://{s}.basemaps.cartocdn.com/"
|
||||
};
|
||||
|
||||
function transformToHTTP(tilesTemplate) {
|
||||
for(var url in HTTPS_TO_HTTP) {
|
||||
if(tilesTemplate.indexOf(url) !== -1) {
|
||||
return tilesTemplate.replace(url, HTTPS_TO_HTTP[url])
|
||||
}
|
||||
}
|
||||
return tilesTemplate;
|
||||
}
|
||||
|
||||
function transformToHTTPS(tilesTemplate) {
|
||||
for(var url in HTTPS_TO_HTTP) {
|
||||
var httpsUrl = HTTPS_TO_HTTP[url];
|
||||
if(tilesTemplate.indexOf(httpsUrl) !== -1) {
|
||||
return tilesTemplate.replace(httpsUrl, url);
|
||||
}
|
||||
}
|
||||
return tilesTemplate;
|
||||
}
|
||||
|
||||
Layers.register('tilejson', function(vis, data) {
|
||||
var url = data.tiles[0];
|
||||
if(vis.https === true) {
|
||||
url = transformToHTTPS(url);
|
||||
}
|
||||
else if(vis.https === false) { // Checking for an explicit false value. If it's undefined the url is left as is.
|
||||
url = transformToHTTP(url);
|
||||
}
|
||||
return new cdb.geo.TileLayer({
|
||||
urlTemplate: url
|
||||
});
|
||||
});
|
||||
|
||||
Layers.register('tiled', function(vis, data) {
|
||||
var url = data.urlTemplate;
|
||||
if(vis.https === true) {
|
||||
url = transformToHTTPS(url);
|
||||
}
|
||||
else if(vis.https === false) { // Checking for an explicit false value. If it's undefined the url is left as is.
|
||||
url = transformToHTTP(url);
|
||||
}
|
||||
|
||||
data.urlTemplate = url;
|
||||
return new cdb.geo.TileLayer(data);
|
||||
});
|
||||
|
||||
Layers.register('wms', function(vis, data) {
|
||||
return new cdb.geo.WMSLayer(data);
|
||||
});
|
||||
|
||||
Layers.register('gmapsbase', function(vis, data) {
|
||||
return new cdb.geo.GMapsBaseLayer(data);
|
||||
});
|
||||
|
||||
Layers.register('plain', function(vis, data) {
|
||||
return new cdb.geo.PlainLayer(data);
|
||||
});
|
||||
|
||||
Layers.register('background', function(vis, data) {
|
||||
return new cdb.geo.PlainLayer(data);
|
||||
});
|
||||
|
||||
|
||||
function normalizeOptions(vis, data) {
|
||||
if(data.infowindow && data.infowindow.fields) {
|
||||
if(data.interactivity) {
|
||||
if(data.interactivity.indexOf('cartodb_id') === -1) {
|
||||
data.interactivity = data.interactivity + ",cartodb_id";
|
||||
}
|
||||
} else {
|
||||
data.interactivity = 'cartodb_id';
|
||||
}
|
||||
}
|
||||
// if https is forced
|
||||
if(vis.https) {
|
||||
data.tiler_protocol = 'https';
|
||||
data.tiler_port = 443;
|
||||
data.sql_api_protocol = 'https';
|
||||
data.sql_api_port = 443;
|
||||
}
|
||||
data.cartodb_logo = vis.cartodb_logo == undefined ? data.cartodb_logo : vis.cartodb_logo;
|
||||
}
|
||||
|
||||
var cartoLayer = function(vis, data) {
|
||||
normalizeOptions(vis, data);
|
||||
// if sublayers are included that means a layergroup should
|
||||
// be created
|
||||
if(data.sublayers) {
|
||||
data.type = 'layergroup';
|
||||
return new cdb.geo.CartoDBGroupLayer(data);
|
||||
}
|
||||
return new cdb.geo.CartoDBLayer(data);
|
||||
};
|
||||
|
||||
Layers.register('cartodb', cartoLayer);
|
||||
Layers.register('carto', cartoLayer);
|
||||
|
||||
Layers.register('layergroup', function(vis, data) {
|
||||
normalizeOptions(vis, data);
|
||||
return new cdb.geo.CartoDBGroupLayer(data);
|
||||
});
|
||||
|
||||
Layers.register('namedmap', function(vis, data) {
|
||||
normalizeOptions(vis, data);
|
||||
return new cdb.geo.CartoDBNamedMapLayer(data);
|
||||
});
|
||||
|
||||
Layers.register('torque', function(vis, data) {
|
||||
normalizeOptions(vis, data);
|
||||
// default is https
|
||||
if(vis.https) {
|
||||
if(data.sql_api_domain && data.sql_api_domain.indexOf('carto.com') !== -1) {
|
||||
data.sql_api_protocol = 'https';
|
||||
data.sql_api_port = 443;
|
||||
data.tiler_protocol = 'https';
|
||||
data.tiler_port = 443;
|
||||
}
|
||||
}
|
||||
data.cartodb_logo = vis.cartodb_logo == undefined ? data.cartodb_logo : vis.cartodb_logo;
|
||||
return new cdb.geo.TorqueLayer(data);
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,454 @@
|
||||
(function() {
|
||||
|
||||
cdb.vis.Overlay.register('logo', function(data, vis) {
|
||||
|
||||
});
|
||||
|
||||
cdb.vis.Overlay.register('slides_controller', function(data, vis) {
|
||||
|
||||
var slides_controller = new cdb.geo.ui.SlidesController({
|
||||
transitions: data.transitions,
|
||||
visualization: vis
|
||||
});
|
||||
|
||||
return slides_controller.render();
|
||||
|
||||
});
|
||||
|
||||
cdb.vis.Overlay.register('mobile', function(data, vis) {
|
||||
|
||||
var template = cdb.core.Template.compile(
|
||||
data.template || '\
|
||||
<div class="backdrop"></div>\
|
||||
<div class="cartodb-header">\
|
||||
<div class="content">\
|
||||
<a href="#" class="fullscreen"></a>\
|
||||
<a href="#" class="toggle"></a>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="aside">\
|
||||
<div class="layer-container">\
|
||||
<div class="scrollpane"><ul class="layers"></ul></div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="cartodb-attribution"></div>\
|
||||
<a href="#" class="cartodb-attribution-button"></a>\
|
||||
<div class="torque"></div>\
|
||||
',
|
||||
data.templateType || 'mustache'
|
||||
);
|
||||
|
||||
var mobile = new cdb.geo.ui.Mobile({
|
||||
template: template,
|
||||
mapView: vis.mapView,
|
||||
overlays: data.overlays,
|
||||
transitions: data.transitions,
|
||||
slides_data: data.slides,
|
||||
visualization: vis,
|
||||
layerView: data.layerView,
|
||||
visibility_options: data.options,
|
||||
torqueLayer: data.torqueLayer,
|
||||
map: data.map
|
||||
});
|
||||
|
||||
return mobile.render();
|
||||
});
|
||||
|
||||
cdb.vis.Overlay.register('image', function(data, vis) {
|
||||
|
||||
var options = data.options;
|
||||
|
||||
var template = cdb.core.Template.compile(
|
||||
data.template || '\
|
||||
<div class="content">\
|
||||
<div class="text widget_text">{{{ content }}}</div>\
|
||||
</div>',
|
||||
data.templateType || 'mustache'
|
||||
);
|
||||
|
||||
var widget = new cdb.geo.ui.Image({
|
||||
model: new cdb.core.Model(options),
|
||||
template: template
|
||||
});
|
||||
|
||||
return widget.render();
|
||||
|
||||
});
|
||||
|
||||
cdb.vis.Overlay.register('text', function(data, vis) {
|
||||
|
||||
var options = data.options;
|
||||
|
||||
var template = cdb.core.Template.compile(
|
||||
data.template || '\
|
||||
<div class="content">\
|
||||
<div class="text widget_text">{{{ text }}}</div>\
|
||||
</div>',
|
||||
data.templateType || 'mustache'
|
||||
);
|
||||
|
||||
var widget = new cdb.geo.ui.Text({
|
||||
model: new cdb.core.Model(options),
|
||||
template: template,
|
||||
className: "cartodb-overlay overlay-text " + options.device
|
||||
});
|
||||
|
||||
return widget.render();
|
||||
|
||||
});
|
||||
|
||||
cdb.vis.Overlay.register('annotation', function(data, vis) {
|
||||
|
||||
var options = data.options;
|
||||
|
||||
var template = cdb.core.Template.compile(
|
||||
data.template || '\
|
||||
<div class="content">\
|
||||
<div class="text widget_text">{{{ text }}}</div>\
|
||||
<div class="stick"><div class="ball"></div></div>\
|
||||
</div>',
|
||||
data.templateType || 'mustache'
|
||||
);
|
||||
|
||||
var options = data.options;
|
||||
|
||||
var widget = new cdb.geo.ui.Annotation({
|
||||
className: "cartodb-overlay overlay-annotation " + options.device,
|
||||
template: template,
|
||||
mapView: vis.mapView,
|
||||
device: options.device,
|
||||
text: options.extra.rendered_text,
|
||||
minZoom: options.style["min-zoom"],
|
||||
maxZoom: options.style["max-zoom"],
|
||||
latlng: options.extra.latlng,
|
||||
style: options.style
|
||||
});
|
||||
|
||||
return widget.render();
|
||||
|
||||
});
|
||||
|
||||
|
||||
cdb.vis.Overlay.register('zoom_info', function(data, vis) {
|
||||
//console.log("placeholder for the zoom_info overlay");
|
||||
});
|
||||
|
||||
cdb.vis.Overlay.register('header', function(data, vis) {
|
||||
|
||||
var options = data.options;
|
||||
|
||||
var template = cdb.core.Template.compile(
|
||||
data.template || '\
|
||||
<div class="content">\
|
||||
<div class="title">{{{ title }}}</div>\
|
||||
<div class="description">{{{ description }}}</div>\
|
||||
</div>',
|
||||
data.templateType || 'mustache'
|
||||
);
|
||||
|
||||
var widget = new cdb.geo.ui.Header({
|
||||
model: new cdb.core.Model(options),
|
||||
transitions: data.transitions,
|
||||
slides: vis.slides,
|
||||
template: template
|
||||
});
|
||||
|
||||
return widget.render();
|
||||
|
||||
});
|
||||
|
||||
// map zoom control
|
||||
cdb.vis.Overlay.register('zoom', function(data, vis) {
|
||||
|
||||
if(!data.template) {
|
||||
vis.trigger('error', 'zoom template is empty')
|
||||
return;
|
||||
}
|
||||
|
||||
var zoom = new cdb.geo.ui.Zoom({
|
||||
model: data.map,
|
||||
template: cdb.core.Template.compile(data.template)
|
||||
});
|
||||
|
||||
return zoom.render();
|
||||
|
||||
});
|
||||
|
||||
// Tiles loader
|
||||
cdb.vis.Overlay.register('loader', function(data) {
|
||||
|
||||
var tilesLoader = new cdb.geo.ui.TilesLoader({
|
||||
template: cdb.core.Template.compile(data.template)
|
||||
});
|
||||
|
||||
return tilesLoader.render();
|
||||
});
|
||||
|
||||
cdb.vis.Overlay.register('time_slider', function(data, viz) {
|
||||
var slider = new cdb.geo.ui.TimeSlider(data);
|
||||
return slider.render();
|
||||
});
|
||||
|
||||
|
||||
// Header to show informtion (title and description)
|
||||
cdb.vis.Overlay.register('_header', function(data, vis) {
|
||||
var MAX_SHORT_DESCRIPTION_LENGTH = 100;
|
||||
|
||||
// Add the complete url for facebook and twitter
|
||||
if (location.href) {
|
||||
data.share_url = encodeURIComponent(location.href);
|
||||
} else {
|
||||
data.share_url = data.url;
|
||||
}
|
||||
|
||||
var template = cdb.core.Template.compile(
|
||||
data.template || "\
|
||||
{{#title}}\
|
||||
<h1>\
|
||||
{{#url}}\
|
||||
<a href='#' onmousedown=\"window.open('{{url}}')\">{{title}}</a>\
|
||||
{{/url}}\
|
||||
{{^url}}\
|
||||
{{title}}\
|
||||
{{/url}}\
|
||||
</h1>\
|
||||
{{/title}}\
|
||||
{{#description}}<p>{{{description}}}</p>{{/description}}\
|
||||
{{#mobile_shareable}}\
|
||||
<div class='social'>\
|
||||
<a class='facebook' target='_blank'\
|
||||
href='http://www.facebook.com/sharer.php?u={{share_url}}&text=Map of {{title}}: {{description}}'>F</a>\
|
||||
<a class='twitter' href='https://twitter.com/share?url={{share_url}}&text={{twitter_title}}'\
|
||||
target='_blank'>T</a>\
|
||||
</div>\
|
||||
{{/mobile_shareable}}\
|
||||
",
|
||||
data.templateType || 'mustache'
|
||||
);
|
||||
|
||||
function truncate(s, length) {
|
||||
return s.substr(0, length-1) + (s.length > length ? '…' : '');
|
||||
}
|
||||
|
||||
var title = data.map.get('title');
|
||||
var description = data.map.get('description');
|
||||
|
||||
var facebook_title = title + ": " + description;
|
||||
var twitter_title;
|
||||
|
||||
if (title && description) {
|
||||
twitter_title = truncate(title + ": " + description, 112) + " %23map "
|
||||
} else if (title) {
|
||||
twitter_title = truncate(title, 112) + " %23map"
|
||||
} else if (description){
|
||||
twitter_title = truncate(description, 112) + " %23map"
|
||||
} else {
|
||||
twitter_title = "%23map"
|
||||
}
|
||||
|
||||
var shareable = (data.shareable == "false" || !data.shareable) ? null : data.shareable;
|
||||
var mobile_shareable = shareable;
|
||||
|
||||
mobile_shareable = mobile_shareable && (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
|
||||
|
||||
var header = new cdb.geo.ui.Header({
|
||||
title: title,
|
||||
description: description,
|
||||
facebook_title: facebook_title,
|
||||
twitter_title: twitter_title,
|
||||
url: data.url,
|
||||
share_url: data.share_url,
|
||||
mobile_shareable: mobile_shareable,
|
||||
shareable: shareable && !mobile_shareable,
|
||||
template: template
|
||||
});
|
||||
|
||||
return header.render();
|
||||
});
|
||||
|
||||
// infowindow
|
||||
cdb.vis.Overlay.register('infowindow', function(data, vis) {
|
||||
|
||||
if (_.size(data.fields) == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var infowindowModel = new cdb.geo.ui.InfowindowModel({
|
||||
template: data.template,
|
||||
template_type: data.templateType,
|
||||
alternative_names: data.alternative_names,
|
||||
fields: data.fields,
|
||||
template_name: data.template_name
|
||||
});
|
||||
|
||||
var infowindow = new cdb.geo.ui.Infowindow({
|
||||
model: infowindowModel,
|
||||
mapView: vis.mapView,
|
||||
template: data.template
|
||||
});
|
||||
|
||||
return infowindow;
|
||||
});
|
||||
|
||||
|
||||
// layer_selector
|
||||
cdb.vis.Overlay.register('layer_selector', function(data, vis) {
|
||||
|
||||
var options = data.options;
|
||||
//if (!options.display) return;
|
||||
|
||||
var template = cdb.core.Template.compile(
|
||||
data.template || '\
|
||||
<a href="#/change-visibility" class="layers">Visible layers<div class="count"></div></a>\
|
||||
',
|
||||
data.templateType || 'underscore'
|
||||
);
|
||||
|
||||
var dropdown_template = cdb.core.Template.compile(
|
||||
data.template || '\
|
||||
<ul></ul><div class="tail"><span class="border"></span></div>\
|
||||
',
|
||||
data.templateType || 'underscore'
|
||||
);
|
||||
|
||||
var layerSelector = new cdb.geo.ui.LayerSelector({
|
||||
model: new cdb.core.Model(options),
|
||||
mapView: vis.mapView,
|
||||
template: template,
|
||||
dropdown_template: dropdown_template,
|
||||
layer_names: data.layer_names
|
||||
});
|
||||
|
||||
var timeSlider = vis.timeSlider;
|
||||
if (timeSlider) {
|
||||
layerSelector.bind('change:visible', function(visible, order, layer) {
|
||||
if (layer.get('type') === 'torque') {
|
||||
timeSlider[visible ? 'show': 'hide']();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (vis.legends) {
|
||||
|
||||
layerSelector.bind('change:visible', function(visible, order, layer) {
|
||||
|
||||
|
||||
if (layer.get('type') === 'layergroup' || layer.get('type') === 'torque') {
|
||||
|
||||
var legend = vis.legends && vis.legends.getLegendByIndex(order);
|
||||
|
||||
if (legend) {
|
||||
legend[visible ? 'show': 'hide']();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
return layerSelector.render();
|
||||
|
||||
});
|
||||
|
||||
// fullscreen
|
||||
cdb.vis.Overlay.register('fullscreen', function(data, vis) {
|
||||
|
||||
var options = data.options;
|
||||
|
||||
options.allowWheelOnFullscreen = false;
|
||||
|
||||
var template = cdb.core.Template.compile(
|
||||
data.template || '<a href="{{ mapUrl }}" target="_blank"></a>',
|
||||
data.templateType || 'mustache'
|
||||
);
|
||||
|
||||
var fullscreen = new cdb.ui.common.FullScreen({
|
||||
doc: "#map > div",
|
||||
model: new cdb.core.Model(options),
|
||||
mapView: vis.mapView,
|
||||
template: template
|
||||
});
|
||||
|
||||
return fullscreen.render();
|
||||
|
||||
});
|
||||
|
||||
// share content
|
||||
cdb.vis.Overlay.register('share', function(data, vis) {
|
||||
|
||||
var options = data.options;
|
||||
|
||||
var template = cdb.core.Template.compile(
|
||||
data.template || '<a href="#"></a>',
|
||||
data.templateType || 'mustache'
|
||||
);
|
||||
|
||||
var widget = new cdb.geo.ui.Share({
|
||||
model: new cdb.core.Model(options),
|
||||
vis: vis,
|
||||
map: vis.map,
|
||||
template: template
|
||||
});
|
||||
|
||||
widget.createDialog();
|
||||
|
||||
return widget.render();
|
||||
|
||||
});
|
||||
|
||||
// search content
|
||||
cdb.vis.Overlay.register('search', function(data, vis) {
|
||||
|
||||
var template = cdb.core.Template.compile(
|
||||
data.template || '\
|
||||
<form>\
|
||||
<span class="loader"></span>\
|
||||
<input type="text" class="text" value="" />\
|
||||
<input type="submit" class="submit" value="" />\
|
||||
</form>\
|
||||
',
|
||||
data.templateType || 'mustache'
|
||||
);
|
||||
|
||||
var search = new cdb.geo.ui.Search(
|
||||
_.extend(data, {
|
||||
template: template,
|
||||
mapView: vis.mapView,
|
||||
model: vis.map
|
||||
})
|
||||
);
|
||||
|
||||
return search.render();
|
||||
|
||||
});
|
||||
|
||||
// tooltip
|
||||
cdb.vis.Overlay.register('tooltip', function(data, vis) {
|
||||
if (!data.layer && vis.getLayers().length <= 1) {
|
||||
throw new Error("layer is null");
|
||||
}
|
||||
data.layer = data.layer || vis.getLayers()[1];
|
||||
data.layer.setInteraction(true);
|
||||
data.mapView = vis.mapView;
|
||||
return new cdb.geo.ui.Tooltip(data);
|
||||
});
|
||||
|
||||
cdb.vis.Overlay.register('infobox', function(data, vis) {
|
||||
var layer;
|
||||
var layers = vis.getLayers();
|
||||
if (!data.layer) {
|
||||
if(layers.length > 1) {
|
||||
layer = layers[1];
|
||||
}
|
||||
data.layer = layer;
|
||||
}
|
||||
if(!data.layer) {
|
||||
throw new Error("layer is null");
|
||||
}
|
||||
data.layer.setInteraction(true);
|
||||
var infobox = new cdb.geo.ui.InfoBox(data);
|
||||
return infobox;
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user