In the BEAM product model, an EO data product (class Product) owns a list of bands (class Band). The raster data of a band is retrieved using the readRasterData() method. Products are read from a file using a ProductReader. This interface is a factory for products and also knows how to reload raster data from a file via its readRasterData() method. In the nominal case, if a band is requested to read raster data, it delegates the request to the product reader of the product it belongs to. In BEAM 1.0 this was true for all bands. In BEAM 4.0, there are sub-classes of Band, namely VirtualBand and FilterBand subclasses, which override the default behaviour of the readRasterData() operation:
- A virtual band reads raster data by computing it given a band arithmetic expression.
- A filter band uses another band as source and provides some operation on it, e.g. convolution filters and other linear and non-linear filters.
Also, the ProductReader has some implementations which behave similar to a filter band, all derived from the abstract ProductBuilder class which implements ProductReader. Product builders take a source product as input, instead of a file, and perform some operations on it, e.g. map projections and subsetting.
In BEAM 4.1, the Graph Processing Framework (GPF) has been introduced. The GPF generalizes the product builder pattern and introduces the GPF Operator. GPF operators can take any number of source products, some processing parameters and generate a single target product. The target products created by a GPF operator have an OperatorProductReader which is used by its bands to retrieve raster data, which will then delegate to the associated operator to compute the pixels. Since the GPF utilizes the Java Advanced Imaging API (JAI) for pull processing and tile caching, the Band class has been extended by an image property of type RenderedImage. In the case of products generated by a GPF operator, the GPF framework sets the image of all bands to special JAI operator image (javax.media.jai.OpImage) of type OperatorImage, which delegates its tile computation to the GPF operator. In order to allow the readRasterData() method of the bands to function properly, the GPF target products have a product reader of type OperatorProductReader. This special reader type reads raster data from the image (a OperatorImage) associated with the band.
Currently, there are obviously many ways to obtain raster data from a band and this becomes confusing, to put it mildly. In order to reduce complexity, We propose the following refactorings
- Replace VirtualBand, FilterBand and subclasses by a syntetic band (SyntheticBand class?) which retrieves its raster data from its underlying image property, which is in the general case a JAI planar image.
- Replace the product builder pattern and its implementing classes by dedicated GPF operators.
Refactoring #1 also would have the extra benefit that any JAI operator generating a 1-band tiled image can be used as data source for bands. A generalised synthetic bands would at least need the following properties, behaviours and strategies:
- The sources on which it operates (a single band, even other products, another JAI image)
- Parameters.
- A factory which creates a new instance of the (JAI) image with given sources and parameters.
- An optional GUI used to change the parameters and recreate the (JAI) image.
- A DOM I/O so that it can be serialized/deserialised to XML (e.g. BEAM-DIMAP header)
Since it is always possible to write the raster data to file, other writers beside the BEAM-DIMAP writer should keep on functioning also without having extra knowledge about the actual synthetic band implementation.
Since the synthetic band is a very general concept, its interface will likely change in the future. Additionally, letting a data model class providing its user interface does not sound like good design. A design pattern which lets a band provide future and unpredictable extensions and also allows to seperate the model from the UI is the Extension Object Pattern.