General

How do I create and use a GridCoverage2D?

See the overview in the module home page.


How do I change the CRS of an existing GridCoverage2D?

GridCoverage2D instances are mostly immutable; their CRS can not be changed. If a change need to be performed - for example because the coverage has been created with the wrong CRS by a code that can't be easily fixed - then a new GridCoverage2D instance need to be created with the data of the previous coverage:

GridCoverage2D oldGC = ...;
GridCoverageBuilder builder = new GridCoverageBuilder();
builder.setGridCoverage(oldGC);
builder.setCoordinateReferenceSystem(newCRS);
GridCoverage2D newGC = builder.getGridCoverage2D();

Note that this FAQ is about fixing a CRS value which was wrong in the first place. In order to reproject the pixel values to a new CRS, use the resample operation.

Image I/O

How do I get the minimal and maximal values stored in a NetCDF file?

When using the Java Image I/O API, this kind of information can be stored in an IIOMetadata object. The Geotk project defines a format-neutral spatial format as a subset of the ISO 19115-2 metadata standard with few additions. If the NetCDF file defines explicit minimal and maximal values, then they should appear in the minValue and maxValue nodes of the above-cited metadata tree. A convenient way to access those values is as below:

NetcdfImageReader reader = ...;
SpatialMetadata metadata = reader.getImageMetadata(0);

// From that point, there is a choice. You can explore
// the metadata using the standard API like a XML tree.
// Or you can use the convenience methods below.

List<SampleDimension> bands = metadata.getListForType(SampleDimension.class);
SampleDimension firstBand = bands.get(0);
Double minValue = firstBand.getMinValue(); // WARNING: Can be null!
Double maxValue = firstBand.getMaxValue(); // WARNING: Can be null!

Tip: If you wish to explore visually the metadata found in the NetCDF file, then the ImageFileChooser widget (defined in the geotk-widgets-swing module) may be useful:

ImageFileChooser chooser = new ImageFileChooser("NetCDF", true);
chooser.showOpenDialog(null);

Select the NetCDF file, click on the "Metadata" tabs on the right side and select the metadata format in the combo box. The metadata tree should appear just below the combo box.


I only get a gray rectangle for my NetCDF image.

Some file formats like NetCDF do not contain color information. In such case, the color palette (a gray scale by default) is applied by the ImageReader. That color palette is scaled from the minimal value to the maximal value, which need to be provided by the image reader in an IIOMetadata object. If this information is missing, then the color palette will be scaled for an arbitrary range, typically much too large resulting in all useful values looking the same color.

Using the ImageFileChooser widget (introduced in the above tip), select the file, click on the Metadata tab and select Geospatial - your image in the combo box where "your image is the name of the image to load. In the tree below the combo box, expand the Image Description node, then Dimensions and the specific dimension to inspect. Check if the min value and max value nodes exist, and if their values are reasonable.

If the minimal and maximal values do not appear, they can be specified explicitly either by using the geotk-coverage-sql module, or by creating a subclass like below:

class MyReader extends NetcdfImageReader {
    @Override
    protected SpatialMetadata createMetadata(int imageIndex) throws IOException {
        SpatialMetadata metadata = super.createMetadata(imageIndex);
        if (imageIndex >= 0) {
            double minValue, maxValue = ...; //  Get your min and max values here.
            MetadataAccessor accessor = new MetadataAccessor(metadata, SpatialMetadataFormat.FORMAT_NAME,
                    "ImageDescription/Dimensions", "Dimension");
            accessor.selectChild(0); // You may use an other index than 0 if there is many children.
            accessor.setAttribute("minValue", minValue);
            accessor.setAttribute("maxValue", maxValue);
        }
        return metadata;
    }
}

How do I declare the actual georeferencing of an image file?

The Coordinate Reference System (CRS) in an image file should be detected automatically by the Image I/O plugin. However is some circonstances the plugin may fail to detect the CRS.

Using the ImageFileChooser widget (introduced in the above tip), select the file, click on the Metadata tab and select Geospatial - your image in the combo box where "your image is the name of the image to load. In the tree below the combo box, expand the Rectified Grid Domain node. Some sub-nodes of special interest are:

  • If Coordinate reference system is missing or contains irrelevant information, then a CRS will need to be specified explicitely.
  • If Offset vectors is missing or contains wrong information, then a grid to CRS transform will need to be specified.

Those metadata can be specified explicitely in a manner similar to the way minimal and maximal values were set in the above FAQ:

class MyReader extends NetcdfImageReader {
    @Override
    protected SpatialMetadata createMetadata(int imageIndex) throws IOException {
        SpatialMetadata metadata = super.createMetadata(imageIndex);
        if (imageIndex >= 0) {
            CoordinateReferenceSystem crs = ...; // choose your CRS here
            ReferencingBuilder rb = new ReferencingBuilder(metadata);
            rb.setCoordinateReferenceSystem(crs);
            // If the "grid to CRS" transform need to be modified, change it here
            MetadataAccessor accessor = new MetadataAccessor(metadata, SpatialMetadataFormat.FORMAT_NAME,
                    "RectifiedGridDomain/OffsetVectors", "OffsetVector");
            accessor.selectChild(accessor.appendChild());
            accessor.setAttribute("values", ...put the first vector here...);
            accessor.selectChild(accessor.appendChild());
            accessor.setAttribute("values", ...put the second vector here...);
            // etc.
        }
        return metadata;
    }
}

Deployment

Can't read a TIFF image from an applet, while it worked well in standalone application.

Some applications tested successfully as a standalone application or in the applet viewer may throw the following exception when executed as an applet in an Internet browser:

org.geotoolkit.coverage.io.CoverageStoreException: Can't read file "world.tiff".
No suitable image reader for this input.

The reason is that World file and GeoTIFF image readers need an other "plain" TIFF image reader for reading pixel values. They are basically wrappers around a "plain" reader adding geographic metadata parsing capability.

A standard TIFF image reader is provided in the Image I/O extension for JAI library, which must be reachable on the classpath. However in the particular case of applets, having the JAI library on the classpath is not sufficient. For unknown reasons, the automatic Image I/O registration does not seem to work in applet context. Registration must be forced programmatically as below:

import javax.imageio.spi.IIORegistry;
import com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi;
import org.geotoolkit.image.io.plugin.WorldFileImageReader;
import org.geotoolkit.image.io.plugin.GeoTiffImageReader;

(...snip...)

IIORegistry registry = IIORegistry.getDefaultInstance();
registry.registerServiceProvider(new TIFFImageReaderSpi(), ImageReaderSpi.class);
registry.registerServiceProvider(new GeoTiffImageReader.Spi("TIFF"), ImageReaderSpi.class);
WorldFileImageReader.Spi.registerDefaults(registry);