This quick start offers examples of the most common use cases for working with filters. For more detail about the concepts and API, see The OGC Filter Model.
Creating or decoding a filter
Creating a filter
You can create filters using the classes in the com.luciad.ogc.filter.model
package.
For example:
//The code uses a static import to have easy access to the static methods from that class
//import static com.luciad.ogc.filter.model.TLcdOGCFilterFactory.*;
ILcdOGCCondition condition = eq(property("roadType"), literal("highway"));
TLcdOGCFilter filter = new TLcdOGCFilter(condition);
This results in a TLcdOGCFilter
, which is the Java representation of an OGC filter.
Decoding a filter
Often filters are encoded in the XML format. For decoding purposes, you can convert the XML to an TLcdOGCFilter
using the TLcdOGCFilterDecoder
.
TLcdOGCFilterDecoder decoder = new TLcdOGCFilterDecoder();
TLcdOGCFilter filter = (TLcdOGCFilter) decoder.decode(filterSourceName);
return filter;
When the filter XML is in a String
or an InputStream
rather than a file, you can use the static factory methods on TLcdOGCFilterDecoder
:
String
String filterAsXML = ...;
TLcdOGCFilter filter = TLcdOGCFilterDecoder.decodeFromString(filterAsXML);
If the filter XML is not stored in a file, you can either decode directly from an InputStream
or use the static utility method to decode directly from a String
.
For example
InputStream
try(InputStream is = createInputStream()){
TLcdOGCFilter filter = (TLcdOGCFilter) new TLcdOGCFilterDecoder().decode(is);
}
Evaluating a filter
The TLcdOGCFilter
instance contains the definition of the filter only. It cannot be evaluated without extra information.
During the evaluation of an OGC filter, the following functionality is needed:
-
An
ILcdPropertyRetriever
: typical OGC filters compare the value of a property of a domain object with a certain value (for exampleproperty(roadType) == "highWay"
). The retrieval of the property value from the domain object is delegated to this interface. -
An
ILcdOGCFeatureIDRetriever
: if the OGC filter is based on the ID of the objects, the filter delegates the retrieval of the ID to this interface. -
A default
ILcdGeoReference
: this reference is used when the filter contains geometries which are defined without a georeference. The filter assumes that such geometries are defined in that default georeference.
By providing this information it is possible to convert the TLcdOGCFilter
to an ILcdFilter
instance that can be evaluated:
ILcdOGCCondition condition = ...;
TLcdOGCFilter ogcFilter = new TLcdOGCFilter(condition);
TLcdOGCFilterEvaluator evaluator = new TLcdOGCFilterEvaluator();
ILcdFilter filter = evaluator.buildFilter(ogcFilter, new TLcdOGCFilterContext());
Object toEvaluate = ...;
boolean accepted = filter.accept(toEvaluate);
In the code above, default retrievers are used and no custom functions are supported. This works in most cases.
If you don’t need to configure the filter evaluator, you can convert an OGC filter directly into an ILcdFilter
as follows:
ILcdOGCCondition condition = ...;
TLcdOGCFilter ogcFilter = new TLcdOGCFilter(condition);
ILcdFilter filter = ogcFilter.asPredicate(new TLcdOGCFilterContext());
Object toEvaluate = ...;
boolean accepted = filter.accept(toEvaluate);
Supporting custom OGC functions
OGC filter expressions can contain a number of pre-defined operations or filter functions: comparison operations spatial operations, and so on. If you have a need for custom operations, you can define your own filter functions in addition to the pre-defined OGC filter operations.
Supporting custom functions through the whole application
If you have custom functions, and you want to support them throughout the application, you can register them globally so that
they become available to all TLcdOGCFilterEvaluator
instances.
This is done by calling the static TLcdOGCFilterEvaluator.registerDefaultFunction
method.
An example use case for this is a WFS server, where you want to support the custom function for all incoming requests.
//At the start of the application
TLcdXMLName customFunctionName = ...;
ILcdEvaluatorFunction customFunction = ...;
TLcdOGCFilterEvaluator.registerDefaultFunction(customFunctionName, customFunction);
//...
//Later on in the application
ILcdOGCCondition condition = ...;
TLcdOGCFilter ogcFilter = new TLcdOGCFilter(condition);
//This evaluator will support the custom function registered at the start of the application
TLcdOGCFilterEvaluator evaluator = new TLcdOGCFilterEvaluator();
ILcdFilter filter = evaluator.buildFilter(ogcFilter, new TLcdOGCFilterContext());
Object toEvaluate = ...;
boolean accepted = filter.accept(toEvaluate);
Program: Registering a custom function shows an example implementation of a custom ILcdEvaluatorFunction
.
Supporting custom functions in a single evaluator
You can add support for custom functions by registering them on the evaluator instance using the TLcdOGCFilterEvaluator.registerFunction
method.
Note that the custom function will only be supported in that specific evaluator.
ILcdOGCCondition condition = ...;
TLcdOGCFilter ogcFilter = new TLcdOGCFilter(condition);
TLcdOGCFilterEvaluator evaluator = new TLcdOGCFilterEvaluator();
//register the custom function on the evaluator
TLcdXMLName customFunctionName = ...;
ILcdEvaluatorFunction customFunction = ...;
evaluator.registerFunction(customFunctionName, customFunction);
//The evaluation of the filter is identical as without custom functions
ILcdFilter filter = evaluator.buildFilter(ogcFilter, new TLcdOGCFilterContext());
Object toEvaluate = ...;
boolean accepted = filter.accept(toEvaluate);
Program: Registering a custom function shows an example implementation of a custom ILcdEvaluatorFunction
.
Example of a custom function
Program: Registering a custom function shows an example of a custom function implementation, in which a string is converted to upper case.
samples/ogc/filter/xml/MainPanel
)
ILcdEvaluatorFunction toUpperCaseFunction = new ILcdEvaluatorFunction() {
@Override
public Object apply(Object[] aArguments,
Object aCurrentObject,
TLcdOGCFilterContext aOGCFilterContext) {
return aArguments.length == 1 && aArguments[0] != null ?
aArguments[0].toString().toUpperCase() : null;
}
@Override
public int getArgumentCount() {
return 1;
}
};
Encoding a filter
TLcdOGCFilter
instances can be converted back to their XML representation using the TLcdOGCFilterEncoder
.
For example:
TLcdOGCFilter filter = ...;
TLcdOGCFilterEncoder encoder = new TLcdOGCFilterEncoder();
String outputFile = "path/to/file.xml";
encoder.encode(filter, outputFile);
The TLcdOGCFilterEncoder
class also allows to store the XML representation of the TLcdOGCFilter
into a String
or an OutputStream
:
TLcdOGCFilter
into an OutputStream
TLcdOGCFilter filter = ...;
try(Outputstream os = ...){
new TLcdOGCFilterEncoder().encode(filter, os);
}
TLcdOGCFilter
into a String
TLcdOGCFilter filter = ...;
String xmlEncodedFilter = TLcdOGCFilterEncoder.encodeToString(filter);