diff --git a/lib/cartodb/controllers/index.js b/lib/cartodb/controllers/index.js new file mode 100644 index 00000000..8a00dad8 --- /dev/null +++ b/lib/cartodb/controllers/index.js @@ -0,0 +1,6 @@ +module.exports = { + Map: require('./map'), + NamedMaps: require('./named_maps'), + NamedMapsAdmin: require('./named_maps_admin'), + ServerInfo: require('./server_info') +}; \ No newline at end of file diff --git a/lib/cartodb/controllers/map.js b/lib/cartodb/controllers/map.js index 3abcd134..f80c860f 100644 --- a/lib/cartodb/controllers/map.js +++ b/lib/cartodb/controllers/map.js @@ -4,15 +4,26 @@ var step = require('step'); var cors = require('../middleware/cors'); +var MapStoreMapConfigProvider = require('windshaft').model.provider.MapStoreMapConfig; + /** * @param app + * @param {MapStore} mapStore * @param {MapBackend} mapBackend + * @param {TileBackend} tileBackend + * @param {PreviewBackend} previewBackend + * @param {AttributesBackend} attributesBackend * @param layergroupRequestDecorator * @constructor */ -function MapController(app, mapBackend, layergroupRequestDecorator) { +function MapController(app, mapStore, mapBackend, tileBackend, previewBackend, attributesBackend, + layergroupRequestDecorator) { this._app = app; - this._mapBackend = mapBackend; + this.mapStore = mapStore; + this.mapBackend = mapBackend; + this.tileBackend = tileBackend; + this.previewBackend = previewBackend; + this.attributesBackend = attributesBackend; this._layergroupRequestDecorator = layergroupRequestDecorator; } @@ -27,6 +38,10 @@ MapController.prototype.register = function(app) { app.get(app.base_url_mapconfig, cors(), this.createGet.bind(this)); app.post(app.base_url_mapconfig, cors(), this.createPost.bind(this)); app.get(app.base_url_mapconfig + '/:token/:layer/attributes/:fid', cors(), this.attributes.bind(this)); + app.get(app.base_url_mapconfig + '/static/center/:token/:z/:lat/:lng/:width/:height.:format', cors(), + this.center.bind(this)); + app.get(app.base_url_mapconfig + '/static/bbox/:token/:west,:south,:east,:north/:width/:height.:format', cors(), + this.bbox.bind(this)); }; MapController.prototype.attributes = function(req, res) { @@ -43,7 +58,7 @@ MapController.prototype.attributes = function(req, res) { assert.ifError(err); - self._mapBackend.getFeatureAttributes(req.params, false, this); + self.attributesBackend.getFeatureAttributes(req.params, false, this); }, function finish(err, tile, stats) { req.profiler.add(stats || {}); @@ -80,7 +95,7 @@ MapController.prototype.create = function(req, res, prepareConfigFn) { prepareConfigFn, function initLayergroup(err, requestMapConfig) { assert.ifError(err); - self._mapBackend.createLayergroup(requestMapConfig, req.params, layergroupDecorator, this); + self.mapBackend.createLayergroup(requestMapConfig, req.params, layergroupDecorator, this); }, function finish(err, response){ if (err) { @@ -146,7 +161,7 @@ MapController.prototype.tileOrLayer = function (req, res) { if ( err ) { throw err; } - self._mapBackend.getTileOrGrid(req.params, this); + self.tileBackend.getTile(new MapStoreMapConfigProvider(self.mapStore, req.params), req.params, this); }, function mapController$finalize(err, tile, headers, stats) { req.profiler.add(stats); @@ -199,3 +214,56 @@ MapController.prototype.finalizeGetTileOrGrid = function(err, req, res, tile, he global.statsClient.increment('windshaft.tiles.' + formatStat + '.success'); } }; + +MapController.prototype.bbox = function(req, res) { + this.staticMap(req, res, +req.params.width, +req.params.height, { + west: +req.params.west, + north: +req.params.north, + east: +req.params.east, + south: +req.params.south + }); +}; + +MapController.prototype.center = function(req, res) { + this.staticMap(req, res, +req.params.width, +req.params.height, +req.params.z, { + lng: +req.params.lng, + lat: +req.params.lat + }); +}; + +MapController.prototype.staticMap = function(req, res, width, height, zoom /* bounds */, center) { + var format = req.params.format === 'jpg' ? 'jpeg' : 'png'; + + var self = this; + + step( + function() { + self._app.req2params(req, this); + }, + function(err) { + req.profiler.done('req2params'); + assert.ifError(err); + if (center) { + self.previewBackend.getImage(new MapStoreMapConfigProvider(self.mapStore, req.params), + req.params, width, height, zoom, center, this); + } else { + self.previewBackend.getImage(new MapStoreMapConfigProvider(self.mapStore, req.params), + req.params, width, height, zoom /* bounds */, this); + } + }, + function handleImage(err, image, headers, stats) { + req.profiler.done('render-' + format); + req.profiler.add(stats || {}); + + if (err) { + if (!err.error) { + err.error = err.message; + } + self._app.sendError(res, {errors: ['' + err] }, self._app.findStatusCode(err), 'STATIC_MAP', err); + } else { + res.setHeader('Content-Type', headers['Content-Type'] || 'image/' + format); + self._app.sendResponse(res, [image, 200]); + } + } + ); +}; diff --git a/lib/cartodb/controllers/server_info.js b/lib/cartodb/controllers/server_info.js index 99dfcf4b..49d3f340 100644 --- a/lib/cartodb/controllers/server_info.js +++ b/lib/cartodb/controllers/server_info.js @@ -1,11 +1,19 @@ +var windshaft = require('windshaft'); var HealthCheck = require('../monitoring/health_check'); var WELCOME_MSG = "This is the CartoDB Maps API, " + "see the documentation at http://docs.cartodb.com/cartodb-platform/maps-api.html"; -function ServerInfoController(versions) { - this.versions = versions || {}; +var versions = { + windshaft: windshaft.version, + grainstore: windshaft.grainstore.version(), + node_mapnik: windshaft.mapnik.version, + mapnik: windshaft.mapnik.versions.mapnik, + windshaft_cartodb: require('../../../package.json').version +}; + +function ServerInfoController() { this.healthConfig = global.environment.health || {}; this.healthCheck = new HealthCheck(); } @@ -23,7 +31,7 @@ ServerInfoController.prototype.welcome = function(req, res) { }; ServerInfoController.prototype.version = function(req, res) { - res.send(this.versions, 200); + res.send(versions, 200); }; ServerInfoController.prototype.health = function(req, res) { diff --git a/lib/cartodb/controllers/static_maps.js b/lib/cartodb/controllers/static_maps.js deleted file mode 100644 index c147e842..00000000 --- a/lib/cartodb/controllers/static_maps.js +++ /dev/null @@ -1,70 +0,0 @@ -var step = require('step'); -var assert = require('assert'); -var cors = require('../middleware/cors'); - -function StaticMapsController(app, staticMapBackend) { - this._app = app; - this._staticMapBackend = staticMapBackend; -} - -module.exports = StaticMapsController; - - -StaticMapsController.prototype.register = function(app) { - app.get(app.base_url_mapconfig + '/static/center/:token/:z/:lat/:lng/:width/:height.:format', cors(), - this.center.bind(this)); - - app.get(app.base_url_mapconfig + '/static/bbox/:token/:west,:south,:east,:north/:width/:height.:format', cors(), - this.bbox.bind(this)); -}; - -StaticMapsController.prototype.bbox = function(req, res) { - this.staticMap(req, res, +req.params.width, +req.params.height, { - west: +req.params.west, - north: +req.params.north, - east: +req.params.east, - south: +req.params.south - }); -}; - -StaticMapsController.prototype.center = function(req, res) { - this.staticMap(req, res, +req.params.width, +req.params.height, +req.params.z, { - lng: +req.params.lng, - lat: +req.params.lat - }); -}; - -StaticMapsController.prototype.staticMap = function(req, res, width, height, zoom /* bounds */, center) { - var format = req.params.format === 'jpg' ? 'jpeg' : 'png'; - - var self = this; - - step( - function() { - self._app.req2params(req, this); - }, - function(err) { - req.profiler.done('req2params'); - assert.ifError(err); - if (center) { - self._staticMapBackend.getImage(req.params, width, height, zoom, center, this); - } else { - self._staticMapBackend.getImage(req.params, width, height, zoom /* bounds */, this); - } - }, - function handleImage(err, image, headers, stats) { - req.profiler.done('render-' + format); - req.profiler.add(stats || {}); - - if (err) { - if (!err.error) { - err.error = err.message; - } - self._app.sendError(res, {errors: ['' + err] }, self._app.findStatusCode(err), 'STATIC_MAP', err); - } else { - res.setHeader('Content-Type', headers['Content-Type'] || 'image/' + format); - self._app.sendResponse(res, [image, 200]); - } - } - ); -}; diff --git a/lib/cartodb/server.js b/lib/cartodb/server.js index f336a09f..110c8c4b 100644 --- a/lib/cartodb/server.js +++ b/lib/cartodb/server.js @@ -6,8 +6,7 @@ var cartodbRedis = require('cartodb-redis'); var _ = require('underscore'); var step = require('step'); -var StaticMapsController = require('./controllers/static_maps'); -var MapController = require('./controllers/map'); +var controller = require('./controllers'); var SurrogateKeysCache = require('./cache/surrogate_keys_cache'); var NamedMapsCacheEntry = require('./cache/model/named_maps_entry'); @@ -18,7 +17,6 @@ var MapConfigNamedLayersAdapter = require('./models/mapconfig_named_layers_adapt var windshaft = require('windshaft'); -var grainstore = windshaft.grainstore; var mapnik = windshaft.mapnik; var TemplateMaps = require('./backends/template_maps.js'); @@ -183,8 +181,12 @@ module.exports = function(serverOptions) { } }); var rendererCache = new windshaft.cache.RendererCache(rendererCacheOpts, mapStore, rendererFactory); - var mapBackend = new windshaft.backend.Map(rendererCache, mapStore); - var staticMapBackend = new windshaft.backend.StaticMap(rendererCache); + + var attributesBackend = new windshaft.backend.Attributes(rendererCache, mapStore); + var previewBackend = new windshaft.backend.Preview(rendererCache); + var tileBackend = new windshaft.backend.Tile(rendererCache); + var mapValidatorBackend = new windshaft.backend.MapValidator(tileBackend, attributesBackend); + var mapBackend = new windshaft.backend.Map(rendererCache, mapStore, mapValidatorBackend); app.findStatusCode = function(err) { var statusCode; @@ -196,15 +198,6 @@ module.exports = function(serverOptions) { return statusCode; }; - /******************************************************************************************************************* - * Routing - ******************************************************************************************************************/ - - app.all('*', function(req, res, next) { - req.context.user = cdbRequest.userByReq(req); - next(); - }); - var namedLayersAdapter = new MapConfigNamedLayersAdapter(templateMaps); var layergroupRequestDecorator = { beforeLayergroupCreate: function(req, requestMapConfig, callback) { @@ -304,42 +297,43 @@ module.exports = function(serverOptions) { } }; - var mapController = new MapController(app, mapBackend, layergroupRequestDecorator); - mapController.register(app); - - var staticMapsController = new StaticMapsController(app, staticMapBackend); - staticMapsController.register(app); - var TablesExtentApi = require('./api/tables_extent_api'); var tablesExtentApi = new TablesExtentApi(pgQueryRunner); - var NamedMapsController = require('./controllers/named_maps'), - namedMapsController = new NamedMapsController( - app, - templateMaps, - metadataBackend, - mapBackend, - staticMapBackend, - template_baseurl, - surrogateKeysCache, - layergroupRequestDecorator, - tablesExtentApi - ); - namedMapsController.register(app); + /******************************************************************************************************************* + * Routing + ******************************************************************************************************************/ - var NamedMapsAdminController = require('./controllers/named_maps_admin'), - namedMapsAdminController = new NamedMapsAdminController(app, templateMaps, template_baseurl); - namedMapsAdminController.register(app); + app.all('*', function(req, res, next) { + req.context.user = cdbRequest.userByReq(req); + next(); + }); - var ServerInfoController = require('./controllers/server_info'), - serverInfoController = new ServerInfoController({ - windshaft: windshaft.version, - grainstore: grainstore.version(), - node_mapnik: mapnik.version, - mapnik: mapnik.versions.mapnik, - windshaft_cartodb: require('../../package.json').version - }); - serverInfoController.register(app); + new controller.Map( + app, + mapStore, + mapBackend, + tileBackend, + previewBackend, + attributesBackend, + layergroupRequestDecorator + ).register(app); + + new controller.NamedMaps( + app, + templateMaps, + metadataBackend, + mapBackend, + previewBackend, + template_baseurl, + surrogateKeysCache, + layergroupRequestDecorator, + tablesExtentApi + ).register(app); + + new controller.NamedMapsAdmin(app, templateMaps, template_baseurl).register(app); + + new controller.ServerInfo().register(app); /******************************************************************************************************************* * END Routing