gisserver.parsers.wfs20 package

WFS 2.0 element parsing.

These classes parse the XML request body.

The full spec can be found at: https://www.ogc.org/publications/standard/wfs/. Secondly, using https://www.mediamaps.ch/ogc/schemas-xsdoc/sld/1.2/wfs_xsd.html can be very helpful to see which options each object type should support.

class gisserver.parsers.wfs20.AdhocQuery(typeNames: list[str], aliases: list[str] | None = None, handle: str = '', srsName: CRS | None = None, property_names: list[PropertyName] | None = None, filter: Filter | None = None, sortBy: SortBy | None = None)

Bases: QueryExpression

The Ad hoc query expression parameters.

This parses and handles the syntax:

<wfs:Query typeNames="...">
    <wfs:PropertyName>...</wfs:PropertyName>
    <fes:Filter>...</fes:Filter>
    <fes:SortBy>...</fes:SortBy>
</wfs:Query>

And supports the KVP syntax:

?SERVICE=WFS&...&TYPENAMES=ns:myType&FILTER=...&SORTBY=...&SRSNAME=...&PROPERTYNAME=...
?SERVICE=WFS&...&TYPENAMES=ns:myType&BBOX=...&SORTBY=...&SRSNAME=...&PROPERTYNAME=...
?SERVICE=WFS&...&TYPENAMES=ns:myType&RESOURCEID=...

This represents all dynamic queries received as request (hence “adhoc”), such as the “FILTER” and “BBOX” arguments from an HTTP GET.

The WFS Spec has 3 class levels for this:

  • AdhocQueryExpression (types, projection, selection, sorting)

  • Query (adds srsName, featureVersion)

  • StoredQuery (adds storedQueryID)

For KVP requests, this class seems almost identifical to the provided parameters. However, the KVP format allows to provide parameter lists, to perform support multiple queries in a single request!

__init__(typeNames: list[str], aliases: list[str] | None = None, handle: str = '', srsName: CRS | None = None, property_names: list[PropertyName] | None = None, filter: Filter | None = None, sortBy: SortBy | None = None) None
aliases: list[str] | None = None

Aliases for typeNames are used for joining the same table twice. (JOIN statements are not supported yet).

as_kvp() dict

Translate the POST request into KVP GET parameters. This is needed for pagination.

bind(*args, **kwargs)

Override to make sure the ‘locator’ points to the actual object that defined the type.

build_query(compiler: CompiledQuery) Q | None

Apply our collected filter data to the compiler.

filter: Filter | None = None

Selection clause (implements fes:AbstractSelectionClause). - for XML POST this is encoded in a <fes:Filter> tag. - for HTTP GET, this is encoded as FILTER, FILTER_LANGUAGE, RESOURCEID, BBOX.

classmethod from_kvp_request(kvp: KVPRequest)

Build this object from an HTTP GET (key-value-pair) request.

Note the caller should have split the KVP request parameter lists. This class only handles a single parameter pair.

classmethod from_xml(element: NSElement) AdhocQuery

Parse the XML element of the Query tag.

get_projection() FeatureProjection

Tell how the <wfs:Query> element should be displayed.

get_type_names() list[str]

Tell which type names this query uses. Multiple values means a JOIN is made (not supported yet).

handle: str = ''

For XML POST requests, this handle value is returned in the <ows:Exception>.

property_names: list[PropertyName] | None = None

Projection clause (implements fes:AbstractProjectionClause)

property query_locator

Overrides the ‘query_locator’ attribute, so the ‘locator’ argument is correctly set.

sortBy: SortBy | None = None

Sorting Clause (implements fes:AbstractSortingClause)

srsName: CRS | None = None

The Coordinate Reference System to render the tag in

typeNames: list[str]

The ‘typeNames’ value if the request provided them. use get_type_names() instead.

class gisserver.parsers.wfs20.DescribeFeatureType(service: str, version: str | None, handle: str | None, typeNames: list[str] | None = None, outputFormat: str | None = 'XMLSCHEMA')

Bases: BaseOwsRequest

The <wfs:DescribeFeatureType> element.

This parses the syntax:

