Unlike WMS, a WFS request brings you the actual raw data in the form of features. By working with the features directly, you are no more dealing with a static rendering of features, that is, a map; you can take fine control of the shapes by setting drawing rules on the client side.
WFS comes in several different flavors or, more precisely, in different protocol versions. GeoServer supports 1.0.0, 1.1.0, and 2.0.0. Each version differs in the formats supported and the query capabilities supported. For example, WFS 2.0.0 supports the use of temporal queries and joins.
We are using a JavaScript application to perform a WFS query on GeoServer. This is a common use case in the era of web mapping, besides using the OpenLayers framework to assist you in building a complicated request.
The HTML and CSS part of the script is quite easy. As you must have noticed, the core of this little program is the init()
function, which is called at page loading.
We first create a map
object and set the allOverlays
variable to true
. The default value of false
makes it mandatory for a layer to be basemap
; in this recipe, we don't want to have basemap
, which is a layer that is always turned on in the map:
Then, we start to add data on the map. First, we use the raster data from the NASA Blue Marble dataset. We use the OpenLayers.Layer.WMS
class; you just need to set a name and URL for the WMS service. The format
and transparent
parameters are optional, but they let you control the file produced by GeoServer. The code is as follows:
Note
While we are using a raster dataset in this request, you can, of course, use vector data in the WMS request
Then we create a new layer using the OpenLayers.Layer.Vector
class, and this layer can use a different source data format:
We add a strategy, BBOX
, to let OpenLayers
query the server for data intersecting the current map extent:
With the protocol
parameter, we set the data format. Of course, we use WFS, and this class defaults to the 1.0.0 version of the standard:
We need to set some mandatory parameters when invoking the constructor for the WFS class. The geometryName
parameter is optional, but it defaults to the_geom
value. So, you need to set it to the actual name of the geometry column in your data. The code is as follows:
WFS returns raw data, not an image map like WMS. So, you need to draw each feature yourself; you have to set some rules for feature drawing. Inside the StyleMap
class, you set the color, line width, and other rendering parameters that will be used to represent features in the map, as shown in the following code:
What happens when you load this app in your browser? You can use a browser extension to check the actual request sent to GeoServer.
Note
Firebug is a powerful extension for FireFox, and with Chrome, you can use the developer console.
Using FireFox with Firebug, you should see a few requests upon loading the ch01_wfsVersion.html
file. OpenLayers executes the POST
WFS request with our parameters; you can see that the version is 1.0.0, the operation is GetFeature
, and there is a bounding box filter defined in GML 2:
Now, try to load the ch01_wfsVersion110.html
file; the request is a little bit different. Of course, now the version is 1.1.0, but the filter looks different as well:
You need to be aware that WFS 1.1.0 uses GML 3, which uses a different representation of geometry. In this case, OpenLayers hides the complexity of creating the correct geometry filter.
You probably noted when downloading the Blue Marble dataset that the GeoTIFF file is quite a big file. To render this file, GeoServer must navigate the file contents and read blocks of pixels off the disk. To optimize data storage and enhance rendering speed, you can use GDAL tools to restructure the contents of the file for faster access.
If you have GDAL tools at your fingertips, you can check the metadata of the file:
Now, let's transform the file using a compression method to reduce the file size and tile the dataset for faster access:
Tiling organizes the file contents on disk into tiles, ideally locating blocks of pixels next to each other on disk. This optimization helps in performance when GeoServer is zoomed in to a small area of interest.
Then, we will add an overview to further hasten the data extraction:
An overview creates a small summary image, which can be used by GeoServer when zoomed out. By drawing using the overview, GeoServer can read fewer pixels off disk and avoid having to sample through the entire file.
By executing the gdalinfo
tool again, you can check that these have actually been applied successfully: