e9a4fc4b2c
Sampling is performed only when placement, columns or dimensions are specified; otherwise the regular centroid/grid-point/grid-center is used without sampling.
122 lines
3.6 KiB
JavaScript
122 lines
3.6 KiB
JavaScript
const MapConfig = require('windshaft').model.MapConfig;
|
|
const aggregationQuery = require('./aggregation-query');
|
|
const aggregationValidator = require('./aggregation-validator');
|
|
const {
|
|
createPositiveNumberValidator,
|
|
createIncludesValueValidator,
|
|
createAggregationColumnsValidator
|
|
} = aggregationValidator;
|
|
|
|
module.exports = class AggregationMapConfig extends MapConfig {
|
|
static get AGGREGATIONS () {
|
|
return aggregationQuery.SUPPORTED_AGGREGATE_FUNCTIONS;
|
|
}
|
|
|
|
static get PLACEMENTS () {
|
|
return aggregationQuery.SUPPORTED_PLACEMENTS;
|
|
}
|
|
|
|
static get THRESHOLD () {
|
|
return 1e5; // 100K
|
|
}
|
|
|
|
static get RESOLUTION () {
|
|
return 1;
|
|
}
|
|
|
|
static get SUPPORTED_GEOMETRY_TYPES () {
|
|
return [
|
|
'ST_Point'
|
|
];
|
|
}
|
|
|
|
static supportsGeometryType(geometryType) {
|
|
return AggregationMapConfig.SUPPORTED_GEOMETRY_TYPES.includes(geometryType);
|
|
}
|
|
|
|
constructor (config, datasource) {
|
|
super(config, datasource);
|
|
|
|
const validate = aggregationValidator(this);
|
|
const positiveNumberValidator = createPositiveNumberValidator(this);
|
|
const includesValidPlacementsValidator = createIncludesValueValidator(this, AggregationMapConfig.PLACEMENTS);
|
|
const aggregationColumnsValidator = createAggregationColumnsValidator(this, AggregationMapConfig.AGGREGATIONS);
|
|
|
|
validate('resolution', positiveNumberValidator);
|
|
validate('placement', includesValidPlacementsValidator);
|
|
validate('threshold', positiveNumberValidator);
|
|
validate('columns', aggregationColumnsValidator);
|
|
}
|
|
|
|
getAggregatedQuery (index) {
|
|
const { sql_raw, sql } = this.getLayer(index).options;
|
|
const {
|
|
// The default aggregation has no placement, columns or dimensions;
|
|
// this enables the special "full-sample" aggregation.
|
|
resolution = AggregationMapConfig.RESOLUTION,
|
|
threshold = AggregationMapConfig.THRESHOLD,
|
|
placement = null,
|
|
columns = {},
|
|
dimensions = {}
|
|
} = this.getAggregation(index);
|
|
|
|
return aggregationQuery({
|
|
query: sql_raw || sql,
|
|
resolution,
|
|
threshold,
|
|
placement,
|
|
columns,
|
|
dimensions
|
|
});
|
|
}
|
|
|
|
isAggregationMapConfig () {
|
|
return this.isVectorOnlyMapConfig() || this.hasAnyLayerAggregation();
|
|
}
|
|
|
|
isAggregationLayer (index) {
|
|
return this.isVectorOnlyMapConfig() || this.hasLayerAggregation(index);
|
|
}
|
|
|
|
hasAnyLayerAggregation () {
|
|
const layers = this.getLayers();
|
|
|
|
for (let index = 0; index < layers.length; index++) {
|
|
if (this.hasLayerAggregation(index)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
hasLayerAggregation (index) {
|
|
const layer = this.getLayer(index);
|
|
const { aggregation } = layer.options;
|
|
|
|
return aggregation !== undefined && (typeof aggregation === 'object' || typeof aggregation === 'boolean');
|
|
}
|
|
|
|
getAggregation (index) {
|
|
if (!this.hasLayerAggregation(index)) {
|
|
return;
|
|
}
|
|
|
|
const { aggregation } = this.getLayer(index).options;
|
|
|
|
if (typeof aggregation === 'boolean') {
|
|
return {};
|
|
}
|
|
|
|
return aggregation;
|
|
}
|
|
|
|
doesLayerReachThreshold(index, featureCount) {
|
|
const threshold = this.getAggregation(index) && this.getAggregation(index).threshold ?
|
|
this.getAggregation(index).threshold :
|
|
AggregationMapConfig.THRESHOLD;
|
|
|
|
return featureCount >= threshold;
|
|
}
|
|
};
|