<wfs:DescribeFeatureType version="2.0.0" service="WFS">
  <wfs:TypeName>ns01:TreesA_1M</wfs:TypeName>
  <wfs:TypeName>ns02:RoadL_1M</wfs:TypeName>
</wfs:DescribeFeatureType>

And supports the GET syntax as well:

?SERVICE=WFS&VERSION=2.0.0&REQUEST=DescribeFeatureType&TYPENAMES=ns01:TreesA_1M,ns02:RoadL_1M
__init__(service: str, version: str | None, handle: str | None, typeNames: list[str] | None = None, outputFormat: str | None = 'XMLSCHEMA') None
classmethod from_kvp_request(kvp: KVPRequest)

Parse the KVP GET request

classmethod from_xml(element: NSElement)

Parse the XML POST request.

outputFormat: str | None = 'XMLSCHEMA'
typeNames: list[str] | None = None
class gisserver.parsers.wfs20.DescribeStoredQueries(service: str, version: str | None, handle: str | None, storedQueryId: list[str] | None = None)

Bases: BaseOwsRequest

The <wfs:DescribeStoredQueries> element.

This parses the syntax:

<wfs:DescribeStoredQueries>
  <wfs:StoredQueryId>...</wfs:StoredQueryId>
  <wfs:StoredQueryId>...</wfs:StoredQueryId>
</wfs:DescribeStoredQueries>

And the KVP syntax:

?REQUEST=DescribeStoredQueries&STOREDQUERY_ID=...,...
__init__(service: str, version: str | None, handle: str | None, storedQueryId: list[str] | None = None) None
classmethod from_kvp_request(kvp: KVPRequest)

Parse the KVP GET request.

classmethod from_xml(element: NSElement)

Parse the XML POST request.

storedQueryId: list[str] | None = None
class gisserver.parsers.wfs20.GetCapabilities(service: str, version: str | None, handle: str | None, updateSequence: str | None = None, acceptVersions: list[str] | None = None, sections: list[str] | None = None, acceptFormats: list[str] | None = None, acceptLanguages: list[str] | None = None)

Bases: BaseOwsRequest

Request parsing for GetCapabilities.

This parses and handles the syntax:

<wfs:GetCapabilities service="WFS" updateSequence="" version="">
    <ows:AcceptVersions>
        <ows:Version>...</ows:Version>
    </ows:AcceptVersions>
    <ows:Sections>
        <ows:Section>...</ows:Section>
        <ows:Section>...</ows:Section>
    </ows:Sections>
    <ows:AcceptFormats>
        <ows:OutputFormat>...</ows:OutputFormat>
        <ows:OutputFormat>...</ows:OutputFormat>
    </ows:AcceptFormats>
    <ows:AcceptLanguages>
        <ows:Language>...</ows:Language>
        <ows:Language>...</ows:Language>
    </ows:AcceptLanguages>
</wfs:GetCapabilities>

And supports the GET syntax as well:

?SERVICE=WFS&REQUEST=GetCapabilities&ACCEPTVERSIONS=2.0.0,1.1.0
__init__(service: str, version: str | None, handle: str | None, updateSequence: str | None = None, acceptVersions: list[str] | None = None, sections: list[str] | None = None, acceptFormats: list[str] | None = None, acceptLanguages: list[str] | None = None) None
acceptFormats: list[str] | None = None
acceptLanguages: list[str] | None = None
acceptVersions: list[str] | None = None
classmethod from_kvp_request(kvp: KVPRequest)

Parse the KVP request format.

classmethod from_xml(element: NSElement)

Parse the XML tag for the GetCapabilities.

sections: list[str] | None = None
updateSequence: str | None = None
class gisserver.parsers.wfs20.GetFeature(service: str, version: str | None, handle: str | None, queries: list[QueryExpression] = None, resolve: ResolveValue = ResolveValue.none, resolveDepth: int | None = None, resolveTimeout: int = 300, count: int | None = None, outputFormat: str = 'application/gml+xml; version=3.2', resultType: ResultType = ResultType.results, startIndex: int = 0)

