Development¶
When you follow the source of the WFSView
, WFSMethod
and Parameter
classes,
you’ll find that it’s written with extensibility in mind. Extra parameters and operations
can easily be added there. You could even do that within your own projects and implementations.
A lot of the internal classes and object names are direct copies from the WFS spec. By following these type definitions, a lot of the logic and code structure follows naturally.
The Makefile
gives you all you need to start working on the project.
Typing make
gives an overview of all possible shortcut commands.
Running tests¶
The Makefile
has all options. Just typing make
gives a list of all commands.
Using make test
, and make retest
should run the pytest suite.
A special make docker-test
runs the tests as they would run within Travis-CI.
This helps to debug any differences between coordinate transformations due to
different PROJ.4 versions being installed.
Accessing the CITE tests¶
To perform CITE conformance testing against a server, use https://cite.opengeospatial.org/teamengine/.
- At the bottom of the page, there is a Create an account button.
- Create a new WFS 2.0 test session
- At the next page, enter the URL to the
GetCapabilities
document, e.g.:
http://example.org/v1/wfs/?VERSION=2.0.0&REQUEST=GetCapabilities
Local testing can’t be done with NGrok, as it exceeds the rate limiting. Instead, consider opening a temporary port-forward at your router/modem.
Internal logic¶
Features and Fields¶
Each FeatureField
is transformed into
an internal XsdElement
object. The model field access happens
through XsdElement.get_value()
.
Note that the type
can either reference either an XsdTypes
or XsdComplexType
object.
Each FeatureType
is transformed into
an internal XsdComplexType
definition:
Data Retrieval¶
When GetFeature
or GetPropertyValue
is called, several things happen:
- Request parsing.
- Query construction.
- Query execution.
- Output rendering.
The whole <fes:Filter>
contents is translated an an internal “abstract syntax tree” (AST)
which closely resembles all class names that the FES standard defines.
Then, the views .get_query()
method constructs the proper query object based on the request parameters.
The query class diagram looks like:
All regular requests such as ?FILTER=...
, ?BBOX=...
, ?SORTBY=...
and ?RESOURCEID=...
are handled by the AdhocQuery
class.
A subclass of StoredQuery
is used for ?STOREDQUERY_ID=...
requests.
The query is executed:
The CompiledQuery
collects all intermediate data needed
to translate the <fes:Filter>
queries to a Django ORM call.
This object is passed though all nodes of the filter,
so each build...()
function can add their lookups and annotations.
Finally, the query returns a FeatureCollection
that iterates over all results.
Each FeatureType
is represented by a SimpleFeatureCollection
member.
These collections attempt to use queryset-iterator logic as much as possible,
unless it would cause multiple queries (such as needing the number_matched
data early).
Output Rendering¶
Each WFSMethod
has a list of OutputFormat
objects:
class GetFeature(BaseWFSGetDataMethod):
output_formats = [
OutputFormat("application/gml+xml", version="3.2", renderer_class=output.gml32_renderer),
OutputFormat("text/xml", subtype="gml/3.2.1", renderer_class=output.gml32_renderer),
OutputFormat("application/json", subtype="geojson", charset="utf-8", renderer_class=output.geojson_renderer),
OutputFormat("text/csv", subtype="csv", charset="utf-8", renderer_class=output.csv_renderer),
# OutputFormat("shapezip"),
# OutputFormat("application/zip"),
]
The OutputFormat
class may reference an renderer_class
which points to an OutputRenderer
object.
Various output formats have an DB-optimized version where the heavy rendering of the EWKT, JSON or GML fragments is done by the database server. Most output formats return a streaming response for performance.
Alternatively, the WFSMethod
may render an XML template using Django templates.
WFS Specification¶
The WFS specification and examples be found at:
- https://www.opengeospatial.org/standards/ (all OGC standards)
- https://docs.opengeospatial.org/ (HTML versions)
Some deeplinks:
- https://www.opengeospatial.org/standards/common (OGC Web Service Common)
- https://www.opengeospatial.org/standards/wfs#downloads (OGC WFS)
- https://portal.opengeospatial.org/files/09-025r2 (WFS 2.0 spec)
- https://portal.opengeospatial.org/files/09-026r1 (OpenGIS Filter Encoding 2.0)
- https://portal.opengeospatial.org/files/07-036 (GML 3.2.1)
Other links:
- http://schemas.opengis.net/wfs/2.0/ (XSD and examples)
- https://mapserver.org/development/rfc/ms-rfc-105.html (more examples)
Coordinate systems, and axis orientation:
- https://macwright.com/lonlat/ (the inconsistency of lat/lon or lon/lat)
- https://macwright.com/2015/03/23/geojson-second-bite.html (More than you ever wanted to know about GeoJSON)
- https://mapserver.org/ogc/wms_server.html#coordinate-systems-and-axis-orientation (mapserver WMS part)
- https://mapserver.org/ogc/wfs_server.html#axis-orientation-in-wfs-1-1-and-2-0 (mapserver WFS part)
- https://docs.geoserver.org/stable/en/user/services/wms/basics.html#axis-ordering (geoserver WMS part)
- https://docs.geoserver.org/stable/en/user/services/wfs/axis_order.html (geoserver WFS part)