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();
}
Aggregations