Search in sources :

Example 1 with Literal

use of org.apache.sis.internal.geoapi.filter.Literal in project sis by apache.

the class BinaryGeometryFilter method optimize.

/**
 * Tries to optimize this filter. This method checks if any expression is a literal.
 * If both expressions are literal, we can evaluate immediately. If any expression
 * is a literal and returns {@code null}, then the result is known in advance too.
 */
@Override
public final Filter<? super R> optimize(final Optimization optimization) {
    Expression<? super R, ?> geometry1 = unwrap(expression1);
    Expression<? super R, ?> geometry2 = unwrap(expression2);
    Expression<? super R, ?> effective1 = optimization.apply(geometry1);
    Expression<? super R, ?> effective2 = optimization.apply(geometry2);
    // The expression which is not literal.
    Expression<? super R, ?> other;
    Expression<? super R, GeometryWrapper<G>> wrapper;
    Literal<? super R, ?> literal;
    // true if the filter should be evaluated immediately.
    boolean immediate;
    // true if one of the literal value is null.
    boolean literalIsNull;
    if (effective2 instanceof Literal<?, ?>) {
        other = effective1;
        wrapper = expression2;
        literal = (Literal<? super R, ?>) effective2;
        immediate = (effective1 instanceof Literal<?, ?>);
    } else if (effective1 instanceof Literal<?, ?>) {
        other = effective2;
        wrapper = expression1;
        literal = (Literal<? super R, ?>) effective1;
        immediate = false;
    } else {
        return this;
    }
    literalIsNull = (literal.getValue() == null);
    final boolean result;
    if (literalIsNull) {
        // If the literal has no value, then the filter will always evaluate to a negative result.
        result = negativeResult();
    } else {
        /*
             * If we are optimizing for a feature type, and if the other expression is a property value,
             * then try to fetch the CRS of the property values. If we can transform the literal to that
             * CRS, do it now in order to avoid doing this transformation for all feature instances.
             */
        final DefaultFeatureType featureType = optimization.getFeatureType();
        if (featureType != null && other instanceof ValueReference<?, ?>)
            try {
                final CoordinateReferenceSystem targetCRS = AttributeConvention.getCRSCharacteristic(featureType, featureType.getProperty(((ValueReference<?, ?>) other).getXPath()));
                if (targetCRS != null) {
                    final GeometryWrapper<G> geometry = wrapper.apply(null);
                    final GeometryWrapper<G> transformed = geometry.transform(targetCRS);
                    if (geometry != transformed) {
                        literal = (Literal<? super R, ?>) Optimization.literal(transformed);
                        if (literal == effective1)
                            effective1 = literal;
                        else
                            effective2 = literal;
                    }
                }
            } catch (IllegalArgumentException | TransformException e) {
                warning(e, true);
            }
        /*
             * If one of the "effective" parameter has been modified, recreate a new filter.
             * If all operands are literal, we can evaluate that filter immediately.
             */
        Filter<? super R> filter = this;
        if ((effective1 != geometry1) || (effective2 != geometry2)) {
            filter = recreate(effective1, effective2);
        }
        if (!immediate) {
            return filter;
        }
        result = filter.test(null);
    }
    return result ? Filter.include() : Filter.exclude();
}
Also used : DefaultFeatureType(org.apache.sis.feature.DefaultFeatureType) Literal(org.apache.sis.internal.geoapi.filter.Literal) GeometryWrapper(org.apache.sis.internal.feature.GeometryWrapper) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem)

Aggregations

DefaultFeatureType (org.apache.sis.feature.DefaultFeatureType)1 GeometryWrapper (org.apache.sis.internal.feature.GeometryWrapper)1 Literal (org.apache.sis.internal.geoapi.filter.Literal)1 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)1