Use bounding box of dataviews to select overviews level

This commit is contained in:
Javier Goizueta
2016-05-13 20:47:36 +02:00
parent 224eb392ba
commit 9d82e8c27c
4 changed files with 49 additions and 17 deletions
+5 -1
View File
@@ -136,13 +136,17 @@ DataviewBackend.prototype.getDataview = function (mapConfigProvider, user, param
);
}
}
var dataviewFactory = DataviewFactoryWithOverviews.getFactory(overviewsQueryRewriter, queryRewriteData);
if (params.bbox) {
var bboxFilter = new BBoxFilter({column: 'the_geom', srid: 4326}, {bbox: params.bbox});
query = bboxFilter.sql(query);
queryRewriteData = _.extend(queryRewriteData, { bbox_filter: bboxFilter });
}
var dataviewFactory = DataviewFactoryWithOverviews.getFactory(
overviewsQueryRewriter, queryRewriteData, { bbox: params.bbox }
);
var overrideParams = _.reduce(_.pick(params, 'start', 'end', 'bins'),
function castNumbers(overrides, val, k) {
overrides[k] = Number.isFinite(+val) ? +val : val;
@@ -1,9 +1,10 @@
var parentFactory = require('../factory');
var dataviews = require('./');
function OverviewsDataviewFactory(queryRewriter, queryRewriteData) {
function OverviewsDataviewFactory(queryRewriter, queryRewriteData, options) {
this.queryRewriter = queryRewriter;
this.queryRewriteData = queryRewriteData;
this.options = options;
}
OverviewsDataviewFactory.prototype.getDataview = function(query, dataviewDefinition) {
@@ -12,7 +13,9 @@ OverviewsDataviewFactory.prototype.getDataview = function(query, dataviewDefinit
if ( !this.queryRewriter || !this.queryRewriteData || !dataviews[type] ) {
return parentFactory.getDataview(query, dataviewDefinition);
}
return new dataviews[type](query, dataviewDefinition.options, this.queryRewriter, this.queryRewriteData);
return new dataviews[type](
query, dataviewDefinition.options, this.queryRewriter, this.queryRewriteData, this.options
);
};
var OverviewsDataviewMetaFactory = {
@@ -21,8 +24,8 @@ var OverviewsDataviewMetaFactory = {
return allDataviews;
}, {}),
getFactory: function(queryRewriter, queryRewriteData) {
return new OverviewsDataviewFactory(queryRewriter, queryRewriteData);
getFactory: function(queryRewriter, queryRewriteData, options) {
return new OverviewsDataviewFactory(queryRewriter, queryRewriteData, options);
},
};
@@ -1,3 +1,4 @@
var _ = require('underscore');
var BaseWidget = require('../base');
var BaseDataview = require('../formula');
@@ -27,13 +28,14 @@ var formulaQueryTpls = {
].join('\n')),
};
function Formula(query, options, queryRewriter, queryRewriteData) {
function Formula(query, options, queryRewriter, queryRewriteData, params) {
this.base_dataview = new BaseDataview(query, options);
this.query = query;
this.column = options.column || '1';
this.operation = options.operation;
this.queryRewriter = queryRewriter;
this.queryRewriteData = queryRewriteData;
this.options = params;
}
Formula.prototype = new BaseWidget();
@@ -41,21 +43,39 @@ Formula.prototype.constructor = Formula;
module.exports = Formula;
var zoom_level_factor = 100.0;
// Compute zoom level so that the the resolution grid size of the
// selected overview is smaller (zoom_level_factor times smaller at least)
// than the bounding box size.
function zoom_level_for_bbox(bbox) {
var px_per_tile = 256.0;
var earth_width = 360.0;
// TODO: now we assume overviews are computed for 1-pixel tolerance;
// should use extended overviews metadata to compute this properly.
if ( bbox ) {
var bbox_values = _.map(bbox.split(','), function(v) { return +v; });
// TODO: look at possible crossing-180º issues
var w = Math.abs(bbox_values[2]-bbox_values[0]);
var h = Math.abs(bbox_values[3]-bbox_values[1]);
var max_dim = Math.min(w, h);
// Find minimum suitable z
// note that the QueryRewirter will use the minimum level overview
// of level >= z if it exists, and otherwise the base table
var z = Math.ceil(-Math.log(max_dim*px_per_tile/earth_width/zoom_level_factor)/Math.log(2.0));
return Math.max(z, 0);
}
return 0;
}
Formula.prototype.sql = function(psql, filters, override, callback) {
var _query = this.query;
var formulaQueryTpl = formulaQueryTpls[this.operation];
if ( formulaQueryTpl ) {
// supported formula for use with overviews
// TODO: determine zoom level using bounding box so that the resolution
// (grid size) of the overview much smaller thatn the bounding box.
// This could be left to be computed by the queryRewriter passing the
// bounding box to it.
// The bounding box could be passed to the dataview constructor, or
// it could b extracted from the query.
var zoom_level = 0;
var zoom_level = zoom_level_for_bbox(this.options.bbox);
_query = this.queryRewriter.query(_query, this.queryRewriteData, { zoom_level: zoom_level });
var formulaSql = formulaQueryTpl({
_query: _query,
@@ -64,6 +84,7 @@ Formula.prototype.sql = function(psql, filters, override, callback) {
});
debug(formulaSql);
callback = callback || override;
return callback(null, formulaSql);
}
@@ -3,11 +3,14 @@ var TableNameParser = require('./table_name_parser');
// this is meant as a hack for development
var queryBuilder = require('camshaft/lib/filter/query-builder');
function apply_filters_to_query(query, filters) {
function apply_filters_to_query(query, filters, bbox_filter) {
// TODO: implement filter application here
if ( filters && !_.isEmpty(filters)) {
query = queryBuilder.getSql(query, filters);
}
if ( bbox_filter ) {
query = bbox_filter.sql(query);
}
return query;
}
@@ -227,6 +230,7 @@ OverviewsQueryRewriter.prototype.query = function(query, data, options) {
var overviews = data && data.overviews;
var unfiltered_query = data && data.unfiltered_query;
var filters = data && data.filters;
var bbox_filter = data && data.bbox_filter;
if ( !unfiltered_query ) {
unfiltered_query = query;
@@ -252,7 +256,7 @@ OverviewsQueryRewriter.prototype.query = function(query, data, options) {
// Applicability of the filters should depend both on the expected
// row count of the result and on the columns to be filter and the
// way they're agregated in overviews.
rewritten_query = apply_filters_to_query(rewritten_query, filters);
rewritten_query = apply_filters_to_query(rewritten_query, filters, bbox_filter);
}
return rewritten_query;