histograms with filters

This commit is contained in:
javi 2015-11-18 11:05:04 +01:00
parent b210ba8b22
commit d95f044ffc
3 changed files with 119 additions and 33 deletions

View File

@ -17,6 +17,31 @@ L.Mixin.TileLoader = {
this._removeTiles();
},
visibleTiles: function() {
if (!this._map) { return []; }
var j, i, point, tiles = [];
var bounds = this._map.getPixelBounds(),
zoom = this._map.getZoom(),
tileSize = this.options.tileSize;
var nwTilePoint = new L.Point(
Math.floor(bounds.min.x / tileSize),
Math.floor(bounds.min.y / tileSize)),
seTilePoint = new L.Point(
Math.floor(bounds.max.x / tileSize),
Math.floor(bounds.max.y / tileSize)),
tileBounds = new L.Bounds(nwTilePoint, seTilePoint);
for (j = tileBounds.min.y; j <= tileBounds.max.y; j++) {
for (i = tileBounds.min.x; i <= tileBounds.max.x; i++) {
tiles.push({ x: i, y: j, z: zoom });
}
}
return tiles;
},
_updateTiles: function () {
if (!this._map) { return; }

View File

@ -212,24 +212,9 @@ L.TorqueLayer = L.CanvasLayer.extend({
}
},
getHistogramForVisibleRegion: function(varName, callback){
var tiles= []
for(var key in this._tiles){
if (this._tiles[key]) {
tiles.push(this._tiles[key].coord)
}
}
var tilesFilter = this.provider._generateBoundsQuery(tiles);
this.provider.tablesForFilter(tilesFilter, function(tables) {
// select the table with less than 100k records
var table = tables.filter(function(f) {
return f.nrows < 50000;
})
table = table.length ? table[0].table_name: this.options.overview_tables[this.options.overview_tables.length - 1]
this.provider.getHistogramForTiles(varName, tiles, table, callback)
}.bind(this));
getHistogramForVisibleRegion: function(varName, start, end, bins, callback){
var tiles = this.visibleTiles();
this.provider.getHistogramForTiles(varName, start, end, bins, tiles, callback);
},
getHistogram:function(variable,callback,noBins){

View File

@ -439,7 +439,6 @@ var Profiler = require('../profiler');
sql = sql.join(' ')
var query = format(sql,{
x: tile.x,
y: tile.y,
@ -453,11 +452,11 @@ var Profiler = require('../profiler');
})
this.sql(query,function(data){
if(data) {
if (data) {
var rows = JSON.parse(data.responseText).rows;
callback(rows)
}
else{
else {
callback(null)
}
})
@ -618,18 +617,48 @@ var Profiler = require('../profiler');
}).join(" or ")
},
getHistogramForTiles: function(varName, tiles, table, callback){
getHistogramForTiles: function(varName, start, end, bins, tiles, callback) {
var tilesFilter = this._generateBoundsQuery(tiles);
this.tablesForFilter(tilesFilter, function(tables) {
// select the table with less than 100k records
var table = tables.filter(function(f) {
return f.nrows < 50000;
})
table = table.length ? table[0].table_name: this.options.overview_tables[this.options.overview_tables.length - 1]
this._getHistogramForTiles(varName, start, end, bins, tiles, table, callback)
}.bind(this));
},
_getHistogramForTiles: function(varName, start, end, bins, tiles, table, callback){
var sql = [
'with source as (',
'select {varName} from {table} where ({bounds}) {filters}',
'),',
'width as (',
'select min({varName}) as min,',
'max({varName}) as max,',
'{bins} as buckets',
'from source',
'),',
'select {varName} from {table} {tiles} where {bounds} {filters}',
'),'
]
if (start !== undefined) {
sql = sql.concat([
'width as (',
'select {start} as min,',
'{end} as max,',
'{bins} as buckets',
'),'
])
} else {
start = start === undefined ? 'min(' + varName + ')': start;
end = end === undefined ? 'max(' + varName + ')': end;
bins = bins === undefined ? 100: bins;
sql = sql.concat([
'width as (',
'select {start} as min,',
'{end} as max,',
'{bins} as buckets',
'from source',
'),'
])
}
sql = sql.concat([
'_bw as ( select (max - min)/buckets as bw from width ),',
'histogram as (',
'select width_bucket({varName}, min, max, buckets) as bucket,',
@ -640,16 +669,35 @@ var Profiler = require('../profiler');
'order by bucket',
')',
'select bucket*bw as start, (bucket+1)*bw as end, bucket as bin, lower(range) as min, upper(range) as max, freq from histogram, _bw;'
]
]);
var filters = this._generateFiltersSQL(false, [varName]) ? " and "+ this._generateFiltersSQL(false, [varName]) : ""
var tiles_query = tiles.map(function (t, i) {
return "xyz2range(" + t.x + "," + t.y + "," + t.z + ") q" + i;
}).join(',')
if (tiles_query) {
tiles_query = "," + tiles_query
}
var bounds = tiles.map(function(t, i) {
return format("(quadkey between q{i}.min and q{i}.max)", { i: i })
}).join('or')
if (bounds) {
bounds = '(' + bounds + ')';
}
var query = format(sql.join('\n'), {
varName: varName,
table: table,
tiles: tiles_query,
filters: filters,
bounds: this._generateBoundsQuery(tiles),
bins: 20
bounds: bounds,
bins: bins,
start: start,
end: end
});
var self = this;
@ -663,6 +711,34 @@ var Profiler = require('../profiler');
});
},
getCatHistogramForTiles: function(varName, tiles, table, callback){
var sql = [
'select {varName}, count(1) from {table} where ({bounds}) {filters} group by 1 order by 2 desc limit {num_cats}',
]
var filters = this._generateFiltersSQL(false, [varName]) ? " and "+ this._generateFiltersSQL(false, [varName]) : ""
var query = format(sql.join('\n'), {
varName: varName,
table: table,
filters: filters,
bounds: this._generateBoundsQuery(tiles),
num_cats: 20
});
var self = this;
this.sql(query, function (data) {
if (data) {
var rows = JSON.parse(data.responseText).rows;
callback(rows);
} else {
callback(null);
}
});
},
tablesForFilter: function(filter, callback) {
var filters = this._generateFiltersSQL()
if (filters) {