histograms with filters
This commit is contained in:
parent
b210ba8b22
commit
d95f044ffc
@ -17,6 +17,31 @@ L.Mixin.TileLoader = {
|
|||||||
this._removeTiles();
|
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 () {
|
_updateTiles: function () {
|
||||||
|
|
||||||
if (!this._map) { return; }
|
if (!this._map) { return; }
|
||||||
|
@ -212,24 +212,9 @@ L.TorqueLayer = L.CanvasLayer.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getHistogramForVisibleRegion: function(varName, callback){
|
getHistogramForVisibleRegion: function(varName, start, end, bins, callback){
|
||||||
var tiles= []
|
var tiles = this.visibleTiles();
|
||||||
for(var key in this._tiles){
|
this.provider.getHistogramForTiles(varName, start, end, bins, tiles, callback);
|
||||||
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));
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getHistogram:function(variable,callback,noBins){
|
getHistogram:function(variable,callback,noBins){
|
||||||
|
@ -439,7 +439,6 @@ var Profiler = require('../profiler');
|
|||||||
|
|
||||||
sql = sql.join(' ')
|
sql = sql.join(' ')
|
||||||
|
|
||||||
|
|
||||||
var query = format(sql,{
|
var query = format(sql,{
|
||||||
x: tile.x,
|
x: tile.x,
|
||||||
y: tile.y,
|
y: tile.y,
|
||||||
@ -618,18 +617,48 @@ var Profiler = require('../profiler');
|
|||||||
}).join(" or ")
|
}).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 = [
|
var sql = [
|
||||||
'with source as (',
|
'with source as (',
|
||||||
'select {varName} from {table} where ({bounds}) {filters}',
|
'select {varName} from {table} {tiles} where {bounds} {filters}',
|
||||||
'),',
|
'),'
|
||||||
|
]
|
||||||
|
if (start !== undefined) {
|
||||||
|
sql = sql.concat([
|
||||||
'width as (',
|
'width as (',
|
||||||
'select min({varName}) as min,',
|
'select {start} as min,',
|
||||||
'max({varName}) as max,',
|
'{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',
|
'{bins} as buckets',
|
||||||
'from source',
|
'from source',
|
||||||
'),',
|
'),'
|
||||||
|
])
|
||||||
|
}
|
||||||
|
sql = sql.concat([
|
||||||
'_bw as ( select (max - min)/buckets as bw from width ),',
|
'_bw as ( select (max - min)/buckets as bw from width ),',
|
||||||
'histogram as (',
|
'histogram as (',
|
||||||
'select width_bucket({varName}, min, max, buckets) as bucket,',
|
'select width_bucket({varName}, min, max, buckets) as bucket,',
|
||||||
@ -640,16 +669,35 @@ var Profiler = require('../profiler');
|
|||||||
'order by bucket',
|
'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;'
|
'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 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'), {
|
var query = format(sql.join('\n'), {
|
||||||
varName: varName,
|
varName: varName,
|
||||||
table: table,
|
table: table,
|
||||||
|
tiles: tiles_query,
|
||||||
filters: filters,
|
filters: filters,
|
||||||
bounds: this._generateBoundsQuery(tiles),
|
bounds: bounds,
|
||||||
bins: 20
|
bins: bins,
|
||||||
|
start: start,
|
||||||
|
end: end
|
||||||
});
|
});
|
||||||
|
|
||||||
var self = this;
|
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) {
|
tablesForFilter: function(filter, callback) {
|
||||||
var filters = this._generateFiltersSQL()
|
var filters = this._generateFiltersSQL()
|
||||||
if (filters) {
|
if (filters) {
|
||||||
|
Loading…
Reference in New Issue
Block a user