MapServer 发布服务都是通过 Mapfile 来配置的,WFS 服务也不例外,和配置 WMS 类似,发布 WFS 要在 Mapfile 配置文件中的 METADATA 部分添加关于 WFS 的键值对。只有在图层满足如下条件的时候, MapServer 才会包含 WFS 的功能:
point
、 line
、 polygon
三者之一;wfs_onlineresource
和 wfs_enable_request
必须设置。MapServer 本身可以配置支持 WFS,另外,还可以使用 TinyOWS 。使用 TinyOWS 能够支持 WFS-T ,实现在线编辑保存的功能。
我们在发布 WMS 的 Mapfile 配置基础上,添加 WFS 配置,下面是一个配置好 WMS 和 WFS 的 Mapfile 实例。
Mapfile 如下:
01 MAP
02 IMAGETYPE "PNG"
03 EXTENT -180 -90 180 90
04 SIZE 600 300
05 SHAPEPATH "/gdata"
06 IMAGECOLOR 255 255 255
07 WEB
08 METADATA
09 "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
37 END
相对于只配置 WMS 的 Mapfile,主要的改变在于 MAP 对象的 METADATA 子对象和 LAYER 对象的 METADATA 子对象,在 MAP 对象的 METADATA 中,增加的键值对包括:
wfs_title
,必需, GetCapabilities
请求中作为服务响应的 XML 文档的 title
元素返回;wfs_onlineresource
,必需,提供 wfs
的服务器地址;wfs_srs
,数据的空间参考系(Spatial Reference System);wfs_abstract
, GetCapabilities
请求中作为服务响应的 XML 文档的 Abstract
元素返回;wfs_enable_request
,表示配置 MapServer 地图全局支持 wfs
的所有操作。LAYER 对象的 METADATA 增加的键值对如下(注:配置和 MAP 对象的 METADATA 有很多重复,如果不设置,就会继承 MAP 对象的 METADATA 的配置,如果设置就会使用 LAYER 的配置,这在一个 MAP 对象包含多个 LAYER 时非常有用):
wfs_title
, GetCapabilities
请求中作为服务响应的 XML 文档的 title
元素返回;wfs_srs
,数据的空间参考系(Spatial Reference System);gml_featureid
,图层对应的要素 ID 属性名;wfs_enable_request
,配置图层支持 wfs 的所有操作。我们通过 URL 便可以调用 MapServer WFS 服务, WFS 缺省会返回 GML 格式的结果,在浏览器中可看其调用结果。WFS 包含很多操作,从 GetCapabilities
响应中可以看到 Mapfile 支持的 WFS 操作:
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
在操作数据库的时候,我们有时需要反射数据库的结构,在使用 WFS 的时候我们也存在同样问题。有时候我们需要知道某个FeatureType有哪些属性以及分别是什么类型,这时我们就需要 DescribeFeatureType
方法。一个典型的 DescribeFeatureType
调用是这样的:
下面是使用全球城市的:
配置的时候注意,
::
"gml_include_items" "all" # 这个关键词得注意, 不配置的话,默认是没有属性的。
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
终于到了这个方法,这个方法可以说是WFS的基础,它的用途一目了然,获得Feature。如果你敲入这个调用: 下面的链接返回所有的要素。
下面是使用全球城市的:
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
,可以限制返回的要素数目。
下面是使用全球城市的:
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
的要素 :
>>> [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>