use of org.apache.sis.filter.Optimization in project sis by apache.
the class RegistryTestCase method testFeatureOptimization.
/**
* Tests {@link Optimization} on an arbitrary expression on feature instances.
*/
@Test
public void testFeatureOptimization() {
geometry = library.createPoint(10, 30);
setGeometryCRS(HardCodedCRS.WGS84_LATITUDE_FIRST);
function = factory.function("ST_Union", factory.property(P_NAME), factory.literal(geometry));
final Optimization optimization = new Optimization();
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
ftb.addAttribute(library.pointClass).setName(P_NAME).setCRS(HardCodedCRS.WGS84);
optimization.setFeatureType(ftb.setName("Test").build());
final Expression<? super AbstractFeature, ?> optimized = optimization.apply(function);
assertNotSame("Optimization should produce a new expression.", function, optimized);
/*
* Get the second parameter, which should be a literal, and get the point coordinates.
* Verify that the order is swapped compared to the order at the beginning of this method.
*/
final Object literal = optimized.getParameters().get(1).apply(null);
final DirectPosition point = library.castOrWrap(literal).getCentroid();
assertArrayEquals(new double[] { 30, 10 }, point.getCoordinate(), STRICT);
}
use of org.apache.sis.filter.Optimization in project sis by apache.
the class FeatureStream method filter.
/**
* Returns a stream with features of this stream that match the given predicate.
* If the given predicate is an instance of {@link Filter}, then this method tries
* to express the filter using SQL statements.
*/
@Override
public Stream<AbstractFeature> filter(final Predicate<? super AbstractFeature> predicate) {
ArgumentChecks.ensureNonNull("predicate", predicate);
if (predicate == Filter.include())
return this;
if (predicate == Filter.exclude())
return empty();
if (isPagined()) {
/*
* Offset/limit executed before the filter. Can not continue to build an SQL statement
* because the SQL `OFFSET ... FETCH NEXT` clause would be executed after the filter.
*/
return delegate().filter(predicate);
}
if (!(predicate instanceof Filter<?>)) {
hasPredicates = true;
return super.filter(predicate);
}
if (selection == null) {
selection = new SelectionClause(table);
filterToSQL = table.database.getFilterToSupportedSQL();
}
/*
* Simplify/optimize the filter (it may cause `include` or `exclude` filters to emerge) and try
* to convert the filter to SQL statements. This is not necessarily an all or nothing operation:
* if we have a "F₀ AND F₁ AND F₂" chain, it is possible to have some Fₙ as SQL statements and
* other Fₙ executed in Java code.
*/
final Optimization optimization = new Optimization();
optimization.setFeatureType(table.featureType);
Stream<AbstractFeature> stream = this;
for (final Filter<? super AbstractFeature> filter : optimization.applyAndDecompose((Filter<? super AbstractFeature>) predicate)) {
if (filter == Filter.include())
continue;
if (filter == Filter.exclude())
return empty();
if (!selection.tryAppend(filterToSQL, filter)) {
// Delegate to Java code all filters that we can not translate to SQL statement.
stream = super.filter(filter);
hasPredicates = true;
}
}
return stream;
}
use of org.apache.sis.filter.Optimization in project sis by apache.
the class RegistryTestCase method testOptimization.
/**
* Tests {@link Optimization} on an arbitrary expression.
* This method uses data tested by {@link #testTransform()}.
*/
@Test
public void testOptimization() {
geometry = library.createPoint(10, 30);
setGeometryCRS(HardCodedCRS.WGS84);
function = factory.function("ST_Transform", factory.literal(geometry), factory.literal(HardCodedCRS.WGS84_LATITUDE_FIRST));
assertPointEquals(function.apply(null), HardCodedCRS.WGS84_LATITUDE_FIRST, 30, 10);
/*
* Optimization should evaluate the point immediately.
*/
final Expression<? super AbstractFeature, ?> optimized = new Optimization().apply(function);
assertNotSame("Optimization should produce a new expression.", function, optimized);
assertInstanceOf("Expected immediate expression evaluation.", Literal.class, optimized);
assertPointEquals(((Literal) optimized).getValue(), HardCodedCRS.WGS84_LATITUDE_FIRST, 30, 10);
}
use of org.apache.sis.filter.Optimization in project sis by apache.
the class SelectionClauseWriterTest method testGeometricFilterWithTransform.
/**
* Verifies that a spatial operator transforms literal value before-hand if possible.
*/
private void testGeometricFilterWithTransform() {
final GeneralEnvelope bbox = new GeneralEnvelope(HardCodedCRS.WGS84_LATITUDE_FIRST);
bbox.setEnvelope(-10, 20, -5, 25);
Filter<AbstractFeature> filter = FF.intersects(FF.property("BETA"), FF.literal(bbox));
final Optimization optimization = new Optimization();
optimization.setFeatureType(table.featureType);
verifySQL(optimization.apply(filter), "ST_Intersects(\"BETA\", " + "ST_GeomFromText('POLYGON ((20 -10, 25 -10, 25 -5, 20 -5, 20 -10))'))");
}
use of org.apache.sis.filter.Optimization in project sis by apache.
the class FeatureQuery method execute.
/**
* Applies this query on the given feature set.
* This method is invoked by the default implementation of {@link FeatureSet#subset(Query)}.
* The default implementation executes the query using the default {@link java.util.stream.Stream} methods.
* Queries executed by this method may not benefit from accelerations provided for example by databases.
* This method should be used only as a fallback when the query can not be executed natively
* by {@link FeatureSet#subset(Query)}.
*
* <p>The returned {@code FeatureSet} does not cache the resulting {@code Feature} instances;
* the query is processed on every call to the {@link FeatureSet#features(boolean)} method.</p>
*
* @param source the set of features to filter, sort or process.
* @return a view over the given feature set containing only the filtered feature instances.
* @throws DataStoreException if an error occurred during creation of the subset.
*
* @see FeatureSet#subset(Query)
* @see CoverageQuery#execute(GridCoverageResource)
*
* @since 1.2
*/
protected FeatureSet execute(final FeatureSet source) throws DataStoreException {
ArgumentChecks.ensureNonNull("source", source);
final FeatureQuery query = clone();
if (query.selection != null) {
final Optimization optimization = new Optimization();
optimization.setFeatureType(source.getType());
query.selection = optimization.apply(query.selection);
}
return new FeatureSubset(source, query);
}
Aggregations