From 7114311b75f2cdc2e83b480f671352bdeb6e8470 Mon Sep 17 00:00:00 2001 From: Raul Ochoa Date: Tue, 21 Jun 2016 15:05:44 +0200 Subject: [PATCH] Split turbo-carto adapter substitutions tokens query --- NEWS.md | 3 + .../mapconfig/adapter/turbo-carto-adapter.js | 106 +++++++++++------- 2 files changed, 66 insertions(+), 43 deletions(-) diff --git a/NEWS.md b/NEWS.md index 1e18e2fc..c9ce3cbd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,9 @@ Released 2016-mm-dd +Enhancements: + - Split turbo-carto adapter substitutions tokens query. + ## 2.50.0 diff --git a/lib/cartodb/models/mapconfig/adapter/turbo-carto-adapter.js b/lib/cartodb/models/mapconfig/adapter/turbo-carto-adapter.js index 43a3ffaa..8efaf5a6 100644 --- a/lib/cartodb/models/mapconfig/adapter/turbo-carto-adapter.js +++ b/lib/cartodb/models/mapconfig/adapter/turbo-carto-adapter.js @@ -40,56 +40,38 @@ TurboCartoAdapter.prototype.getMapConfig = function (user, requestMapConfig, par }); }; -var bboxTemplate = dot.template('(select ST_SetSRID(st_extent(the_geom_webmercator), 3857) from ({{=it._sql}}) __c)'); -var zoomTemplate = dot.template([ - 'GREATEST(', - 'ceil(log(40075017000 / 256 / GREATEST(', - ' st_xmax({{=it._bbox}}) - st_xmin({{=it._bbox}}),', - ' st_ymax({{=it._bbox}}) - st_ymin({{=it._bbox}})', - '))/log(2)),', - '0', - ')' +var tokensQueryTpl = dot.template([ + 'WITH input_query AS (', + ' {{=it._sql}}', + '),', + 'bbox_query AS (', + ' SELECT ST_SetSRID(ST_Extent(the_geom_webmercator), 3857) as bbox from input_query', + '),', + 'zoom_query as (', + ' SELECT GREATEST(', + ' ceil(log(40075017000 / 256 / GREATEST(ST_XMax(bbox) - ST_XMin(bbox), ST_YMax(bbox) - ST_YMin(bbox)))/log(2)),', + ' 0) as zoom', + ' FROM bbox_query', + '),', + 'pixel_size_query as (', + ' SELECT 40075017 * cos(radians(ST_Y(ST_Transform(ST_Centroid(bbox), 4326)))) / 2 ^ ((zoom) + 8) as pixel_size', + ' FROM bbox_query, zoom_query', + '),', + 'scale_denominator_query as (', + ' SELECT (pixel_size / 0.00028)::numeric as scale_denominator', + ' FROM pixel_size_query', + ')', + 'select ST_AsText(bbox) bbox, pixel_size, scale_denominator, zoom', + 'from bbox_query, pixel_size_query, scale_denominator_query, zoom_query' ].join('\n')); -// http://wiki.openstreetmap.org/wiki/Zoom_levels -var pixelSizeTemplate = dot.template( - '40075017 * cos(radians(ST_Y(ST_Transform(ST_Centroid({{=it._bbox}}), 4326)))) / (2 ^ ({{=it._zoom}} + 8))' -); -var scaleDenominatorTemplate = dot.template('({{=it._pixelSize}} / 0.00028)::numeric'); - TurboCartoAdapter.prototype._parseCartoCss = function (username, params, layer, index, callback) { if (!shouldParseLayerCartocss(layer)) { return callback(null, layer); } - var tokens = { - bbox: 'ST_MakeEnvelope(-20037508.34,-20037508.34,20037508.34,20037508.34,3857)', - scale_denominator: '500000001', - pixel_width: '156412', - pixel_height: '156412' - }; - - var layerSql = layer.options.sql; - var layerRawSql = layer.options.sql_raw; - if (SubstitutionTokens.hasTokens(layerSql) && layerRawSql) { - var bbox = bboxTemplate({ _sql: layerRawSql }); - var zoom = zoomTemplate({ _bbox: bbox }); - var pixelSize = pixelSizeTemplate({ _bbox: bbox, _zoom: zoom }); - var scaleDenominator = scaleDenominatorTemplate({ _pixelSize: pixelSize }); - - tokens = { - bbox: bbox, - scale_denominator: scaleDenominator, - pixel_width: pixelSize, - pixel_height: pixelSize - }; - } - - var sql = SubstitutionTokens.replace(layerSql, tokens); - var pg = new PSQL(dbParamsFromReqParams(params)); - - this.process(pg, layer.options.cartocss, sql, function (err, cartocss) { + function processCallback(err, cartocss) { // Only return turbo-carto errors if (err && err.name === 'TurboCartoError') { var error = new Error('turbo-carto: ' + err.message); @@ -109,7 +91,45 @@ TurboCartoAdapter.prototype._parseCartoCss = function (username, params, layer, layer.options.cartocss = cartocss; } return callback(null, layer); - }); + } + + var layerSql = layer.options.sql; + var layerRawSql = layer.options.sql_raw; + if (SubstitutionTokens.hasTokens(layerSql) && layerRawSql) { + var self = this; + var tokensQuery = tokensQueryTpl({_sql: layerRawSql}); + return pg.query(tokensQuery, function(err, resultSet) { + if (err) { + var error = new Error('turbo-carto: ' + err.message); + error.type = 'turbo-carto'; + return callback(error); + } + + resultSet = resultSet || {}; + var rows = resultSet.rows || []; + var result = rows[0] || {}; + + var tokens = { + bbox: 'ST_SetSRID(ST_GeomFromText(\'' + result.bbox + '\'), 3857)', + scale_denominator: result.scale_denominator, + pixel_width: result.pixel_size, + pixel_height: result.pixel_size + }; + + var sql = SubstitutionTokens.replace(layerSql, tokens); + self.process(pg, layer.options.cartocss, sql, processCallback); + }, true); // use read-only transaction + } + + var tokens = { + bbox: 'ST_MakeEnvelope(-20037508.34,-20037508.34,20037508.34,20037508.34,3857)', + scale_denominator: '500000001', + pixel_width: '156412', + pixel_height: '156412' + }; + + var sql = SubstitutionTokens.replace(layerSql, tokens); + this.process(pg, layer.options.cartocss, sql, processCallback); }; TurboCartoAdapter.prototype.process = function (psql, cartocss, sql, callback) {