Purpose
In the SNAP product data model, bands obtain their pixel data from source images which are in instances of type com.bc.ceres.glevel.MultiLevelImage
. A MultiLevelImage
is a actually a java.awt.image.RenderedImage
with the additional capability to serve sub-sampled versions of itself for given resolution levels ranging from zero to maximum value. Level zero is the MultiLevelImage
itself. MultiLevelImage
s are designed to somehow provide (e.g. compute or read) pixel data at requested resolutioon resolution levels and for requested image tiles at that resolution level. A number of sub-classes exists as well as a number of helper classes.
Example
The following example explains how a band "magnitude" is computed from two input bands "real" and "imag" using the following helper classes:
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
private static Product createTestProduct(int width, int height, int tileSize, int numResolutionsMax) { Product product = new Product("test", "test", width, height); product.setPreferredTileSize(tileSize, tileSize); product.setNumResolutionsMax(numResolutionsMax); Band realBand = product.addBand("real", "X * X - Y * Y", ProductData.TYPE_FLOAT64); Band imagBand = product.addBand("imag", "2 * X * Y", ProductData.TYPE_FLOAT64); Band magnitudeBand = product.addBand("magnitude", ProductData.TYPE_FLOAT64); final MultiLevelModel multiLevelModel = ImageManager.getMultiLevelModel(realBand); final MultiLevelSource multiLevelSource = new AbstractMultiLevelSource(multiLevelModel) { @Override public void reset() { super.reset(); magnitudeBand.fireProductNodeDataChanged(); } @Override public RenderedImage createImage(int level) { return new MagnitudeOpImage(magnitudeBand, ResolutionLevel.create(getModel(), level), realBand, imagBand); } }; magnitudeBand.setSourceImage(new DefaultMultiLevelImage(multiLevelSource)); return product; } private static class MagnitudeOpImage extends RasterDataNodeOpImage { private final Band realBand; private final Band imagBand; public MagnitudeOpImage(Band outputBand, ResolutionLevel level, Band realBand, Band imagBand) { super(outputBand, level); this.realBand = realBand; this.imagBand = imagBand; } @Override protected void computeProductData(ProductData outputData, Rectangle region) throws IOException { ProductData realData = getRawProductData(realBand, region); ProductData imagData = getRawProductData(imagBand, region); int numElems = region.width * region.height; for (int i = 0; i < numElems; i++) { double real = realData.getElemDoubleAt(i); double imag = imagData.getElemDoubleAt(i); double result = Math.sqrt(real * real + imag * imag); outputData.setElemDoubleAt(i, result); } } } |
References:
Jira Legacy | ||||||||
---|---|---|---|---|---|---|---|---|
|