Merge pull request #883 from CartoDB/fix-named-map-format
Do not force format for default named tiles
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user