isce3  0.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
Raster Tutorial

Table of Contents

ISCE delegates raster data handling to the Geospatial Data Abstraction Library (GDAL). Hence, it uses all the conventions defined by the GDAL data model to simplify the interface. You will find detailed documentation of all the methods available here: isce3::io::Raster.

Include headers

In general, one only needs to include the isce3::io::Raster headerfile.

#include "isce3/io/Raster.h"

If one is looking to create Rasters as part of your workflow, include appropriate the main GDAL header file. This will provide access to pre-defined data types and enum variables.

#include "gdal.h"

If one is looking to use advanecd features from GDAL, you might need additional appropriate header files.

Constructors

Read-Only Mode

Raster imagery that already exists can be opened in Read-Only mode in a simple manner with just a string with the filename to be used.

isce3::io::Raster raster(inputFilename);

All the GDAL environment variables and driver settings are respected. One should also be able to access remotely located resources using vsicurl / vsis3 etc. One can also use standard GDAL interfaces to access raster imagery within NETCDF and HDF5 by treating them as subdatasets (see here for details on NETCDF and HDF5). For a complete list of supported formats in your GDAL build , refer to output of

> gdalinfo --formats

Update Mode

An existing GDAL-compatible raster can be opened in Update mode in ISCE as follows

//Will need to include gdal.h for definition of GA_Update
isce3::io::Raster raster(inputFilename, GA_Update)

Create new rasters

The most general interface to creation of rasters is exposed via isce3::io::Raster(const std::string& fname, size_t width, size_t length, size_t numBands, GDALDataType dtype, const std::string& driverName).

  1. If numBands is not provided, it is assumed that user wants to create a single band raster.
  2. If no dtype is provided, it is assumed that user wants to work with isce3::io::defaultGDALDataType.
  3. If no driverName is provided, it is assumed that user wants to work with isce3::io::defaultGDALDriver.

See the full range of isce3::io::Raster constructors available for options. Note that you will need to include gdal.h to use GDAL type definitions.

Todo:
Add ability to pass creation options to Raster object. This could possibly be done by accepting a vector of strings as an additional input, that is then passed directly to the GDAL driver during creation.

Working with HDF5 files

NISAR mission will produce Level 1 and Level 2 products in HDF5 format. However, GDAL does not include HDF5 creation support. ISCE provides two different interfaces to work with HDF5 files. Since, GDAL does not include HDF5 creation support

IH5 - Extension of H5 C++ interface

ISCE includes an easy to use HDF5 interface using isce3::io namespace, that can be used to create/ manipulate HDF5 groups and datasets. The documentation for the following classes are useful to understand HDF5 manipulation at the C++ level:

//This provides access to our extensions of H5 C++
#include "isce3/io/IH5Dataset.h"
//Create a HDF5 file in write mode
std::string filename = "example.h5";
isce3::io::IH5File(filename, 'w');
//Create a group inside the file
//Set groupname to "/" for root
std::string groupname = "level1/level2";
isce3::io::IGroup grp = fid.createGroup(groupname);
//Create a dataset inside the group
std::string dsetname = "data";
std::array<int, 2> shape = {100, 200}; //{length, width}
isce3::io::IDataSet dset = grp.createDataSet<float>(dsetname, shape); //Simple dataset

The IH5 classes are extensively documented and we refer users to browse the documentation for alternate interfaces that might suit their use case. In general, the following set of rules are useful to remember:

  1. Use isce3::io::IH5File::createGroup to create new groups and isce3::io::IH5File::openGroup to access existing groups.
  2. Use isce3::io::IGroup::createDataSet to create new groups and isce3::io::IH5File::openDataSet / isce3::io::IGroup::openDataSet to access existing datasets.
  3. There are numerous interfaces to creating HDF5 datasets - all overloaded under isce3::io::IH5File::createDataset. Please spend some time on choosing the right interface for your implementation.
  4. IEEE float16 data types are available under isce3::io::float16 and these can be used with IH5 interfaces to create datasets. Note that this type is not available for computation. Any I/O operation transforms data stored in isce3::io::float16 or std::complex<isce3::io::float16> this to user requested native type.
  5. isce3::io::IDataSet::read and isce3::io::IDataSet::write methods can then be used to read / write to datasets.
  6. isce3::io::IDataSet::createAttribute or isce3::io::IGroup::createAttribute can be used to create attributes.
  7. isce3::io::IDataSet::read or isce3::io::IGroup::read have been overloaded to read attributes.

