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:
@@ -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';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user