6.1. Geographic Web Services#

MapServer publishing services are configured through Mapfile, and WFS services are no exception. Similar to configuring WMS, to publish WFS, add key-value pairs about WFS in the METADATA section of the Mapfile configuration file. MapServer will only include WFS functionality if the layer meets the following conditions:

  • The data source is vector data: shapefile, OGR, Postgis, sde (ArcSDE);

  • Layer name must be set;

  • The layer data space type must be one of point , line , polygon;

  • wfs_onlineresource and wfs_enable_request must be set.

MapServer itself can be configured to support WFS, and you can also use TinyOWS. Using TinyOWS can support WFS-T and realize the function of online editing and saving.

6.1.1. Configure an instance#

Based on the Mapfile configuration of the published WMS, add the WFS configuration. The following is a Mapfile instance with WMS and WFS configured.

Mapfile is as follows:

 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.pub/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

Compared with the Mapfile that only configures WMS, the main change lies in the METADATA sub-object of the MAP object and the METADATA sub-object of the LAYER object. In the METADATA of the MAP object, the added key-value pairs include:

  • wfs_title , required, returned in the GetCapabilities request as the title element of the XML document in the service response;

  • wfs_onlineresource, required, provide the server address of wfs;

  • wfs_srs, the spatial reference system of the data (Spatial Reference System);

  • wfs_abstract , returned by the Abstract element of the XML document in the GetCapabilities request as the service response;

  • wfs_enable_request, which means to configure MapServer map to support all operations of wfs globally.

The key-value pair added to the METADATA of the LAYER object is as follows (Note: There are many repetitions of the METADATA of the configuration and the MAP object. If it is not set, the METADATA configuration of the MAP object will be inherited. If it is set, the configuration of the LAYER will be used, which is in a MAP Useful when the object contains multiple layers):

  • wfs_title , returned by the title element of the XML document in the GetCapabilities request as the service’s response;

  • wfs_srs, the Spatial Reference System of the data;

  • gml_featureid , the attribute name of the feature ID corresponding to the layer;

  • wfs_enable_request , configures the layer to support all wfs operations.

6.1.2. Access#

We can call the MapServer WFS service through the URL. By default, WFS will return the result in GML format, and the call result can be viewed in the browser. WFS contains many operations, you can see the WFS operations supported by Mapfile from the GetCapabilities response:

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

The following are those that use cities around the world:

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

The URL is parsed as follows:

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

6.1.3. DescribeFeatureType#

When operating the database, we sometimes need to reflect the structure of the database, and we also have the same problem when using WFS. Sometimes we need to know what attributes a FeatureType has and what type they are, then we need the DescribeFeatureType method. A typical DescribeFeatureType call looks like this:

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

The following are those that use cities around the world:

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

Pay attention to when configuring

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

The URL is parsed as follows:

>>> [print(idx, x) for idx, x  in enumerate(url.split('&'))]
0 http://webgis.pub/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#

Finally arrived at this method, this method can be said to be the basis of WFS, its purpose is clear at a glance, get Feature. If you type this call: The link below returns all the elements.

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

The following are those that use cities around the world:

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

The URL is parsed as follows:

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

This call means that all the data is returned, usually resulting in a large XML/GML document.

A limited number of features can be returned#

By using parameters count=2 You can limit the number of features returned

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

The following are those that use cities around the world:

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

The resolution of URL is as follows:

>>> [print(idx, x) for idx, x in enumerate(url.split('&'))]
0 http://webgis.pub/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

Return features according to the index#

You can return features based on the index, and to do this, you need to configure:

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

Here OBJECTID Is a field in Shapefile.

The following link returns the ID number as 227 Elements of:

http://webgis.pub/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.pub/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

Use Filter#

According to the selector, such as:

http://webgis.pub/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>

The URL is resolved as follows:

>>> [print(idx, x) for idx, x  in enumerate(url.split('&'))]
0 http://webgis.pub/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>

More meaningfully, choose according to the name. Note the selection here, and the comparison of attributes is case-sensitive.

http://webgis.pub/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>

The resolution of URL is as follows:

>>> [print(idx, x) for idx, x  in enumerate(url.split('&'))]
0 http://webgis.pub/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>