Bases: StandardPresentationParameters, StandardResolveParameters, CommonQueryParameters, BaseOwsRequest

The <wfs:GetFeature> element.

This parses the syntax:

<wfs:GetFeature outputFormat="application/gml+xml; version=3.2">
   <wfs:Query typeName="myns:InWaterA_1M">
      <fes:Filter>
          ...
      </fes:Filter>
   </wfs:Query>
</wfs:GetFeature>

And supports the KVP syntax:

?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=myns:InWaterA_1M&FILTER=...
__init__(service: str, version: str | None, handle: str | None, queries: list[QueryExpression] = None, resolve: ResolveValue = ResolveValue.none, resolveDepth: int | None = None, resolveTimeout: int = 300, count: int | None = None, outputFormat: str = 'application/gml+xml; version=3.2', resultType: ResultType = ResultType.results, startIndex: int = 0) None
class gisserver.parsers.wfs20.GetPropertyValue(service: str, version: str | None, handle: str | None, queries: list[QueryExpression] = None, resolve: ResolveValue = ResolveValue.none, resolveDepth: int | None = None, resolveTimeout: int = 300, count: int | None = None, outputFormat: str = 'application/gml+xml; version=3.2', resultType: ResultType = ResultType.results, startIndex: int = 0, resolvePath: str | None = None, valueReference: ValueReference = None)

Bases: StandardPresentationParameters, StandardResolveParameters, CommonQueryParameters, BaseOwsRequest

The <wfs:GetPropertyValue> element.

This parses the syntax:

<wfs:GetPropertyValue valueReference="...">
   <wfs:Query typeName="myns:InWaterA_1M">
      <fes:Filter>
          ...
      </fes:Filter>
   </wfs:Query>
</wfs:GetFeature>

As this is so similar to the GetFeature syntax, these inherit from each other.

The KVP-syntax is also supported:

?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetPropertyName&...&&VALUEREFERENCE=...
__init__(service: str, version: str | None, handle: str | None, queries: list[QueryExpression] = None, resolve: ResolveValue = ResolveValue.none, resolveDepth: int | None = None, resolveTimeout: int = 300, count: int | None = None, outputFormat: str = 'application/gml+xml; version=3.2', resultType: ResultType = ResultType.results, startIndex: int = 0, resolvePath: str | None = None, valueReference: ValueReference = None) None
as_kvp() dict

Translate the POST request into KVP GET parameters. This is needed for pagination.

classmethod from_kvp_request(kvp: KVPRequest)

Parse the KVP GET request.

classmethod from_xml(element: NSElement)

Parse the XML POST request.

resolvePath: str | None = None
valueReference: ValueReference = None
class gisserver.parsers.wfs20.ListStoredQueries(service: str, version: str | None, handle: str | None)

Bases: BaseOwsRequest

The <wfs:ListStoredQueries> element.

classmethod from_xml(element: NSElement)

Initialize from an XML POST request.

class gisserver.parsers.wfs20.PropertyName(xpath: str, xpath_ns_aliases: dict[str, str], resolve: ResolveValue = ResolveValue.none, resolve_depth: int | None = None, resolve_path: str | None = None, resolve_timeout: int = 300)

Bases: AstNode

The <wfs:PropertyName> element in the projection clause.

This parses and handles the syntax:

<wfs:PropertyName>ns0:tagname</wfs:PropertyName>

More advanced syntax is not supported, such as:

<wfs:PropertyName resolve="all" resolvePath="valueOf(relatedTo)">valueOf(registerEntry)</wfs:PropertyName>

Note this element exists in the WFS namespace, not the FES namespace! The <fes:PropertyName> is an old FES 1.x element that has been replaced by <fes:ValueReference>. The old <fes:PropertyName> is still supported as an alias by this server.

__init__(xpath: str, xpath_ns_aliases: dict[str, str], resolve: ResolveValue = ResolveValue.none, resolve_depth: int | None = None, resolve_path: str | None = None, resolve_timeout: int = 300) None
decorate_query(compiler: CompiledQuery)

Update the low-level query based on this property projection.

classmethod from_xml(element: NSElement)

Parse the XML tag.

