Analyses are now an array and layers consume from their nodes

Layers now can define a `source: {id: 'a0'}` option to point to an
analysis node that will be used as the query for that layer.
This commit is contained in:
Raul Ochoa
2016-03-09 17:39:20 +01:00
parent d5fbcfcecb
commit 7fa8d1e0c9
@@ -1,5 +1,4 @@
var queue = require('queue-async');
var _ = require('underscore');
var camshaft = require('camshaft');
var dot = require('dot');
@@ -21,39 +20,6 @@ function skipColumns(columnNames) {
.filter(function(columnName) { return !SKIP_COLUMNS[columnName]; });
}
var multitypeStyleTemplate = dot.template([
"#points['mapnik::geometry_type'=1] {",
" marker-fill-opacity: {{=it._opacity}};",
" marker-line-color: #FFF;",
" marker-line-width: 0.5;",
" marker-line-opacity: {{=it._opacity}};",
" marker-placement: point;",
" marker-type: ellipse;",
" marker-width: 4;",
" marker-fill: {{=it._color}};",
" marker-allow-overlap: true;",
"}",
"#lines['mapnik::geometry_type'=2] {",
" line-color: {{=it._color}};",
" line-width: 2;",
" line-opacity: {{=it._opacity}};",
"}",
"#polygons['mapnik::geometry_type'=3] {",
" polygon-fill: {{=it._color}};",
" polygon-opacity: {{=it._opacity}};",
" line-color: #FFF;",
" line-width: 0.5;",
" line-opacity: {{=it._opacity}};",
"}"
].join('\n'));
function multiTypeStyle(color, opacity) {
return multitypeStyleTemplate({
_opacity: opacity || 1.0,
_color: color || 'red'
});
}
var layerQueryTemplate = dot.template([
'SELECT ST_Transform(the_geom, 3857) the_geom_webmercator, {{=it._columns}}',
'FROM ({{=it._query}}) _cdb_analysis_query'
@@ -63,100 +29,54 @@ function layerQuery(query, columnNames) {
return layerQueryTemplate({ _query: query, _columns: skipColumns(columnNames).join(', ') });
}
function getLayer(query, columnNames, color, opacity) {
return {
type: 'mapnik',
options: {
sql: layerQuery(query, columnNames),
cartocss: multiTypeStyle(color, opacity),
cartocss_version: '2.3.0'
}
};
}
function getLayerWithStyle(query, columnNames, cartocss) {
return {
type: 'mapnik',
options: {
sql: layerQuery(query, columnNames),
cartocss: cartocss,
cartocss_version: '2.3.0'
}
};
function shouldAdaptLayers(requestMapConfig) {
return Array.isArray(requestMapConfig.layers) &&
Array.isArray(requestMapConfig.analyses) && requestMapConfig.analyses.length > 0;
}
MapConfigAnalysisLayersAdapter.prototype.getLayers = function(analysisConfiguration, requestMapConfig, callback) {
if (!Array.isArray(requestMapConfig.layers)) {
if (!shouldAdaptLayers(requestMapConfig)) {
return callback(null, requestMapConfig);
}
function adaptLayer(layer, done) {
if (isAnalysisTypeLayer(layer)) {
var analysisDefinition = JSON.parse(layer.options.def);
camshaft.create(analysisConfiguration, analysisDefinition, function(err, analysis) {
if (err) {
return done(err);
}
var layers = [];
analysis.getSortedNodes().reverse().forEach(function(node, i) {
if (node.params && node.params.debug) {
var layer = getLayer(node.getQuery(), node.getColumns(), '#333', 0.1 * i);
if (!!node.params && !!node.params.cartocss) {
layer = getLayerWithStyle(node.getQuery(), node.getColumns(), node.params.cartocss);
}
layers.push(layer);
}
});
layers.push(getLayerWithStyle(
analysis.getQuery(),
analysis.getRoot().getColumns(),
layer.options.cartocss
));
return done(null, { layers: layers });
});
} else {
return done(null, { layers: [layer] });
}
function createAnalysis(analysisDefinition, done) {
camshaft.create(analysisConfiguration, analysisDefinition, done);
}
function layersAdaptQueueFinish(err, layersResults) {
var analysesQueue = queue(requestMapConfig.analyses.length);
requestMapConfig.analyses.forEach(function(analysis) {
analysesQueue.defer(createAnalysis, analysis);
});
analysesQueue.awaitAll(function(err, analysesResults) {
if (err) {
return callback(err);
}
if (!layersResults || layersResults.length === 0) {
return callback(new Error('Missing layers array from layergroup config'));
}
var sourceId2Node = analysesResults.reduce(function(sourceId2Query, analysis) {
var rootNode = analysis.getRoot();
if (rootNode.params && rootNode.params.id) {
sourceId2Query[rootNode.params.id] = rootNode;
}
var layers = [];
layersResults.forEach(function(layersResult) {
layers = layers.concat(layersResult.layers);
analysis.getSortedNodes().forEach(function(node) {
if (node.params && node.params.id) {
sourceId2Query[node.params.id] = node;
}
});
return sourceId2Query;
}, {});
requestMapConfig.layers = requestMapConfig.layers.map(function(layer) {
if (layer.options.source && layer.options.source.id) {
var layerNode = sourceId2Node[layer.options.source.id];
layer.options.sql = layerQuery(layerNode.getQuery(), layerNode.getColumns());
}
return layer;
});
requestMapConfig.layers = layers;
return callback(null, requestMapConfig);
}
var adaptLayersQueue = queue(requestMapConfig.layers.length);
if (_.some(requestMapConfig.layers, isAnalysisTypeLayer)) {
requestMapConfig.layers.forEach(function(layer) {
adaptLayersQueue.defer(adaptLayer, layer);
});
adaptLayersQueue.awaitAll(layersAdaptQueueFinish);
} else {
return callback(null, requestMapConfig);
}
});
};
function isAnalysisTypeLayer(layer) {
return layer.type === 'analysis';
}