WFS - OGC WFS service

(GDAL/OGR >= 1.8.0)

This driver can connect to a OGC WFS service. It supports WFS 1.0, 1.1 and 2.0 protocols. GDAL/OGR must be built with Curl support in order to the WFS driver to be compiled. Usually WFS requests return results in GML format, so the GML driver should generally be set-up for read support (thus requiring GDAL/OGR to be built with Xerces or Expat support). It is sometimes possible to use alternate underlying formats when the server supports them (such as OUTPUTFORMAT=json).

The driver supports read-only services, as well as Transactionnal ones (WFS-T).

Dataset name syntax

The minimal syntax to open a WFS datasource is : WFS:http://path/to/WFS/service or http://path/to/WFS/service?SERVICE=WFS

Additional optional parameters can be specified such as TYPENAME, VERSION, MAXFEATURES as specified in WFS specification.

The name provided to the TYPENAME parameter must be exactly the layer name reported by OGR, in particular with its namespace prefix when its exists. Note: starting with GDAL 1.10, several type names can be provided and separated by comma.

It is also possible to specify the name of an XML file whose content matches the following syntax (the <OGRWFSDataSource> element must be the first bytes of the file):

<OGRWFSDataSource>
    <URL>http://path/to/WFS/service[?OPTIONAL_PARAMETER1=VALUE[&amp;OPTIONAL_PARAMETER2=VALUE]]</URL>
</OGRWFSDataSource>

Note: the URL must be XML-escaped, for example the & character must be written as &amp;

At the first opening, the content of the result of the GetCapabilities request will be appended to the file, so that it can be cached for later openings of the dataset. The same applies for the DescribeFeatureType request issued to discover the field definition of each layer.

The service description file has the following additional elements as immediate children of the OGRWFSDataSource element that may be optionally set.

Request paging

Before OGR 1.10, when reading the first feature from a layer, the whole layer content will be fetched from the server.

Some servers (such as MapServer >= 6.0) support the use of STARTINDEX that allows to do the requests per "page", and thus to avoid downloading the whole content of the layer in a single request. Paging was introduced in WFS 2.0.0 but servers may support it as an vendor specific option also with WFS 1.0.0 and 1.1.0. The OGR WFS client will use paging when the OGR_WFS_PAGING_ALLOWED configuration option is set to ON. The page size (number of features fetched in a single request) is limited to 100 by default. It can be changed by setting the OGR_WFS_PAGE_SIZE configuration option.
WFS 2.0.2 specification has clarified that the first feature in paging is at index 0. But some server implementations of WFS paging have considered that it was at index 1 (including MapServer <= 6.2). Starting with OGR 1.10, the default base start index is 0, as mandated by the specification. The OGR_WFS_BASE_START_INDEX configuration option can however be set to 1 to be compatible with the server implementations that considered the first feature to be at index 1.
Those 3 options (OGR_WFS_PAGING_ALLOWED, OGR_WFS_PAGE_SIZE, OGR_WFS_BASE_START_INDEX) can also be set in a WFS XML description file with the elements of similar names (PagingAllowed, PageSize, BaseStartIndex).

Starting with OGR 1.10, the WFS driver will read the GML content as a stream instead as a whole file, which will improve interactivity and help when the content cannot fit into memory. This can be turned off by setting the OGR_WFS_USE_STREAMING configuration option to NO if this is not desirable (for example, when iterating several times on a layer that can fit into memory). When streaming is enabled, GZip compression is also requested. It has been observed that some WFS servers, that cannot do on-the-fly compression, will cache on their side the whole content to be sent before sending the first bytes on the wire. To avoid this, you can set the CPL_CURL_GZIP configuration option to NO.

Starting with GDAL 2.0, the WFS driver will automatically detect if server supports paging, when requesting a WFS 2.0 server.

Filtering

The driver will forward any spatial filter set with SetSpatialFilter() to the server. It also makes its best effort to do the same for attribute filters set with SetAttributeFilter() when possible (turning OGR SQL language into OGC filter description). When this is not possible, it will default to client-side only filtering, which can be a slow operation because involving fetching all the features from the servers.

Starting with GDAL 2.0, the following spatial functions can be used :

Note that those spatial functions are only supported as server-side filters.

Layer joins

Starting with GDAL 2.0, and for WFS 2.0 servers that support joins, SELECT statements that involve joins will be run on server side. Spatial joins can also be done by using the above mentioned spatial functions, if the server supports spatial joins.

