Skip to end of metadata
Go to start of metadata

You are viewing an old version of this content. View the current version.

Compare with Current View Version History

Version 1 Current »

Overview

An OGC Filter is a Open Geospatial Consortium (OGC) standard that describes a query expression in terms of Extensible Markup Language (XML) and key-value pairs (KVP). The DDF Catalog Framework does not use the XML representation of the OGC Filter standard.

DDF

instead utilizes the Java implementation provided by Geotools. Geotools provides Java equivalent classes for OGC Filter XML elements. Geotools originally provided the standard Java classes for the OGC Filter Encoding 1.0 under the package name org.opengis.filter. The same package name is used today and is currently used by

DDF

.  Java developers do not parse or view the XML representation of a Filter in

DDF

. Developers instead solely use the Java objects to complete query tasks.

Note that the ddf.catalog.operation.Query interface extends the org.opengis.filter.Filter interface, which means that a Query object is an OGC Java Filter with Query Options.

A Query is an OGC Filter
public interface Query extends Filter 

Usage

FilterBuilder API

To abstract developers from the complexities of working with the Filter interface directly and implementing the DDF Profile of the Filter specification, the DDF Catalog includes an API, primarily in ddf.filter, to build Filters using a fluent API.

To use the FilterBuilder API, an instance of ddf.filter.FilterBuilder should be used via the OSGi registry.  Typically this will be injected via a dependency injection framework.  Once an instance of FilterBuilder is available, methods can be called to create and combine Filters.

The fluent API is best accessed using an IDE that supports code-completion.  For additional details, refer to the Catalog API Javadoc.

Boolean Operators

FilterBuilder.allOf(Filter ...) creates a new Filter that requires all provided Filters are satisfied (Boolean AND), either from a List or Array of Filter instances.

FilterBuilder.anyOf(Filter ...) creates a new Filter that requires all provided Filters are satisfied (Boolean OR), either from a List or Array of Filter instances.

FilterBuilder.not(Filter filter) creates a new Filter that requires the provided Filter must not be match (Boolean NOT).

Attribute

FilterBuilder.attribute(String attributeName) begins a fluent API for creating an Attribute-based Filter, i.e., a Filter that matches on Metacards with Attributes of a particular value.

XPath

FilterBuilder.xpath(String xpath) begins a fluent API for creating an XPath-based Filter, i.e., a Filter that matches on Metacards with Attributes of type XML that match when evaluating a provided XPath selector.

Contextual Operators
FilterBuilder.attribute(attributeName).is().like().text(String contextualSearchPhrase);
FilterBuilder.attribute(attributeName).is().like().caseSensitiveText(String caseSensitiveContextualSearchPhrase);
FilterBuilder.attribute(attributeName).is().like().fuzzyText(String fuzzySearchPhrase);

Directly implementing the Filter (advanced)

Implementing the Filter interface directly is only for extremely advanced use cases and is highly discouraged. Instead, use of the DDF-specific FilterBuilder API is recommended.

 

Developers create a Filter object in order to "filter" or constrain the amount of records returned from a Source. The OGC Filter Specification has several types of filters that can be combined in a tree-like structure to describe the set of metacards that should be returned. 

Categories of Filters

  • Comparison Operators
  • Logical Operators
  • Expressions
  • Literals
  • Functions
  • Spatial Operators
  • Temporal Operators

Units of Measure

According to the OGC Filter Specifications 09-026r1 and 04-095, units of measure can be expressed as a URI. In order to fulfill that requirement, 

DDF

 utilizes the Geotools class org.geotools.styling.UomOgcMapping for spatial filters requiring a standard for units of measure for scalar distances. The UomOgcMapping essentially maps the OGC Symbology Encoding standard URI's to Java Units. This class provides three options for units of measure: 

  • FOOT
  • METRE
  • PIXEL

DDF

 only supports FOOT and METRE since they are the most applicable to scalar distances.

Creation

The common way to create a Filter is to use the Geotools FilterFactoryImpl object which provides Java implementations for the various types of filters in the Filter Specification. Examples are the easiest way to understand how to properly create a Filter and a Query

Refer to the Geotools javadoc for more information on FilterFactoryImpl.

The example below illustrates creating a query, and thus an OGC Filter, that does a case-insensitive search for the phrase "mission" in the entire Metacard's text. Note that the PropertyIsLike OGC Filter is used for this simple contextual query.

Example Creating-Filters-1 
Simple Contextual Search
org.opengis.filter.FilterFactory filterFactory = new FilterFactoryImpl() ;
boolean isCaseSensitive = false ; 
 
String wildcardChar = "*" ; // used to match zero or more characters
String singleChar = "?" ; // used to match exactly one character
String escapeChar = "\\" ; // used to escape the meaning of the wildCard, singleChar, and the escapeChar itself
 
