histograms with filters
This commit is contained in:
parent
b210ba8b22
commit
d95f044ffc
@ -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; }
|
||||
|
@ -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){
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user