This WCS investigation started off because my PDOKServicesPlugin was not working for the PDOK WCS services anymore. I wanted to see all fired network requests, so am creating a future plugin for that: https://github.com/rduivenvoorde/qgisnetworklogger. But I hit all kind of issues when trying out the service(s). This is some write up of my findings and hopefully is interesting enough for some people interested in WCS’s….
WCS is the WebCoverageService, an OGC api to serve Coverage data. In OGC terms a Coverage is “raster-data”: like geo tiff’s, ecw’s being rasterized, DEM’s (Digital Elevation Models) etc.
Our national opendata service: ‘PDOK’ has an WCS endpoint to the AHN (our national DEM available at max 50cm, though governmental agencies can go up to 10cm resolution).
One of the drawbacks of WCS is that there are already so many different versions: 1.0.0, 1.0.1, 1.1.2, 2.0.0, 2.1.0 etc etc
QGIS WCS provider supports the versions: 1.0.0, 1.1.0, 1.1.2.
WCS is part of the OWS-family of api’s: the ‘OGC Web Services’.
To determine the capabilities of a service you use (just like every other OWS service) a ‘GetCapabilities’-request, like:
This shows you the general information of the service, AND which datasets are available.
To fetch more information about one dataset, we use the ‘DescribeCoverage’-request, like:
(in newer versions of the WCS you also have to add the CoverageId to the request)
After you received this information (well, actually nothing more then some crs, layernames and dimension information, I’ve never understood why you would not add data statistic in this also…) you are ready to actually GET the data with a so called ‘GetCoverage’-request. In this request you set the desired data type.
And example to retrieve a part of our 5m National DEM around Haarlem as a tiff raster image:
Save this to disk and you can automagically load it in QGIS, because this is besides a true tiff-image also a geotiff, meaning it has some metadata in it keeping information about the crs (Coordinate Reference System/Projection) and it’s scale and place on earth:
As you can see, for example by using the identify tool, in this image there is just one ‘band’: Band 1. Where I clicked the data shows 43, note that this is NOT the height there, but the RGB value of the pixel in the position, going from 0 to 255. So this is NOT the actual data?
You can also load the following url in your browser to ask the service to provide a png image:
Saving THAT one to disk and loading it in QGIS shows you that it will NOT be placed nicely in the right position of the map. That is because a png image does NOT contain the mentioned metadata (you can provide it as a separate worldfile next to it though).
When you use QGIS to look into the png image, you will find 3 bands: 1,2 and 3 (actually RGB) all holding the same values.
So the service encoded the (actual) raster data into some kind of image where the values are spread over the range 0 till 255…. It is still possible to have some general view of the height variations in this area (actually not that much, besides the dunes in the west 🙂 ) by providing some styling to the png or tiff:
But what are the real data values of the cells of the raster?
To find that you can (either use the capabilities url and load the service via QGIS, OR use the following request, which should get exact the same data but encoded as 32 bit floats in a tiff (GEOTIFF_FLOAT32):
NOW you receive actual data, data in every cell has it’s (modelled) height in meters, ranging from -4.485 meter below seelevel (in the lower right corner) upto 55.5212 meter: I think some ‘high’ dunes in the west or maybe some tower 🙂
Mmm, not sure what is going on here, because measuring the cellen, they are not 0.5 meter x 0.5 meter ???
Let’s try the actual service then: use the GetCapabilities service url from above, create a WCS connection and request the ahn3_05m_dsm (raw data) in the format FLOAT32. This takes some time but NOW you will have 0.5×0.5m cells (though it takes some time to retrieve the data….
Open the Layer props, and from the ‘Render type’ dropdown just select ‘Hillshade’. Zoomed in at Haarlem, you will see:
Nice and easy he? The ‘mountain’ in the middle is an old ‘landfill’, now ‘recreation area’, 17 meters high.
What are the issues I hit with WCS?
WCS as Standard
– There are just too many variables and options in the ‘standard’. Because of that both WCS client-implementations AND WCS server-implementations often do not play well together. In my case the server change at PDOK from Geoserver -> Mapserver made the Formats totally different. NOT so much a problem if you have a highly configurable client like QGIS. But if you have a more simple client (as my plugin, or some OpenLayers or Leaflet plugin) it would be good if those formats stay more or like the same.
– All the capability documents are (very) different in the different versions
– So: please OGC: Keep It Simple and backward compatible please!
WCS and Server and Services
– the idea is that a WCS is able to server actual data. Why then are most server implementations also serving those image/rgb format (why a PNG with values of 0 – 255 if you want to know the height???). IF you want something like that, use a WMS to serve the data. So PDOK, maybe just only server the FLOAT32 version? As the height/data is in meters so having integers makes the height-resolution rather low.
– why do you not get back the real data if you request an area in float32 in a browser?
– Not sure how realistic it is to server a DEM from a small country like NL via WCS. As you can imagine the actual data is HUGE, so I was thinking: why did we not come up with WCTC (a Tiled version of the WCS) ???
WCS as client
– looking at all the requests QGIS is firing to the server, it seems like it tries to find out some stats first (for the whole dataset), killing the WCS or at least timing out pretty often. Not sure how valid the stats are from the whole extent (but created from the pyramid by gdal?). Anyway: in my view QGIS fires way to much requests to the server. In case of a tiny tiff serving as wcs that is not a problem, but the AHN/DEM of NL is just to big for that. WHY is that raster-statistics info not available in the GetCapabilities or DescribeCoverage response?
PDOK serving WCS’s
– why is PDOK (or it’s data-providers) using different values for the NODATA value for every different service. Can we try to use some standard for that (at least between those services of the same kin)? Like -9999 (as we know nowhere in NL we go that low…).
– should the AHN not being served as float32 only (and a WMS next to it if you want images)?
Serving the AHN as WCS is doable, but you really have to be patient, raise your network timeout value, hope that PDOK internally does not time out, find out about the data first by a lot of trial and error and THEN you can have fun.