@geogirafe/lib-geoportal
Version:
GeoGirafe is a flexible application to build online geoportals.
76 lines (75 loc) • 3.24 kB
JavaScript
// SPDX-License-Identifier: Apache-2.0
import { and, not, or } from 'ol/format/filter.js';
import WfsFilterCondition from './wfsfiltercondition.js';
/**
* Represents a WFS filter expression consisting of one or more conditions chained with a logical operator (`and` or `or`).
* Filters can be nested to form a more complex filter expression, e.g.:
* condition 1 and (condition2 or condition3)
*/
export default class WfsFilter {
conditions;
logicalOperator;
constructor(conditions, logicalOperator) {
this.conditions = conditions;
this.logicalOperator = logicalOperator;
this.checkValidParameters();
}
checkValidParameters() {
if (this.conditions.length > 1 && !this.logicalOperator) {
throw new Error('Logical Operator is required when more than one filter condition is provided');
}
}
/**
* Checks if the filter is simple, meaning it has only one condition and no logical operator.
* Simple filters can be displayed in the `QueryBuilderComponent` (layer tree filter).
*/
isSimpleFilter() {
return (this.conditions.length === 1 &&
!this.logicalOperator &&
this.conditions[0] instanceof WfsFilterCondition &&
this.conditions[0].isSimpleCondition);
}
isAdvancedFilter() {
return !this.isSimpleFilter();
}
toOpenLayersFilter() {
const olFilters = this.conditions.flatMap((filter) => WfsFilter.toOpenLayersFilterRecursively(filter));
return WfsFilter.toChainedOpenLayersFilter(olFilters, this.logicalOperator);
}
static toOpenLayersFilterRecursively(filter) {
if (filter instanceof WfsFilter) {
const olSubFilters = filter.conditions.flatMap((subFilter) => WfsFilter.toOpenLayersFilterRecursively(subFilter));
const chainedFilter = WfsFilter.toChainedOpenLayersFilter(olSubFilters, filter.logicalOperator);
return chainedFilter ? [chainedFilter] : [];
}
const olFilter = filter.toOpenLayersFilter();
return olFilter ? [olFilter] : [];
}
static toChainedOpenLayersFilter(olFilters, operator) {
if (olFilters.length === 0)
return;
if (olFilters.length === 1 && operator === 'not')
return not(olFilters[0]);
if (olFilters.length === 1 || !operator)
return olFilters[0];
if (operator === 'and') {
return and(...olFilters);
}
else if (operator === 'or') {
return or(...olFilters);
}
return undefined;
}
toWmsGetMapFilter() {
if (this.conditions.length === 0)
return '';
if (this.conditions.length === 1 && this.logicalOperator === 'not') {
return WfsFilterCondition.buildNestedExpression([this.conditions[0].toWmsGetMapFilter()], this.logicalOperator);
}
if (this.conditions.length === 1 || !this.logicalOperator) {
return this.conditions[0].toWmsGetMapFilter();
}
const filterStrings = this.conditions.map((f) => f.toWmsGetMapFilter()).filter((s) => s !== '');
return WfsFilterCondition.buildNestedExpression(filterStrings, this.logicalOperator);
}
}