String searchPhrase = "mission" ;
org.opengis.filter.Filter propertyIsLikeFilter = 
    filterFactory.like(filterFactory.property(Metacard.ANY_TEXT), searchPhrase, wildcardChar, singleChar, escapeChar, isCaseSensitive);		
ddf.catalog.operation.QueryImpl query = new QueryImpl( propertyIsLikeFilter );

The example below illustrates creating an absolute temporal query, meaning the query is searching for Metacards whose modified timestamp occurred during a specific time range. Note that this query uses the During OGC Filter for an absolute temporal query.

Example Creating-Filters-2
Absolute Temporal Search
org.opengis.filter.FilterFactory filterFactory = new FilterFactoryImpl() ;
org.opengis.temporal.Instant startInstant = new org.geotools.temporal.object.DefaultInstant(new DefaultPosition(start));
 
org.opengis.temporal.Instant endInstant = new org.geotools.temporal.object.DefaultInstant(new DefaultPosition(end));
 
org.opengis.temporal.Period period = 
 new org.geotools.temporal.object.DefaultPeriod(startInstant, endInstant);

String property = Metacard.MODIFIED ; // modified date of a metacard
 
org.opengis.filter.Filter filter = filterFactory.during( filterFactory.property(property), filterFactory.literal(period) 	);
 
ddf.catalog.operation.QueryImpl query = new QueryImpl(filter) ;

Contextual Searches

Most contextual searches can be expressed using the PropertyIsLike Filter. The special characters that have meaning in a PropertyIsLike Filter are the wildcard, single wildcard, and escape characters (see Example Creating-Filters-1).

PropertyIsLike Special Characters

CharacterDescription
Wildcard

Matches zero or more characters.

Single Wildcard

Matches exactly one character.

Escape

Escapes the meaning of the Wildcard, Single Wildcard, and the Escape character itself

Characters and words such as AND&andOR|orNOT~not{, and } are treated as literals in a PropertyIsLike Filter. In order to create equivalent logical queries, a developer must instead use the Logical Operator Filters {AND, OR, NOT}. The Logical Operator filters can be combined together with PropertyIsLike filters to create a tree that represents the search phrase expression. 

Example Creating-Filters-3
Creating the search phrase "mission and planning"
org.opengis.filter.FilterFactory filterFactory = new FilterFactoryImpl() ; 

boolean isCaseSensitive = false ; 
 
String wildcardChar = "*" ; // used to match zero or more characters
String singleChar = "?" ; // used to match exactly one character
String escapeChar = "\\" ; // used to escape the meaning of the wildCard, singleChar, and the escapeChar itself

Filter filter = 
    filterFactory.and(
       filterFactory.like(filterFactory.property(Metacard.METADATA), "mission" , wildcardChar, singleChar, escapeChar, isCaseSensitive),
       filterFactory.like(filterFactory.property(Metacard.METADATA), "planning" , wildcardChar, singleChar, escapeChar, isCaseSensitive) 
    );
 
ddf.catalog.operation.QueryImpl query = new QueryImpl( filter ); 
Tree View of Example Creating-Filters-3 

Filters used in 

DDF

 can always be represented in a tree diagram.

XML View of Example Creating-Filters-3

Another way to view this type of Filter is through an XML model as below:

Pseudo XML of Example Creating-Filters-3
<Filter>
   <And> 
      <PropertyIsLike wildCard="*" singleChar="?" escapeChar="\">
           <PropertyName>metadata</PropertyName>
           <Literal>mission</Literal>
      </PropertyIsLike>
      <PropertyIsLike wildCard="*" singleChar="?" escapeChar="\">
           <PropertyName>metadata</PropertyName>
           <Literal>planning</Literal>
      </PropertyIsLike> 
   <And> 
</Filter>

Using the Logical Operators and PropertyIsLike Filters, a developer can create a whole language of search phrase expressions.

Fuzzy Operation 

DDF

 only supports one custom function. The Filter specification does not include a fuzzy operator, so a Filter function was created to represent a fuzzy operation. The function and class is called FuzzyFunction which is used by clients to flag to Sources when to do a fuzzy search. The syntax expected by providers is similar to the Fuzzy Function. Usage example below.

Fuzzy Function Usage
String wildcardChar = "*" ; // used to match zero or more characters
String singleChar = "?" ; // used to match exactly one character
String escapeChar = "\\" ; // used to escape the meaning of the wildCard, singleChar 
 
boolean isCaseSensitive = false ; 
 
Filter fuzzyFilter = filterFactory.like(
     new ddf.catalog.impl.filter.FuzzyFunction(
          Arrays.asList((Expression) (filterFactory.property(Metacard.ANY_TEXT))),
          filterFactory.literal("")), 
     searchPhrase, 
     wildcardChar, 
     singleChar, 
     escapeChar, 
     isCaseSensitive);

QueryImpl query = new QueryImpl(fuzzyFilter); 

Additional Reading

  • No labels