From 7fa8d1e0c93d258d48c953b079904860586ec4f1 Mon Sep 17 00:00:00 2001 From: Raul Ochoa Date: Wed, 9 Mar 2016 17:39:20 +0100 Subject: [PATCH] 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. --- .../mapconfig_analysis_layers_adapter.js | 146 ++++-------------- 1 file changed, 33 insertions(+), 113 deletions(-) diff --git a/lib/cartodb/models/mapconfig_analysis_layers_adapter.js b/lib/cartodb/models/mapconfig_analysis_layers_adapter.js index cce72595..de3ea242 100644 --- a/lib/cartodb/models/mapconfig_analysis_layers_adapter.js +++ b/lib/cartodb/models/mapconfig_analysis_layers_adapter.js @@ -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'; -}