Add CartoDB tile source.

This commit is contained in:
Alessandro Isaacs
2015-10-30 16:15:04 -07:00
parent cf9e24feb1
commit 8389c16315
5 changed files with 317 additions and 0 deletions

26
examples/cartodb.html Normal file
View File

@@ -0,0 +1,26 @@
---
template: example.html
title: CartoDB source example
shortdesc: Example of a cartodb map.
docs: >
A simple map with customized Attribution control.
tags: "simple, openstreetmap, attribution"
---
<div class="row-fluid">
<div class="span12">
<div id="map" class="map"></div>
<div>
<form class="form-horizontal">
<label>
Show countries larger than
<select id="country-area" class="form-control">
<option value="0" default>0 ㎢</option>
<option value="5000">5000 ㎢</option>
<option value="10000">10000 ㎢</option>
<option value="50000">50000 ㎢</option>
<option value="100000">100000 ㎢</option>
</select>
</label>
</form>
</div>
</div>

48
examples/cartodb.js Normal file
View File

@@ -0,0 +1,48 @@
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.layer.Tile');
goog.require('ol.source.CartoDB');
goog.require('ol.source.OSM');
var mapConfig = {
'layers': [{
'type': 'cartodb',
'options': {
'cartocss_version': '2.1.1',
'cartocss': '#layer { polygon-fill: #F00; }',
'sql': 'select * from european_countries_e where area > 0'
}
}]
};
var cartoDBSource = new ol.source.CartoDB({
account: 'documentation',
config: mapConfig
});
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
new ol.layer.Tile({
source: cartoDBSource
})
],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
function setArea(n) {
mapConfig.layers[0].options.sql =
'select * from european_countries_e where area > ' + n;
cartoDBSource.setConfig(mapConfig);
}
document.getElementById('country-area').addEventListener('change', function() {
setArea(this.value);
});

View File

@@ -6209,6 +6209,104 @@ olx.source.XYZOptions.prototype.urls;
*/ */
olx.source.XYZOptions.prototype.wrapX; olx.source.XYZOptions.prototype.wrapX;
/**
* @typedef {{attributions: (Array.<ol.Attribution>|undefined),
* crossOrigin: (null|string|undefined),
* logo: (string|olx.LogoOptions|undefined),
* projection: ol.proj.ProjectionLike,
* maxZoom: (number|undefined),
* minZoom: (number|undefined),
* wrapX: (boolean|undefined),
* config: (Object|undefined),
* map: string,
* account: (string|undefined)}}
* @api
*/
olx.source.CartoDBOptions;
/**
* Attributions.
* @type {Array.<ol.Attribution>|undefined}
* @api stable
*/
olx.source.CartoDBOptions.prototype.attributions;
/**
* The `crossOrigin` attribute for loaded images. Note that you must provide a
* `crossOrigin` value if you are using the WebGL renderer or if you want to
* access pixel data with the Canvas renderer. See
* {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image}
* for more detail.
* @type {null|string|undefined}
* @api stable
*/
olx.source.CartoDBOptions.prototype.crossOrigin;
/**
* Logo.
* @type {string|olx.LogoOptions|undefined}
* @api stable
*/
olx.source.CartoDBOptions.prototype.logo;
/**
* Projection. Default is `EPSG:3857`.
* @type {ol.proj.ProjectionLike}
* @api
*/
olx.source.CartoDBOptions.prototype.projection;
/**
* Optional max zoom level. Default is `18`.
* @type {number|undefined}
* @api
*/
olx.source.CartoDBOptions.prototype.maxZoom;
/**
* Whether to wrap the world horizontally. Default is `true`.
* @type {boolean|undefined}
* @api
*/
olx.source.CartoDBOptions.prototype.wrapX;
/**
* If using anonymous maps, the CartoDB config to use. See
* {@link http://docs.cartodb.com/cartodb-platform/maps-api.html#anonymous-maps}
* for more detail.
* If using named maps, a key-value lookup with the template parameters.
* See {@link http://docs.cartodb.com/cartodb-platform/maps-api.html#named-maps}
* for more detail.
* @type {Object|undefined}
* @api
*/
olx.source.CartoDBOptions.prototype.config;
/**
* If using named maps, this will be the name of the template to load.
* See {@link http://docs.cartodb.com/cartodb-platform/maps-api.html#named-maps}
* for more detail.
* @type {boolean|undefined}
* @api
*/
olx.source.CartoDBOptions.prototype.map;
/**
* CartoDB account name
* @type {string}
* @api
*/
olx.source.CartoDBOptions.prototype.account;
/** /**
* @typedef {{attributions: (olx.source.AttributionOption|undefined), * @typedef {{attributions: (olx.source.AttributionOption|undefined),

127
src/ol/source/cartodb.js Normal file
View File

@@ -0,0 +1,127 @@
goog.provide('ol.source.CartoDB');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.net.EventType');
goog.require('goog.net.XhrIo');
goog.require('goog.net.XhrIo.ResponseType');
goog.require('ol.source.XYZ');
/**
* @classdesc
* Layer source for the CartoDB tiles.
*
* @constructor
* @extends {ol.source.XYZ}
* @param {olx.source.CartoDBOptions} options CartoDB options.
* @api
*/
ol.source.CartoDB = function(options) {
this.account_ = options.account;
this.mapId_ = options.map || '';
this.config_ = options.config || {};
this.templateCache_ = {};
delete options.map;
goog.base(this, options);
this.initializeMap_();
};
goog.inherits(ol.source.CartoDB, ol.source.XYZ);
/**
* Returns the current config.
* @return {Object} The current configuration.
* @api
*/
ol.source.CartoDB.prototype.getConfig = function() {
return this.config_;
};
/**
* Updates the carto db config.
* @param {Object} config a key-value lookup. Values will replace current values
* in the config.
* @api
*/
ol.source.CartoDB.prototype.updateConfig = function(config) {
for (var key in config) {
this.config_[key] = config[key];
}
this.initializeMap_();
};
/**
* Sets the CartoDB config
* @param {Object} config In the case of anonymous maps, a CartoDB configuration
* object.
* If using named maps, a key-value lookup with the template parameters.
*/
ol.source.CartoDB.prototype.setConfig = function(config) {
this.config_ = config || {};
this.initializeMap_();
};
/**
* Issue a request to initialize the CartoDB map.
* @private
*/
ol.source.CartoDB.prototype.initializeMap_ = function() {
var paramHash = JSON.stringify(this.config_);
if (this.templateCache_[paramHash]) {
this.applyTemplate_(this.templateCache_[paramHash]);
return;
}
var protocol = window.location.protocol;
var mapUrl = protocol + '//' + this.account_ +
'.cartodb.com/api/v1/map';
if (this.mapId_) {
mapUrl += '/named/' + this.mapId_;
}
var xhrIo = new goog.net.XhrIo();
xhrIo.setResponseType(goog.net.XhrIo.ResponseType.TEXT);
xhrIo.setWithCredentials(false);
goog.events.listen(xhrIo, goog.net.EventType.COMPLETE,
this.handleInitResponse_.bind(this, paramHash));
xhrIo.send(mapUrl,
'POST',
JSON.stringify(this.config_),
{'Content-Type': 'application/json'});
};
/**
* Handle map initialization response.
* @param {string} paramHash a hash representing the parameter set that was used
* for the request
* @param {Event} event Event.
* @private
*/
ol.source.CartoDB.prototype.handleInitResponse_ = function(paramHash, event) {
var xhrIo = event.target;
goog.asserts.assertInstanceof(xhrIo, goog.net.XhrIo,
'event.target/xhrIo is an instance of goog.net.XhrIo');
var data = xhrIo.getResponseJson();
if (xhrIo.isSuccess()) {
this.applyTemplate_(data);
}
this.templateCache_[paramHash] = data;
};
/**
* Apply the new tile urls returned by carto db
* @param {Object} data Result of carto db call.
* @private
*/
ol.source.CartoDB.prototype.applyTemplate_ = function(data) {
var layerId = data['layergroupid'];
var tilesUrl = 'https://' + data['cdn_url']['https'] + '/' + this.account_ +
'/api/v1/map/' + layerId + '/{z}/{x}/{y}.png';
this.setUrl(tilesUrl);
};

View File

@@ -0,0 +1,18 @@
goog.provide('ol.test.source.CartoDBSource');
goog.require('ol.source.CartoDB');
goog.require('ol.source.XYZ');
describe('ol.source.CartoDB', function() {
describe('constructor', function() {
it('returns a CartoDB source', function() {
var source = new ol.source.CartoDB({
map: 'example',
config: {}
});
expect(source).to.be.a(ol.source.XYZ);
expect(source).to.be.a(ol.source.CartoDB);
});
});
});