Windshaft-cartodb/lib/utils/layergroup-metadata.js
2019-10-21 19:07:24 +02:00

192 lines
8.0 KiB
JavaScript

'use strict';
const dateWrapper = require('./date-wrapper');
const querystring = require('querystring');
module.exports = class LayergroupMetadata {
constructor (resourceLocator) {
this.resourceLocator = resourceLocator;
}
// TODO this should take into account several URL patterns
addDataviewsAndWidgetsUrls (username, layergroup, mapConfig) {
this._addDataviewsUrls(username, layergroup, mapConfig);
this._addWidgetsUrl(username, layergroup, mapConfig);
}
_addDataviewsUrls (username, layergroup, mapConfig) {
layergroup.metadata.dataviews = layergroup.metadata.dataviews || {};
var dataviews = mapConfig.dataviews || {};
Object.keys(dataviews).forEach((dataviewName) => {
var resource = layergroup.layergroupid + '/dataview/' + dataviewName;
layergroup.metadata.dataviews[dataviewName] = {
url: this.resourceLocator.getUrls(username, resource)
};
});
}
_addWidgetsUrl (username, layergroup, mapConfig) {
if (layergroup.metadata && Array.isArray(layergroup.metadata.layers) && Array.isArray(mapConfig.layers)) {
layergroup.metadata.layers = layergroup.metadata.layers.map((layer, layerIndex) => {
var mapConfigLayer = mapConfig.layers[layerIndex];
if (mapConfigLayer.options && mapConfigLayer.options.widgets) {
layer.widgets = layer.widgets || {};
Object.keys(mapConfigLayer.options.widgets).forEach((widgetName) => {
var resource = layergroup.layergroupid + '/' + layerIndex + '/widget/' + widgetName;
layer.widgets[widgetName] = {
type: mapConfigLayer.options.widgets[widgetName].type,
url: this.resourceLocator.getUrls(username, resource)
};
});
}
return layer;
});
}
}
addAnalysesMetadata (username, layergroup, analysesResults, includeQuery) {
includeQuery = includeQuery || false;
analysesResults = analysesResults || [];
layergroup.metadata.analyses = [];
analysesResults.forEach((analysis) => {
var nodes = analysis.getNodes();
layergroup.metadata.analyses.push({
nodes: nodes.reduce((nodesIdMap, node) => {
if (node.params.id) {
var nodeResource = layergroup.layergroupid + '/analysis/node/' + node.id();
var nodeRepr = {
status: node.getStatus(),
url: this.resourceLocator.getUrls(username, nodeResource)
};
if (includeQuery) {
nodeRepr.query = node.getQuery();
}
if (node.getStatus() === 'failed') {
nodeRepr.error_message = node.getErrorMessage();
}
nodesIdMap[node.params.id] = nodeRepr;
}
return nodesIdMap;
}, {})
});
});
}
addAggregationContextMetadata (layergroup, mapConfig, context) {
if (layergroup.metadata && Array.isArray(layergroup.metadata.layers) && Array.isArray(mapConfig.layers)) {
layergroup.metadata.layers = layergroup.metadata.layers.map(function (layer, layerIndex) {
if (context.aggregation && Array.isArray(context.aggregation.layers)) {
layer.meta.aggregation = context.aggregation.layers[layerIndex];
}
return layer;
});
}
}
addTileJsonMetadata (layergroup, user, mapconfig, userApiKey = null) {
const isVectorOnlyMapConfig = mapconfig.isVectorOnlyMapConfig();
let hasMapnikLayers = false;
const apiKey = userApiKey ? '?' + querystring.stringify({ api_key: userApiKey }) : '';
layergroup.metadata.layers.forEach((layerMetadata, index) => {
const layerId = mapconfig.getLayerId(index);
const rasterResource = `${layergroup.layergroupid}/${layerId}/{z}/{x}/{y}.png${apiKey}`;
if (mapconfig.layerType(index) === 'mapnik') {
hasMapnikLayers = true;
const vectorResource = `${layergroup.layergroupid}/${layerId}/{z}/{x}/{y}.mvt${apiKey}`;
const layerTilejson = {
vector: this._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${apiKey}`;
grids = this.resourceLocator.getTileUrls(user, gridResource);
}
layerTilejson.raster = this._getTilejson(
this.resourceLocator.getTileUrls(user, rasterResource),
grids
);
}
layerMetadata.tilejson = layerTilejson;
} else {
layerMetadata.tilejson = {
raster: this._getTilejson(this.resourceLocator.getTileUrls(user, rasterResource))
};
}
});
const tilejson = {};
const url = {};
if (hasMapnikLayers) {
const vectorResource = `${layergroup.layergroupid}/{z}/{x}/{y}.mvt${apiKey}`;
tilejson.vector = this._getTilejson(
this.resourceLocator.getTileUrls(user, vectorResource)
);
url.vector = this._getTemplateUrl(this.resourceLocator.getTemplateUrls(user, vectorResource));
if (!isVectorOnlyMapConfig) {
const rasterResource = `${layergroup.layergroupid}/{z}/{x}/{y}.png${apiKey}`;
tilejson.raster = this._getTilejson(
this.resourceLocator.getTileUrls(user, rasterResource)
);
url.raster = this._getTemplateUrl(this.resourceLocator.getTemplateUrls(user, rasterResource));
}
}
layergroup.metadata.tilejson = tilejson;
layergroup.metadata.url = url;
}
_getTilejson (tiles, grids) {
const tilejson = {
tilejson: '2.2.0',
tiles: tiles.https || tiles.http
};
if (grids) {
tilejson.grids = grids.https || grids.http;
}
return tilejson;
}
_getTemplateUrl (url) {
return url.https || url.http;
}
addTurboCartoContextMetadata (layergroup, mapConfig, context) {
if (layergroup.metadata && Array.isArray(layergroup.metadata.layers) && Array.isArray(mapConfig.layers)) {
layergroup.metadata.layers = layergroup.metadata.layers.map(function (layer, layerIndex) {
if (context.turboCarto && Array.isArray(context.turboCarto.layers)) {
layer.meta.cartocss_meta = context.turboCarto.layers[layerIndex];
}
return layer;
});
}
}
addDateWrappingMetadata (layergroup, mapConfig) {
if (layergroup.metadata && Array.isArray(layergroup.metadata.layers) && Array.isArray(mapConfig.layers)) {
layergroup.metadata.layers = layergroup.metadata.layers.map(function (layer, layerIndex) {
const mapConfigLayer = mapConfig.layers[layerIndex];
const layerOptions = mapConfigLayer.options;
if (layerOptions.dates_as_numbers && layerOptions.sql) {
const wrappedColumns = dateWrapper.getColumnsWithWrappedDates(layerOptions.sql);
if (wrappedColumns) {
layer.meta.dates_as_numbers = wrappedColumns;
}
}
return layer;
});
}
}
};