Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac296411d5 | ||
|
|
09cea4d6d4 | ||
|
|
382ff2416f | ||
|
|
27036379dd | ||
|
|
f4e6e140e0 | ||
|
|
b4e5cb88d9 | ||
|
|
3269fef845 | ||
|
|
e797719b41 | ||
|
|
284a8f2465 | ||
|
|
54ea656da2 | ||
|
|
b4aaadf40b | ||
|
|
74d2e3ef75 | ||
|
|
b10e4c11d9 | ||
|
|
075e141a9c | ||
|
|
04acf895f0 | ||
|
|
21608bf2e2 | ||
|
|
653beb1952 | ||
|
|
050d33ff14 | ||
|
|
1ae86e039b | ||
|
|
f75cadf6ba | ||
|
|
93d0fe9176 |
18
NEWS.md
18
NEWS.md
@@ -1,5 +1,23 @@
|
||||
# Changelog
|
||||
|
||||
## 2.46.0
|
||||
|
||||
Released 2016-06-09
|
||||
|
||||
Improvements:
|
||||
- Support for substitution tokens in geojson tiles
|
||||
- Warn on application start about non-matching dependencies
|
||||
|
||||
Announcements:
|
||||
- Upgrades windshaft to [2.3.0](https://github.com/CartoDB/camshaft/releases/tag/2.3.0)
|
||||
- Upgrades camshaft to [0.13.0](https://github.com/CartoDB/camshaft/releases/tag/0.13.0)
|
||||
- Upgrades turbo-carto to [0.11.0](https://github.com/CartoDB/turbo-carto/releases/tag/0.11.0)
|
||||
|
||||
Bug fixes:
|
||||
- Column provided for geojson renderer should not be null #476
|
||||
- Dataviews/widgets adapter working with non sql, non source, and non widgets layers
|
||||
|
||||
|
||||
## 2.45.0
|
||||
|
||||
Released 2016-06-02
|
||||
|
||||
@@ -137,14 +137,14 @@ DataviewBackend.prototype.getDataview = function (mapConfigProvider, user, param
|
||||
}
|
||||
|
||||
if (params.bbox) {
|
||||
var bboxFilter = new BBoxFilter({column: 'the_geom', srid: 4326}, {bbox: params.bbox});
|
||||
var bboxFilter = new BBoxFilter({column: 'the_geom_webmercator', srid: 3857}, {bbox: params.bbox});
|
||||
query = bboxFilter.sql(query);
|
||||
if ( queryRewriteData ) {
|
||||
var bbox_filter_definition = {
|
||||
type: 'bbox',
|
||||
options: {
|
||||
column: 'the_geom',
|
||||
srid: 4326,
|
||||
column: 'the_geom_webmercator',
|
||||
srid: 3857
|
||||
},
|
||||
params: {
|
||||
bbox: params.bbox
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
var windshaft = require('windshaft');
|
||||
var HealthCheck = require('../monitoring/health_check');
|
||||
|
||||
var WELCOME_MSG = "This is the CartoDB Maps API, " +
|
||||
"see the documentation at http://docs.cartodb.com/cartodb-platform/maps-api.html";
|
||||
|
||||
|
||||
var versions = {
|
||||
windshaft: windshaft.version,
|
||||
grainstore: windshaft.grainstore.version(),
|
||||
node_mapnik: windshaft.mapnik.version,
|
||||
mapnik: windshaft.mapnik.versions.mapnik,
|
||||
windshaft_cartodb: require('../../../package.json').version
|
||||
};
|
||||
|
||||
function ServerInfoController() {
|
||||
function ServerInfoController(versions) {
|
||||
this.healthConfig = global.environment.health || {};
|
||||
this.healthCheck = new HealthCheck(global.environment.disabled_file);
|
||||
this.versions = versions || {};
|
||||
}
|
||||
|
||||
module.exports = ServerInfoController;
|
||||
@@ -31,7 +23,7 @@ ServerInfoController.prototype.welcome = function(req, res) {
|
||||
};
|
||||
|
||||
ServerInfoController.prototype.version = function(req, res) {
|
||||
res.status(200).send(versions);
|
||||
res.status(200).send(this.versions);
|
||||
};
|
||||
|
||||
ServerInfoController.prototype.health = function(req, res) {
|
||||
|
||||
@@ -174,8 +174,8 @@ Histogram.prototype.sql = function(psql, override, callback) {
|
||||
basicsQuery = overrideBasicsQueryTpl({
|
||||
_query: _query,
|
||||
_column: _column,
|
||||
_start: override.start,
|
||||
_end: override.end
|
||||
_start: getBinStart(override),
|
||||
_end: getBinEnd(override)
|
||||
});
|
||||
|
||||
binsQuery = [
|
||||
@@ -248,7 +248,7 @@ Histogram.prototype.format = function(result, override) {
|
||||
width = firstRow.bin_width || width;
|
||||
avg = firstRow.avg_val;
|
||||
nulls = firstRow.nulls_count;
|
||||
binsStart = override.hasOwnProperty('start') ? override.start : firstRow.min;
|
||||
binsStart = override.hasOwnProperty('start') ? getBinStart(override) : firstRow.min;
|
||||
|
||||
buckets = result.rows.map(function(row) {
|
||||
return _.omit(row, 'bins_number', 'bin_width', 'nulls_count', 'avg_val');
|
||||
@@ -266,9 +266,19 @@ Histogram.prototype.format = function(result, override) {
|
||||
};
|
||||
|
||||
function getBinStart(override) {
|
||||
if (override.hasOwnProperty('start') && override.hasOwnProperty('end')) {
|
||||
return Math.min(override.start, override.end);
|
||||
}
|
||||
return override.start || 0;
|
||||
}
|
||||
|
||||
function getBinEnd(override) {
|
||||
if (override.hasOwnProperty('start') && override.hasOwnProperty('end')) {
|
||||
return Math.max(override.start, override.end);
|
||||
}
|
||||
return override.end || 0;
|
||||
}
|
||||
|
||||
function getBinsCount(override) {
|
||||
return override.bins || 0;
|
||||
}
|
||||
|
||||
@@ -101,10 +101,7 @@ AnalysisMapConfigAdapter.prototype.getMapConfig = function(user, requestMapConfi
|
||||
analysisSql = sqlQueryWrap.replace(/<%=\s*sql\s*%>/g, analysisSql);
|
||||
}
|
||||
layer.options.sql = analysisSql;
|
||||
var layerDataviews = getLayerDataviews(layer, dataviews);
|
||||
layer.options.columns = layerDataviews.reduce(function(columns, dataview) {
|
||||
return columns.concat(getDataviewColumns(dataview));
|
||||
}, []);
|
||||
layer.options.columns = getDataviewsColumns(getLayerDataviews(layer, dataviews));
|
||||
} else {
|
||||
missingNodesErrors.push(
|
||||
new Error('Missing analysis node.id="' + layerSourceId +'" for layer='+layerIndex)
|
||||
@@ -208,11 +205,22 @@ function getLayerDataviews(layer, dataviews) {
|
||||
return layerDataviews;
|
||||
}
|
||||
|
||||
function getDataviewsColumns(dataviews) {
|
||||
return Object.keys(dataviews.reduce(function(columnsDict, dataview) {
|
||||
getDataviewColumns(dataview).forEach(function(columnName) {
|
||||
if (!!columnName) {
|
||||
columnsDict[columnName] = true;
|
||||
}
|
||||
});
|
||||
return columnsDict;
|
||||
}, {}));
|
||||
}
|
||||
|
||||
function getDataviewColumns(dataview) {
|
||||
var columns = [];
|
||||
var options = dataview.options;
|
||||
['column', 'aggregationColumn'].forEach(function(opt) {
|
||||
if (options.hasOwnProperty(opt)) {
|
||||
if (options.hasOwnProperty(opt) && !!options[opt]) {
|
||||
columns.push(options[opt]);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -15,6 +15,15 @@ DataviewsWidgetsMapConfigAdapter.prototype.getMapConfig = function(user, request
|
||||
|
||||
requestMapConfig.layers.forEach(function(layer, index) {
|
||||
var layerSourceId = getLayerSourceId(layer);
|
||||
|
||||
if (!layer.options.widgets) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!layerSourceId && !layer.options.sql) {
|
||||
return;
|
||||
}
|
||||
|
||||
var dataviewSourceId = layerSourceId || 'cdb-layer-source-' + index;
|
||||
// Append a new analysis if layer has no source id but sql.
|
||||
if (!layerSourceId) {
|
||||
@@ -29,7 +38,7 @@ DataviewsWidgetsMapConfigAdapter.prototype.getMapConfig = function(user, request
|
||||
);
|
||||
}
|
||||
var source = { id: dataviewSourceId };
|
||||
var layerWidgets = layer.options.widgets;
|
||||
var layerWidgets = layer.options.widgets || {};
|
||||
Object.keys(layerWidgets).forEach(function(widgetId) {
|
||||
var dataview = layerWidgets[widgetId];
|
||||
requestMapConfig.dataviews[widgetId] = {
|
||||
@@ -67,7 +76,6 @@ DataviewsWidgetsMapConfigAdapter.prototype.getMapConfig = function(user, request
|
||||
};
|
||||
|
||||
function shouldAdapt(requestMapConfig) {
|
||||
// return false;
|
||||
return Array.isArray(requestMapConfig.layers) && requestMapConfig.layers.some(function hasWidgets(layer) {
|
||||
return layer.options && layer.options.widgets && Object.keys(layer.options.widgets).length > 0;
|
||||
});
|
||||
|
||||
@@ -3,7 +3,6 @@ var bodyParser = require('body-parser');
|
||||
var RedisPool = require('redis-mpool');
|
||||
var cartodbRedis = require('cartodb-redis');
|
||||
var _ = require('underscore');
|
||||
var debug = require('debug')('windshaft:cartodb');
|
||||
|
||||
var controller = require('./controllers');
|
||||
|
||||
@@ -183,6 +182,8 @@ module.exports = function(serverOptions) {
|
||||
var TablesExtentApi = require('./api/tables_extent_api');
|
||||
var tablesExtentApi = new TablesExtentApi(pgQueryRunner);
|
||||
|
||||
var versions = getAndValidateVersions(serverOptions);
|
||||
|
||||
/*******************************************************************************************************************
|
||||
* Routing
|
||||
******************************************************************************************************************/
|
||||
@@ -225,7 +226,7 @@ module.exports = function(serverOptions) {
|
||||
|
||||
new controller.NamedMapsAdmin(authApi, pgConnection, templateMaps).register(app);
|
||||
|
||||
new controller.ServerInfo().register(app);
|
||||
new controller.ServerInfo(versions).register(app);
|
||||
|
||||
/*******************************************************************************************************************
|
||||
* END Routing
|
||||
@@ -238,12 +239,45 @@ function validateOptions(opts) {
|
||||
if (!_.isString(opts.base_url) || !_.isString(opts.base_url_mapconfig) || !_.isString(opts.base_url_templated)) {
|
||||
throw new Error("Must initialise server with: 'base_url'/'base_url_mapconfig'/'base_url_templated' URLs");
|
||||
}
|
||||
}
|
||||
|
||||
// Be nice and warn if configured mapnik version is != instaled mapnik version
|
||||
if (mapnik.versions.mapnik !== opts.grainstore.mapnik_version) {
|
||||
debug('WARNING: detected mapnik version (' + mapnik.versions.mapnik + ')' +
|
||||
' != configured mapnik version (' + opts.grainstore.mapnik_version + ')');
|
||||
function getAndValidateVersions(options) {
|
||||
// jshint undef:false
|
||||
var warn = console.warn.bind(console);
|
||||
// jshint undef:true
|
||||
|
||||
var packageDefinition = require('../../package.json');
|
||||
|
||||
var declaredDependencies = packageDefinition.dependencies || {};
|
||||
var installedDependenciesVersions = {
|
||||
camshaft: require('camshaft').version,
|
||||
grainstore: windshaft.grainstore.version(),
|
||||
mapnik: windshaft.mapnik.versions.mapnik,
|
||||
node_mapnik: windshaft.mapnik.version,
|
||||
'turbo-carto': require('turbo-carto').version,
|
||||
windshaft: windshaft.version,
|
||||
windshaft_cartodb: packageDefinition.version
|
||||
};
|
||||
|
||||
var dependenciesToValidate = ['camshaft', 'turbo-carto', 'windshaft'];
|
||||
dependenciesToValidate.forEach(function(depName) {
|
||||
var declaredDependencyVersion = declaredDependencies[depName];
|
||||
var installedDependencyVersion = installedDependenciesVersions[depName];
|
||||
if (declaredDependencyVersion !== installedDependencyVersion) {
|
||||
warn(
|
||||
'Dependency="%s" installed version="%s" does not match declared version="%s". Check your installation.',
|
||||
depName, installedDependencyVersion, declaredDependencyVersion
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Be nice and warn if configured mapnik version is != installed mapnik version
|
||||
if (mapnik.versions.mapnik !== options.grainstore.mapnik_version) {
|
||||
warn('WARNING: detected mapnik version (' + mapnik.versions.mapnik + ')' +
|
||||
' != configured mapnik version (' + options.grainstore.mapnik_version + ')');
|
||||
}
|
||||
|
||||
return installedDependenciesVersions;
|
||||
}
|
||||
|
||||
function bootstrapFonts(opts) {
|
||||
|
||||
118
npm-shrinkwrap.json
generated
118
npm-shrinkwrap.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "windshaft-cartodb",
|
||||
"version": "2.45.0",
|
||||
"version": "2.46.0",
|
||||
"dependencies": {
|
||||
"body-parser": {
|
||||
"version": "1.14.2",
|
||||
@@ -105,9 +105,9 @@
|
||||
}
|
||||
},
|
||||
"camshaft": {
|
||||
"version": "0.12.1",
|
||||
"from": "camshaft@0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/camshaft/-/camshaft-0.12.1.tgz",
|
||||
"version": "0.13.0",
|
||||
"from": "camshaft@0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/camshaft/-/camshaft-0.13.0.tgz",
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "1.5.2",
|
||||
@@ -146,7 +146,7 @@
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <2.1.0",
|
||||
"from": "inherits@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
},
|
||||
"isarray": {
|
||||
@@ -648,7 +648,7 @@
|
||||
"dependencies": {
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"from": "unpipe@1.0.0",
|
||||
"from": "unpipe@>=1.0.0 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
@@ -804,7 +804,7 @@
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.13",
|
||||
"from": "type-is@>=1.6.6 <1.7.0",
|
||||
"from": "type-is@>=1.6.10 <1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.13.tgz",
|
||||
"dependencies": {
|
||||
"media-typer": {
|
||||
@@ -1029,7 +1029,7 @@
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.11",
|
||||
"from": "mime-types@>=2.1.11 <2.2.0",
|
||||
"from": "mime-types@>=2.1.2 <2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz",
|
||||
"dependencies": {
|
||||
"mime-db": {
|
||||
@@ -1257,9 +1257,9 @@
|
||||
"resolved": "https://registry.npmjs.org/step-profiler/-/step-profiler-0.3.0.tgz"
|
||||
},
|
||||
"turbo-carto": {
|
||||
"version": "0.10.1",
|
||||
"from": "turbo-carto@0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/turbo-carto/-/turbo-carto-0.10.1.tgz",
|
||||
"version": "0.11.0",
|
||||
"from": "turbo-carto@0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/turbo-carto/-/turbo-carto-0.11.0.tgz",
|
||||
"dependencies": {
|
||||
"colorbrewer": {
|
||||
"version": "1.0.0",
|
||||
@@ -1318,9 +1318,9 @@
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz"
|
||||
},
|
||||
"windshaft": {
|
||||
"version": "2.0.1",
|
||||
"from": "windshaft@2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/windshaft/-/windshaft-2.0.1.tgz",
|
||||
"version": "2.3.0",
|
||||
"from": "windshaft@2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/windshaft/-/windshaft-2.3.0.tgz",
|
||||
"dependencies": {
|
||||
"abaculus": {
|
||||
"version": "1.1.0-cdb5",
|
||||
@@ -1369,9 +1369,9 @@
|
||||
}
|
||||
},
|
||||
"grainstore": {
|
||||
"version": "1.1.1",
|
||||
"from": "grainstore@1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/grainstore/-/grainstore-1.1.1.tgz",
|
||||
"version": "1.2.0",
|
||||
"from": "grainstore@1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/grainstore/-/grainstore-1.2.0.tgz",
|
||||
"dependencies": {
|
||||
"carto": {
|
||||
"version": "0.9.5-cdb2",
|
||||
@@ -3151,6 +3151,11 @@
|
||||
"from": "glob@>=7.0.0 <8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.0.3.tgz"
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.1.4",
|
||||
"from": "graceful-fs@>=4.1.2 <5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.4.tgz"
|
||||
},
|
||||
"graceful-readlink": {
|
||||
"version": "1.0.1",
|
||||
"from": "graceful-readlink@>=1.0.0",
|
||||
@@ -3161,11 +3166,6 @@
|
||||
"from": "har-validator@>=2.0.6 <2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz"
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.1.4",
|
||||
"from": "graceful-fs@>=4.1.2 <5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.4.tgz"
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"from": "has-ansi@>=2.0.0 <3.0.0",
|
||||
@@ -3186,16 +3186,16 @@
|
||||
"from": "hoek@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz"
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.4",
|
||||
"from": "inflight@>=1.0.4 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz"
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.1.1",
|
||||
"from": "http-signature@>=1.1.0 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz"
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.4",
|
||||
"from": "inflight@>=1.0.4 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <2.1.0",
|
||||
@@ -3236,16 +3236,16 @@
|
||||
"from": "jodid25519@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz"
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.0",
|
||||
"from": "jsbn@>=0.1.0 <0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz"
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.2",
|
||||
"from": "json-schema@0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz"
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.0",
|
||||
"from": "jsbn@>=0.1.0 <0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz"
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"from": "json-stringify-safe@>=5.0.1 <5.1.0",
|
||||
@@ -3416,31 +3416,31 @@
|
||||
"from": "strip-json-comments@>=1.0.4 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz"
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"from": "supports-color@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
|
||||
},
|
||||
"tar": {
|
||||
"version": "2.2.1",
|
||||
"from": "tar@>=2.2.0 <2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz"
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"from": "supports-color@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.2.2",
|
||||
"from": "tough-cookie@>=2.2.0 <2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz"
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.4.3",
|
||||
"from": "tunnel-agent@>=0.4.1 <0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz"
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.13.3",
|
||||
"from": "tweetnacl@>=0.13.0 <0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz"
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.4.3",
|
||||
"from": "tunnel-agent@>=0.4.1 <0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz"
|
||||
},
|
||||
"uid-number": {
|
||||
"version": "0.0.6",
|
||||
"from": "uid-number@>=0.0.6 <0.1.0",
|
||||
@@ -3456,16 +3456,16 @@
|
||||
"from": "verror@1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz"
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
"from": "xtend@>=4.0.0 <5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz"
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.1",
|
||||
"from": "wrappy@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
"from": "xtend@>=4.0.0 <5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz"
|
||||
},
|
||||
"bl": {
|
||||
"version": "1.1.2",
|
||||
"from": "bl@>=1.1.2 <1.2.0",
|
||||
@@ -3478,18 +3478,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.6",
|
||||
"from": "getpass@>=0.1.1 <0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz",
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"from": "assert-plus@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.13.1",
|
||||
"from": "dashdash@>=1.12.0 <2.0.0",
|
||||
@@ -3514,6 +3502,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.6",
|
||||
"from": "getpass@>=0.1.1 <0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz",
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"from": "assert-plus@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.8.3",
|
||||
"from": "sshpk@>=1.7.0 <2.0.0",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "windshaft-cartodb",
|
||||
"version": "2.45.0",
|
||||
"version": "2.46.0",
|
||||
"description": "A map tile server for CartoDB",
|
||||
"keywords": [
|
||||
"cartodb"
|
||||
@@ -20,7 +20,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"body-parser": "~1.14.0",
|
||||
"camshaft": "0.12.1",
|
||||
"camshaft": "0.13.0",
|
||||
"cartodb-psql": "~0.6.1",
|
||||
"cartodb-query-tables": "~0.1.0",
|
||||
"cartodb-redis": "~0.13.0",
|
||||
@@ -37,9 +37,9 @@
|
||||
"request": "~2.62.0",
|
||||
"step": "~0.0.6",
|
||||
"step-profiler": "~0.3.0",
|
||||
"turbo-carto": "0.10.1",
|
||||
"turbo-carto": "0.11.0",
|
||||
"underscore": "~1.6.0",
|
||||
"windshaft": "2.0.1"
|
||||
"windshaft": "2.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"istanbul": "~0.4.3",
|
||||
|
||||
80
test/acceptance/dataviews/histogram.js
Normal file
80
test/acceptance/dataviews/histogram.js
Normal file
@@ -0,0 +1,80 @@
|
||||
require('../../support/test_helper');
|
||||
|
||||
var assert = require('../../support/assert');
|
||||
var TestClient = require('../../support/test-client');
|
||||
|
||||
describe('histogram-dataview', function() {
|
||||
|
||||
afterEach(function(done) {
|
||||
if (this.testClient) {
|
||||
this.testClient.drain(done);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
function createMapConfig(layers, dataviews, analysis) {
|
||||
return {
|
||||
version: '1.5.0',
|
||||
layers: layers,
|
||||
dataviews: dataviews || {},
|
||||
analyses: analysis || []
|
||||
};
|
||||
}
|
||||
|
||||
var mapConfig = createMapConfig(
|
||||
[
|
||||
{
|
||||
"type": "cartodb",
|
||||
"options": {
|
||||
"source": {
|
||||
"id": "2570e105-7b37-40d2-bdf4-1af889598745"
|
||||
},
|
||||
"cartocss": "#points { marker-width: 10; marker-fill: red; }",
|
||||
"cartocss_version": "2.3.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
{
|
||||
pop_max_histogram: {
|
||||
source: {
|
||||
id: '2570e105-7b37-40d2-bdf4-1af889598745'
|
||||
},
|
||||
type: 'histogram',
|
||||
options: {
|
||||
column: 'x'
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"id": "2570e105-7b37-40d2-bdf4-1af889598745",
|
||||
"type": "source",
|
||||
"params": {
|
||||
"query": "select null::geometry the_geom_webmercator, x from generate_series(0,1000) x"
|
||||
}
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
it('should get bin_width right when max > min in filter', function(done) {
|
||||
var params = {
|
||||
bins: 10,
|
||||
start: 1e3,
|
||||
end: 0
|
||||
};
|
||||
|
||||
this.testClient = new TestClient(mapConfig, 1234);
|
||||
this.testClient.getDataview('pop_max_histogram', params, function(err, dataview) {
|
||||
assert.ok(!err, err);
|
||||
|
||||
assert.equal(dataview.type, 'histogram');
|
||||
assert.ok(dataview.bin_width > 0, 'Unexpected bin width: ' + dataview.bin_width);
|
||||
dataview.bins.forEach(function(bin) {
|
||||
assert.ok(bin.min <= bin.max, 'bin min < bin max: ' + JSON.stringify(bin));
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -168,4 +168,176 @@ describe('use only needed columns', function() {
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
it('should work with mapnik substitution tokens', function(done) {
|
||||
var cartocss = [
|
||||
"#layer {",
|
||||
" line-width: 2;",
|
||||
" line-color: #3B3B58;",
|
||||
" line-opacity: 1;",
|
||||
" polygon-opacity: 0.7;",
|
||||
" polygon-fill: ramp([points_count], (#E5F5F9,#99D8C9,#2CA25F))",
|
||||
"}"
|
||||
].join('\n');
|
||||
|
||||
var sql = [
|
||||
'WITH hgrid AS (',
|
||||
' SELECT CDB_HexagonGrid(',
|
||||
' ST_Expand(!bbox!, greatest(!pixel_width!,!pixel_height!) * 100),',
|
||||
' greatest(!pixel_width!,!pixel_height!) * 100',
|
||||
' ) as cell',
|
||||
')',
|
||||
'SELECT',
|
||||
' hgrid.cell as the_geom_webmercator,',
|
||||
' count(1) as points_count,',
|
||||
' count(1)/power(100 * CDB_XYZ_Resolution(CDB_ZoomFromScale(!scale_denominator!)), 2) as points_density,',
|
||||
' 1 as cartodb_id',
|
||||
'FROM hgrid, (SELECT * FROM populated_places_simple_reduced) i',
|
||||
'where ST_Intersects(i.the_geom_webmercator, hgrid.cell)',
|
||||
'GROUP BY hgrid.cell'
|
||||
].join('\n');
|
||||
|
||||
var mapConfig = {
|
||||
"version": "1.4.0",
|
||||
"layers": [
|
||||
{
|
||||
"type": 'mapnik',
|
||||
"options": {
|
||||
"cartocss_version": '2.3.0',
|
||||
"sql": sql,
|
||||
"cartocss": cartocss
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
this.testClient = new TestClient(mapConfig);
|
||||
this.testClient.getTile(0, 0, 0, { format: 'geojson', layer: 0 }, function(err, res, geojson) {
|
||||
assert.ok(!err, err);
|
||||
|
||||
assert.ok(geojson);
|
||||
assert.equal(geojson.features.length, 5);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should skip empty and null columns for geojson tiles', function(done) {
|
||||
|
||||
var mapConfig = {
|
||||
"analyses": [
|
||||
{
|
||||
"id": "a0",
|
||||
"params": {
|
||||
"query": "SELECT * FROM test_table"
|
||||
},
|
||||
"type": "source"
|
||||
}
|
||||
],
|
||||
"dataviews": {
|
||||
"4e7b0e07-6d21-4b83-9adb-6d7e17eea6ca": {
|
||||
"options": {
|
||||
"aggregationColumn": null,
|
||||
"column": "cartodb_id",
|
||||
"operation": "avg"
|
||||
},
|
||||
"source": {
|
||||
"id": "a0"
|
||||
},
|
||||
"type": "formula"
|
||||
},
|
||||
"74f590f8-625c-4e95-922f-34ad3e9919c0": {
|
||||
"options": {
|
||||
"aggregation": "sum",
|
||||
"aggregationColumn": "cartodb_id",
|
||||
"column": "name"
|
||||
},
|
||||
"source": {
|
||||
"id": "a0"
|
||||
},
|
||||
"type": "aggregation"
|
||||
},
|
||||
"98a75757-3006-400a-b028-fb613a6c0b69": {
|
||||
"options": {
|
||||
"aggregationColumn": null,
|
||||
"column": "cartodb_id",
|
||||
"operation": "sum"
|
||||
},
|
||||
"source": {
|
||||
"id": "a0"
|
||||
},
|
||||
"type": "formula"
|
||||
},
|
||||
"ebbc97b2-87d2-4895-9e1f-2f012df3679d": {
|
||||
"options": {
|
||||
"aggregationColumn": null,
|
||||
"bins": "12",
|
||||
"column": "cartodb_id"
|
||||
},
|
||||
"source": {
|
||||
"id": "a0"
|
||||
},
|
||||
"type": "histogram"
|
||||
},
|
||||
"ebc0653f-3581-469c-8b31-c969e440a865": {
|
||||
"options": {
|
||||
"aggregationColumn": null,
|
||||
"column": "cartodb_id",
|
||||
"operation": "avg"
|
||||
},
|
||||
"source": {
|
||||
"id": "a0"
|
||||
},
|
||||
"type": "formula"
|
||||
}
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"options": {
|
||||
"subdomains": "abcd",
|
||||
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png"
|
||||
},
|
||||
"type": "http"
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"attributes": {
|
||||
"columns": [
|
||||
"name",
|
||||
"address"
|
||||
],
|
||||
"id": "cartodb_id"
|
||||
},
|
||||
"cartocss": "#layer { marker-width: 10; marker-fill: red; }",
|
||||
"cartocss_version": "2.3.0",
|
||||
"interactivity": "cartodb_id",
|
||||
"layer_name": "wadus",
|
||||
"source": {
|
||||
"id": "a0"
|
||||
}
|
||||
},
|
||||
"type": "cartodb"
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"subdomains": "abcd",
|
||||
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png"
|
||||
},
|
||||
"type": "http"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
this.testClient = new TestClient(mapConfig);
|
||||
this.testClient.getTile(0, 0, 0, { format: 'geojson', layer: 0 }, function(err, res, geojson) {
|
||||
assert.ok(!err, err);
|
||||
|
||||
assert.ok(geojson);
|
||||
assert.equal(geojson.features.length, 5);
|
||||
|
||||
assert.deepEqual(Object.keys(geojson.features[0].properties), ['cartodb_id', 'name']);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
223
test/acceptance/widgets/regressions.js
Normal file
223
test/acceptance/widgets/regressions.js
Normal file
@@ -0,0 +1,223 @@
|
||||
require('../../support/test_helper');
|
||||
|
||||
var assert = require('../../support/assert');
|
||||
var TestClient = require('../../support/test-client');
|
||||
|
||||
describe('widgets-regressions', function() {
|
||||
|
||||
describe('aggregations', function() {
|
||||
|
||||
afterEach(function(done) {
|
||||
if (this.testClient) {
|
||||
this.testClient.drain(done);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('should work when there is a mix of layers with and without widgets', function(done) {
|
||||
var layersWithNoWidgetsMapConfig = {
|
||||
version: '1.5.0',
|
||||
layers: [
|
||||
{
|
||||
type: 'mapnik',
|
||||
options: {
|
||||
sql: 'select * from populated_places_simple_reduced',
|
||||
cartocss: '#layer0 { marker-fill: red; marker-width: 10; }',
|
||||
cartocss_version: '2.0.1',
|
||||
widgets: {
|
||||
adm0name: {
|
||||
type: 'aggregation',
|
||||
options: {
|
||||
column: 'adm0name',
|
||||
aggregation: 'sum',
|
||||
aggregationColumn: 'pop_max'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'mapnik',
|
||||
options: {
|
||||
sql: 'select * from populated_places_simple_reduced limit 100',
|
||||
cartocss: '#layer0 { marker-fill: red; marker-width: 10; }',
|
||||
cartocss_version: '2.0.1'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
this.testClient = new TestClient(layersWithNoWidgetsMapConfig);
|
||||
this.testClient.getWidget('adm0name', { own_filter: 0 }, function (err, res, aggregation) {
|
||||
assert.ok(!err, err);
|
||||
assert.ok(aggregation);
|
||||
assert.equal(aggregation.type, 'aggregation');
|
||||
|
||||
assert.equal(aggregation.categories.length, 6);
|
||||
|
||||
assert.deepEqual(
|
||||
aggregation.categories[0],
|
||||
{ category: 'China', value: 374537585, agg: false }
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
aggregation.categories[aggregation.categories.length - 1],
|
||||
{ category: 'Other', value: 1412626289, agg: true }
|
||||
);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should work when there is a mix of layers with and without widgets, source and sql', function(done) {
|
||||
var mixOfLayersMapConfig = {
|
||||
version: '1.5.0',
|
||||
layers: [
|
||||
{
|
||||
type: 'mapnik',
|
||||
options: {
|
||||
sql: 'select * from populated_places_simple_reduced',
|
||||
cartocss: '#layer0 { marker-fill: red; marker-width: 10; }',
|
||||
cartocss_version: '2.0.1',
|
||||
widgets: {
|
||||
adm0name_categories: {
|
||||
type: 'aggregation',
|
||||
options: {
|
||||
column: 'adm0name',
|
||||
aggregation: 'sum',
|
||||
aggregationColumn: 'pop_max'
|
||||
}
|
||||
},
|
||||
adm1name_categories: {
|
||||
type: 'aggregation',
|
||||
options: {
|
||||
column: 'adm1name',
|
||||
aggregation: 'sum',
|
||||
aggregationColumn: 'pop_max'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'mapnik',
|
||||
options: {
|
||||
source: {id: 'head-limited'},
|
||||
cartocss: '#layer0 { marker-fill: red; marker-width: 10; }',
|
||||
cartocss_version: '2.0.1',
|
||||
widgets: {
|
||||
pop_max_histogram: {
|
||||
type: 'histogram',
|
||||
options: {
|
||||
column: 'pop_max'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "http",
|
||||
"options": {
|
||||
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
|
||||
"subdomains": "abcd"
|
||||
}
|
||||
}
|
||||
],
|
||||
analyses: [
|
||||
{
|
||||
id: 'head-limited',
|
||||
type: 'source',
|
||||
params: {
|
||||
query: 'select * from populated_places_simple_reduced limit 100'
|
||||
}
|
||||
}
|
||||
],
|
||||
dataviews: {
|
||||
wadus: {
|
||||
type: 'histogram',
|
||||
source: {
|
||||
id: 'head-limited'
|
||||
},
|
||||
options: {
|
||||
column: 'population'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.testClient = new TestClient(mixOfLayersMapConfig);
|
||||
this.testClient.getLayergroup(function(err, layergroup) {
|
||||
assert.ok(!err, err);
|
||||
assert.ok(layergroup.metadata);
|
||||
var metadata = layergroup.metadata;
|
||||
assert.equal(metadata.layers.length, 3);
|
||||
assert.equal(metadata.analyses.length, 2);
|
||||
assert.equal(Object.keys(metadata.dataviews).length, 4);
|
||||
assert.deepEqual(
|
||||
Object.keys(metadata.dataviews),
|
||||
['wadus', 'adm0name_categories', 'adm1name_categories', 'pop_max_histogram']
|
||||
);
|
||||
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with layers not containing sql', function(done) {
|
||||
var nonSqlLayersMapConfig = {
|
||||
version: '1.5.0',
|
||||
layers: [
|
||||
{
|
||||
type: 'mapnik',
|
||||
options: {
|
||||
sql: 'select * from populated_places_simple_reduced',
|
||||
cartocss: '#layer0 { marker-fill: red; marker-width: 10; }',
|
||||
cartocss_version: '2.0.1',
|
||||
widgets: {
|
||||
adm0name: {
|
||||
type: 'aggregation',
|
||||
options: {
|
||||
column: 'adm0name',
|
||||
aggregation: 'sum',
|
||||
aggregationColumn: 'pop_max'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "http",
|
||||
"options": {
|
||||
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
|
||||
"subdomains": "abcd"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
this.testClient = new TestClient(nonSqlLayersMapConfig);
|
||||
this.testClient.getWidget('adm0name', { own_filter: 0 }, function (err, res, aggregation) {
|
||||
assert.ok(!err, err);
|
||||
assert.ok(aggregation);
|
||||
assert.equal(aggregation.type, 'aggregation');
|
||||
|
||||
assert.equal(aggregation.categories.length, 6);
|
||||
|
||||
assert.deepEqual(
|
||||
aggregation.categories[0],
|
||||
{ category: 'China', value: 374537585, agg: false }
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
aggregation.categories[aggregation.categories.length - 1],
|
||||
{ category: 'Other', value: 1412626289, agg: true }
|
||||
);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -310,9 +310,13 @@ TestClient.prototype.getDataview = function(dataviewName, params, callback) {
|
||||
var urlParams = {
|
||||
own_filter: params.hasOwnProperty('own_filter') ? params.own_filter : 1
|
||||
};
|
||||
if (params && params.bbox) {
|
||||
urlParams.bbox = params.bbox;
|
||||
}
|
||||
|
||||
['bbox', 'bins', 'start', 'end'].forEach(function(extraParam) {
|
||||
if (params.hasOwnProperty(extraParam)) {
|
||||
urlParams[extraParam] = params[extraParam];
|
||||
}
|
||||
});
|
||||
|
||||
if (self.apiKey) {
|
||||
urlParams.api_key = self.apiKey;
|
||||
}
|
||||
@@ -341,10 +345,10 @@ TestClient.prototype.getDataview = function(dataviewName, params, callback) {
|
||||
}
|
||||
);
|
||||
},
|
||||
function finish(err, res) {
|
||||
function finish(err, dataview) {
|
||||
self.keysToDelete['map_cfg|' + LayergroupToken.parse(layergroupId).token] = 0;
|
||||
self.keysToDelete['user:localhost:mapviews:global'] = 5;
|
||||
return callback(err, res);
|
||||
return callback(err, dataview);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user