The ENVISAT product reader is implemented by two classes
The "normal" way to obtain an instance of an ENVISAT product reader through the product I/O framework of the MERIS/(A)ATSR Toolbox is very simple:
// Get a reader instance for the ENVISAT format ProductReader reader = ProductIO.getReader("ENVISAT");
Once the reader is obtained the product can be read into memory:
// Read the product, no subset given Product product = reader.readProduct("E:/data/MERIS/L1B/MER_FR__1P.prd", null);
Important: The product I/O framework does not automatically load the raster data of geophysical bands contained in the product. This must be done explicitely. In the following code snippet an entire band is loaded:
// get the band named radiance_2 RsBand band = product.getBand("radiance_2"); // load the entire band Raster raster = band.loadData(); // ... do something with the raster data in 'raster'
If just a portion of a band is desired, e.g. in order to read a band line-by-line, the product reader should be used instead:
// Create a raster for a single scan line. Raster lineRaster = band.createCompatibleRaster(new Rectangle(0, 0, band.getWidth(), 1)); float[] lineData = ((DataBufferFloat) lineRaster.getDataBuffer()).getData(); // The offset where reading begins (in the data product's pixel co-ordinates) Point offset = new Point(0, 0); // Read line-by-line for (int y = 0; y < band.getHeight(); y++) { offset.y = y; // The next read call modifies the contents in 'lineData' reader.readBandData(band, lineRaster, offset); // ... do something with the data in 'lineData' }
The {@link org.esa.beam.dataio.envisat.EnvisatProductReader} class implements the {@link org.esa.beam.framework.dataio.ProductReader}
interface by delegating low level read operations to an instance of the {@link org.esa.beam.dataio.envisat.ProductFile} class.
Developers can also use ProductFile
class directly in order to access ENVISAT
product files. There is no need to use use the product I/O framework.
The classes in this package provide direct reading of ENVISAT data in two different ways:
The starting point in both cases is the ProductFile
class. It has a static method which
allows to open a data product file. From the opened product file a record reader for raw data access
can be obtained for each of the datasets contained in the product. The record reader is - as the name says -
used to read single records. Records are again composed of fields carrying the data. Each field can have
multiple data elements stored in an native array type. For example, in ENVISAT products all samples of a
scan line are stored in a single field as part of a measurement dataset record ('MDSR' in ENVISAT
terminology). The following code snipped shows how to read a measurement dataset in it's raw form
record-by-record:
ProductFile file = ProductFile.open("E:/data/MERIS/L1B/MER_FR__1P.prd"); RecordReader reader = file.getRecordReader("Norm._rho_surf_-_MDS(2)"); // Pre-create a record with a well defined structure Record record = reader.createCompatibleRecord(); // Process all records int n = reader.getNumRecords(); for (int i = 0; i < n; i++) { // Read the record from the file reader.readRecord(i, record); // we know from the ENVISAT spec., samples are stored in the 3rd field Field field = record.getFieldAt(2); // we know from the ENVISAT spec., samples are stored as 2241 (unsigned) 16-bit values short[] samples = (short[]) field.getData(); // ... do something with the data }In this example we pre-created the record before we read data into it. By passing this record to the
reader.readRecord()
method it gets recycled, and the field data is
overwritten each time the method is called. If record data should remain in the fields,
new records should be created for each read call: Then, replace the
reader.readRecord(i, record);by the non-recycling call
record = reader.readRecord(i, null);Now, each time the method is called a new record is created, read-in and returned.
ProductFile.open
method. But this time a ProductFile file = ProductFile.open("E:/data/MERIS/L1B/MER_FR__1P.prd"); BandReader reader = file.getBandReader("radiance_2"); // Create a raster covering the entrire product scene Raster raster = reader.createCompatibleRaster(); readBandRaster(raster, null, 1, 1); float[] data = ((DataBufferFloat) raster.getDataBuffer()).getData(); // ... do something with the data in 'data' file.close();Reading the complete band is not often the best choice, particulary if multiple huge band rasters have to be processed. The one should consider reading the band line by line as shown in the following example:
ProductFile file = ProductFile.open("E:/data/MERIS/L1B/MER_FR__1P.prd"); int sceneWidth = file.getNumColumns(); int sceneHeight = file.getNumLines(); BandReader reader = file.getBandReader("radiance_2"); // Define the area from which to read (in the product's pixel co-ordinates) Rectangle sourceArea = new Rectangle(0, 0, sceneWidth, 1); // Create a raster covering one single scan line WritableRaster lineRaster = reader.createCompatibleRaster(sourceArea, 1, 1); float[] lineData = ((DataBufferFloat) lineRaster.getDataBuffer()).getData(); for (int y = 0; y < sceneHeight; y++) { sourceArea.y = y; // The next read call modifies the contents in 'lineData' reader.readBandRaster(lineRaster, sourceArea, 1, 1); // ... do something with the data in 'lineData' } file.close();
This implementation of the data product reading algorithms are based on the internal ESA documents
describing the ENVISAT-1 PRODUCT SPECIFICATION (PO-RS-MDA-GS-2009) as part of the ENVISAT
payload data segment: