第8章 OGC Web Feature Service
WFS标准定义了一套对地理要素访问的接口和支持事务的框架,且以独立于底层数据源的方式提供。用户通过WFS提供的操作对空间或属性数据进行查询,设置样式,编辑(创建,更新和删除)以及下载。更多信息请访问OGC官网(http://www.opengeospatial.org/standards/wfs)。
8.1 WFS版本差异
OGC WFS有三个版1.0.0,1.1.0和2.0.0,这三个版本间有一些细微差别:
-
WFS 1.1.0和2.0.0将以GML3作为默认的GML返回,而在WFS
1.0.0中,默认值为GML2。GML3采用略微不同的方式来描述几何体。GeoServer支持GML3和GML2格式的请求。 -
在WFS
1.1.0和2.0.0中,SRS(空间参考系统或投影)是用urn:x-ogc:def:crs:EPSG:XXXX方式描述,而在WFS
1.0.0中,规范是http://www.opengis.net/gml/srs/epsg.xml#XXXX,这一不同导致返回数据的X和Y轴顺序。WFS
1.0.0以经度/纬度(x/y)顺序返回地理坐标,这是最常用的方式。但是,在传统的地理和制图系统中轴顺序是相反的纬度/经度(y/x),后来的WFS规范也是这样。 -
WFS 1.1.0和2.0.0支持数据的动态重投影,支持重投影到与自身SRS不同的SRS。
-
WFS 2.0.0引入了新的过滤器编码规范,增加了对时间过滤器的支持。
-
WFS 2.0.0通过GetFeature请求支持连接查询。
-
WFS
2.0.0增加了通过startIndex和count参数对GetFeature请求结果进行分页的功能。但GeoServer支持在WFS
1.0.0和1.1.0中使用此功能。 -
WFS
2.0.0支持存储查询,这些存储查询是存储在服务器上的常规WFS查询,因此可以通过使用WFS请求时传递一个适当的标识符来调用它们。 -
WFS 2.0.0支持使用SOAP(简单对象访问协议)替代OGC接口。
注意:参数名称也有两处更改,可能会导致混淆。WFS
2.0.0使用count参数来限制返回的要素数量,而不是先前版本中使用的maxFeatures参数。WFS
2.0.0中将之前的typeName改为typeNames,但是在GeoServer中typeNames在之前的版本中也会被接受。
8.2 WFS 操作
WFS请求中包含以下操作:
操作 | 描述 |
---|---|
GetCapabitities | 返回服务级元数据,它是对服务信息内容和请求参数的一种描述。 |
DescribeFeatureType | 返回WFS服务支持的FeatureType的描述。 |
GetFeature | 根据请求参数,查询并返回符合条件的要素。 |
LockFeature | 通过持久性功能锁禁止编辑功能。 |
Transaction | 编辑(创建,更新和删除)现有FeatureType。 |
在2.0.0版中提供以下操作:
操作 | 描述 |
---|---|
GetPropertyValue | 通过使用查询表达式,从数据存储中检索要素属性的值或要素属性值的一部分。 |
GetFeatureWithLock | 查询要素并且将这些要素在后续的事务操作中处于锁定状态。 |
CreateStoredQuery | 根据请求参数,查询并返回符合条件的要素。 |
DropStoredQuery | 通过持久性功能锁禁止编辑功能。 |
ListStoredQueries | 编辑(创建,更新和删除)现有FeatureType。 |
DescribeStoredQueries | 返回每个存储查询的详细描述信息。 |
8.2.1 GetCapabilities
GetCapabilities操作获取WFS的功能文档,包括支持的操作,地图服务,数据等元数据信息。
GetCapabilities的请求参数:
参数 | 是否必须 | 描述 |
---|---|---|
service | 是 | 服务名称,对于WFS服务,当然是“WFS”了。 |
version | 是 | 服务版本,可以是1.0.0、1.1.0和2.0.0。 |
request | 是 | 操作名称,这里是GetCapabilities。 |
根据规范上述所有参数都是必需的,但对于GeoServer可以省略任意参数,GeoServer将提供默认值。
下面是一个GetCapabilities的GET请求示例:
http://localhost:8080/geoserver/wfs?service=wfs&version=1.1.0&request=GetCapabilities
因为GET请求的数据量有限制,一般用POST请求,以上请求的等效请求为:
Url为http://localhost:8080/geoserver/wfs;
Body为xml文档:
<GetCapabilities
service = “WFS”
xmlns = “http://www.opengis.net/wfs”
xmlns:xsi = “http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation = “http: //www.opengis.net/wfs
http://schemas.opengis.net/wfs/1.1.0/wfs.xsd“ />
GetCapabilities返回一个冗长的XML文档,且不同的版本其格式有可能不同。GetCapabilities文档中有五个主要部分:
名称 | 描述 |
---|---|
ServiceIdentification | 包含服务的基本信息,例如标题、关键字、服务类型等。这些内容的配置参见3.2.1。 |
ServiceProvider | 提供有关发布WFS服务的公司的联系信息,包括电话,网站和电子邮件。这些内容在“关于和状态”中的“联系方式”配置。 |
OperationsMetadata | 描述WFS服务器支持的操作以及每个操作的参数。但并不是说WFS服务器实现了所有的操作。 |
FeatureTypeList | 列出WFS服务器发布的FeatureType(类似于WMS服务中的layer,可以理解为图层)。还列出了每个FeatureType的投影信息,边界范围等。 |
Filter_Capabilities | 列出可用于组成查询语句的过滤器(可以称作表达式),例如空间操作SpatialOperators(Equals,Touches等)和逻辑操作ComparisonOperators(LessThan,GreaterThan等)。 |
GeoServer的WFS功能文档可通过欢迎页面中的服务能力获取,请参见1.2.8节。
8.2.2 DescribeFeatureType
DescribeFeatureType在请求实际数据之前请求有关单个FeatureType的信息。具体而言,该操作将获取指定FeatureType的要素和属性列表,或者不指定FeatureType时列出可用的FeatureType。
DescribeFeatureType的请求参数:
参数 | 是否必须 | 描述 |
---|---|---|
service | 是 | 服务名称,对于WFS服务,当然是“WFS”了。 |
version | 是 | 服务版本,可以是1.0.0、1.1.0和2.0.0。 |
request | 是 | 操作名称,这里是DescribeFeatureType。 |
typeNames | 是 | 要描述的FeatureType的名称(WFS 1.1.0和更早版本中使用typeName)。GeoServer中可不指定该参数,则返回可用的FeatureType列表。 |
exceptions | 否 | 异常报告的输出格式,默认为application/ vnd.ogc.se_xml |
outputFormat | 否 | 输出格式,默认为xml。 |
下面是一个DescribeFeatureType的GET请求示例:
8.2.3 GetFeature
GetFeature操作即从数据源中查询数据并返回。
GetFeature操作的参数较多,可自由组合从而支持多样的查询条件,下面给出几个例子。
获取指定FeatureType的所有要素的空间和属性信息:
通过包含featureID(即FeatureType的id)来获取单个要素:
使用count(WFS 2.0.0)或maxFeatures(WFS
2.0.0之前的版本)参数设置最大返回要素数量:
使用sortBy参数可以根据属性值对返回的数据进行排序:
默认排序操作是按升序排序,在属性名上附加一个+A,表示升序。相反,+D表示按降序排序,如下所示:
若只想获取某个属性,请使用propertyName参数。您可以指定单个属性,也可以指定用逗号分隔的多个属性:
GetFeature也支持空间查询,如指定BBOX参数可查询一个范围的要素。BBOX的值是表示一个矩形范围的四至,坐标顺序取决于使用的坐标系,一般为minx,miny,maxx,maxy。另外可通过srsName指定您希望使用的坐标系。
空间查询的GET请求中可用的条件有限, POST请求则有更多可用选项。
另外还有geometryName指定使用的空间字段、startIndex用于分页、filter支持更复杂的查询等。
8.2.4 LockFeature
LockFeature操作提供了一个持久性锁定机制,确保编辑事务的一致性。在一个客户端提交对某个要素的修改之前,锁会阻止其他客户端对同一要素进行更改,从而确保最高级别的事务隔离。如果WFS服务器支持此操作,它将在GetCapabilities响应中体现。
下面是一个LockFeature的GET请求示例:
http://localhost:8080/geoserver/wfs?service=wfs&version=2.0.0&request=LockFeature&typeNames=namespace:featuretype
8.2.5 Transaction
Transaction操作可以创建,修改和删除由WFS发布的数据。每个事务将包含零个或多个Insert,Update或Delete操作,每个事务按顺序执行。每个GeoServer事务都是原子的,这意味着如果任何一个操作失败,则放弃整个事务,并且数据不会更改。支持事务的
WFS服务器有时称为WFS-T服务器。GeoServer完全支持事务。
下面是一个Transaction的POST请求的Body示例:
<wfs:Transaction service="WFS" version="1.0.0"
xmlns:cdf="http://www.opengis.net/cite/data"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:wfs="http://www.opengis.net/wfs"
xmlns:topp="http://www.openplans.org/topp">
<wfs:Delete typeName="topp:tasmania_roads">
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>topp:TYPE</ogc:PropertyName>
<ogc:Literal>alley</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
</wfs:Delete>
</wfs:Transaction>
8.2.6 GetPropertyValue
通过使用查询表达式,从数据存储中检索要素属性的值或要素属性值的一部分。
以下示例检索topp:states图层中要素的空间属性:
其中,valueReference参数的值表示要检索的属性。
8.2.7 GetFeatureWithLock
GetFeatureWithLock操作类似于GetFeature,不同之处在于当查询到的要素从WFS服务器返回后,这些要素在后续的事务操作中也处于锁定状态。
以下示例使用POST方法检索topp:states图层的要素,且将这些要素锁定五分钟。
<wfs:GetFeatureWithLock service='WFS' version='2.0.0'
handle='GetFeatureWithLock-tc1' expiry='5' resultType='results'
xmlns:topp='http://www.openplans.org/topp'
xmlns:fes='http://www.opengis.net/fes/2.0'
xmlns:wfs='http://www.opengis.net/wfs/2.0'
valueReference='the_geom'>
<wfs:Query typeNames='topp:states'/>
</wfs:GetFeatureWithLock>
其中,expiry参数表示锁定的时间。
8.2.8 CreateStoredQuery
WFS支持将一个查询存储在服务器上,有时我们的查询很复杂且频繁使用,就可以定义存储查询,之后就像调用函数一样调用该存储查询来实现具体的功能。
CreateStoredQuery操作用来创建一个存储查询,通过StoredQueryDefinition参数定义该存储查询,并设置一个id以便在具体的查询操作中引用(就好比是函数名)。
以下示例使用POST方法创建存储查询,该查询是查询World:COUNTRY的place属性中包含{name}的要素,其id为GetFeatureByName。
<CreateStoredQuery xmlns="http://www.opengis.net/wfs/2.0" service="WFS" version="2.0.0">
<StoredQueryDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="GetFeatureByName">
<Title>GetFeatureByName</Title>
<Abstract>Returns feature representations by name. The name value must occur in a gml:name property.</Abstract>
<Parameter name="name" type="xsd:string">
<Abstract>Name of feature instance (required)</Abstract>
</Parameter>
<QueryExpressionText xmlns:fes="http://www.opengis.net/fes/2.0"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:ns42="http://cite.opengeospatial.org/gmlsf"
isPrivate="false"
language="urn:ogc:def:queryLanguage:OGC-WFS::WFSQueryExpression"
returnFeatureTypes="World:COUNTRY">
<Query typeNames="World:COUNTRY">
<fes:Filter>
<fes:PropertyIsLike escapeChar="\\" singleChar="?" wildCard="*">
<fes:ValueReference>gml:place</fes:ValueReference>
<fes:Literal>*${name}*</fes:Literal>
</fes:PropertyIsLike>
</fes:Filter>
</Query>
</QueryExpressionText>
</StoredQueryDefinition>
</CreateStoredQuery>
若想要在GetFeature中使用该存储查询则可以使用如下请求:
8.2.9 DropStoredQuery
DropStoredQuery操作用于删除由CreateStoredQuery操作创建的存储查询。请求参数是要删除的存储查询的ID。
http://localhost:8080/geoserver/wfs?request=DropStoredQuery&storedQuery_Id=GetFeatureByName
8.2.10 ListStoredQueries
ListStoredQueries操作返回当前由WFS服务器维护的存储查询列表。
请求如下所示:
http://localhost:8080/geoserver/wfs?request=ListStoredQueries&service=wfs&version=2.0.0
返回结果如下所示:
<wfs:StoredQueryDescription id="urn:ogc:def:query:OGC-WFS::GetFeatureById">
<wfs:Title xml:lang="en">Get feature by identifier</wfs:Title>
<wfs:Parameter name="ID" type="xs:string"/>
<wfs:QueryExpressionText isPrivate="true" language="urn:ogc:def:queryLanguage:OGC-WFS::WFSQueryExpression" returnFeatureTypes=""/>
</wfs:StoredQueryDescription>
<wfs:StoredQueryDescription id="GetFeatureByName">
<wfs:Title xml:lang="en">GetFeatureByName</wfs:Title>
<wfs:Abstract xml:lang="en">…</wfs:Abstract>
<wfs:Parameter name="name" type="xs:string">
<wfs:Abstract xml:lang="en">…</wfs:Abstract>
</wfs:Parameter>
<wfs:QueryExpressionText isPrivate="false" language="urn:ogc:def:queryLanguage:OGC-WFS::WFSQueryExpression" returnFeatureTypes="World:COUNTRY">
<wfs:Query wfs:typeNames="World:COUNTRY">
<fes:Filter>
<fes:PropertyIsLike wfs:escapeChar="\\" wfs:singleChar="?" wfs:wildCard="*">
<fes:ValueReference>gml:place</fes:ValueReference>
<fes:Literal>*${name}*</fes:Literal>
</fes:PropertyIsLike>
</fes:Filter>
</wfs:Query>
</wfs:QueryExpressionText>