Filters¶
Filters are predicates that allow rules to be applied selectively.
A filter can take a great many different forms.
Note
A scale is a type of filter, but is discussed separately.
Note
For more information, please see the GeoTools CQL documentation and GeoServer CQL tutorial.
Syntax¶
The basic syntax of a filter is:
rules:
...
filter: ${<expression>}
...
where <expression>
is any valid CQL/ECQL filter.
Note
Be aware that filters are applied to rules and so appear inside them, but outside of any symbolizers.
Types of filters¶
As mentioned above, the filter can be any valid construction made with CQL/ECQL (Extended/Contextual Query Language).
CQL is written using a familiar text-based syntax with strong similarities to SQL statements. One can think of a CQL expression as the “WHERE” clause of a SQL statement.
The following are all standard filter constructions:
Object comparison¶
This filter will test to see if a comparison to an attribute is true. It has the following form:
${<attribute> <operator> <value>}
where:
Attribute |
Required? |
Description |
Default value |
---|---|---|---|
|
Yes |
That to which something is going to be compared. Typically an attribute name. May be case sensitive. |
N/A |
|
Yes |
Method of comparison. Valid operators are |
N/A |
|
Yes |
That which the |
N/A |
The following is a description of all available operators:
Operator |
Description |
---|---|
|
Equals |
|
Less than (non-inclusive) |
|
Greater than (non-inclusive) |
|
Less than or equal to (inclusive) |
|
Greater than or equal to (inclusive) |
|
Fuzzy matching for strings and other non-numeric attributes. Add |
|
Case-insensitive version of |
|
Tests if a value that is between two given values |
|
For testing against a |
|
Used when specifying a list. Must be contained in the list for the statement to be true. |
|
Negates a boolean (true/false) condition. Can be used with an additional operator such as |
|
Not equal (used when comparing a string or numeric value only) |
Note
These operators are not case sensitive, but are shown here in all caps for legibility and consistency.
Spatial filters¶
Filters can be spatial in nature. Any valid spatial construction in WKT (Well Known Text) can be used. Spatial filters include INTERSECTS
, DISJOINT
, CONTAINS
, WITHIN
, TOUCHES
, CROSSES
, EQUALS
, DWITHIN
, and BBOX
. NOT
can be added to negate the condition.
For more details about these spatial filters and their syntax, please see the GeoServer ECQL reference or uDig CQL reference.
Compound statements¶
The filter can be a combination of statements. A common case is testing if the value of an attribute is greater than one value but less than another.
The syntax for creating compound statements is to use standard Boolean notation such as AND
, OR
, and NOT
along with relevant parentheses.
For example, a filter where both statements need to be true would be:
filter: ${<statement1> AND <statement2>}
A filter where either statement would need to be true would be:
filter: ${<statement1> OR <statement2>}
Larger filters can be built up in this way:
filter: ${(<statement1> OR <statement2>) AND <statement3> OR NOT <statement4>}
In these examples, every <statement>
is a valid filter.
In terms of precedence, AND
is evaluated first, followed by OR
, unless modified by parentheses. So, in the last example above, (<statement1> OR <statement2>)
will be evaluated first, followed by the result of that AND <statement3>
, and finally the result of that with OR NOT <statement4>
.
Examples¶
Filter size based on an attribute
Filters are used to style different features of a layer based on certain conditions. The ILIKE
operator is used to compare two strings (ignoring case) to see if they are similar. When using LIKE
or ILIKE
, the %
character matches any number of letters (So %hwy
matches any streetname ending in hwy
). This example uses filters to distinguish between Highways, Roads, and other streets, and draw them using different colors and sizes:
feature-styles:
- rules:
- filter: ${streetname ILIKE '%hwy'}
symbolizers:
- line:
stroke-color: '#007799'
stroke-width: 8
- filter: ${streetname ILIKE '%rd'}
symbolizers:
- line:
stroke-color: '#00AA00'
stroke-width: 4
- else: true
symbolizers:
- line:
stroke-color: black
stroke-width: 2
Filter color based on attribute value
Filters can also be used to color a map based on attributes of the data. The following example uses the YEARBLT
attribute to color different lots based on the year they were built. The else
rule applies only if no other filter rule applies
Note
The Recode function can perform the same functionality in a more compact syntax.
name: Year Built Filter
feature-styles:
- rules:
- filter: ${YEARBLT > 2000}
symbolizers:
- polygon:
stroke-color: '#000000'
stroke-width: 0.5
fill-color: '#00FF00'
- filter: ${YEARBLT > 1990 AND YEARBLT < 2000}
symbolizers:
- polygon:
stroke-color: '#000000'
stroke-width: 0.5
fill-color: '#22DD00'
- filter: ${YEARBLT > 1980 AND YEARBLT < 1990}
symbolizers:
- polygon:
stroke-color: '#000000'
stroke-width: 0.5
fill-color: '#44BB00'
- filter: ${YEARBLT > 1970 AND YEARBLT < 1980}
symbolizers:
- polygon:
stroke-color: '#000000'
stroke-width: 0.5
fill-color: '#668800'
- else: true
symbolizers:
- polygon:
stroke-color: '#000000'
stroke-width: 0.5
fill-color: '#DD4400'
Filter by bounding box
Spatial filters can be used to filter a layer based on its geometry. The bbox
filter can be used to select features that are contained within a bounding box. This example colors polygons orange within the bounding box, and blue outside the bounding box:
name: Spatial Filter
feature-styles:
- name: name
rules:
- filter: bbox(the_geom, -122.9, 42.36, -122.85, 42.28)
symbolizers:
- polygon:
fill-color: '#99CC00'
- else: true
symbolizers:
- polygon:
fill-color: '#0099CC'
Filter by arbitrary geometries
Spatial filters can also be used to compare layer geometries against arbitrary geometries, not just bounding boxes. In this example, the within
filter is used to select all buildings inside a triangular region defined using Well-Known Text (WKT) and color them green. All other features are colored blue:
feature-styles:
- name: name
rules:
- filter: within(the_geom, POLYGON ((-122.9075 42.3625, -122.8225 42.3625, -122.8268 42.2803, -122.9075 42.3625)))
symbolizers:
- polygon:
fill-color: '#00CC00'
- else: true
symbolizers:
- polygon:
fill-color: '#0099CC'