Return tilejson in metadata

It returns tilejson for each individual layer and also for all vector and raster layers.
This commit is contained in:
Raul Ochoa 2018-01-03 16:54:45 +01:00
parent 5d4d2bddd6
commit bf40b240d3
2 changed files with 273 additions and 0 deletions

View File

@ -90,6 +90,7 @@ MapController.prototype.composeCreateMapMiddleware = function (useTemplate = fal
this.setAnalysesMetadataToLayergroup(includeQuery),
this.setTurboCartoMetadataToLayergroup(),
this.setAggregationMetadataToLayergroup(),
this.setTilejsonMetadataToLayergroup(),
this.setSurrogateKeyHeader(),
this.sendResponse(),
this.augmentError({ label, addContext })
@ -313,6 +314,74 @@ MapController.prototype.augmentLayergroupData = function () {
};
};
function getTilejson(tiles, grids) {
const tilejson = {
tilejson: '2.2.0',
tiles: tiles.https || tiles.http
};
if (grids) {
tilejson.grids = grids.https || grids.http;
}
return tilejson;
}
MapController.prototype.setTilejsonMetadataToLayergroup = function () {
return function augmentLayergroupDataMiddleware (req, res, next) {
const { layergroup, user, mapconfig } = res.locals;
const isVectorOnlyMapConfig = mapconfig.isVectorOnlyMapConfig();
let hasMapnikLayers = false;
layergroup.metadata.layers.forEach((layerMetadata, index) => {
const layerId = mapconfig.getLayerId(index);
const rasterResource = `${layergroup.layergroupid}/${layerId}/{z}/{x}/{y}.png`;
if (mapconfig.layerType(index) === 'mapnik') {
hasMapnikLayers = true;
const vectorResource = `${layergroup.layergroupid}/${layerId}/{z}/{x}/{y}.mvt`;
const layerTilejson = {
vector: getTilejson(this.resourceLocator.getTileUrls(user, vectorResource))
};
if (!isVectorOnlyMapConfig) {
let grids = null;
const layer = mapconfig.getLayer(index);
if (layer.options.interactivity) {
const gridResource = `${layergroup.layergroupid}/${layerId}/{z}/{x}/{y}.grid.json`;
grids = this.resourceLocator.getTileUrls(user, gridResource);
}
layerTilejson.raster = getTilejson(
this.resourceLocator.getTileUrls(user, rasterResource),
grids
);
}
layerMetadata.tilejson = layerTilejson;
} else {
layerMetadata.tilejson = {
raster: getTilejson(this.resourceLocator.getTileUrls(user, rasterResource))
};
}
});
const tilejson = {};
if (hasMapnikLayers) {
tilejson.vector = getTilejson(
this.resourceLocator.getTileUrls(user, `${layergroup.layergroupid}/{z}/{x}/{y}.mvt`)
);
if (!isVectorOnlyMapConfig) {
tilejson.raster = getTilejson(
this.resourceLocator.getTileUrls(user, `${layergroup.layergroupid}/{z}/{x}/{y}.png`)
);
}
}
layergroup.metadata.tilejson = tilejson;
next();
}.bind(this);
};
MapController.prototype.getAffectedTables = function () {
return function getAffectedTablesMiddleware (req, res, next) {
const { dbname, layergroup, user, mapconfig } = res.locals;

204
test/acceptance/tilejson.js Normal file
View File

@ -0,0 +1,204 @@
require('../support/test_helper');
const assert = require('../support/assert');
const TestClient = require('../support/test-client');
describe('tilejson', function() {
function tilejsonValidation(tilejson, shouldHaveGrid = false) {
assert.equal(tilejson.tilejson, '2.2.0');
assert.ok(Array.isArray(tilejson.tiles));
assert.ok(tilejson.tiles.length > 0);
if (shouldHaveGrid) {
assert.ok(Array.isArray(tilejson.grids));
assert.ok(tilejson.grids.length > 0);
}
}
const sql = 'SELECT * FROM populated_places_simple_reduced';
const cartocss = TestClient.CARTOCSS.POINTS;
const cartocss_version = '3.0.12';
const RASTER_LAYER = {
options: {
sql, cartocss, cartocss_version
}
};
const RASTER_INTERACTIVITY_LAYER = {
options: {
sql, cartocss, cartocss_version,
interactivity: ['cartodb_id']
}
};
const VECTOR_LAYER = {
options: {
sql
}
};
const PLAIN_LAYER = {
type: 'plain',
options: {
color: '#000000'
}
};
function mapConfig(layers) {
return {
version: '1.7.0',
layers: Array.isArray(layers) ? layers : [layers]
};
}
describe('per layer', function() {
it('should expose raster + vector tilejson for raster layers', function(done) {
var testClient = new TestClient(mapConfig(RASTER_LAYER));
testClient.getLayergroup(function(err, layergroupResult) {
assert.ok(!err, err);
const metadata = layergroupResult.metadata;
assert.ok(metadata);
assert.equal(metadata.layers.length, 1);
const layer = metadata.layers[0];
assert.deepEqual(Object.keys(layer.tilejson), ['vector', 'raster']);
Object.keys(layer.tilejson).forEach(k => {
tilejsonValidation(layer.tilejson[k]);
});
testClient.drain(done);
});
});
it('should expose just the vector tilejson vector only layers', function(done) {
var testClient = new TestClient(mapConfig(VECTOR_LAYER));
testClient.getLayergroup(function(err, layergroupResult) {
assert.ok(!err, err);
const metadata = layergroupResult.metadata;
assert.ok(metadata);
assert.equal(metadata.layers.length, 1);
const layer = metadata.layers[0];
assert.deepEqual(Object.keys(layer.tilejson), ['vector']);
Object.keys(layer.tilejson).forEach(k => {
tilejsonValidation(layer.tilejson[k]);
});
testClient.drain(done);
});
});
it('should expose just the raster tilejson plain layers', function(done) {
var testClient = new TestClient(mapConfig(PLAIN_LAYER));
testClient.getLayergroup(function(err, layergroupResult) {
assert.ok(!err, err);
const metadata = layergroupResult.metadata;
assert.ok(metadata);
assert.equal(metadata.layers.length, 1);
const layer = metadata.layers[0];
assert.deepEqual(Object.keys(layer.tilejson), ['raster']);
Object.keys(layer.tilejson).forEach(k => {
tilejsonValidation(layer.tilejson[k]);
});
testClient.drain(done);
});
});
it('should expose grids for the raster layer with interactivity', function(done) {
var testClient = new TestClient(mapConfig(RASTER_INTERACTIVITY_LAYER));
testClient.getLayergroup(function(err, layergroupResult) {
assert.ok(!err, err);
const metadata = layergroupResult.metadata;
assert.ok(metadata);
assert.equal(metadata.layers.length, 1);
const layer = metadata.layers[0];
assert.deepEqual(Object.keys(layer.tilejson), ['vector', 'raster']);
tilejsonValidation(layer.tilejson.vector);
tilejsonValidation(layer.tilejson.raster, true);
testClient.drain(done);
});
});
it('should work with several layers', function(done) {
var testClient = new TestClient(mapConfig([RASTER_LAYER, RASTER_INTERACTIVITY_LAYER]));
testClient.getLayergroup(function(err, layergroupResult) {
assert.ok(!err, err);
const metadata = layergroupResult.metadata;
assert.ok(metadata);
assert.equal(metadata.layers.length, 2);
assert.deepEqual(Object.keys(metadata.layers[0].tilejson), ['vector', 'raster']);
tilejsonValidation(metadata.layers[0].tilejson.vector);
tilejsonValidation(metadata.layers[0].tilejson.raster);
assert.deepEqual(Object.keys(metadata.layers[1].tilejson), ['vector', 'raster']);
tilejsonValidation(metadata.layers[1].tilejson.vector);
tilejsonValidation(metadata.layers[1].tilejson.raster, true);
testClient.drain(done);
});
});
});
describe('root tilejson', function() {
it('should expose just the `vector` tilejson when for vector only mapnik layers', function(done) {
var testClient = new TestClient(mapConfig(VECTOR_LAYER));
testClient.getLayergroup(function(err, layergroupResult) {
assert.ok(!err, err);
const metadata = layergroupResult.metadata;
assert.ok(metadata);
const tilejson = metadata.tilejson;
assert.deepEqual(Object.keys(tilejson), ['vector']);
Object.keys(tilejson).forEach(k => {
tilejsonValidation(tilejson[k]);
});
testClient.drain(done);
});
});
it('should expose just the `vector` and `raster` tilejson for mapnik layers', function(done) {
var testClient = new TestClient(mapConfig(RASTER_LAYER));
testClient.getLayergroup(function(err, layergroupResult) {
assert.ok(!err, err);
const metadata = layergroupResult.metadata;
assert.ok(metadata);
const tilejson = metadata.tilejson;
assert.deepEqual(Object.keys(tilejson), ['vector', 'raster']);
Object.keys(tilejson).forEach(k => {
tilejsonValidation(tilejson[k]);
});
testClient.drain(done);
});
});
});
});