6.1. 地理Web服务

MapServer发布服务是通过Mapfile配置的,WFS服务也不例外。与配置WMS类似,要发布WFS,请在Mapfile配置文件的元数据部分添加关于WFS的键值对。只有在图层满足以下条件时,MapServer才会包含WFS功能:

  • 数据源为矢量数据:Shapefile、OGR、Postgis、SDE(ArcSDE);

  • 必须设置层名称;

  • 图层数据空间类型必须为以下类型之一 pointlinepolygon

  • wfs_onlineresourcewfs_enable_request 必须设置。

MapServer本身可以配置为支持WFS,也可以使用TinyOWS。使用TinyOWS可以支持WFS-T,并实现在线编辑和保存功能。

6.1.1. 配置实例

根据发布的WMS的Mapfile配置,添加WFS配置。以下是配置了WMS和WFS的Mapfile实例。

Mapfile如下:

 1MAP
 2    IMAGETYPE "PNG"
 3    EXTENT -180 -90 180 90
 4    SIZE 600 300
 5    SHAPEPATH "/gdata"
 6    IMAGECOLOR 255 255 255
 7    WEB
 8        METADATA
 9            "wfs_title" "world country"
10            "wfs_onlineresource" "http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map"
11            "wfs_srs" "EPSG:4326"
12            "wfs_abstract" "This text describes your wfs service"
13            "wfs_enable_request" "*"
14            "ows_keywordlist" "world"
15        END
16    END
17    LAYER
18        NAME "world-country"
19        DATA "wcountry.shp"
20        STATUS OFF
21        TYPE POLYGON
22        METADATA
23            "wfs_title" "worldcountry"
24            "wfs_srs" "EPSG:4326"
25            "wfs_enable_request" "*"
26            "gml_include_items" "all"
27            "gml_featureid" "OBJECTID"
28        END
29        CLASS
30            NAME "The Upper Great Lakes States"
31            STYLE
32                COLOR 232 232 232
33                OUTLINECOLOR 32 32 32
34            END
35        END
36    END
37END

与只配置WMS的Mapfile相比,主要的变化在于地图对象的元数据子对象和Layer对象的元数据子对象。在MAP对象的元数据中,添加的键值对包括:

  • wfs_title ,必填,在 GetCapabilities 请求中作为服务响应XML文档的 title 元素返回;

  • wfs_onlineresource ,提供的服务器地址为 wfs

  • wfs_srs ,数据的空间参照系(Spatial Reference System);

  • wfs_abstract ,由 GetCapabilities 请求中XML文档的 Abstract 元素返回作为服务响应;

  • wfs_enable_request ,这意味着要将MapServer地图配置为为全局支持 wfs 的所有操作。

添加到Layer对象的元数据的键值对如下(注:配置和地图对象的元数据有很多重复。如果不设置,将继承地图对象的元数据配置。如果设置了该值,将使用该层的配置,当对象包含多个层时,该配置在地图中非常有用):

  • wfs_title ,由 title 元素中XML文档的 GetCapabilities 请求作为服务的响应;

  • wfs_srs ,数据的空间参考系;

  • gml_featureid ,该层对应的特征ID的属性名称;

  • wfs_enable_request ,将层配置为支持所有WFS操作。

6.1.2. 访问

我们可以通过URL调用MapServer WFS服务。默认情况下,WFS会以GML格式返回结果,可以在浏览器中查看调用结果。WFS包含许多操作,可从``GetCapabilities`` 回应:

http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetCapabilities

以下是那些在世界各地使用城市的公司:

http://webgis.cn/cgi-bin/mapserv?map=/owg/mft2.map&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetCapabilities

URL的解析方式如下:

>>> [print(idx, x) for idx, x  in enumerate(url.split('&'))]
0 http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map
1 SERVICE=WFS
2 VERSION=2.0.0
3 REQUEST=GetCapabilities

6.1.3. DescribeFeatureType

在操作数据库时,有时需要反映数据库的结构,使用WFS时也存在同样的问题。有时我们需要知道FeatureType具有哪些属性以及它们是什么类型,同时需要 DescribeFeatureType 方法。典型的 DescribeFeatureType 调用如下所示:

http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map&service=WFS&VERSION=2.0.0&request=DescribeFeatureType&TypeName=world-country

