GeoTools : Using Grid Coverage Exchange

work in progress (please help)


To access a Grid Coverage (rasters described in the Using Grid Coverage) in geotools you need to use the new GridCoverageExchange interface.

See the GridCoverageExchange design notes for some more information than that presented below.

To use GridCoverageExchanges:

The GridCoverageExchange interface allows you to read and write grid coverages from and to persistent formats (files). This can be thought of as a peer to the DataStore interface.

Currently there are three GridCoverageExchange implementations:



StreamGridCoverageExchange is the simplest incarnation.

Using StreamGridCoverage:

Reading – Creating a GridCoverage

  • Get the list of Format objects from the exchange
  • Call the accepts( *Object* ) to see if the format can interpret the object
    • Object can be a stream, URL, file or even a URL formatted String
    • Accepts() in some implementations isn't good so if you know the format type then it is better to choose by name
  • call getReader(Object) to obtain a reader
    • Object can be a stream, URL, file or even a URL formatted String
  • call to create a GridCoverage

The following code sample is from the SpearFishSample described on the Demo Code page. The GridCoverageExchange is similar to the DataStoreFinder and the Format is similar to a DataStore. The Format object describes any parameters needed to read and write the grid coverage and is use to obtain a reader and writer.

// create the grid coverage reader
URL url = ArcGridReader.class.getClassLoader().getResource("org/geotools/sampleData/spearfish_dem.asc.gz");
GridCoverageExchange gce = new StreamGridCoverageExchange();
GridCoverageReader reader = gce.getReader(url);
Format format = reader.getFormat();
//get the parameters and set them
ParameterDescriptorGroup paramDescriptor = format.getReadParameters();
ParameterGroup params = (ParameterGroup) paramDescriptor.createValue();
params.parameter( "Compressed" ).setValue( true );
params.parameter( "GRASS" ).setValue( true );
//read the grid
GridCoverage gcDem = params );

Alternately, the Format object can be created directly from its constructor, by passing the GridCoverageExchange. This method is similar to creating a DataStore from its constructor and is use in the ArcGridReader demo .

URL url = ArcGridReader.class.getClassLoader().getResource("org/geotools/sampleData/spearfish_dem.asc.gz");
Format f = new org.geotools.gce.arcgrid.ArcGridFormat();
GridCoverageReader reader = f.getReader(url);

Writing – Writing a GridCoverage

  • Get the list of Format objects from the exchange
  • Choose the output format
  • call getWriter(Output) to obtain a writer
    • Object can be a stream, URL, file or even a URL formatted String
  • call writer.write() to write the GridCoverage to an output stream


FileSystemGridCoverageExchange has all the same functionality of StreamGridCoverage except that is also a catalog for a FileSystem. See the org.opengis.catalog for the Catalog interfaces.

Some of the functionality provided by Catalog is the following:

  • Browse the entire Catalog:
    • call the iterator() method to browse all CatalogEntries
  • Query the catalog
    • Create a org.geotools.metadata.Query (May soon move to catalog package)
    • Create a org.geotools.catalog.QueryDefinition passing the Query to the constructor
    • call query( QueryDefinition ) to obtain a QueryResult that contains all the CatalogEntries that match the query

A CatalogEntry has a Metadata that describes the file, it has a name and a date for example. The FileMetadata subclass also contains a Format object that can read the file. If a format exists, otherwise a object is referenced. Finally the CatalogEntry also has a reference to the File that is refers to. The File can be obtained using the getResource() method.

This needs some sample code showing the use of the GCE.


This needs to be updated. The Parameter API has changed considerably.

The WMSGridCoverageExchange is used to retrieve GridCoverages from OGC Web Map Servers. It is not possible to write to Web Map Servers, so the write methods do not work.

This grid coverage exchange works a little different compared to the others, as the API had to be bent a bit to allow it to function properly.

The basic steps:

  • Create a WMSGridCoverageExchange, passing it the URL of a Web Map Server's getCapabilities document.
  • Retrieve a WMSReader from the exchange. This is used to read a GridCoverage.
  • Retrieve a WMSFormat from the reader. This is used to access and create parameters for the reader. It is vital that you retrieve the WMSFormat from the WMSReader and do not create your own.
  • Retrieve the parameters from the WMSFormat using .getReadParameters();
  • Set up the parameters.
  • Call read on the WMSReader to retrieve a GridCoverage.

The class in plugin/wms/test has an example of using the WMSGridCoverageExchange.

Parsing the parameters is a little more complicated. The example does so by looping through the array returned by format.getReadParameters() and checking each one. Most of the time it uses the available defaults. Not all parameters have defaults available, so it is best to check first.

The layers parameter is a little more complex and required a bit of a hack to work. Ignore the validValues parameter and instead look at parameter.getAvailableLayers(). This is a list containing several SimpleLayer classes, each representing a layer in the GetCapabilities document. Each SimpleLayer contains the name of the layer it represents, as well as the set of all the styles that that layer can use. You must set the style to one of those. The list that is then passed into the new WMSParameterValue() constructor is ordered. The SimpleLayer at index 0 is drawn at the bottom of the map, with the last SimpleLayer on top.

Here is some example code:
Setting up the exchange, reader, and format:

URL server = new URL("");
WMSGridCoverageExchange exchange = new WMSGridCoverageExchange(server);
WMSReader reader = (WMSReader) exchange.getReader(server);
WMSFormat format = (WMSFormat) reader.getFormat(); 

Setting up the parameters:

WMSParameterValue[] params = new WMSParameterValue[16];
GeneralOperationParameter[] newParams = format.getReadParameters();
for (int i = 0; i < newParams.length; i++) {
	WMSOperationParameter parameter = (WMSOperationParameter) newParams[i];
	if (parameter.getName(null).equals("LAYERS")) {
		ArrayList layerList = new ArrayList();
		List availableLayers = parameter.getAvailableLayers();
		for (int j = 0; j < availableLayers.size(); j++) {
			SimpleLayer simpleLayer = (SimpleLayer) availableLayers.get(j);
			layerList.add(j, simpleLayer);
		params[i] = new WMSParameterValue(layerList, parameter);
	if (parameter.getName(null).equals("FORMAT")) {
		Iterator iter = parameter.getValidValues().iterator();
		if (iter.hasNext()) {
			String format = (String);
			params[i] = new WMSParameterValue(format, parameter);
	if (parameter.getName(null).equals("WIDTH") || parameter.getName(null).equals("HEIGHT")) {
		params[i] = new WMSParameterValue("400", parameter);

	params[i] = new WMSParameterValue(parameter.getDefaultValue(), parameter);

Retrieving a GridCoverage:

GridCoverage coverage =;