Passing HDF5 datasets to Raster interface

Once access to HDF5 datasets has been setup using the IH5 interface discussed above, users can create an isce3::io::Raster object from it as shown below:

//Header file for the GDAL interface
#include "isce3/io/IH5Dataset.h"
//Register custom IH5 Driver
GDALAllRegister();
//Open HDF5 file for reading
isce3::io::IH5File file("NISAR_SLC.h5");
//Access dataset
isce3::io::IDataSet dset = file.openDataSet("/science/LSAR/SLC/swaths/frequencyA/HH");
//Pass on to raster
isce3::io::Raster slc( dset.toGDAL(), GA_ReadOnly);

Rasters created using IH5 interface are equivalent to any other GDAL Dataset and same interface can be used to populate / read data from these Rasters. isce3::io::IDataSet::toGDAL generates a string that is interpreted by GDAL's custom IH5 driver, in a manner very similar to GDAL's inbuilt MEM driver.

Reading/Writing Single Pixel

Note that all pixels are indexed by the Top-Left corner (see Raster Overview). One can read the data into a buffer of a type different from the storage format, as GDAL will handle the type translation.

We use isce3::io::Raster::getValue to read a pixel value from Band 2 of the raster image in this example. If band number is not provided, it is assumed to be 1.

//Open existing tiff file
isce3::io::Raster raster("test.tif");
double val;
//Get value from Band 2
raster.getValue(val, 5, 10, 2);
std::cout << "Image dimensions: " << raster.width() << " x " << raster.length() << "\n";
std::cout << "Value at 5P, 10L = " << val << "\n"

Similarly, isce3::io::Raster::setValue can be used to set a pixel value.

//Create a Float32 raster of 100 pixels by 200 lines
isce3::io::Raster raster("test.tif", 100, 200,1, GDT_Float32, "GTiff");
//Set value in Band 1
int val = 25;
raster.setValue(val, 5,10);

Reading/Writing Single line

ISCE Raster object can currently interact with 3 types of containers - a raw buffer (no size checks), std::vector and std::valarray. One can use any of the 3 interfaces with the isce3::io::Raster::getLine and isce3::io::Raster::setLine methods.

//Create a Float32 raster of 100 pixels by 200 lines
isce3::io::Raster raster("test.vrt", 100, 200);
//Create a vector and valarray for reading
std::vector<float> input(100);
std::valarray<double> output(200);
for(int ii=0; ii<100; ii++)
input[ii] = ii * 2.0;
//Set line number 10
raster.setLine(input, 10);
//Read line number 10
raster.getLine(output, 10);

Reading/Writing Single block

Like single line I/O, one can use any of the 3 interfaces (pointer, vector, valarray) with the isce3::io::Raster::getBlock and isce3::io::Raster::setBlock methods. Note that all data is read in from or to a contiguous bufferin row major order. Currently, there is no interface to read/write from a blocked interface. If one wishes to do this see the section on advanced usage below to work with the GDAL Dataset pointer directly.

//Create a Float32 raster of 100 pixels by 200 lines
isce3::io::Raster raster("test.vrt", 100, 200);
//Create a vector and valarray for reading
//Assuming a block of 5 x 5
std::vector<float> input(25);
std::valarray<double> output(25);
for(int ii=0; ii<25; ii++)
input[ii] = ii * 2.0;
//Set block of 5x5 with top left at (2,3)
raster.setBlock(input, 2, 3, 5, 5);
//Read the block we just wrote
raster.getBlock(output, 2, 3, 5, 5);

Advanced usage - direct access to GDAL dataset

ISCE Raster class is a thin wrapper over GDAL's GDALDataset class. One can access the underlying pointer using the isce3::io::Raster::dataset method.


Generated for ISCE3.0 by doxygen 1.8.5.