以下是那些在世界各地使用城市的公司:

http://webgis.cn/cgi-bin/mapserv?map=/owg/mf21.map&service=WFS&VERSION=2.0.0&request=DescribeFeatureType&TypeName=world-country

配置时请注意

"gml_include_items" "all" #  Note that this keyword has no attributes by default if it is not configured.

URL的解析方式如下:

>>> [print(idx, x) for idx, x  in enumerate(url.split('&'))]
0 http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map
1 service=WFS
2 VERSION=2.0.0
3 request=DescribeFeatureType
4 TypeName=world-country

6.1.4. GetFeature

最终得出了这种方法,这种方法可以说是WFS的基础,其目的是一目了然,获取功能。如果输入此调用:下面的链接将返回所有元素。

http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map&service=WFS&VERSION=2.0.0&request=GetFeature&TypeName=world-country

以下是那些在世界各地使用城市的公司:

http://webgis.cn/cgi-bin/mapserv?map=/owg/mft2.map&service=WFS&VERSION=2.0.0&request=GetFeature&TypeName=world-country

URL的解析方式如下:

>>> [print(idx, x) for idx, x  in enumerate(url.split('&'))]
0 http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map
1 service=WFS
2 VERSION=2.0.0
3 request=GetFeature
4 TypeName=world-country

该调用意味着返回所有数据,通常会产生一个大的XML/GML文档。

可以返回的要素数量有限

通过使用参数 count=2 可限制返回的要素数量

http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map&service=WFS&VERSION=2.0.0&request=GetFeature&TypeName=world-country&count=2

以下是那些在世界各地使用城市的公司:

http://webgis.cn/cgi-bin/mapserv?map=/owg/mft2.map&service=WFS&VERSION=2.0.0&request=GetFeature&TypeName=world-country&count=2

URL的解析方式如下:

>>> [print(idx, x) for idx, x in enumerate(url.split('&'))]
0 http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map
1 service=WFS
2 VERSION=2.0.0
3 request=GetFeature
4 TypeName=world-country
5 count=2

根据索引返回要素

可根据索引返回要素,为此需要配置:

"gml_include_items" "all" ## Optional (serves all attributes for layer)
"gml_featureid"     "OBJECTID" ## REQUIRED

此处 OBJECTID 是Shapefile中的一个字段。

下面的链接将ID号返回为 227 以下元素:

http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map&service=WFS&VERSION=2.0.0&request=GetFeature&TypeName=world-country&FeatureId=world-country.227

>>> [print(idx, x) for idx, x  in enumerate(url.split('&'))]
0 http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map
1 service=WFS
2 VERSION=2.0.0
3 request=GetFeature
4 TypeName=world-country
5 FeatureId=world-country.227

使用滤镜

根据选择器,例如:

http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map&service=WFS&VERSION=2.0.0&request=GetFeature&TypeName=world-country&Filter=<Filter><PropertyIsEqualTo><PropertyName>OBJECTID</PropertyName><Literal>227</Literal></PropertyIsEqualTo></Filter>

该URL的解析方式如下:

>>> [print(idx, x) for idx, x  in enumerate(url.split('&'))]
0 http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map
1 service=WFS
2 VERSION=2.0.0
3 request=GetFeature
4 TypeName=world-country
5 Filter=<Filter><PropertyIsEqualTo><PropertyName>OBJECTID</PropertyName><Literal>227</Literal></PropertyIsEqualTo></Filter>

更有意义的是,根据名字来选择。请注意此处的选择,属性的比较区分大小写。

http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map&service=WFS&VERSION=2.0.0&request=GetFeature&TypeName=world-country&Filter=<Filter><PropertyIsEqualTo><PropertyName>NAME</PropertyName><Literal>CHINA</Literal></PropertyIsEqualTo></Filter>

URL的解析方式如下:

>>> [print(idx, x) for idx, x  in enumerate(url.split('&'))]
0 http://webgis.cn/cgi-bin/mapserv?map=/owg/mfw1.map
1 service=WFS
2 VERSION=2.0.0
3 request=GetFeature
4 TypeName=world-country
5 Filter=<Filter><PropertyIsEqualTo><PropertyName>NAME</PropertyName><Literal>CHINA</Literal></PropertyIsEqualTo></Filter>