A Guide for Developers Traveling Through OpenLayers - 9. Filtering Data
A Guide for Developers Traveling Through OpenLayers - 9. Filtering Data
When calling WFS or WMS, there may be cases where more varied filtering is needed. You might need to call objects outside a specific area, call only data that spans a specific area, or query data by combining various conditions.
This is where the OGC Filter comes in handy. The OGC Filter takes the form of XML and, when included in a request, enables a wider variety of geospatial data filtering.
You can use the OGC Filter by specifying its value with the filter parameter in the request URL. It can also be used in the Transaction command.
The binary comparison operators are as follows.
- PropertyIsEqualTo: Data that matches
- PropertyIsNotEqualTo: Data that does not match
- PropertyIsLessThan: Data that is less than
- PropertyIsLessThanOrEqualTo: Data that is less than or equal to
- PropertyIsGreaterThan: Data that is greater than
- PropertyIsGreaterThanOrEqualTo: Data that is greater than or equal to
| Name | Required | value |
|---|---|---|
| PropertyName | Y | Column name |
| Literal | Y | Value |
XML
<!-- Filter only data whose CITY column is Seoul --> <PropertyIsEqualTo> <PropertyName>CITY</PropertyName> <Literal>서울</Literal> </PropertyIsEqualTo> <!-- Filter only data whose AREA column is 350 or less --> <PropertyIsLessThanOrEqualTo> <PropertyName>AREA</PropertyName> <Literal>350</Literal> </PropertyIsLessThanOrEqualTo>
The value comparison operators are as follows.
- PropertyIsLike: Data that contains a value
- PropertyIsNull: Data whose value is NULL
- PropertyIsBetween: Data whose value falls between specified values
The format differs slightly by operator.
- PropertyIsLike
| Name | Required | value |
|---|---|---|
| PropertyName | Y | Column name |
| Literal | Y | Value |
You can use the following 3 attributes on the PropertyName tag.
- wildCard: Wildcard
- singleChar: A single character
- escapeChar: Newline character
If you assign a string to the above attribute, that string will carry the same meaning as above.
Multiple attributes can be used at the same time.
XML
<!-- Filter only data whose CITY column contains the word Seoul --> <PropertyIsLike> <PropertyName>CITY</PropertyName> <Literal>서울</Literal> </PropertyIsLike> <!-- Filter only data whose CITY column contains a 3-character word starting with Seoul --> <PropertyIsLike> <PropertyName>CITY</PropertyName> <Literal singleChar="_">서울_</Literal> </PropertyIsLike> <!-- Filter only data whose CITY column contains a word starting with Seo and ending with ul --> <PropertyIsLike> <PropertyName>CITY</PropertyName> <Literal wildCard="%">서%울</Literal> </PropertyIsLike> <!-- Filter only data whose CITY column contains a newline-escaped 3-character word starting with Seoul --> <PropertyIsLike> <PropertyName>CITY</PropertyName> <Literal singleChar="_" escapeChar="-">서울_-</Literal> </PropertyIsLike>
- PropertyIsNull
| Name | Required | value |
|---|---|---|
| PropertyName | Y | Column name |
Since it only compares whether the column value is NULL, the notable point is that a Literal is not needed.
XML
<!-- Filter only data whose CITY column is NULL --> <PropertyIsNull> <PropertyName>CITY</PropertyName> </PropertyIsNull>
- PropertyIsBetween
| Name | Required | value |
|---|---|---|
| PropertyName | Y | Column name |
| UpperBoundary | Y | Maximum |
| LowerBoundary | Y | Minimum |
| Literal | Y | Value (under Boundary) |
XML
<!-- Filter only data whose COUNT column is between 500 and 1000 --> <PropertyIsBetween> <PropertyName>COUNT</PropertyName> <UpperBoundary> <Literal>1000</Literal> </UpperBoundary> <LowerBoundary> <Literal>500</Literal> </LowerBoundary> </PropertyIsBetween>
Note that the Literal tag goes inside the Boundary tag.
You can construct a filter based on space, such as coordinates or an area.
- Intersects: Data that is contained within or spans the given space
- Disjoint: Data that is not contained within the given space
- Contains: Data that is contained within the given space
- Within: Data inside the given space
- Touches: Data that touches the given space
- Crosses: Data that crosses the given space
- Overlaps: Data that overlaps the given space
- Equlas: Data identical to the given space
This can be somewhat ambiguous in writing, so let's look at the image below to help understand.
Differences like this exist.
| Name | Required | value |
|---|---|---|
| PropertyName | Y | Geospatial column name |
| gml | Y | Geospatial XML |
The geospatial XML can be found in the previous chapter.
XML
<!-- Filter only data that is contained within or spans the given area --> <Intersects> <PropertyName>GEOM</PropertyName> <gml:Polygon srsName="EPSG:0000"> <gml:outerBoundaryIs> <gml:LinearRing> <gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4 x1,y1</gml:coordinates> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polygon> </Intersects> <!-- Filter only data that crosses the given line --> <Crosses> <PropertyName>GEOM</PropertyName> <gml:LineString srsName="EPSG:0000"> <gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4</gml:coordinates> </gml:LineString> </Crosses>
Due to the nature of spatial operations, point data has low potential for use here.
Constructs a filter based on the distance of data.
- DWithin: Data within the given distance
- Beyond: Data beyond the given distance
| Name | Required | value |
|---|---|---|
| PropertyName | Y | Geospatial column name |
| gml | Y | Geospatial XML |
| Distance | Y | Distance |
The units attribute of Distance can be used to denote the unit of distance.
XML
<!-- Filter only data within 100m of the given point --> <DWithin> <PropertyName>GEOM</PropertyName> <gml:Point srsName="EPSG:0000"> <gml:coordinates>x,y</gml:coordinates> </gml:Point> <Distance units="m">100</Distance> </DWithin>
Constructs a filter based on the area of data.
- BBOX: Data that is contained within or spans the given space (same as Intersects)
| Name | Required | value |
|---|---|---|
| PropertyName | Y | Geospatial column name |
| Literal | Y | Value |
| gml | Y | Geospatial XML |
XML
<!-- Filter only data that is contained within or spans the given area --> <BBOX> <PropertyName>GEOM</PropertyName> <Literal> <gml:Polygon srsName="EPSG:0000"> <gml:outerBoundaryIs> <gml:LinearRing> <gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4 x1,y1</gml:coordinates> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polygon> </Literal> </BBOX>
This effectively produces the same result as Intersects among the spatial operators.
Combine multiple conditions to construct a filter.
- And: Data that satisfies all conditions
- Or: Data that satisfies at least one condition
- Not: Data that does not satisfy a condition
XML
<!-- Data that is contained within or spans the given area, and where AREA is 350 or less --> <And> <BBOX> <PropertyName>GEOM</PropertyName> <Literal> <gml:Polygon srsName="EPSG:0000"> <gml:outerBoundaryIs> <gml:LinearRing> <gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4 x1,y1</gml:coordinates> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polygon> </Literal> </BBOX> <PropertyIsLessThanOrEqualTo> <PropertyName>AREA</PropertyName> <Literal>350</Literal> </PropertyIsLessThanOrEqualTo> </And>
By appropriately nesting logical operators, you can construct complex filters.
Besides the OGC Filter, there is also something called the CQL Filter. Let's take a brief look at it.
Depending on the user, the CQL Filter can be easier than the OGC Filter, since it closely resembles the form of SQL.
You can use the CQL Filter by specifying its value with the cql_filter parameter in the request URL.
For example, it can be used as follows.
- PropertyIsLike
TXT
CITY LIKE '%서울%'
Expressing this in OGC would look like the following.
XML
<!-- Filter only data whose CITY column contains the word Seoul --> <PropertyIsLike> <PropertyName>CITY</PropertyName> <Literal>서울</Literal> </PropertyIsLike>
- Intersects
TXT
INTERSECTS(GEOM, POLYGON((x1 y1, x2 y2, x3 y3, x4 y4, x1 y1)))
Expressing this in OGC would look like the following.
XML
<!-- Filter only data that is contained within or spans the given area --> <Intersects> <PropertyName>GEOM</PropertyName> <gml:Polygon srsName="EPSG:0000"> <gml:outerBoundaryIs> <gml:LinearRing> <gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4 x1,y1</gml:coordinates> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polygon> </Intersects>
Since filters become simpler this way, they are much easier to use when filtering via URL.
We looked at the OGC Filter and the CQL Filter.
They will come in handy when you need to perform detailed filtering of data.
- OGC: An XML-form filter. Convenient for filtering XML-based data such as WFS Transactions.
- CQL: A text-form filter. Convenient for applying to a URL, as with WFS and WMS APIs.
If you need more information on the OGC and CQL Filters, check the sites below.
