WFS User Manual¶
This is a brief explanation of using a WFS server.
Commonly, a WFS server can is accessed by GIS-software, such as QGis.
The URL that’s configured inside urls.py
can be used directly as WFS endpoint.
For example, add https://api.data.amsterdam.nl/v1/wfs/gebieden/ to QGis.
Everything, for querying and viewing can be done in QGis.
Tip
The parameters ?SERVICE=WFS&VERSION=2.0.0&REQUEST=..
are appended to the URL
by QGis. It’s not required to add these yourself.
The WFS server can also be accessed directly from a HTTP client (e.g. curl) or web browser. In such case, use the basic URL above, and include the query parameters:
?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=featurename
The available feature types can be found in the GetCapabilities request:
?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetCapabilities
The remaining part of this page assumes this manual access.
Export Formats¶
The following export formats are available:
- GeoJSON
- CSV
These can be queried by manually crafting a GetFeature request.
The parameters TYPENAMES=feature-name
and OUTPUTFORMAT=format
should be included.
For example:
Tip
In the example links above, a COUNT=
parameter is included to activate pagination.
When this parameter is omitted, all objects will be returned in a single request.
For most datasets, the server is capable of efficiently delivering all results in a single response.
Geometry Projections¶
The exportlink can be extended with the SRSNAME
parameter to define the geometry projection
of all geo data. For example, SRSNAME=urn:ogc:def:crs:EPSG::3857
activates the web-mercator projection
which is used by Google Maps. A common default is urn:ogc:def:crs:EPSG::4326
, which is the
worldwide WGS 84 longitude-latitude.
Simple Filters¶
The WFS protocol offers a powerful syntax to filter data.
Use the request REQUEST=GetFeature
with a FILTER
argument.
The filter value is expressed as XML.
For example, to query all neighbourhoods (typename buurten) of the central district (stadsdeel) in Amsterdam:
<Filter>
<PropertyIsEqualTo>
<ValueReference>ligt_in_stadsdeel/naam</ValueReference>
<Literal>Centrum</Literal>
</PropertyIsEqualTo>
</Filter>
This can be included in the request, for example:
- …&TYPENAMES=wijken&OUTPUTFORMAT=geojson&FILTER=%3CFilter%3E%3CPropertyIsEqualTo%3E%3CValueReference…
The FILTER
parameter replaces the separate BBOX
and RESOURCEID
parameters.
If you use these parameters as well, they should be included in the filter:
<Filter>
<And>
<BBOX>
<gml:Envelope srsName="EPSG:4326">
<gml:lowerCorner>4.58565 52.03560</gml:lowerCorner>
<gml:upperCorner>5.31360 52.48769</gml:upperCorner>
</gml:Envelope>
</BBOX>
<PropertyIsEqualTo>
<ValueReference>status</ValueReference>
<Literal>1</Literal>
</PropertyIsEqualTo>
</And>
</Filter>
The RESOURCEID
parameter has a <ResourceId>
equivalent which can appear several times in the filter:
<Filter>
<ResourceId rid="TYPENAME.123" />
<ResourceId rid="TYPENAME.4325" />
<ResourceId rid="OTHERTYPE.567" />
</Filter>
Complex Filters¶
The WFS Filter Encoding Standaard (FES) supports many operators. These tags are all supported:
Element | SQL equivalent | Description |
---|---|---|
<PropertyIsEqualTo> |
a == b |
Values must be equal. |
<PropertyIsNotEqualTo> |
a != b |
Values must not be equal. |
<PropertyIsLessThan> |
a < b |
Value 1 must be less than value 2. |
<PropertyIsGreaterThan> |
a > b |
Value 1 must be greater than value 2. |
<PropertyIsLessThanOrEqualTo> |
a <= b |
Value 1 must be less than or equal to value 2. |
<PropertyIsGreaterThanOrEqualTo> |
a >= b |
Value 1 must be greater than or equal to value 2. |
<PropertyIsBetween> |
a BETWEEN x AND y |
Compares between <LowerBoundary> and <UpperBoundary> ,
which both contain an expression. |
<PropertyIsLike> |
a LIKE b |
Performs a wildcard comparison. |
<PropertyIsNil> |
a IS NULL |
Value must be NULL (xsi:nil="true" in XML). |
<PropertyIsNull> |
n.a. | Property may not exist (currently implemented as <PropertyIsNil> ). |
<BBOX> |
ST_Intersects(a, b) |
Geometry must be in value 2. The field name may be omitted to use the default. |
<Contains> |
ST_Contains(a, b) |
Geometry 1 completely contains geometry 2. |
<Crosses> |
ST_Crosses(a, b) |
The geometries have some common interior points. |
<Disjoint> |
ST_Disjoint(a, b) |
The geometries are not connected in any way. |
<Equals> |
ST_Equals(a, b) |
The geometries are identical. |
<Intersects> |
ST_Intersects(a, b) |
The geometries share some space. |
<Touches> |
ST_Touches(a, b) |
The edges of the geometries touch each other. |
<Overlaps> |
ST_Overlaps(a, b) |
The geometries overlap. |
<Within> |
ST_Within(a, b) |
Geometry 1 is completely contained within geometry 2. |
<DWithin> |
ST_DWithin(a, b, d) |
The geometries are within a given distance of each other. |
<Beyond> |
NOT ST_DWithin(a, b, d) |
The geometries are not within a given distance. |
<And> |
a AND b |
The nested elements must all be true. |
<Or> |
a OR b |
Only one of the nested elements has to be true. |
<Not> |
NOT a |
Negation of the nested element. |
<ResourceId> |
table.id == value / table.id IN (v1, v2, ...) |
Searches only one element for “type name.identifier”.
Combines multiple elements into an IN query. |
Tip
For the <BBOX>
operator the geometry field may be omitted.
The standard geometry field is then used (usually the first field).
Note
Although a number of geometry operators seem to be identical for surfaces
(such as <Intersects>
, <Crosses>
and <Overlaps>
),
their mutual differences are particularly visible when comparing points with surfaces.
Various expressions may be used as values:
Expression | SQL equivalent | Description |
---|---|---|
<ValueReference> |
field-name |
References a field. |
<Literal> |
value | Literal value, can also be a GML-object. |
<Function> |
function-name(..) |
Executes a function, such as abs , sin , strLength . |
<Add> |
a + b |
Addition (WFS 1 expression). |
<Sub> |
a - b |
Subtraction (WFS 1 expression). |
<Mul> |
a * b |
Multiplication (WFS 1 expression). |
<Div> |
a / b |
Division (WFS 1 expression). |
This allows to create complex filters, such as:
<Filter>
<And>
<PropertyIsEqualTo>
<ValueReference>status</ValueReference>
<Literal>1</Literal>
</PropertyIsEqualTo>
<Or>
<PropertyIsEqualTo>
<ValueReference>container_type</ValueReference>
<Literal>Other</Literal>
</PropertyIsEqualTo>
<PropertyIsEqualTo>
<ValueReference>container_type</ValueReference>
<Literal>Textile</Literal>
</PropertyIsEqualTo>
<PropertyIsEqualTo>
<ValueReference>container_type</ValueReference>
<Literal>Glass</Literal>
</PropertyIsEqualTo>
<PropertyIsEqualTo>
<ValueReference>container_type</ValueReference>
<Literal>Papier</Literal>
</PropertyIsEqualTo>
<PropertyIsEqualTo>
<ValueReference>container_type</ValueReference>
<Literal>Organic</Literal>
</PropertyIsEqualTo>
<PropertyIsEqualTo>
<ValueReference>container_type</ValueReference>
<Literal>Plastic</Literal>
</PropertyIsEqualTo>
</Or>
</And>
</Filter>
Functions¶
Functions are executed by using the tag <Function name="..">..</Function>
.
This can be used anywhere as an expression instead of a <ValueReference>
or <Literal>
.
Inside the function, the parameters are also given as expressions:
a <ValueReference>
, <Literal>
or new <Function>
.
As a simple example:
<fes:Function name="sin">
<fes:ValueReference>fieldname</fes:ValueReference>
</fes:Function>
The following functions are available in the server:
Functie | SQL equivalent | Description |
---|---|---|
strConcat(string) |
CONCAT() |
Concatenates strings |
strToLowerCase(string) |
LOWER() |
Convert text to lowercase. |
strToUpperCase(string) |
UPPER() |
Convert text to uppercase. |
strTrim(string) |
TRIM() |
Remove white space at the beginning and end. |
strLength(string) |
LENGTH() / CHAR_LENGTH() |
Determines text length. |
length(string) |
LENGTH() / CHAR_LENGTH() |
Alias of strLength() . |
abs(number) |
ABS() |
Invert negative numbers. |
ceil(number) |
CEIL() |
Rounding up. |
floor(number) |
FLOOR() |
Rounding down. |
round(value) |
ROUND() |
Regular rounding. |
min(value1, value2) |
LEAST() |
Uses the smallest number. |
max(value1, value2) |
GREATEST() |
Uses the largest number. |
pow(base, exponent) |
POWER() |
Exponentiation |
exp(value) |
EXP() |
Exponent of 𝑒 (2,71828…; natural logarithm). |
log(value) |
LOG() |
Logarithm; inverse of an exponent. |
sqrt(value) |
SQRT() |
Square root, inverse of exponentiation. |
acos(value) |
ACOS() |
Arccosine; inverse of cosine. |
asin(value) |
ASIN() |
Arcsine; inverse van sine. |
atan(value) |
ATAN() |
Arctangent; inverse of tangent. |
atan2(x, y) |
ATAN2() |
Arctangent, for usage outside the range of a circle. |
cos(radians) |
COS() |
Cosine |
sin(radians) |
SIN() |
Sine |
tan(radians) |
TAN() |
Tangent |
pi() |
PI |
The value of π (3,141592653…) |
toDegrees(radians) |
DEGREES() |
Conversion of radians to degrees. |
toRadians(degree) |
RADIANS() |
Conversion degrees to radians. |
Area(geometry) |
ST_AREA() |
Convert geometry to area. |
Centroid(features) |
ST_Centroid() |
Return geometric center as “gravity point”. |
Difference(geometry1, geometry2) |
ST_Difference() |
Parts of geometry 1 that do not overlap with geometry 2. |
distance(geometry1, geometry2) |
ST_Distance() |
Minimum distance between 2 geometries. |
Envelope(geometry) |
ST_Envelope() |
Convert geometry to bounding box. |
Intersection(geometry1, geometry2) |
ST_Intersection() |
Parts of geometry 1 that overlap with geometry 2. |
Union(geometry1, geometry2) |
ST_Union() |
Merge Geometry 1 and 2. |
Filter Compatibility¶
Strictly speaking, XML namespaces are required in the filter. Since many clients omit them, the server also supports requests without namespaces. For the sake of completeness, a request with namespaces included looks like this:
<fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/fes/2.0
http://schemas.opengis.net/filter/2.0/filterAll.xsd">
<fes:PropertyIsEqualTo>
<fes:ValueReference>stadsdeel/naam</fes:ValueReference>
<fes:Literal>Centrum</fes:Literal>
</fes:PropertyIsEqualTo>
</fes:Filter>
When a geometry filter is included, this also requires the GML namespace:
<fes:Filter
xmlns:fes="http://www.opengis.net/fes/2.0"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/fes/2.0
http://schemas.opengis.net/filter/2.0/filterAll.xsd
http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd">
<fes:BBOX>
<gml:Polygon gml:id="P1" srsName="http://www.opengis.net/def/crs/epsg/0/4326">
<gml:exterior>
<gml:LinearRing>
<gml:posList>10 10 20 20 30 30 40 40 10 10</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</fes:BBOX>
</fes:Filter>
According to the XML rules, the “fes” namespace alias can be renamed here
or omitted if only xmlns="..."`
is used instead of xmlns:fes="..."
.
Several existing clients still use other WFS 1 elements, such as <PropertyName>
instead of
of <ValueReference>
. For compatibility this tag is also supported.
The WFS 1 expressions <Add>
, <Sub>
, <Mul>
and <Div>
are also implemented
to support arithmetic operations from QGis (addition, subtraction, multiplication and division).