There might be restrictions set by server on the complexity of the joins. The OGR WFS driver also restricts column selection to be column names, potentially with aliases and type casts, but not expressions. The ON and WHERE clauses must also be evaluated on server side, so no OGR special fields are allowed for example. ORDER BY clauses are supported, but the fields must belong to the primary table.

Example of valid statement :

SELECT t1.id, t1.val1, t1.geom, t2.val1 FROM my_table AS t1 JOIN another_table AS t2 ON t1.id = t2.t1id
or
SELECT * FROM my_table AS t1 JOIN another_table AS t2 ON ST_Intersects(t1.geom, t2.geom)

Write support / WFS-T

The WFS-T protocol only enables the user to operate at feature level. No datasource, layer or field creations are possible.

Write support is only enabled when the datasource is opened in update mode.

The mapping between the operations of the WFS Transaction service and the OGR concepts is the following:

Lock operations (LockFeature service) are not available at that time.

There are a few caveats to keep in mind. OGR feature ID (FID) is an integer based value, whereas WFS/GML gml:id attribute is a string. Thus it is not always possible to match both values. The WFS driver exposes then the gml:id attribute of a feature as a 'gml_id' field.

When inserting a new feature with CreateFeature(), and if the command is successful, OGR will fetch the returned gml:id and set the 'gml_id' field of the feature accordingly. It will also try to set the OGR FID if the gml:id is of the form layer_name.numeric_value. Otherwise the FID will be left to its unset default value.

When updating an existing feature with SetFeature(), the OGR FID field will be ignored. The request issued to the driver will only take into account the value of the gml:id field of the feature. The same applies for DeleteFeature().

Write support and OGR transactions

The above operations are by default issued to the server synchronously with the OGR API call. This however can cause performance penalties when issuing a lot of commands due to many client/server exchanges.

It is possible to surround those operations between OGRLayer::StartTransaction() and OGRLayer::CommitTransaction(). The operations will be stored into memory and only executed at the time CommitTransaction() is called.

The drawback for CreateFeature() is that the user cannot know which gml:id have been assigned to the inserted features. A special SQL statement has been introduced into the WFS driver to workaround this : by issuing the "SELECT _LAST_INSERTED_FIDS_ FROM layer_name" (where layer_name is to be replaced with the actual layer_name) command through the OGRDataSource::ExecuteSQL(), a layer will be returned with as many rows with a single attribute gml_id as the count of inserted features during the last committed transaction.

Note : currently, only CreateFeature() makes use of OGR transaction mechanism. SetFeature() and DeleteFeature() will still be issued immediately.

Special SQL commands

The following SQL / pseudo-SQL commands passed to OGRDataSource::ExecuteSQL() are specific of the WFS driver :

Currently, any other SQL command will be processed by the generic layer, meaning client-side only processing. Server side spatial and attribute filtering must be done through the SetSpatialFilter() and SetAttributeFilter() interfaces.

Special layer : WFSLayerMetadata

(OGR >= 1.9.0)

A "hidden" layer called "WFSLayerMetadata" is filled with records with metadata for each WFS layer.

Each record contains a "layer_name", "title" and "abstract" field, from the document returned by GetCapabilities.

That layer is returned through GetLayerByName("WFSLayerMetadata").

Special layer : WFSGetCapabilities

(OGR >= 1.9.0)

A "hidden" layer called "WFSGetCapabilities" is filled with the raw XML result of the GetCapabilities request.

That layer is returned through GetLayerByName("WFSGetCapabilities").

Open options (GDAL >= 2.0)

The following options are available:

Examples

  • Listing the types of a WFS server :
    ogrinfo -ro WFS:http://www2.dmsolutions.ca/cgi-bin/mswfs_gmap
    

  • Listing the types of a WFS server whose layer structures are cached in a XML file:
    ogrinfo -ro mswfs_gmap.xml
    

  • Listing the features of the popplace layer, with a spatial filter :
    ogrinfo -ro WFS:http://www2.dmsolutions.ca/cgi-bin/mswfs_gmap popplace -spat 0 0 2961766.250000 3798856.750000
    
  • Retrieving the features of gml:id "world.2" and "world.3" from the tows:world layer :
    ogrinfo "WFS:http://www.tinyows.org/cgi-bin/tinyows" tows:world -ro -al -where "gml_id='world.2' or gml_id='world.3'"
    
  • Display layer metadata (OGR >= 1.9.0):
    ogrinfo -ro -al "WFS:http://v2.suite.opengeo.org/geoserver/ows" WFSLayerMetadata
    

    See Also