2018-01-01 23:54:35 +08:00
|
|
|
const NamedMapsCacheEntry = require('../cache/model/named_maps_entry');
|
|
|
|
const cors = require('../middleware/cors');
|
|
|
|
const userMiddleware = require('../middleware/user');
|
2018-03-16 02:38:11 +08:00
|
|
|
const locals = require('../middleware/locals');
|
|
|
|
const cleanUpQueryParams = require('../middleware/clean-up-query-params');
|
|
|
|
const layergroupToken = require('../middleware/layergroup-token');
|
|
|
|
const credentials = require('../middleware/credentials');
|
2018-03-15 22:33:20 +08:00
|
|
|
const dbConnSetup = require('../middleware/db-conn-setup');
|
2018-03-16 01:48:29 +08:00
|
|
|
const authorize = require('../middleware/authorize');
|
2018-01-01 23:54:35 +08:00
|
|
|
const vectorError = require('../middleware/vector-error');
|
2015-09-16 22:18:26 +08:00
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
const DEFAULT_ZOOM_CENTER = {
|
|
|
|
zoom: 1,
|
|
|
|
center: {
|
|
|
|
lng: 0,
|
|
|
|
lat: 0
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function numMapper(n) {
|
|
|
|
return +n;
|
|
|
|
}
|
2015-01-20 23:56:06 +08:00
|
|
|
|
2018-01-16 01:09:54 +08:00
|
|
|
function getRequestParams(locals) {
|
|
|
|
const params = Object.assign({}, locals);
|
|
|
|
|
|
|
|
delete params.template;
|
|
|
|
delete params.affectedTablesAndLastUpdate;
|
|
|
|
delete params.namedMapProvider;
|
|
|
|
delete params.allowedQueryParams;
|
|
|
|
|
|
|
|
return params;
|
|
|
|
}
|
|
|
|
|
2018-03-16 02:38:11 +08:00
|
|
|
function NamedMapsController(namedMapProviderCache, tileBackend, previewBackend,
|
2018-03-16 01:48:29 +08:00
|
|
|
surrogateKeysCache, tablesExtentApi, metadataBackend, pgConnection, authApi) {
|
2015-07-15 02:53:06 +08:00
|
|
|
this.namedMapProviderCache = namedMapProviderCache;
|
2015-07-09 19:37:00 +08:00
|
|
|
this.tileBackend = tileBackend;
|
|
|
|
this.previewBackend = previewBackend;
|
2015-01-23 23:37:38 +08:00
|
|
|
this.surrogateKeysCache = surrogateKeysCache;
|
2015-07-08 21:50:59 +08:00
|
|
|
this.tablesExtentApi = tablesExtentApi;
|
2015-09-29 18:21:11 +08:00
|
|
|
this.metadataBackend = metadataBackend;
|
2018-03-15 22:33:20 +08:00
|
|
|
this.pgConnection = pgConnection;
|
2018-03-16 01:48:29 +08:00
|
|
|
this.authApi = authApi;
|
2015-01-20 23:56:06 +08:00
|
|
|
}
|
|
|
|
|
2015-04-27 21:01:49 +08:00
|
|
|
module.exports = NamedMapsController;
|
2015-01-20 23:56:06 +08:00
|
|
|
|
2015-04-27 21:01:49 +08:00
|
|
|
NamedMapsController.prototype.register = function(app) {
|
2018-03-16 20:04:42 +08:00
|
|
|
const { base_url_mapconfig: mapconfigBasePath, base_url_templated: templateBasePath } = app;
|
2018-03-15 00:33:54 +08:00
|
|
|
|
2017-09-22 06:48:44 +08:00
|
|
|
app.get(
|
2018-03-16 20:04:42 +08:00
|
|
|
`${templateBasePath}/:template_id/:layer/:z/:x/:y.(:format)`,
|
2017-09-22 06:48:44 +08:00
|
|
|
cors(),
|
2018-03-16 02:38:11 +08:00
|
|
|
cleanUpQueryParams(),
|
2018-03-16 23:12:36 +08:00
|
|
|
locals(),
|
|
|
|
userMiddleware(),
|
2018-03-16 02:38:11 +08:00
|
|
|
layergroupToken(),
|
|
|
|
credentials(),
|
2018-03-16 01:48:29 +08:00
|
|
|
authorize(this.authApi),
|
2018-03-15 22:33:20 +08:00
|
|
|
dbConnSetup(this.pgConnection),
|
2018-03-15 00:08:04 +08:00
|
|
|
getNamedMapProvider({
|
|
|
|
namedMapProviderCache: this.namedMapProviderCache,
|
|
|
|
label: 'NAMED_MAP_TILE'
|
|
|
|
}),
|
2018-03-14 20:01:07 +08:00
|
|
|
getAffectedTables(),
|
2018-03-15 00:08:04 +08:00
|
|
|
getTile({
|
|
|
|
tileBackend: this.tileBackend,
|
|
|
|
label: 'NAMED_MAP_TILE'
|
|
|
|
}),
|
2018-03-14 20:25:42 +08:00
|
|
|
setSurrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
|
2018-03-14 20:19:56 +08:00
|
|
|
setCacheChannelHeader(),
|
2018-03-14 20:27:56 +08:00
|
|
|
setLastModifiedHeader(),
|
2018-03-14 20:30:27 +08:00
|
|
|
setCacheControlHeader(),
|
2018-03-14 20:31:39 +08:00
|
|
|
setContentTypeHeader(),
|
2018-03-14 20:32:43 +08:00
|
|
|
sendResponse(),
|
2017-12-12 20:20:22 +08:00
|
|
|
vectorError()
|
2017-09-22 06:48:44 +08:00
|
|
|
);
|
2015-09-30 23:17:01 +08:00
|
|
|
|
2017-09-22 06:48:44 +08:00
|
|
|
app.get(
|
2018-03-16 20:04:42 +08:00
|
|
|
`${mapconfigBasePath}/static/named/:template_id/:width/:height.:format`,
|
2017-09-22 06:48:44 +08:00
|
|
|
cors(),
|
2018-03-16 21:03:59 +08:00
|
|
|
cleanUpQueryParams(['layer', 'zoom', 'lon', 'lat', 'bbox']),
|
2018-03-16 23:12:36 +08:00
|
|
|
locals(),
|
|
|
|
userMiddleware(),
|
2018-03-16 02:38:11 +08:00
|
|
|
layergroupToken(),
|
|
|
|
credentials(),
|
2018-03-16 01:48:29 +08:00
|
|
|
authorize(this.authApi),
|
2018-03-15 22:33:20 +08:00
|
|
|
dbConnSetup(this.pgConnection),
|
2018-03-15 00:15:50 +08:00
|
|
|
getNamedMapProvider({
|
|
|
|
namedMapProviderCache: this.namedMapProviderCache,
|
|
|
|
label: 'STATIC_VIZ_MAP', forcedFormat: 'png'
|
|
|
|
}),
|
2018-03-14 20:01:07 +08:00
|
|
|
getAffectedTables(),
|
2018-03-15 00:08:04 +08:00
|
|
|
getTemplate({ label: 'STATIC_VIZ_MAP' }),
|
|
|
|
prepareLayerFilterFromPreviewLayers({
|
|
|
|
namedMapProviderCache: this.namedMapProviderCache,
|
|
|
|
label: 'STATIC_VIZ_MAP'
|
|
|
|
}),
|
2018-03-14 20:10:24 +08:00
|
|
|
getStaticImageOptions({ tablesExtentApi: this.tablesExtentApi }),
|
2018-03-15 00:08:04 +08:00
|
|
|
getImage({ previewBackend: this.previewBackend, label: 'STATIC_VIZ_MAP' }),
|
2018-03-14 20:18:37 +08:00
|
|
|
incrementMapViews({ metadataBackend: this.metadataBackend }),
|
2018-03-14 20:25:42 +08:00
|
|
|
setSurrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
|
2018-03-14 20:19:56 +08:00
|
|
|
setCacheChannelHeader(),
|
2018-03-14 20:27:56 +08:00
|
|
|
setLastModifiedHeader(),
|
2018-03-14 20:30:27 +08:00
|
|
|
setCacheControlHeader(),
|
2018-03-14 20:31:39 +08:00
|
|
|
setContentTypeHeader(),
|
2018-03-14 20:32:43 +08:00
|
|
|
sendResponse()
|
2017-09-22 06:48:44 +08:00
|
|
|
);
|
2015-07-09 19:37:00 +08:00
|
|
|
};
|
|
|
|
|
2018-03-14 19:58:56 +08:00
|
|
|
function getNamedMapProvider ({ namedMapProviderCache, label, forcedFormat = null }) {
|
2017-12-30 02:31:02 +08:00
|
|
|
return function getNamedMapProviderMiddleware (req, res, next) {
|
|
|
|
const { user } = res.locals;
|
|
|
|
const { config, auth_token } = req.query;
|
|
|
|
const { template_id } = req.params;
|
2018-01-17 00:57:22 +08:00
|
|
|
|
2018-03-03 01:25:23 +08:00
|
|
|
if (forcedFormat) {
|
|
|
|
res.locals.format = forcedFormat;
|
|
|
|
res.locals.layer = res.locals.layer || 'all';
|
|
|
|
}
|
2018-01-17 00:57:22 +08:00
|
|
|
|
2018-01-16 01:09:54 +08:00
|
|
|
const params = getRequestParams(res.locals);
|
2017-12-30 02:31:02 +08:00
|
|
|
|
2018-03-14 19:58:56 +08:00
|
|
|
namedMapProviderCache.get(user, template_id, config, auth_token, params, (err, namedMapProvider) => {
|
2017-12-30 02:31:02 +08:00
|
|
|
if (err) {
|
2017-12-30 23:08:46 +08:00
|
|
|
err.label = label;
|
2017-12-30 02:31:02 +08:00
|
|
|
return next(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
res.locals.namedMapProvider = namedMapProvider;
|
|
|
|
|
|
|
|
next();
|
|
|
|
});
|
2018-03-14 19:58:56 +08:00
|
|
|
};
|
2018-03-14 20:10:24 +08:00
|
|
|
}
|
2017-12-30 02:31:02 +08:00
|
|
|
|
2018-03-14 20:01:07 +08:00
|
|
|
function getAffectedTables () {
|
2018-01-01 23:21:22 +08:00
|
|
|
return function getAffectedTables (req, res, next) {
|
|
|
|
const { namedMapProvider } = res.locals;
|
|
|
|
|
|
|
|
namedMapProvider.getAffectedTablesAndLastUpdatedTime((err, affectedTablesAndLastUpdate) => {
|
|
|
|
req.profiler.done('affectedTables');
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
return next(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
res.locals.affectedTablesAndLastUpdate = affectedTablesAndLastUpdate;
|
|
|
|
|
|
|
|
next();
|
|
|
|
});
|
2018-03-14 20:01:07 +08:00
|
|
|
};
|
2018-03-14 20:10:24 +08:00
|
|
|
}
|
2018-01-01 23:21:22 +08:00
|
|
|
|
2018-03-14 20:02:49 +08:00
|
|
|
function getTemplate ({ label }) {
|
2018-01-01 23:54:35 +08:00
|
|
|
return function getTemplateMiddleware (req, res, next) {
|
|
|
|
const { namedMapProvider } = res.locals;
|
2017-12-30 21:13:23 +08:00
|
|
|
|
|
|
|
namedMapProvider.getTemplate((err, template) => {
|
|
|
|
if (err) {
|
2017-12-30 23:08:46 +08:00
|
|
|
err.label = label;
|
2017-12-30 21:13:23 +08:00
|
|
|
return next(err);
|
|
|
|
}
|
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
res.locals.template = template;
|
2017-12-30 21:13:23 +08:00
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
next();
|
|
|
|
});
|
|
|
|
};
|
2018-03-14 20:10:24 +08:00
|
|
|
}
|
2017-12-30 21:13:23 +08:00
|
|
|
|
2018-03-14 20:05:05 +08:00
|
|
|
function prepareLayerFilterFromPreviewLayers ({ namedMapProviderCache, label }) {
|
2018-01-01 23:54:35 +08:00
|
|
|
return function prepareLayerFilterFromPreviewLayersMiddleware (req, res, next) {
|
|
|
|
const { user, template } = res.locals;
|
|
|
|
const { template_id } = req.params;
|
|
|
|
const { config, auth_token } = req.query;
|
2017-12-30 21:13:23 +08:00
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
if (!template || !template.view || !template.view.preview_layers) {
|
|
|
|
return next();
|
|
|
|
}
|
|
|
|
|
|
|
|
var previewLayers = template.view.preview_layers;
|
|
|
|
var layerVisibilityFilter = [];
|
|
|
|
|
2018-01-09 18:20:20 +08:00
|
|
|
template.layergroup.layers.forEach((layer, index) => {
|
2018-01-01 23:54:35 +08:00
|
|
|
if (previewLayers[''+index] !== false && previewLayers[layer.id] !== false) {
|
|
|
|
layerVisibilityFilter.push(''+index);
|
2017-12-30 21:13:23 +08:00
|
|
|
}
|
2018-01-01 23:54:35 +08:00
|
|
|
});
|
2017-12-30 21:13:23 +08:00
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
if (!layerVisibilityFilter.length) {
|
|
|
|
return next();
|
|
|
|
}
|
2017-12-30 21:13:23 +08:00
|
|
|
|
2018-01-16 01:09:54 +08:00
|
|
|
const params = getRequestParams(res.locals);
|
2018-01-16 00:08:54 +08:00
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
// overwrites 'all' default filter
|
2018-01-16 00:08:54 +08:00
|
|
|
params.layer = layerVisibilityFilter.join(',');
|
2017-12-30 21:13:23 +08:00
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
// recreates the provider
|
2018-03-14 20:05:05 +08:00
|
|
|
namedMapProviderCache.get(user, template_id, config, auth_token, params, (err, provider) => {
|
2018-01-01 23:54:35 +08:00
|
|
|
if (err) {
|
|
|
|
err.label = label;
|
|
|
|
return next(err);
|
|
|
|
}
|
2017-12-30 21:13:23 +08:00
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
res.locals.namedMapProvider = provider;
|
|
|
|
|
|
|
|
next();
|
2017-12-30 21:13:23 +08:00
|
|
|
});
|
2018-03-14 20:05:05 +08:00
|
|
|
};
|
2018-03-14 20:10:24 +08:00
|
|
|
}
|
2017-12-30 21:13:23 +08:00
|
|
|
|
2018-03-14 20:07:40 +08:00
|
|
|
function getTile ({ tileBackend, label }) {
|
2017-12-31 00:18:12 +08:00
|
|
|
return function getTileMiddleware (req, res, next) {
|
|
|
|
const { namedMapProvider } = res.locals;
|
2015-07-15 02:10:55 +08:00
|
|
|
|
2018-03-14 20:07:40 +08:00
|
|
|
tileBackend.getTile(namedMapProvider, req.params, (err, tile, headers, stats) => {
|
2017-12-31 00:18:12 +08:00
|
|
|
req.profiler.add(stats);
|
2015-07-15 02:10:55 +08:00
|
|
|
|
|
|
|
if (err) {
|
2018-01-17 00:55:09 +08:00
|
|
|
err.label = label;
|
2017-12-31 00:18:12 +08:00
|
|
|
return next(err);
|
2015-07-15 02:10:55 +08:00
|
|
|
}
|
|
|
|
|
2017-12-31 00:18:12 +08:00
|
|
|
res.locals.body = tile;
|
|
|
|
res.locals.headers = headers;
|
|
|
|
res.locals.stats = stats;
|
2017-12-30 02:33:49 +08:00
|
|
|
|
2017-12-31 00:18:12 +08:00
|
|
|
next();
|
|
|
|
});
|
2018-03-14 20:07:40 +08:00
|
|
|
};
|
2018-03-14 20:10:24 +08:00
|
|
|
}
|
2015-06-29 22:39:35 +08:00
|
|
|
|
2018-03-14 20:10:24 +08:00
|
|
|
function getStaticImageOptions ({ tablesExtentApi }) {
|
2017-12-30 22:21:20 +08:00
|
|
|
return function getStaticImageOptionsMiddleware(req, res, next) {
|
2018-01-02 01:06:56 +08:00
|
|
|
const { user, namedMapProvider, template } = res.locals;
|
2017-12-30 22:21:20 +08:00
|
|
|
|
2018-01-02 01:06:56 +08:00
|
|
|
const imageOpts = getImageOptions(res.locals, template);
|
2017-12-30 22:21:20 +08:00
|
|
|
|
2018-01-02 01:06:56 +08:00
|
|
|
if (imageOpts) {
|
|
|
|
res.locals.imageOpts = imageOpts;
|
|
|
|
return next();
|
2018-01-01 23:54:35 +08:00
|
|
|
}
|
2015-09-23 19:04:46 +08:00
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
res.locals.imageOpts = DEFAULT_ZOOM_CENTER;
|
2017-12-31 01:02:48 +08:00
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
namedMapProvider.getAffectedTablesAndLastUpdatedTime((err, affectedTablesAndLastUpdate) => {
|
|
|
|
if (err) {
|
|
|
|
return next();
|
|
|
|
}
|
|
|
|
|
|
|
|
var affectedTables = affectedTablesAndLastUpdate.tables || [];
|
2017-12-30 22:21:20 +08:00
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
if (affectedTables.length === 0) {
|
|
|
|
return next();
|
|
|
|
}
|
2017-12-30 22:21:20 +08:00
|
|
|
|
2018-03-14 20:10:24 +08:00
|
|
|
tablesExtentApi.getBounds(user, affectedTables, (err, bounds) => {
|
2018-01-01 23:54:35 +08:00
|
|
|
if (err) {
|
2017-12-31 01:02:48 +08:00
|
|
|
return next();
|
|
|
|
}
|
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
res.locals.imageOpts = bounds;
|
2018-01-02 01:06:56 +08:00
|
|
|
|
2018-01-01 23:54:35 +08:00
|
|
|
return next();
|
2017-12-31 01:02:48 +08:00
|
|
|
});
|
|
|
|
});
|
2018-03-14 20:10:24 +08:00
|
|
|
};
|
|
|
|
}
|
2015-09-23 19:04:46 +08:00
|
|
|
|
2018-01-02 01:06:56 +08:00
|
|
|
function getImageOptions (params, template) {
|
|
|
|
const { zoom, lon, lat, bbox } = params;
|
|
|
|
|
|
|
|
let imageOpts = getImageOptionsFromCoordinates(zoom, lon, lat);
|
|
|
|
if (imageOpts) {
|
|
|
|
return imageOpts;
|
|
|
|
}
|
|
|
|
|
|
|
|
imageOpts = getImageOptionsFromBoundingBox(bbox);
|
|
|
|
if (imageOpts) {
|
|
|
|
return imageOpts;
|
|
|
|
}
|
|
|
|
|
|
|
|
imageOpts = getImageOptionsFromTemplate(template, zoom);
|
|
|
|
if (imageOpts) {
|
|
|
|
return imageOpts;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getImageOptionsFromCoordinates (zoom, lon, lat) {
|
|
|
|
if ([zoom, lon, lat].map(numMapper).every(Number.isFinite)) {
|
|
|
|
return {
|
|
|
|
zoom: zoom,
|
|
|
|
center: {
|
|
|
|
lng: lon,
|
|
|
|
lat: lat
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function getImageOptionsFromTemplate (template, zoom) {
|
|
|
|
if (template.view) {
|
|
|
|
var zoomCenter = templateZoomCenter(template.view);
|
|
|
|
if (zoomCenter) {
|
|
|
|
if (Number.isFinite(+zoom)) {
|
|
|
|
zoomCenter.zoom = +zoom;
|
|
|
|
}
|
|
|
|
|
|
|
|
return zoomCenter;
|
|
|
|
}
|
|
|
|
|
|
|
|
var bounds = templateBounds(template.view);
|
|
|
|
if (bounds) {
|
|
|
|
return bounds;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-02 17:56:45 +08:00
|
|
|
function getImageOptionsFromBoundingBox (bbox = '') {
|
|
|
|
var _bbox = bbox.split(',').map(numMapper);
|
|
|
|
|
|
|
|
if (_bbox.length === 4 && _bbox.every(Number.isFinite)) {
|
|
|
|
return {
|
|
|
|
bounds: {
|
|
|
|
west: _bbox[0],
|
|
|
|
south: _bbox[1],
|
|
|
|
east: _bbox[2],
|
|
|
|
north: _bbox[3]
|
|
|
|
}
|
|
|
|
};
|
2018-01-02 01:06:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-14 20:15:38 +08:00
|
|
|
function getImage({ previewBackend, label }) {
|
2017-12-30 22:21:20 +08:00
|
|
|
return function getImageMiddleware (req, res, next) {
|
|
|
|
const { imageOpts, namedMapProvider } = res.locals;
|
|
|
|
const { zoom, center, bounds } = imageOpts;
|
|
|
|
|
|
|
|
let { width, height } = req.params;
|
2015-09-23 19:04:46 +08:00
|
|
|
|
2017-12-30 22:21:20 +08:00
|
|
|
width = +width;
|
|
|
|
height = +height;
|
2015-09-23 19:04:46 +08:00
|
|
|
|
2017-12-30 22:21:20 +08:00
|
|
|
const format = req.params.format === 'jpg' ? 'jpeg' : 'png';
|
|
|
|
|
2017-12-31 01:18:37 +08:00
|
|
|
if (zoom !== undefined && center) {
|
2018-03-14 20:15:38 +08:00
|
|
|
return previewBackend.getImage(namedMapProvider, format, width, height, zoom, center,
|
2017-12-30 22:21:20 +08:00
|
|
|
(err, image, headers, stats) => {
|
|
|
|
if (err) {
|
2017-12-30 23:08:46 +08:00
|
|
|
err.label = label;
|
2017-12-30 22:21:20 +08:00
|
|
|
return next(err);
|
2015-09-23 19:04:46 +08:00
|
|
|
}
|
|
|
|
|
2017-12-31 00:18:12 +08:00
|
|
|
res.locals.body = image;
|
2017-12-30 22:21:20 +08:00
|
|
|
res.locals.headers = headers;
|
|
|
|
res.locals.stats = stats;
|
2015-09-23 19:04:46 +08:00
|
|
|
|
2017-12-30 22:21:20 +08:00
|
|
|
next();
|
|
|
|
});
|
2015-07-08 21:50:59 +08:00
|
|
|
}
|
2017-12-30 22:21:20 +08:00
|
|
|
|
2018-03-14 20:15:38 +08:00
|
|
|
previewBackend.getImage(namedMapProvider, format, width, height, bounds, (err, image, headers, stats) => {
|
2017-12-30 22:21:20 +08:00
|
|
|
if (err) {
|
2017-12-30 23:08:46 +08:00
|
|
|
err.label = label;
|
2017-12-30 22:21:20 +08:00
|
|
|
return next(err);
|
|
|
|
}
|
|
|
|
|
2017-12-31 00:18:12 +08:00
|
|
|
res.locals.body = image;
|
2017-12-30 22:21:20 +08:00
|
|
|
res.locals.headers = headers;
|
|
|
|
res.locals.stats = stats;
|
|
|
|
|
|
|
|
next();
|
|
|
|
});
|
2018-03-14 20:15:38 +08:00
|
|
|
};
|
|
|
|
}
|
2015-07-08 21:50:59 +08:00
|
|
|
|
2018-01-09 18:17:07 +08:00
|
|
|
function incrementMapViewsError (ctx) {
|
|
|
|
return `ERROR: failed to increment mapview count for user '${ctx.user}': ${ctx.err}`;
|
|
|
|
}
|
2017-12-30 23:04:24 +08:00
|
|
|
|
2018-03-14 20:18:37 +08:00
|
|
|
function incrementMapViews ({ metadataBackend }) {
|
2017-12-30 23:04:24 +08:00
|
|
|
return function incrementMapViewsMiddleware(req, res, next) {
|
|
|
|
const { user, namedMapProvider } = res.locals;
|
|
|
|
|
|
|
|
namedMapProvider.getMapConfig((err, mapConfig) => {
|
|
|
|
if (err) {
|
|
|
|
global.logger.log(incrementMapViewsError({ user, err }));
|
|
|
|
return next();
|
|
|
|
}
|
|
|
|
|
|
|
|
const statTag = mapConfig.obj().stat_tag;
|
|
|
|
|
2018-03-14 20:18:37 +08:00
|
|
|
metadataBackend.incMapviewCount(user, statTag, (err) => {
|
2017-12-30 23:04:24 +08:00
|
|
|
if (err) {
|
|
|
|
global.logger.log(incrementMapViewsError({ user, err }));
|
|
|
|
}
|
|
|
|
|
|
|
|
next();
|
|
|
|
});
|
|
|
|
});
|
2018-03-14 20:18:37 +08:00
|
|
|
};
|
|
|
|
}
|
2017-12-30 23:04:24 +08:00
|
|
|
|
2015-07-08 21:50:59 +08:00
|
|
|
function templateZoomCenter(view) {
|
2017-12-31 01:18:37 +08:00
|
|
|
if (view.zoom !== undefined && view.center) {
|
2015-07-08 21:50:59 +08:00
|
|
|
return {
|
|
|
|
zoom: view.zoom,
|
|
|
|
center: view.center
|
|
|
|
};
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function templateBounds(view) {
|
|
|
|
if (view.bounds) {
|
2018-01-09 18:20:20 +08:00
|
|
|
var hasAllBounds = ['west', 'south', 'east', 'north'].every(prop => Number.isFinite(view.bounds[prop]));
|
2017-12-31 01:18:37 +08:00
|
|
|
|
2015-07-08 21:50:59 +08:00
|
|
|
if (hasAllBounds) {
|
|
|
|
return {
|
|
|
|
bounds: {
|
|
|
|
west: view.bounds.west,
|
|
|
|
south: view.bounds.south,
|
|
|
|
east: view.bounds.east,
|
|
|
|
north: view.bounds.north
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2017-12-31 00:18:12 +08:00
|
|
|
|
2018-03-14 20:25:42 +08:00
|
|
|
function setSurrogateKeyHeader ({ surrogateKeysCache }) {
|
|
|
|
return function setSurrogateKeyHeaderMiddleware(req, res, next) {
|
|
|
|
const { user, namedMapProvider, affectedTablesAndLastUpdate } = res.locals;
|
2017-12-31 00:18:12 +08:00
|
|
|
|
2018-03-14 20:25:42 +08:00
|
|
|
surrogateKeysCache.tag(res, new NamedMapsCacheEntry(user, namedMapProvider.getTemplateName()));
|
2018-01-01 23:21:22 +08:00
|
|
|
if (!affectedTablesAndLastUpdate || !!affectedTablesAndLastUpdate.tables) {
|
2018-03-14 20:25:42 +08:00
|
|
|
if (affectedTablesAndLastUpdate.tables.length > 0) {
|
|
|
|
surrogateKeysCache.tag(res, affectedTablesAndLastUpdate);
|
|
|
|
}
|
2018-01-01 23:21:22 +08:00
|
|
|
}
|
2017-12-31 00:18:12 +08:00
|
|
|
|
2018-01-01 23:21:22 +08:00
|
|
|
next();
|
|
|
|
};
|
2018-03-14 20:19:56 +08:00
|
|
|
}
|
2018-01-01 23:21:22 +08:00
|
|
|
|
2018-03-14 20:25:42 +08:00
|
|
|
function setCacheChannelHeader () {
|
|
|
|
return function setCacheChannelHeaderMiddleware (req, res, next) {
|
|
|
|
const { affectedTablesAndLastUpdate } = res.locals;
|
2018-01-01 23:21:22 +08:00
|
|
|
|
|
|
|
if (!affectedTablesAndLastUpdate || !!affectedTablesAndLastUpdate.tables) {
|
2018-03-14 20:25:42 +08:00
|
|
|
res.set('X-Cache-Channel', affectedTablesAndLastUpdate.getCacheChannel());
|
2018-01-01 23:21:22 +08:00
|
|
|
}
|
2017-12-31 00:18:12 +08:00
|
|
|
|
2018-01-01 23:21:22 +08:00
|
|
|
next();
|
2018-03-14 20:25:42 +08:00
|
|
|
};
|
|
|
|
}
|
2017-12-31 00:18:12 +08:00
|
|
|
|
2018-03-14 20:27:56 +08:00
|
|
|
function setLastModifiedHeader () {
|
2018-01-01 23:21:22 +08:00
|
|
|
return function setLastModifiedHeaderMiddleware(req, res, next) {
|
|
|
|
const { affectedTablesAndLastUpdate } = res.locals;
|
2017-12-31 00:18:12 +08:00
|
|
|
|
2018-01-01 23:21:22 +08:00
|
|
|
if (!affectedTablesAndLastUpdate || !!affectedTablesAndLastUpdate.tables) {
|
|
|
|
var lastModifiedDate;
|
|
|
|
if (Number.isFinite(affectedTablesAndLastUpdate.lastUpdatedTime)) {
|
|
|
|
lastModifiedDate = new Date(affectedTablesAndLastUpdate.getLastUpdatedAt());
|
|
|
|
} else {
|
|
|
|
lastModifiedDate = new Date();
|
2017-12-31 00:18:12 +08:00
|
|
|
}
|
|
|
|
|
2018-01-01 23:21:22 +08:00
|
|
|
res.set('Last-Modified', lastModifiedDate.toUTCString());
|
|
|
|
}
|
|
|
|
|
|
|
|
next();
|
|
|
|
};
|
2018-03-14 20:27:56 +08:00
|
|
|
}
|
2018-01-01 23:21:22 +08:00
|
|
|
|
2018-03-14 20:30:27 +08:00
|
|
|
function setCacheControlHeader () {
|
2018-01-01 23:21:22 +08:00
|
|
|
return function setCacheControlHeaderMiddleware(req, res, next) {
|
|
|
|
const { affectedTablesAndLastUpdate } = res.locals;
|
|
|
|
|
|
|
|
res.set('Cache-Control', 'public,max-age=7200,must-revalidate');
|
|
|
|
|
|
|
|
if (!affectedTablesAndLastUpdate || !!affectedTablesAndLastUpdate.tables) {
|
|
|
|
// we increase cache control as we can invalidate it
|
|
|
|
res.set('Cache-Control', 'public,max-age=31536000');
|
|
|
|
}
|
|
|
|
|
|
|
|
next();
|
|
|
|
};
|
2018-03-14 20:30:27 +08:00
|
|
|
}
|
2018-01-01 23:21:22 +08:00
|
|
|
|
2018-03-14 20:31:39 +08:00
|
|
|
function setContentTypeHeader () {
|
2018-01-01 23:21:22 +08:00
|
|
|
return function setContentTypeHeaderMiddleware(req, res, next) {
|
|
|
|
const { headers = {} } = res.locals;
|
|
|
|
|
|
|
|
res.set('Content-Type', headers['content-type'] || headers['Content-Type'] || 'image/png');
|
|
|
|
|
|
|
|
next();
|
|
|
|
};
|
2018-03-14 20:31:39 +08:00
|
|
|
}
|
2017-12-31 00:18:12 +08:00
|
|
|
|
2018-03-14 20:32:43 +08:00
|
|
|
function sendResponse () {
|
|
|
|
return function sendResponseMiddleware (req, res) {
|
2017-12-31 00:18:12 +08:00
|
|
|
const { body, stats = {}, format } = res.locals;
|
|
|
|
|
|
|
|
req.profiler.done('render-' + format);
|
|
|
|
req.profiler.add(stats);
|
|
|
|
|
|
|
|
res.status(200);
|
|
|
|
res.send(body);
|
|
|
|
};
|
2018-03-14 20:32:43 +08:00
|
|
|
}
|