parse_xpath(feature_types: list) XPathMatch

Convert the XPath into the required ORM query elements.

resolve: ResolveValue = 'none'
resolve_depth: int | None = None
resolve_path: str | None = None
resolve_timeout: int = 300
xpath: str
xpath_ns_aliases: dict[str, str]
class gisserver.parsers.wfs20.QueryExpression

Bases: AstNode

WFS base class for all queries. This object type is defined in the WFS spec (as <fes:AbstractQueryExpression>).

The WFS server can initiate queries in multiple ways. This class provides the common interface for all these query types; whether the request provided “ad-hoc” parameters or called a stored procedure. Each query type has its own way of generating the actual database statement to perform.

The subclasses can override the following logic:

For full control, these methods can also be overwritten instead:

as_kvp() dict

Translate the POST request into KVP GET parameters. This is needed for pagination.

bind(feature_types: list[FeatureType], value_reference: ValueReference | None = None)

Bind the query to context outside its tag definition.

Parameters:
  • feature_types – The corresponding feature types for get_type_names().

  • value_reference – Which field is returned (by GetPropertyValue)

build_query(compiler: CompiledQuery) Q | None

Define the compiled query that filters the queryset.

get_projection() FeatureProjection

Tell how the query should be displayed.

get_queryset() QuerySet

Generate the queryset for the specific feature type.

This method can be overwritten in subclasses to define the returned data. However, consider overwriting build_query() instead of simple data.

get_type_names() list[str]

Tell which type names this query applies to. Multiple values means a JOIN is made (not supported yet).

This method needs to be defined in subclasses.

handle: str = ''

The ‘handle’ that will be returned in exceptions.

property_names: list[PropertyName] | None = None

Projection parameters (overwritten by subclasses) In the WFS spec, this is only part of the operation/presentation. For Django, we’d like to make this part of the query too.

query_locator: ClassVar[str] = None

Configuration for the ‘locator’ argument in exceptions

value_reference: ValueReference | None = None

The valueReference for the GetPropertyValue call, provided here for extra ORM filtering.

class gisserver.parsers.wfs20.ResultType(*values)

Bases: Enum

WFS result type format.

hits = 'HITS'
results = 'RESULTS'
class gisserver.parsers.wfs20.StoredQuery(id: str, parameters: dict[str, ~typing.Any], ns_aliases: dict[str, str] = <factory>)

Bases: QueryExpression

The <wfs:StoredQuery> element.

This loads a predefined query on the server. A good description can be found at: https://mapserver.org/ogc/wfs_server.html#stored-queries-wfs-2-0

This parses the following syntax:

<wfs:StoredQuery handle="" id="">
  <wfs:Parameter name="">...</wfs:Parameter>
  <wfs:Parameter name="">...</wfs:Parameter>
</wfs:StoredQuery>

and the KVP syntax:

?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&STOREDQUERY_ID=...&{parameter}=...

Note that the base class logic (such as <wfs:PropertyName> elements) are still applicable.

This element resolves the stored query using the StoredQueryRegistry, and passes the execution to this custom function.

__init__(id: str, parameters: dict[str, ~typing.Any], ns_aliases: dict[str, str] = <factory>) None
as_kvp() dict

Translate the POST request into KVP GET parameters. This is needed for pagination.

bind(*args, **kwargs)

Associate this query with the application context.

build_query(compiler: CompiledQuery)

Forward queryset creation to the implementation class.

finalize_results(result: SimpleFeatureCollection)
classmethod from_kvp_request(kvp: KVPRequest)

Parse the KVP request syntax. Any query parameters are additional parameters at the query string.

classmethod from_xml(element: NSElement)

Read the XML element.

get_projection() FeatureProjection

Tell how the <wfs:StoredQuery> output should be displayed.

get_type_names() list[str]

Tell which features are touched by the query.

id: str
property implementation: StoredQueryImplementation

Initialize the stored query from this request.

ns_aliases: dict[str, str]
parameters: dict[str, Any]
query_locator: ClassVar[str] = 'STOREDQUERY_ID'

Configuration for the ‘locator’ argument in exceptions