diff --git a/lib/cartodb/controllers/named_maps.js b/lib/cartodb/controllers/named_maps.js index 2c52d2fc..c285b25f 100644 --- a/lib/cartodb/controllers/named_maps.js +++ b/lib/cartodb/controllers/named_maps.js @@ -40,6 +40,8 @@ NamedMapsController.prototype.register = function(app) { this.prepareContext, this.getNamedMapProvider(), this.prepareLayerFilterFromPreviewLayers(), + this.getStaticImageOptions(), + this.getImage(), this.staticMap.bind(this) ); }; @@ -166,47 +168,23 @@ NamedMapsController.prototype.staticMap = function(req, res, next) { var cdbUser = res.locals.user; - var format = req.params.format === 'jpg' ? 'jpeg' : 'png'; - // We force always the tile to be generated using PNG because - // is the only format we support by now - res.locals.format = 'png'; - res.locals.layer = res.locals.layer || 'all'; + const { namedMapProvider, image, headers, stats } = res.locals; - const { namedMapProvider } = res.locals; step( - function prepareImageOptions(err) { - assert.ifError(err); - self.getStaticImageOptions(cdbUser, res.locals, namedMapProvider, this); - }, - function getImage(err, imageOpts) { - assert.ifError(err); - - var width = +req.params.width; - var height = +req.params.height; - - if (!_.isUndefined(imageOpts.zoom) && imageOpts.center) { - self.previewBackend.getImage( - namedMapProvider, format, width, height, imageOpts.zoom, imageOpts.center, this); - } else { - self.previewBackend.getImage( - namedMapProvider, format, width, height, imageOpts.bounds, this); - } - }, - function incrementMapViews(err, image, headers, stats) { - assert.ifError(err); - + function incrementMapViews() { var next = this; namedMapProvider.getMapConfig(function(mapConfigErr, mapConfig) { self.metadataBackend.incMapviewCount(cdbUser, mapConfig.obj().stat_tag, function(sErr) { - if (err) { + if (sErr) { global.logger.log("ERROR: failed to increment mapview count for user '%s': %s", cdbUser, sErr); } - next(err, image, headers, stats); + + next(null, image, headers, stats); }); }); }, function handleImage(err, image, headers, stats) { - req.profiler.done('render-' + format); + req.profiler.done('render-' + res.locals.format); req.profiler.add(stats || {}); if (err) { @@ -231,84 +209,138 @@ function numMapper(n) { return +n; } -NamedMapsController.prototype.getStaticImageOptions = function(cdbUser, params, namedMapProvider, callback) { - var self = this; +NamedMapsController.prototype.getStaticImageOptions = function () { + return function getStaticImageOptionsMiddleware(req, res, next) { + var self = this; - if ([params.zoom, params.lon, params.lat].map(numMapper).every(Number.isFinite)) { - return callback(null, { - zoom: params.zoom, - center: { - lng: params.lon, - lat: params.lat - } - }); - } + const { user, namedMapProvider, zoom, lon, lat, bbox } = res.locals; - if (params.bbox) { - var bbox = params.bbox.split(',').map(numMapper); - if (bbox.length === 4 && bbox.every(Number.isFinite)) { - return callback(null, { - bounds: { - west: bbox[0], - south: bbox[1], - east: bbox[2], - north: bbox[3] + if ([zoom, lon, lat].map(numMapper).every(Number.isFinite)) { + res.locals.imageOpts = { + zoom: zoom, + center: { + lng: lon, + lat: lat } - }); + }; + + return next(); } - } - step( - function getTemplate() { - namedMapProvider.getTemplate(this); - }, - function handleTemplateView(err, template) { - assert.ifError(err); - - if (template.view) { - var zoomCenter = templateZoomCenter(template.view); - if (zoomCenter) { - if (Number.isFinite(+params.zoom)) { - zoomCenter.zoom = +params.zoom; + if (bbox) { + var _bbox = bbox.split(',').map(numMapper); + if (_bbox.length === 4 && _bbox.every(Number.isFinite)) { + res.locals.imageOpts = { + bounds: { + west: _bbox[0], + south: _bbox[1], + east: _bbox[2], + north: _bbox[3] } - return zoomCenter; - } + }; - var bounds = templateBounds(template.view); - if (bounds) { - return bounds; - } + return next(); } - - return false; - }, - function estimateBoundsIfNoImageOpts(err, imageOpts) { - if (imageOpts) { - return imageOpts; - } - - var next = this; - namedMapProvider.getAffectedTablesAndLastUpdatedTime(function(err, affectedTablesAndLastUpdate) { - if (err) { - return next(null); - } - - var affectedTables = affectedTablesAndLastUpdate.tables || []; - - if (affectedTables.length === 0) { - return next(null); - } - - self.tablesExtentApi.getBounds(cdbUser, affectedTables, function(err, result) { - return next(null, result); - }); - }); - - }, - function returnCallback(err, imageOpts) { - return callback(err, imageOpts || DEFAULT_ZOOM_CENTER); } - ); + + step( + function getTemplate() { + namedMapProvider.getTemplate(this); + }, + function handleTemplateView(err, template) { + assert.ifError(err); + + if (template.view) { + var zoomCenter = templateZoomCenter(template.view); + if (zoomCenter) { + if (Number.isFinite(+zoom)) { + zoomCenter.zoom = +zoom; + } + return zoomCenter; + } + + var bounds = templateBounds(template.view); + if (bounds) { + return bounds; + } + } + + return false; + }, + function estimateBoundsIfNoImageOpts(err, imageOpts) { + if (imageOpts) { + return imageOpts; + } + + var _next = this; + namedMapProvider.getAffectedTablesAndLastUpdatedTime(function(err, affectedTablesAndLastUpdate) { + if (err) { + return _next(null); + } + + var affectedTables = affectedTablesAndLastUpdate.tables || []; + + if (affectedTables.length === 0) { + return _next(null); + } + + self.tablesExtentApi.getBounds(user, affectedTables, function (err, result) { + return _next(null, result); + }); + }); + + }, + function returnCallback(err, imageOpts) { + res.locals.imageOpts = imageOpts || DEFAULT_ZOOM_CENTER; + return next(); + } + ); + }.bind(this); +}; + +NamedMapsController.prototype.getImage = function () { + return function getImageMiddleware (req, res, next) { + const { imageOpts, namedMapProvider } = res.locals; + const { zoom, center, bounds } = imageOpts; + + let { width, height } = req.params; + + width = +width; + height = +height; + + const format = req.params.format === 'jpg' ? 'jpeg' : 'png'; + // We force always the tile to be generated using PNG because + // is the only format we support by now + res.locals.format = 'png'; + res.locals.layer = res.locals.layer || 'all'; + + if (!_.isUndefined(zoom) && center) { + return this.previewBackend.getImage(namedMapProvider, format, width, height, zoom, center, + (err, image, headers, stats) => { + if (err) { + return next(err); + } + + res.locals.image = image; + res.locals.headers = headers; + res.locals.stats = stats; + + next(); + }); + } + + this.previewBackend.getImage(namedMapProvider, format, width, height, bounds, (err, image, headers, stats) => { + if (err) { + return next(err); + } + + res.locals.image = image; + res.locals.headers = headers; + res.locals.stats = stats; + + next(); + }); + }.bind(this); }; function templateZoomCenter(view) {