Introduction to Web Feature Service¶
A Web Feature Service provides:
- A set of feature types (one per vector layer)
- The means to describe the attributes of each feature types
- The means to extract data, filtering it by location or alphanumeric attributes
- Starting with version WFS 1.1, the ability to reproject the output
- The (optional) means to edit the vector data
This allows a client to get to the source of the vector data, download it for later visualization and analysis, as well as performing editing over it without exposing the database directly on the internet.
This introduction showcases the WFS 1.0 protocol version, as it’s easier to explain compared to the newer 1.1 and 2.0 versions, in which a different axis order must be used depending on the requested coordinate reference system. The main concepts are similar and so are the requests.
GetCapabilities¶
Let’s have a look at a WFS capabilities document using this url:
http://localhost:8083/geoserver/ows?service=WFS&version=1.0.0&request=GetCapabilities
Note
The XML snippets have been simplified to better fit in the page. They often miss namespace declarations and some attributes, as well as some elements and text.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <?xml version="1.0" encoding="UTF-8"?>
<WFS_Capabilities xmlns="http://www.opengis.net/wfs">
<Service>
<Name>WFS</Name>
<Title>GeoServer Web Feature Service</Title>
<Abstract>This is the reference implementation of WFS 1.0.0 and WFS 1.1.0,
supports all WFS operations including Transaction.</Abstract>
<Keywords>WFS, GEOSERVER</Keywords>
<OnlineResource>http://geoserver.org</OnlineResource>
<Fees>NONE</Fees>
<AccessConstraints>NONE</AccessConstraints>
</Service>
<Capability>
<Request>
<GetCapabilities>
<DCPType>
<HTTP>
<Get onlineResource="http://localhost:8080/geoserver/wfs?request=GetCapabilities"/>
</HTTP>
</DCPType>
<DCPType>
<HTTP>
<Post onlineResource="http://localhost:8080/geoserver/wfs"/>
</HTTP>
</DCPType>
</GetCapabilities>
<DescribeFeatureType>
<SchemaDescriptionLanguage>
<XMLSCHEMA/>
</SchemaDescriptionLanguage>
<DCPType>
<HTTP>
<Get onlineResource="http://localhost:8080/geoserver/wfs?request=DescribeFeatureType"/>
</HTTP>
</DCPType>
<DCPType>
<HTTP>
<Post onlineResource="http://localhost:8080/geoserver/wfs"/>
</HTTP>
</DCPType>
</DescribeFeatureType>
<!-- skipped content -->
</Capability>
<!-- skipped content -->
</WFS_Capabilities>
|
The response as usual is divided into sections:
- A service section with contact information
- A capability section reporting the available requests and their output formats
- A contents section showing all available feature types
- An OGC filter capabilities section, listing what kind of filters (spatial and alphanumeric) the server is able to support
Scrolling down in the feature type list we can find a particular layer, named topp:states
, which
will be used for the following examples:
1 2 3 4 5 6 7 8 9 | <FeatureType>
<Name>topp:states</Name>
<Title>USA Population</Title>
<Abstract>This is some census data on the states.</Abstract>
<Keywords>census, united, boundaries, state, states</Keywords>
<SRS>EPSG:4326</SRS>
<LatLongBoundingBox minx="-124.731422" miny="24.955967"
maxx="-66.969849" maxy="49.371735"/>
</FeatureType>
|
DescribeFeatureType¶
Now let’s request more information for the states
layer using the DescribeFeatureType
request:
http://localhost:8083/geoserver/ows?service=WFS&version=1.0.0&request=DescribeFeatureType&typename=topp:states
Element | Description |
---|---|
http://localhost:8083/geoserver/ows? | The base URL |
service=WFS | The service |
version=1.0.0 | The service version |
request=DescribeFeatureType | The request |
typename=topp:states | The list of feature types that need to be described (comma separated, can be one) |
The output provides more information about the fields names and types as well as the geometry type, in this case MultiPolygon
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
<xsd:complexType name="statesType">
<xsd:complexContent>
<xsd:extension base="gml:AbstractFeatureType">
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="0" name="the_geom" nillable="true" type="gml:MultiPolygonPropertyType"/>
<xsd:element maxOccurs="1" minOccurs="0" name="STATE_NAME" nillable="true" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="STATE_FIPS" nillable="true" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="SUB_REGION" nillable="true" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="STATE_ABBR" nillable="true" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="LAND_KM" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="WATER_KM" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="PERSONS" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="FAMILIES" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="HOUSHOLD" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="MALE" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="FEMALE" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="WORKERS" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="DRVALONE" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="CARPOOL" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="PUBTRANS" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="EMPLOYED" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="UNEMPLOY" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="SERVICE" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="MANUAL" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="P_MALE" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="P_FEMALE" nillable="true" type="xsd:double"/>
<xsd:element maxOccurs="1" minOccurs="0" name="SAMP_POP" nillable="true" type="xsd:double"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="states" substitutionGroup="gml:_Feature" type="topp:statesType"/>
</xsd:schema>
|
GetFeature¶
Once the name and structure of the feautre type are known, it’s possible to issue a GetFeature
to retrieve the data. If no format is specified, a GML2 document will be returned (the default format
for this protocol).
A basic GetFeature
request, looks as follows:
http://localhost:8083/geoserver/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=topp:states
Element | Description |
---|---|
http://localhost:8083/geoserver/ows?service=WFS | The base URL |
service=WFS | The service |
version=1.0.0 | The service version |
request=GetFeature | The request |
typename=topp:states | The list of feature types that need to be described (comma separated, can be one) |
GetFeature in the layer preview¶
A request similar to the above one can also be found in the GeoServer preview page.
Navigate to the GeoServer Welcome Page.
On the Welcome page locate the Layer Preview link (no need to login).
Navigate to the WFS GML output of the states layer.
Depending on the browser, the output may be unformatted or recognized as XML. Here is a snippet of the output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <?xml version="1.0" encoding="UTF-8"?>
<wfs:FeatureCollection xmlns="http://www.opengis.net/wfs">
<gml:featureMember>
<topp:states fid="states.1">
<topp:the_geom>
<gml:MultiPolygon srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
<gml:polygonMember>
<gml:Polygon>
<gml:outerBoundaryIs>
<gml:LinearRing>
<gml:coordinates decimal="." cs="," ts=" ">
-88.071564,37.51099 -88.087883,
<!-- other ordinates skipped -->
,37.583572 -88.071564,37.51099</gml:coordinates>
</gml:LinearRing>
</gml:outerBoundaryIs>
</gml:Polygon>
</gml:polygonMember>
</gml:MultiPolygon>
</topp:the_geom>
<topp:STATE_NAME>Illinois</topp:STATE_NAME>
<topp:STATE_FIPS>17</topp:STATE_FIPS>
<topp:SUB_REGION>E N Cen</topp:SUB_REGION>
<topp:STATE_ABBR>IL</topp:STATE_ABBR>
<topp:LAND_KM>143986.61</topp:LAND_KM>
<topp:WATER_KM>1993.335</topp:WATER_KM>
<topp:PERSONS>1.1430602E7</topp:PERSONS>
<topp:FAMILIES>2924880.0</topp:FAMILIES>
<topp:HOUSHOLD>4202240.0</topp:HOUSHOLD>
<topp:MALE>5552233.0</topp:MALE>
<topp:FEMALE>5878369.0</topp:FEMALE>
<topp:WORKERS>4199206.0</topp:WORKERS>
<topp:DRVALONE>3741715.0</topp:DRVALONE>
<topp:CARPOOL>652603.0</topp:CARPOOL>
<topp:PUBTRANS>538071.0</topp:PUBTRANS>
<topp:EMPLOYED>5417967.0</topp:EMPLOYED>
<topp:UNEMPLOY>385040.0</topp:UNEMPLOY>
<topp:SERVICE>1360159.0</topp:SERVICE>
<topp:MANUAL>828906.0</topp:MANUAL>
<topp:P_MALE>0.486</topp:P_MALE>
<topp:P_FEMALE>0.514</topp:P_FEMALE>
<topp:SAMP_POP>1747776.0</topp:SAMP_POP>
</topp:states>
<!-- Other features would be here -->
</gml:featureMember>
</wfs:FeatureCollection>
|
In the next section we will see how to filter the WFS output based on various attributes.