RFC 43: GDALMajorObject::GetMetadataDomainList?()

Author: Even Rouault
Contact: even dot rouault at mines-paris dot org

Summary

This (mini)RFC proposes a new virtual method, GetMetadataDomainList?(), in the GDALMajorObject class (and a C API) to return the list of all available metadata domains.

Background

GDALMajorObject currently offers the GetMetadata?() and GetMetadataItem?() methods that both accept a metadata domain argument. But there is no way to auto-discover which metadata domains are valid for a given GDALMajorObject (i.e. a dataset or raster band). This make it impossible to have generic code that can exhaustively discover all metadata in a dataset/raster band.

Implementation

The base implementation in GDALMajorObject just calls GetDomainList?() on the internal oMDMD member.

/************************************************************************/
/*                      GetMetadataDomainList()                         */
/************************************************************************/

/**
 * \brief Fetch list of metadata domains.
 *
 * The returned string list is the list of (non-empty) metadata domains.
 *
 * This method does the same thing as the C function GDALGetMetadataDomainList().
 * 
 * @return NULL or a string list. Must be freed with CSLDestroy()
 *
 * @since GDAL 1.11
 */

char **GDALMajorObject::GetMetadataDomainList()
{
    return CSLDuplicate(oMDMD.GetDomainList());
}

This method is also available in the C API ( char ** CPL_STDCALL GDALGetMetadataDomainList( GDALMajorObjectH hObject) ) and Swig bindings.

Impacted drivers

Drivers that have custom implementations of GetMetadata?() and/or GetMetadataItem?() will generally have to also implement GetMetadataDomainList?(), when they don't modify the oMDMD member.

To make it easy to implement the specialized GetMetadataDomainList?(), GDALMajorObject will offer a protected BuildMetadataDomainList?() method that can be used like the following :

/************************************************************************/
/*                      GetMetadataDomainList()                         */
/************************************************************************/

char **NITFDataset::GetMetadataDomainList()
{
    return BuildMetadataDomainList(GDALPamDataset::GetMetadataDomainList(),
                                   TRUE,
                                   "NITF_METADATA", "NITF_DES", "NITF_DES_METADATA",
                                   "NITF_FILE_HEADER_TRES", "NITF_IMAGE_SEGMENT_TRES",
                                   "CGM", "TEXT", "TRE", "xml:TRE", "OVERVIEWS", NULL);
}

The TRUE parameter means that the list of domains that follows are potential domains, and thus BuildMetadataDomainList?() will check for each one that GetMetadata?() returns a non-NULL value.

An exhaustive search in GDAL drivers has been made and all drivers that needed to be updated to implement GetMetadataDomainList?() have been updated: ADRG, BAG, CEOS2, DIMAP, ECW, ENVISAT, ERS, GeoRaster (cannot check myself that it compiles), GIF, GTiff, HDF4, JPEG, MBTILES, netCDF, NITF, OGDI, PCIDSK, PDF, PNG, PostgisRaster?, RasterLite?, RS2, VRT, WCS, WebP, WMS.

A few caveats :

Impacted utilities

The gdalinfo utility is extented to accept :

  • a "-listmdd" option that will print the metadata domains available,
$ gdalinfo ../autotest/gdrivers/data/byte_with_xmp.jpg -listmdd

Driver: JPEG/JPEG JFIF
Files: ../autotest/gdrivers/data/byte_with_xmp.jpg
Size is 20, 20
Coordinate System is `'
Metadata domains:
  xml:XMP
Corner Coordinates:
Upper Left  (    0.0,    0.0)
Lower Left  (    0.0,   20.0)
Upper Right (   20.0,    0.0)
Lower Right (   20.0,   20.0)
Center      (   10.0,   10.0)
Band 1 Block=20x1 Type=Byte, ColorInterp=Gray
  Metadata domains:
    IMAGE_STRUCTURE
  Image Structure Metadata:
    COMPRESSION=JPEG
  • and "-mdd all" will display the content of all metadata domains.
$ gdalinfo ../autotest/gdrivers/data/byte_with_xmp.jpg -mdd all

Driver: JPEG/JPEG JFIF
Files: ../autotest/gdrivers/data/byte_with_xmp.jpg
Size is 20, 20
Coordinate System is `'
Metadata (xml:XMP):
<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 7.89'>
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>

 <rdf:Description rdf:about=''
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
  <dc:description>
   <rdf:Alt>
    <rdf:li xml:lang='x-default'>Description</rdf:li>
   </rdf:Alt>
  </dc:description>
  <dc:subject>
   <rdf:Bag>
    <rdf:li>XMP</rdf:li>
    <rdf:li>Test</rdf:li>
   </rdf:Bag>
  </dc:subject>
  <dc:title>
   </rdf:Alt>
  </dc:title>
 </rdf:Description>

 <rdf:Description rdf:about=''
  xmlns:tiff='http://ns.adobe.com/tiff/1.0/'>
  <tiff:BitsPerSample>
   <rdf:Seq>
    <rdf:li>8</rdf:li>
   </rdf:Seq>
  </tiff:BitsPerSample>
  <tiff:Compression>1</tiff:Compression>
  <tiff:ImageLength>20</tiff:ImageLength>
  <tiff:ImageWidth>20</tiff:ImageWidth>
  <tiff:PhotometricInterpretation>1</tiff:PhotometricInterpretation>
  <tiff:PlanarConfiguration>1</tiff:PlanarConfiguration>
  <tiff:SamplesPerPixel>1</tiff:SamplesPerPixel>
 </rdf:Description>
</rdf:RDF>
</x:xmpmeta>
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
<?xpacket end='w'?>
Corner Coordinates:
Upper Left  (    0.0,    0.0)
Lower Left  (    0.0,   20.0)
Upper Right (   20.0,    0.0)
Lower Right (   20.0,   20.0)
Center      (   10.0,   10.0)
Band 1 Block=20x1 Type=Byte, ColorInterp=Gray
  Image Structure Metadata:
    COMPRESSION=JPEG

Backward Compatibility

This change has no impact on backward compatibility at the C API/ABI and C++ API levels. But it impacts C++ ABI, so it requires a full rebuild of all GDAL drivers.

Testing

The Python autotest suite will be extended to test the new API in a few drivers.

Ticket

Ticket #5275 has been opened to track the progress of this RFC.

The implementation is available in an attachment to ticket 5275.

Voting history

+1 from EvenR, DanielM and JukkaR