Source: map/filters/builders/OGCGeoserver.js

import { AbstractBuilder } from "./AbstractBuilder.js";

export { OGCGeoserver }

/**
 * Represents a builder for constructing filter parameters for the Geoserver OGC filters.
 * @extends AbstractBuilder
 * @memberof vef.map.filters.builders
 */
class OGCGeoserver extends AbstractBuilder {

    /**
     * Returns the filter parameters for the given harmonized filters.
     * @param {Array} harmonizedFilters - The harmonized filters.
     * @returns {Object} - The filter parameters.
     */
    static getFilterParams(harmonizedFilters) {
        const filter = super.getFilterParams(harmonizedFilters);
        return (filter.length) ? { filter: `<Filter xmlns="https://www.opengis.net/ogc">${filter}</Filter>` } : {};
    }

    /**
     * Returns a "between" filter for the given property, begin, and end values.
     * @param {string} property - The property name.
     * @param {number} begin - The begin value.
     * @param {number} end - The end value.
     * @returns {string} - The "between" filter.
     */
    static bt(property, begin, end) {
        return `<And><PropertyIsGreaterThanOrEqualTo><PropertyName>${property}</PropertyName><Literal>${begin}</Literal></PropertyIsGreaterThanOrEqualTo><PropertyIsLessThanOrEqualTo><PropertyName>${property}</PropertyName><Literal>${end}</Literal></PropertyIsLessThanOrEqualTo></And>`;
    }

    /**
     * Returns an "equals" filter for the given property and value.
     * @param {string} property - The property name.
     * @param {string} value - The value.
     * @returns {string} - The "equals" filter.
     */
    static eq(property, value) {
        return `<PropertyIsEqualTo><PropertyName>${property}</PropertyName><Literal>${value}</Literal></PropertyIsEqualTo>`;
    }

    /**
     * Returns a "like" filter for the given property and value.
     * @param {string} property - The property name.
     * @param {string} value - The value.
     * @returns {string} - The "like" filter.
     */
    static like(property, value) {
        return `<PropertyIsLike wildCard="*" singleChar="#" escapeChar="!"><PropertyName>${property}</PropertyName><Literal>${value}</Literal></PropertyIsLike>`;
    }

    /**
     * Returns a "greater than" filter for the given property and value.
     * @param {string} property - The property name.
     * @param {number} value - The value.
     * @returns {string} - The "greater than" filter.
     */
    static gt(property, value) {
        return `<PropertyIsGreaterThan><PropertyName>${property}</PropertyName><Literal>${value}</Literal></PropertyIsGreaterThan>`;
    }

    /**
     * Returns a "greater than or equal to" filter for the given property and value.
     * @param {string} property - The property name.
     * @param {number} value - The value.
     * @returns {string} - The "greater than or equal to" filter.
     */
    static gteq(property, value) {
        return `<PropertyIsGreaterThanOrEqualTo><PropertyName>${property}</PropertyName><Literal>${value}</Literal></PropertyIsGreaterThanOrEqualTo>`;
    }

    /**
     * Returns a "less than" filter for the given property and value.
     * @param {string} property - The property name.
     * @param {number} value - The value.
     * @returns {string} - The "less than" filter.
     */
    static lt(property, value) {
        return `<PropertyIsLessThan><PropertyName>${property}</PropertyName><Literal>${value}</Literal></PropertyIsLess>`;
    }

    /**
     * Returns a "less than or equal to" filter for the given property and value.
     * @param {string} property - The property name.
     * @param {number} value - The value.
     * @returns {string} - The "less than or equal to" filter.
     */
    static lteq(property, value) {
        return `<PropertyIsLessThanOrEqualTo><PropertyName>${property}</PropertyName><Literal>${value}</Literal></PropertyIsLessThanOrEqualTo>`;
    }

    /**
     * Returns an intersection filter for the given boundingbox
     * @param {string} property 
     * @param {number} latMin
     * @param {number} lngMin
     * @param {number} latMax
     * @param {number} lngMax
     * @returns {string} - The "intersection"-filter.
     */
    static bbox(property, latMin, lngMin, latMax, lngMax) {
        return `<Intersects><PropertyName>${property}</PropertyName><gml:Envelope xmlns:gml="https://www.opengis.net/gml" srsName="EPSG:4326"><gml:lowerCorner>${lngMin} ${latMin}</gml:lowerCorner><gml:upperCorner>${lngMax} ${latMax}</gml:upperCorner></gml:Envelope></Intersects>`;
    }

    /**
     * Returns a "null" filter for the given property.
     * @param {string} property - The property name.
     * @returns {string} - The "null" filter.
     */
    static null(property) {
        return `<PropertyIsNull><PropertyName>${property}</PropertyName></PropertyIsNull>`;
    }

    /**
     * Returns an "or" filter for the given filters.
     * @param {Array} filters - The filters.
     * @returns {string} - The "or" filter.
     */
    static or(filters) {
        return this.join_(filters, "Or");
    }

    /**
     * Returns an "and" filter for the given filters.
     * @param {Array} filters - The filters.
     * @returns {string} - The "and" filter.
     */
    static and(filters) {
        return this.join_(filters, "And");
    }

    /**
     * Joins the given filters using the specified operator.
     * @param {Array} filters - The filters.
     * @param {string} operator - The operator ("Or" or "And").
     * @returns {string} - The joined filter.
     * @private
     */
    static join_(filters, operator) {
        if (filters.length == 0) return "";
        if (filters.length == 1) return filters[0];
        const result = filters.join("");
        return `<${operator}>${result}</${operator}>`;
    }

}