- The GDAL input/output capabilities are encapsulated in the
GDALImageIO class, which derivates from ImageIO. This class is in
charge of fetching the metadata from the product (supplier
capabilities inherited from the class MetadataSupplierInterface)
and storing them in memory as a keywordlist. It is also in charge
of writing the metadata to the product (storage capabilities
inherited from the class MetadataStorageInterface).
- An ImageMetadataInterface (IMI) is then called to parse the
metadata. There is one IMI per sensor. We use a classical Factory
to find which one can parse the metadata of a product. The IMI's
*parse* method will pick the metadata from the ImageIO and fill an
*ImageMetadata* object.
- Some metadata are not read by GDAL. To parse those metadata, the
IMI can call other suppliers, depending on the file format:
* to parse XML files, XMLMetadataSupplier uses GDAL's XML parsing
mechanism ("ReadXMLToList" method from the "GDALMDReaderBase"
class) to convert the XML file into a GDAL ListString, which is a
succession of 'key=value' pairs.
* to parse text files, TextMetadataSupplier tries to parse
'key=value' pairs.
Other suppliers can be added if needed. Those classes (including
GDALImageIO) all implement the method *GetMetadataValue* which
returns the value of the metadata from a given key. The base class
also implements the methods *GetAs* and *GetAsVector* which are
used by the IMI.
- The IMI finds the relevant metadata in the different Metadata
Suppliers and use the *Add()* method of the *ImageMetadata* object
to store the metadata. If the parsing returns successfully, the
generated ImageMetadata is given to the *ImageCommon* that
propagate through the pipeline.
## DEM Handler
### Presentation
Before the refactoring, `otb::DEMHandler` class was an adapter class for
OSSIM DEMs. It provided an API to retrieve height from DEM and/or geoid using OSSIM, and was used to set up DEM and geoids to be used by OSSIM internally (which is used in OSSIM RPCs for example).
The `otb::DEMHandler` class is a singleton, a reference to the `otb::DEMHandler` object can be obtained via the `GetInstance()` method. This is a change of API, the Ossim `otb::DEMHandler` returned a ITK smart pointer to the singleton object. This was not a very good design, and a singleton object does not need to use the ITK memory management system.
The new approach is based on `RasterIO` from GDAL. A 2x2 window is extracted around the point of interest, and the height, above ellipsoid or above mean sea level. The following methods are provided:
* GetHeightAboveEllipsoid(lon, lat):
* SRTM and geoid both available: dem_value + geoid_offset
* No SRTM but geoid available: default height above ellipsoid + geoid_offset
* SRTM available, but no geoid: dem_value
* No SRTM and no geoid available: default height above ellipsoid
* GetHeightAboveMSL(lon, lat):
* SRTM and geoid both available: dem_value
* No SRTM but geoid available: 0
* SRTM available, but no geoid: dem_value
* No SRTM and no geoid available: 0
Several DEM tiles can be provided at the same time, using the `OpenDEMDirectory` method. All raster from the input directory will be opened by GDAL. A mosaic of all DEM tiles is then created as a virtual dataset (vrt).
Geoid are managed with the `GDALOpenVerticalShiftGrid` and `GDALApplyVerticalShiftGrid` function from GDAL API. The former opens a 1D raster grid as a GDAL Datasource, and the latter creates a new datasource from the raster grid (geoid) and a raster (the DEM). Vertical datums (shifts from the reference ellipsoid) are applied on the fly.
All raster that can be opened by gdal can be used as a geoid. In Ossim it was common to use the `egm96.grd` file as geoid, this file cannot be opened by GDAL. However it is still possible to use it by using the following `egm96.grd.hdr` file :
```
ENVI
samples = 1441
lines = 721
bands = 1
header offset = 24
file type = ENVI Standard
data type = 4
interleave = bsq
sensor type = Unknown
byte order = 1
wavelength units = Unknown
map info = {Geographic Lat/Lon, 1, 1,-0.125, 90.125, 0.25, 0.25,WGS-84}
coordinate system string = {GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]}
band names = {
Band 1}
```
With this file attached, GDAL will be able to read the `egm96.grd` file as a ENVI dataset
### Migration example
We introduced a slight change in the DEMHandler manipulation. Before, we would manipulate a smart pointer: