Skip navigation links


Support for reading and creating mosaics of geographically referenced images.

See: Description

Package Description

Support for reading and creating mosaics of geographically referenced images. This package uses a subclass of the standard Java ImageReader which tracks the extent and resolution of the component images.

The MosaicImageReader class can generate visual representations of an underlying mosaic for different extents and resolutions based on the parameter values in the ImageReadParam instance passed to the read(...) method. Each image in a mosaic will be a stand alone image in main storage (e.g. disk) and will be represented to the MosaicImageReader as a Tile instance which carries the spatial metadata for the image, including its resolution and extent. In a typical mosaic the tiles will be laid out on a regular grid; in a typical pyramid the tiles will form several mosaic layers at different resolutions. The TileManager tracks the Tile instances for the MosaicImageReader. For the user, the MosaicImageReader can be used as if it were a standard ImageReader backed by a single, huge image.

This package can work directly with an existing image set or mosaic by creating a Tile instance to define the geographic metadata for each image. The package also provides the MosaicBuilder which can generate a new mosaic from an existing one simply by specifying the properties of the desired mosaic. For example, a user can start with a small set of large images, define the geographic extent of each image, and then use the MosaicBuilder to build a mosaic composed of many, small images with which to work more efficiently.

All of the images referenced by a single MosaicImageReader must exist on the same 'grid' which is to say they must share the same axes and have pixel sizes which are integer multiple of the smallest pixel size. The images do not necessarily need to cover a contiguous area nor do the mosaics need to be geo-referenced when they are originally created. Users must first specify the layout of their source images. This step is required whether or not the users wish to use an existing mosaic "as is" or want to generate a new mosaic. Once defined, the mosaic can be used directly to generate images by creating a MosaicImageReader. Alternatively, the mosaic can be used by MosaicBuilder to generate a new mosaic.

  1. Create a collection of Tile objects where each Tile instance describes an existing image. Tile instances contain only metadata about the tiles, not the actual pixel data. Two approaches exist to define the location of a given Tile instance relative to other tiles in the mosaic: the relative location can be described in pixel units by passing Point or Rectangle arguments to the constructor or the information can be calculated from the actual geographic coordinates of the image. In the latter case, an affine transform, which defines the conversion from grid (pixel) coordinates to geographic coordinates, may be passed explicitly to a constructor. Alternatively, this transform can be inferred automatically by the a constructor which uses a 'world file' (TFW) which accompanies the image to calculate the transform.

  2. Create a TileManager from the collection of tiles. The tile manager is created using a factory. The factory will infer the mosaic layout (location of tiles relative to each other, subsampling relative to the tiles having the smallest pixels, etc.) from the affine transform defined for each tile. If the tiles appear to be distributed on a regular grid, then the created TileManager instance will store that information in a compact way that does not require the retention of every Tile object.

The following example creates a TileManager for an existing set of images. In this example the images are TIFF files where each image file is accompanied by a file of the same name but with the ".tfw" extension (its World File). The Tile constructor used here automatically looks for the TFW file and builds the required AffineTransform.
File[] sourceImages = directory.listFiles(new DefaultFileFilter("*.tiff"));
List<Tile> tiles = new ArrayList<Tile>(sourceImages.length);
for (File file : sourceImages) {
    tiles.add(new Tile(null, sourceImages, 0));
TileManager[] originalMosaic = TileManagerFactory.DEFAULT.create(tiles);
Users may want to generate a new mosaic from an existing set of images, typically either to have small regular tiles or to create a mosaic with several layers of images having different resolutions. (The latter is often called a "pyramid" in the geographic community.)

The MosaicBuilder class makes building a new mosaic easy:

MosaicBuilder builder = new MosaicBuilder();
builder.setTileDirectory(new File("output")); // The output directory.
builder.setTileSize(new Dimension(256, 256)); // The size of the output tiles.
builder.setSubsamplings(1, 2, 3, 4);          // Defines the layers.
TileManager newMosaic = builder.createTileManager(originalMosaic, TileWritingPolicy.WRITE_NEWS_NONEMPTY);
Because the cost of building a mosaic can be substantial, it is often worth while to save the TileManager data structure in some way. The mosaic will be used every time an image needs to be read from the mosaic (see next section) while the steps performed up to this point need to be executed only once. An easy way to save the mosaic information is simply to serialize the TileManager instance.

Tip: for an easy way to generate a mosaic using a graphical user interface, see the Image Mosaic Wizard.
To generate images, users need to perform the following steps:
  1. Create a new instance of MosaicImageReader. Instantiation can be done directly using the public constructors, or an instance can be provided by the Java Image I/O framework when the users request for the "mosaic" format.

  2. Set the input of the MosaicImageReader to use the TileManager instance created in the previous section.

  3. Obtain a new instance of MosaicImageReadParam. Instantiation can be done directly using the public constructor, or an instance can be provided by the reader.

  4. Configure the parameters to reference the data of interest. Methods of special interest are setSubsamplingChangeAllowed (non-standard but strongly recommended), setSourceSubsampling and setSourceRegion.

  5. Invoke with the parameters created in the previous step.

Users who wish to generate more images from the same mosaic can repeat only steps 4 and 5. The steps 1 to 3 (and a fortiori the previous section which created the TileManager) need to be done only once.

The example below generates a single image from the mosaic created in the previous section. Note that the source region is given in pixel coordinates.

MosaicImageReader reader = new MosaicImageReader();
MosaicImageReadParam param = reader.getDefaultReadParam();
param.setSubsamplingChangeAllowed(true); // Strongly recommended.
param.setSourceRegion(new Rectangle(2000, 2000, 800, 600));
param.setSourceSubsampling(2, 2, 0, 0);
RenderedImage image =, param);

// Because of setSubsamplingChangeAllowed(true), the subsampling actually used
// may be different than the one we asked for. To get the subsampling which was
// actually used we can do:
int sx = param.getSourceXSubsampling();
int sy = param.getSourceYSubsampling();
// Adjust gridToCRS here using (sx,sy).
The ImageReader API is defined only in terms of pixel coordinates. If the region to read is defined in "real world" coordinates, then it must be converted to pixel coordinates before being given to MosaicImageReadParam. This conversion can be done by obtaining an AffineTransform from the TileManager.getGridGeometry() method and using it as shown here:
Rectangle2D realWorldRegion = ...;
Rectangle sourceRegion = new Rectangle();
AffineTransform tr = newMosaic.getImageGeometry().getGridToCRS();
tr = tr.createInverse();
XAffineTransform.transform(tr, realWorldRegion, sourceRegion);
The above can only be used if the TileManager has been created in one of the following ways:

Martin Desruisseaux (Geomatys)

Defined in the geotk-coverage module

Skip navigation links

Copyright © 2009–2017 All rights reserved.