Sketch of vector overviews support
This commit is contained in:
parent
216e7b7f1d
commit
89590d32df
65
lib/cartodb/api/overviews_api.js
Normal file
65
lib/cartodb/api/overviews_api.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
var queue = require('queue-async');
|
||||||
|
var QueryTablesApi = require('./query_tables_api');
|
||||||
|
|
||||||
|
function OverviewsApi(pgQueryRunner) {
|
||||||
|
if (pgQueryRunner.pgQueryRunner != null) {
|
||||||
|
this.queryTablesApi = pgQueryRunner;
|
||||||
|
this.pgQueryRunner = this.queryTablesApi.pgQueryRunner;
|
||||||
|
} else {
|
||||||
|
this.pgQueryRunner = pgQueryRunner;
|
||||||
|
this.queryTablesApi = new QueryTablesApi(pgQueryRunner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = OverviewsApi;
|
||||||
|
|
||||||
|
OverviewsApi.prototype.getOverviewsMetadata = function (username, sql, callback) {
|
||||||
|
this.queryTablesApi.getAffectedTablesInQuery(username, sql, function(err, tableNames){
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
metadata = {};
|
||||||
|
|
||||||
|
var parallelism = 2;
|
||||||
|
var q = queue(parallelism);
|
||||||
|
|
||||||
|
for ( var i=0; i < tableNames.length; ++i ) {
|
||||||
|
(function(tableName) {
|
||||||
|
q.defer(function(done){
|
||||||
|
var sql = "SELECT * FROM CDB_Overviews('" + tableName + "');";
|
||||||
|
this.pgQueryRunner.run(username, query, handleOverviewsRows, function(err, table_metadata){
|
||||||
|
if (err) {
|
||||||
|
done(err);
|
||||||
|
} else {
|
||||||
|
metadata[tableName] = table_metadata;
|
||||||
|
done(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}(tableNames[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
q.awaitAll(function(err, results){
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
} else {
|
||||||
|
return callback(null, metadata);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleOverviewsRows(err, rows, callback) {
|
||||||
|
if (err){
|
||||||
|
var msg = err.message ? err.message : err;
|
||||||
|
callback(new Error('could not get overviews metadata: ' + msg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var metadata = {};
|
||||||
|
for ( var i=0; i<rows.length; ++i ) {
|
||||||
|
var row = rows[i];
|
||||||
|
metadata[row.z] = { table: row.overview_table };
|
||||||
|
};
|
||||||
|
callback(null, metadata);
|
||||||
|
}
|
@ -18,6 +18,8 @@ var TablesCacheEntry = require('../cache/model/database_tables_entry');
|
|||||||
var MapConfigNamedLayersAdapter = require('../models/mapconfig_named_layers_adapter');
|
var MapConfigNamedLayersAdapter = require('../models/mapconfig_named_layers_adapter');
|
||||||
var NamedMapMapConfigProvider = require('../models/mapconfig/named_map_provider');
|
var NamedMapMapConfigProvider = require('../models/mapconfig/named_map_provider');
|
||||||
var CreateLayergroupMapConfigProvider = require('../models/mapconfig/create_layergroup_provider');
|
var CreateLayergroupMapConfigProvider = require('../models/mapconfig/create_layergroup_provider');
|
||||||
|
var OverviewsApi = require('../api/overviews_api');
|
||||||
|
var MapConfigOverviewsAdapter = require('../models/mapconfig_overviews_adapter');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {AuthApi} authApi
|
* @param {AuthApi} authApi
|
||||||
@ -41,11 +43,13 @@ function MapController(authApi, pgConnection, templateMaps, mapBackend, metadata
|
|||||||
this.mapBackend = mapBackend;
|
this.mapBackend = mapBackend;
|
||||||
this.metadataBackend = metadataBackend;
|
this.metadataBackend = metadataBackend;
|
||||||
this.queryTablesApi = queryTablesApi;
|
this.queryTablesApi = queryTablesApi;
|
||||||
|
this.overviewsApi = new OverviewsApi(this.queryTablesApi);
|
||||||
this.surrogateKeysCache = surrogateKeysCache;
|
this.surrogateKeysCache = surrogateKeysCache;
|
||||||
this.userLimitsApi = userLimitsApi;
|
this.userLimitsApi = userLimitsApi;
|
||||||
this.layergroupAffectedTables = layergroupAffectedTables;
|
this.layergroupAffectedTables = layergroupAffectedTables;
|
||||||
|
|
||||||
this.namedLayersAdapter = new MapConfigNamedLayersAdapter(templateMaps);
|
this.namedLayersAdapter = new MapConfigNamedLayersAdapter(templateMaps);
|
||||||
|
this.overviewsAdapter = new MapConfigOverviewsAdapter(overviewsApi);
|
||||||
}
|
}
|
||||||
|
|
||||||
util.inherits(MapController, BaseController);
|
util.inherits(MapController, BaseController);
|
||||||
@ -148,6 +152,16 @@ MapController.prototype.create = function(req, res, prepareConfigFn) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
function addOverviewsInformation(err, requestMapConfig, datasource) {
|
||||||
|
assert.ifError(err);
|
||||||
|
var next = this;
|
||||||
|
self.overviewsAdapter.getMapConfig(req.context.user, requestMapConfig, function(err, mapconfig) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
return next(null, mapconfig, datasource);
|
||||||
|
});
|
||||||
|
},
|
||||||
function createLayergroup(err, requestMapConfig, datasource) {
|
function createLayergroup(err, requestMapConfig, datasource) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
mapConfig = new MapConfig(requestMapConfig, datasource || Datasource.EmptyDatasource());
|
mapConfig = new MapConfig(requestMapConfig, datasource || Datasource.EmptyDatasource());
|
||||||
|
40
lib/cartodb/models/mapconfig_overviews_adapter.js
Normal file
40
lib/cartodb/models/mapconfig_overviews_adapter.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
var queue = require('queue-async');
|
||||||
|
|
||||||
|
function MapConfigNamedLayersAdapter(overviewsApi) {
|
||||||
|
this.overviewsApi = overviewsApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = MapConfigNamedLayersAdapter;
|
||||||
|
|
||||||
|
MapConfigNamedLayersAdapter.prototype.getMapConfig = function(username, mapconfig, callback) {
|
||||||
|
|
||||||
|
// TODO: we're modifying mapconfig in place and then returning it... not very nice
|
||||||
|
|
||||||
|
var layers = mapconfig.getlayers();
|
||||||
|
|
||||||
|
var parallelism = 2;
|
||||||
|
var q = queue(parallelism);
|
||||||
|
|
||||||
|
for ( var i=0; i < layers.length; ++i ) {
|
||||||
|
(function(layer) {
|
||||||
|
q.defer(function(done){
|
||||||
|
this.overviewsApi.getOverviewsMetadata(username, layer.options.sql, function(err, metadata){
|
||||||
|
// TODO: is it legit to modify layer like this?
|
||||||
|
layer.options.overviews = metadata;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})(layers[i]);
|
||||||
|
};
|
||||||
|
|
||||||
|
q.awaitAll(function(err){
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
} else {
|
||||||
|
return callback(null, mapconfig);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: document in https://github.com/CartoDB/Windshaft/blob/master/doc/MapConfig-1.5.0.md
|
||||||
|
// (as OPTIONAL)
|
||||||
|
// overviews: { table_name: { zoom_level: { table: overview_table_name } }}
|
Loading…
Reference in New Issue
Block a user