Windshaft-cartodb/lib/models/dataview/overviews/base.js

92 lines
3.2 KiB
JavaScript

'use strict';
var _ = require('underscore');
var BaseDataview = require('../base');
function BaseOverviewsDataview (query, queryOptions, BaseDataview, queryRewriter, queryRewriteData, options, queries) {
this.BaseDataview = BaseDataview;
this.query = query;
this.queryOptions = queryOptions;
this.queryRewriter = queryRewriter;
this.queryRewriteData = queryRewriteData;
this.options = options;
this.queries = queries;
this.baseDataview = new this.BaseDataview(this.query, this.queryOptions, this.queries);
}
module.exports = BaseOverviewsDataview;
BaseOverviewsDataview.prototype = new BaseDataview();
BaseOverviewsDataview.prototype.constructor = BaseOverviewsDataview;
// TODO: parameterized these settings
var SETTINGS = {
// use overviews as a default fallback strategy
defaultOverviews: false,
// minimum ratio of bounding box size to grid size
// (this would ideally be based on the viewport size in pixels)
zoomLevelFactor: 1024.0
};
// Compute zoom level so that the the resolution grid size of the
// selected overview is smaller (zoomLevelFactor times smaller at least)
// than the bounding box size.
BaseOverviewsDataview.prototype.zoomLevelForBbox = function (bbox) {
var pxPerTile = 256.0;
var earthWidth = 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 bboxValues = _.map(bbox.split(','), function (v) { return +v; });
var w = Math.abs(bboxValues[2] - bboxValues[0]);
var h = Math.abs(bboxValues[3] - bboxValues[1]);
var maxDim = 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(maxDim * pxPerTile / earthWidth / SETTINGS.zoomLevelFactor) / Math.log(2.0));
return Math.max(z, 0);
}
return 0;
};
BaseOverviewsDataview.prototype.rewrittenQuery = function (query) {
var zoomLevel = this.zoomLevelForBbox(this.options.bbox);
return this.queryRewriter.query(query, this.queryRewriteData, { zoom_level: zoomLevel });
};
// Default behaviour
BaseOverviewsDataview.prototype.defaultSql = function (psql, override, callback) {
var query = this.query;
var dataview = this.baseDataview;
if (SETTINGS.defaultOverviews) {
query = this.rewrittenQuery(query);
dataview = new this.BaseDataview(query, this.queryOptions);
}
return dataview.sql(psql, override, callback);
};
// default implementation that can be override in derived classes:
BaseOverviewsDataview.prototype.sql = function (psql, override, callback) {
return this.defaultSql(psql, override, callback);
};
BaseOverviewsDataview.prototype.search = function (psql, userQuery, callback) {
return this.baseDataview.search(psql, userQuery, callback);
};
BaseOverviewsDataview.prototype.format = function (result) {
return this.baseDataview.format(result);
};
BaseOverviewsDataview.prototype.getType = function () {
return this.baseDataview.getType();
};
BaseOverviewsDataview.prototype.toString = function () {
return this.baseDataview.toString();
};