Merge pull request #883 from CartoDB/fix-named-map-format

Do not force format for default named tiles
This commit is contained in:
Daniel
2018-03-05 11:29:43 +01:00
committed by GitHub
3 changed files with 151 additions and 16 deletions
+24 -15
View File
@@ -41,14 +41,18 @@ function NamedMapsController(prepareContext, namedMapProviderCache, tileBackend,
module.exports = NamedMapsController;
NamedMapsController.prototype.register = function(app) {
const tileOptions = {
label: 'NAMED_MAP_TILE'
};
app.get(
app.base_url_templated + '/:template_id/:layer/:z/:x/:y.(:format)',
cors(),
userMiddleware,
this.prepareContext,
this.getNamedMapProvider('NAMED_MAP_TILE'),
this.getNamedMapProvider(tileOptions),
this.getAffectedTables(),
this.getTile('NAMED_MAP_TILE'),
this.getTile(tileOptions),
this.setSurrogateKey(),
this.setCacheChannelHeader(),
this.setLastModifiedHeader(),
@@ -58,18 +62,23 @@ NamedMapsController.prototype.register = function(app) {
vectorError()
);
const staticOptions = {
forcedFormat: 'png',
label: 'STATIC_VIZ_MAP'
};
app.get(
app.base_url_mapconfig + '/static/named/:template_id/:width/:height.:format',
cors(),
userMiddleware,
allowQueryParams(['layer', 'zoom', 'lon', 'lat', 'bbox']),
this.prepareContext,
this.getNamedMapProvider('STATIC_VIZ_MAP'),
this.getNamedMapProvider(staticOptions),
this.getAffectedTables(),
this.getTemplate('STATIC_VIZ_MAP'),
this.prepareLayerFilterFromPreviewLayers('STATIC_VIZ_MAP'),
this.getTemplate(staticOptions),
this.prepareLayerFilterFromPreviewLayers(staticOptions),
this.getStaticImageOptions(),
this.getImage('STATIC_VIZ_MAP'),
this.getImage(staticOptions),
this.incrementMapViews(),
this.setSurrogateKey(),
this.setCacheChannelHeader(),
@@ -80,16 +89,16 @@ NamedMapsController.prototype.register = function(app) {
);
};
NamedMapsController.prototype.getNamedMapProvider = function (label) {
NamedMapsController.prototype.getNamedMapProvider = function ({ label, forcedFormat = null }) {
return function getNamedMapProviderMiddleware (req, res, next) {
const { user } = res.locals;
const { config, auth_token } = req.query;
const { template_id } = req.params;
// 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 (forcedFormat) {
res.locals.format = forcedFormat;
res.locals.layer = res.locals.layer || 'all';
}
const params = getRequestParams(res.locals);
@@ -124,7 +133,7 @@ NamedMapsController.prototype.getAffectedTables = function () {
}.bind(this);
};
NamedMapsController.prototype.getTemplate = function (label) {
NamedMapsController.prototype.getTemplate = function ({ label }) {
return function getTemplateMiddleware (req, res, next) {
const { namedMapProvider } = res.locals;
@@ -141,7 +150,7 @@ NamedMapsController.prototype.getTemplate = function (label) {
};
};
NamedMapsController.prototype.prepareLayerFilterFromPreviewLayers = function (label) {
NamedMapsController.prototype.prepareLayerFilterFromPreviewLayers = function ({ label }) {
return function prepareLayerFilterFromPreviewLayersMiddleware (req, res, next) {
const { user, template } = res.locals;
const { template_id } = req.params;
@@ -183,7 +192,7 @@ NamedMapsController.prototype.prepareLayerFilterFromPreviewLayers = function (la
}.bind(this);
};
NamedMapsController.prototype.getTile = function (label) {
NamedMapsController.prototype.getTile = function ({ label }) {
return function getTileMiddleware (req, res, next) {
const { namedMapProvider } = res.locals;
@@ -306,7 +315,7 @@ function getImageOptionsFromBoundingBox (bbox = '') {
}
}
NamedMapsController.prototype.getImage = function (label) {
NamedMapsController.prototype.getImage = function ({ label }) {
return function getImageMiddleware (req, res, next) {
const { imageOpts, namedMapProvider } = res.locals;
const { zoom, center, bounds } = imageOpts;
+42
View File
@@ -34,6 +34,48 @@ return function () {
serverOptions.renderer.mvt.usePostGIS = originalUsePostGIS;
});
describe('named map tile', function () {
it('should get default named vector tile', function (done) {
const apikeyToken = 1234;
const templateName = `mvt-template-${usePostGIS ? 'postgis' : 'mapnik'}`;
const template = {
version: '0.0.1',
name: templateName,
placeholders: {
buffersize: {
type: 'number',
default: 0
}
},
layergroup: {
version: '1.7.0',
layers: [{
type: 'cartodb',
options: {
sql: 'select * from populated_places_simple_reduced limit 10',
cartocss: TestClient.CARTOCSS.POINTS,
cartocss_version: '2.3.0',
}
}]
}
};
const testClient = new TestClient(template, apikeyToken);
testClient.getNamedTile(templateName, 0, 0, 0, 'mvt', {}, (err, res, tile) => {
if (err) {
return done(err);
}
const tileJSON = tile.toJSON();
assert.equal(tileJSON[0].features.length, 10);
testClient.drain(done);
});
});
});
describe('analysis-layers-dataviews-mvt', function () {
function createMapConfig(layers, dataviews, analysis) {
+85 -1
View File
@@ -414,7 +414,7 @@ TestClient.prototype.getDataview = function(dataviewName, params, callback) {
var urlParams = {};
if (params.hasOwnProperty('no_filters')) {
urlParams.no_filters = params.no_filters;
}
}
if (params.hasOwnProperty('own_filter')) {
urlParams.own_filter = params.own_filter;
}
@@ -1253,3 +1253,87 @@ TestClient.prototype.getAnalysesCatalog = function (params, callback) {
}
);
};
TestClient.prototype.getNamedTile = function (name, z, x, y, format, options, callback) {
const { params } = options;
if (!this.apiKey) {
return callback(new Error('apiKey param is mandatory to create a new template'));
}
const createTemplateRequest = {
url: `/api/v1/map/named?${qs.stringify({ api_key: this.apiKey })}`,
method: 'POST',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(this.template)
};
const createTemplateResponse = {
status: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
};
assert.response(this.server, createTemplateRequest, createTemplateResponse, (res, err) => {
if (err) {
return callback(err);
}
const templateId = JSON.parse(res.body).template_id;
const queryParams = params ? `?${qs.stringify(params)}` : '';
const url = `/api/v1/map/named/${templateId}/all/${[z,x,y].join('/')}.${format}${queryParams}`;
const namedTileRequest = {
url,
method: 'GET',
headers: {
host: 'localhost'
},
encoding: 'binary'
};
let contentType;
switch (format) {
case 'png':
contentType = 'image/png';
break;
case 'mvt':
contentType = 'application/x-protobuf';
break;
default:
contentType = 'application/json';
break;
}
const namedTileResponse = Object.assign({
status: 200,
headers: {
'content-type': contentType
}
}, options.response);
assert.response(this.server, namedTileRequest, namedTileResponse, (res, err) => {
let body;
switch (res.headers['content-type']) {
case 'image/png':
body = mapnik.Image.fromBytes(new Buffer(res.body, 'binary'));
break;
case 'application/x-protobuf':
body = new mapnik.VectorTile(z, x, y);
body.setDataSync(new Buffer(res.body, 'binary'));
break;
case 'application/json; charset=utf-8':
body = JSON.parse(res.body);
break;
default:
body = res.body;
break;
}
return callback(err, res, body);
});
});
};