GDAL
Simple C Example: gdalinfo.c
/******************************************************************************
* $Id: gdalinfo.c 29781 2015-08-25 16:20:28Z rouault $
*
* Project: GDAL Utilities
* Purpose: Commandline application to list info about a file.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
* ****************************************************************************
* Copyright (c) 1998, Frank Warmerdam
* Copyright (c) 2007-2013, Even Rouault <even dot rouault at mines-paris dot org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/
#include "gdal.h"
#include "gdal_alg.h"
#include "ogr_srs_api.h"
#include "cpl_string.h"
#include "cpl_conv.h"
#include "cpl_multiproc.h"
#include "commonutils.h"
#include "json.h"
#include "ogrgeojsonwriter.h"
CPL_CVSID("$Id: gdalinfo.c 29781 2015-08-25 16:20:28Z rouault $");
static int
GDALInfoReportCorner( GDALDatasetH hDataset,
OGRCoordinateTransformationH hTransform, OGRCoordinateTransformationH hTransformWGS84,
const char * corner_name,
double x, double y,
int bJson, json_object *poCornerCoordinates,
json_object *poWGS84ExtentCoordinates );
static void
GDALInfoReportMetadata( GDALMajorObjectH hObject,
int bListMDD,
int bShowMetadata,
char **papszExtraMDDomains,
int bIsBand,
int bJson,
json_object *poMetadata );
/************************************************************************/
/* Usage() */
/************************************************************************/
void Usage(const char* pszErrorMsg)
{
printf( "Usage: gdalinfo [--help-general] [-json] [-mm] [-stats] [-hist] [-nogcp] [-nomd]\n"
" [-norat] [-noct] [-nofl] [-checksum] [-proj4]\n"
" [-listmdd] [-mdd domain|`all`]*\n"
" [-sd subdataset] [-oo NAME=VALUE]* datasetname\n" );
if( pszErrorMsg != NULL )
fprintf(stderr, "\nFAILURE: %s\n", pszErrorMsg);
exit( 1 );
}
/************************************************************************/
/* main() */
/************************************************************************/
#define CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(nExtraArg) \
do { if (i + nExtraArg >= argc) \
Usage(CPLSPrintf("%s option requires %d argument(s)", argv[i], nExtraArg)); } while(0)
int main( int argc, char ** argv )
{
GDALDatasetH hDataset = NULL;
GDALRasterBandH hBand = NULL;
int i, iBand;
double adfGeoTransform[6];
GDALDriverH hDriver;
int bComputeMinMax = FALSE, bSample = FALSE;
int bShowGCPs = TRUE, bShowMetadata = TRUE, bShowRAT=TRUE;
int bStats = FALSE, bApproxStats = TRUE;
int bShowColorTable = TRUE, bComputeChecksum = FALSE;
int bReportHistograms = FALSE;
int bReportProj4 = FALSE;
int nSubdataset = -1;
const char *pszFilename = NULL;
char **papszExtraMDDomains = NULL, **papszFileList;
int bListMDD = FALSE;
const char *pszProjection = NULL;
OGRCoordinateTransformationH hTransform = NULL, hTransformWGS84 = NULL;
int bShowFileList = TRUE;
char **papszOpenOptions = NULL;
int bJson = FALSE;
json_object *poJsonObject = NULL, *poBands = NULL, *poMetadata = NULL;
/* Check that we are running against at least GDAL 1.5 */
/* Note to developers : if we use newer API, please change the requirement */
if (atoi(GDALVersionInfo("VERSION_NUM")) < 1500)
{
fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, "
"which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
exit(1);
}
EarlySetConfigOptions(argc, argv);
argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
if( argc < 1 )
exit( -argc );
/* -------------------------------------------------------------------- */
/* Parse arguments. */
/* -------------------------------------------------------------------- */
for( i = 1; i < argc; i++ )
{
if( EQUAL(argv[i], "--utility_version") )
{
printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
return 0;
}
else if( EQUAL(argv[i],"--help") )
Usage(NULL);
else if( EQUAL(argv[i],"-json") )
bJson = TRUE;
else if( EQUAL(argv[i], "-mm") )
bComputeMinMax = TRUE;
else if( EQUAL(argv[i], "-hist") )
bReportHistograms = TRUE;
else if( EQUAL(argv[i], "-proj4") )
bReportProj4 = TRUE;
else if( EQUAL(argv[i], "-stats") )
{
bStats = TRUE;
bApproxStats = FALSE;
}
else if( EQUAL(argv[i], "-approx_stats") )
{
bStats = TRUE;
bApproxStats = TRUE;
}
else if( EQUAL(argv[i], "-sample") )
bSample = TRUE;
else if( EQUAL(argv[i], "-checksum") )
bComputeChecksum = TRUE;
else if( EQUAL(argv[i], "-nogcp") )
bShowGCPs = FALSE;
else if( EQUAL(argv[i], "-nomd") )
bShowMetadata = FALSE;
else if( EQUAL(argv[i], "-norat") )
bShowRAT = FALSE;
else if( EQUAL(argv[i], "-noct") )
bShowColorTable = FALSE;
else if( EQUAL(argv[i], "-listmdd") )
bListMDD = TRUE;
else if( EQUAL(argv[i], "-mdd") )
{
CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
papszExtraMDDomains = CSLAddString( papszExtraMDDomains,
argv[++i] );
}
else if( EQUAL(argv[i], "-oo") )
{
CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
papszOpenOptions = CSLAddString( papszOpenOptions,
argv[++i] );
}
else if( EQUAL(argv[i], "-nofl") )
bShowFileList = FALSE;
else if( EQUAL(argv[i], "-sd") )
{
CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
nSubdataset = atoi(argv[++i]);
}
else if( argv[i][0] == '-' )
Usage(CPLSPrintf("Unknown option name '%s'", argv[i]));
else if( pszFilename == NULL )
pszFilename = argv[i];
else
Usage("Too many command options.");
}
if( pszFilename == NULL )
Usage("No datasource specified.");
/* -------------------------------------------------------------------- */
/* Open dataset. */
/* -------------------------------------------------------------------- */
hDataset = GDALOpenEx( pszFilename, GDAL_OF_READONLY | GDAL_OF_RASTER, NULL,
(const char* const* )papszOpenOptions, NULL );
if( hDataset == NULL )
{
fprintf( stderr,
"gdalinfo failed - unable to open '%s'.\n",
pszFilename );
/* -------------------------------------------------------------------- */
/* If argument is a VSIFILE, then print its contents */
/* -------------------------------------------------------------------- */
if ( strncmp( pszFilename, "/vsizip/", 8 ) == 0 ||
strncmp( pszFilename, "/vsitar/", 8 ) == 0 )
{
papszFileList = VSIReadDirRecursive( pszFilename );
if ( papszFileList )
{
int nCount = CSLCount( papszFileList );
fprintf( stdout,
"Unable to open source `%s' directly.\n"
"The archive contains %d files:\n",
pszFilename, nCount );
for ( i = 0; i < nCount; i++ )
{
fprintf( stdout, " %s/%s\n", pszFilename, papszFileList[i] );
}
CSLDestroy( papszFileList );
papszFileList = NULL;
}
}
CSLDestroy( argv );
CSLDestroy( papszExtraMDDomains );
CSLDestroy( papszOpenOptions );
exit( 1 );
}
/* -------------------------------------------------------------------- */
/* Read specified subdataset if requested. */
/* -------------------------------------------------------------------- */
if ( nSubdataset > 0 )
{
char **papszSubdatasets = GDALGetMetadata( hDataset, "SUBDATASETS" );
int nSubdatasets = CSLCount( papszSubdatasets );
if ( nSubdatasets > 0 && nSubdataset <= nSubdatasets )
{
char szKeyName[1024];
char *pszSubdatasetName;
snprintf( szKeyName, sizeof(szKeyName),
"SUBDATASET_%d_NAME", nSubdataset );
szKeyName[sizeof(szKeyName) - 1] = '\0';
pszSubdatasetName =
CPLStrdup( CSLFetchNameValue( papszSubdatasets, szKeyName ) );
GDALClose( hDataset );
hDataset = GDALOpen( pszSubdatasetName, GA_ReadOnly );
CPLFree( pszSubdatasetName );
}
else
{
fprintf( stderr,
"gdalinfo warning: subdataset %d of %d requested. "
"Reading the main dataset.\n",
nSubdataset, nSubdatasets );
}
}
/* -------------------------------------------------------------------- */
/* Report general info. */
/* -------------------------------------------------------------------- */
hDriver = GDALGetDatasetDriver( hDataset );
if(bJson)
{
json_object *poDescription = json_object_new_string(GDALGetDescription(hDataset));
json_object *poDriverShortName = json_object_new_string(GDALGetDriverShortName(hDriver));
json_object *poDriverLongName = json_object_new_string(GDALGetDriverLongName(hDriver));
poJsonObject = json_object_new_object();
poBands = json_object_new_array();
poMetadata = json_object_new_object();
json_object_object_add(poJsonObject, "description", poDescription);
json_object_object_add(poJsonObject, "driverShortName", poDriverShortName);
json_object_object_add(poJsonObject, "driverLongName", poDriverLongName);
}
else
{
printf( "Driver: %s/%s\n",
GDALGetDriverLongName( hDriver ) );
}
papszFileList = GDALGetFileList( hDataset );
if( CSLCount(papszFileList) == 0 )
{
if(bJson)
{
json_object *poFiles = json_object_new_array();
json_object_object_add(poJsonObject, "files", poFiles);
}
else
printf( "Files: none associated\n" );
}
else
{
if(bJson)
{
json_object *poFiles = json_object_new_array();
for(i = 0; papszFileList[i] != NULL; i++)
{
json_object *poFile = json_object_new_string(papszFileList[i]);
json_object_array_add(poFiles, poFile);
}
json_object_object_add(poJsonObject, "files", poFiles);
}
else
{
printf( "Files: %s\n", papszFileList[0] );
if( bShowFileList )
{
for( i = 1; papszFileList[i] != NULL; i++ )
printf( " %s\n", papszFileList[i] );
}
}
}
CSLDestroy( papszFileList );
if(bJson)
{
json_object *poSize = json_object_new_array();
json_object *poSizeX = json_object_new_int(GDALGetRasterXSize(hDataset));
json_object *poSizeY = json_object_new_int(GDALGetRasterYSize(hDataset));
json_object_array_add(poSize, poSizeX);
json_object_array_add(poSize, poSizeY);
json_object_object_add(poJsonObject, "size", poSize);
}
else
printf( "Size is %d, %d\n",
GDALGetRasterXSize( hDataset ),
GDALGetRasterYSize( hDataset ) );
/* -------------------------------------------------------------------- */
/* Report projection. */
/* -------------------------------------------------------------------- */
if( GDALGetProjectionRef( hDataset ) != NULL )
{
OGRSpatialReferenceH hSRS;
char *pszProjection;
json_object *poCoordinateSystem = NULL;
if(bJson)
poCoordinateSystem = json_object_new_object();
pszProjection = (char *) GDALGetProjectionRef( hDataset );
hSRS = OSRNewSpatialReference(NULL);
if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None )
{
char *pszPrettyWkt = NULL;
OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE );
if(bJson)
{
json_object *poWkt = json_object_new_string(pszPrettyWkt);
json_object_object_add(poCoordinateSystem, "wkt", poWkt);
}
else
printf( "Coordinate System is:\n%s\n", pszPrettyWkt );
CPLFree( pszPrettyWkt );
}
else
{
if(bJson)
{
json_object *poWkt = json_object_new_string(GDALGetProjectionRef(hDataset));
json_object_object_add(poCoordinateSystem, "wkt", poWkt);
}
else
printf( "Coordinate System is `%s'\n",
GDALGetProjectionRef( hDataset ) );
}
if ( bReportProj4 )
{
char *pszProj4 = NULL;
OSRExportToProj4( hSRS, &pszProj4 );
if(bJson)
{
json_object *proj4 = json_object_new_string(pszProj4);
json_object_object_add(poCoordinateSystem, "proj4", proj4);
}
else
printf("PROJ.4 string is:\n\'%s\'\n",pszProj4);
CPLFree( pszProj4 );
}
if(bJson)
json_object_object_add(poJsonObject, "coordinateSystem", poCoordinateSystem);
}
/* -------------------------------------------------------------------- */
/* Report Geotransform. */
/* -------------------------------------------------------------------- */
if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
{
if(bJson)
{
json_object *poGeoTransform = json_object_new_array();
for(i = 0; i < 6; i++)
{
json_object *poGeoTransformCoefficient = json_object_new_double_with_precision(adfGeoTransform[i], 16);
json_object_array_add(poGeoTransform, poGeoTransformCoefficient);
}
json_object_object_add(poJsonObject, "geoTransform", poGeoTransform);
}
else
{
if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 )
{
CPLprintf( "Origin = (%.15f,%.15f)\n",
adfGeoTransform[0], adfGeoTransform[3] );
CPLprintf( "Pixel Size = (%.15f,%.15f)\n",
adfGeoTransform[1], adfGeoTransform[5] );
}
else
CPLprintf( "GeoTransform =\n"
" %.16g, %.16g, %.16g\n"
" %.16g, %.16g, %.16g\n",
adfGeoTransform[0],
adfGeoTransform[1],
adfGeoTransform[2],
adfGeoTransform[3],
adfGeoTransform[4],
adfGeoTransform[5] );
}
}
/* -------------------------------------------------------------------- */
/* Report GCPs. */
/* -------------------------------------------------------------------- */
if( bShowGCPs && GDALGetGCPCount( hDataset ) > 0 )
{
json_object *poGCPs = NULL, *poGCPList = NULL;
if(bJson)
poGCPs = json_object_new_object();
if (GDALGetGCPProjection(hDataset) != NULL)
{
json_object *poGCPCoordinateSystem = NULL;
OGRSpatialReferenceH hSRS;
char *pszProjection;
pszProjection = (char *) GDALGetGCPProjection( hDataset );
hSRS = OSRNewSpatialReference(NULL);
if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None )
{
char *pszPrettyWkt = NULL;
OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE );
if(bJson)
{
json_object *poWkt = json_object_new_string(pszPrettyWkt);
poGCPCoordinateSystem = json_object_new_object();
json_object_object_add(poGCPCoordinateSystem, "wkt", poWkt);
}
else
printf( "GCP Projection = \n%s\n", pszPrettyWkt );
CPLFree( pszPrettyWkt );
}
else
{
if(bJson)
{
json_object *poWkt = json_object_new_string(GDALGetGCPProjection(hDataset));
poGCPCoordinateSystem = json_object_new_object();
json_object_object_add(poGCPCoordinateSystem, "wkt", poWkt);
}
else
printf( "GCP Projection = %s\n",
GDALGetGCPProjection( hDataset ) );
}
if(bJson)
json_object_object_add(poGCPs, "coordinateSystem", poGCPCoordinateSystem);
}
if(bJson)
poGCPList = json_object_new_array();
for( i = 0; i < GDALGetGCPCount(hDataset); i++ )
{
const GDAL_GCP *psGCP;
psGCP = GDALGetGCPs( hDataset ) + i;
if(bJson)
{
json_object *poGCP = json_object_new_object();
json_object *poId = json_object_new_string(psGCP->pszId);
json_object *poInfo = json_object_new_string(psGCP->pszInfo);
json_object *poPixel = json_object_new_double_with_precision(psGCP->dfGCPPixel, 15);
json_object *poLine = json_object_new_double_with_precision(psGCP->dfGCPLine, 15);
json_object *poX = json_object_new_double_with_precision(psGCP->dfGCPX, 15);
json_object *poY = json_object_new_double_with_precision(psGCP->dfGCPY, 15);
json_object *poZ = json_object_new_double_with_precision(psGCP->dfGCPZ, 15);
json_object_object_add(poGCP, "id", poId);
json_object_object_add(poGCP, "info", poInfo);
json_object_object_add(poGCP, "pixel", poPixel);
json_object_object_add(poGCP, "line", poLine);
json_object_object_add(poGCP, "x", poX);
json_object_object_add(poGCP, "y", poY);
json_object_object_add(poGCP, "z", poZ);
json_object_array_add(poGCPList, poGCP);
}
else
CPLprintf( "GCP[%3d]: Id=%s, Info=%s\n"
" (%.15g,%.15g) -> (%.15g,%.15g,%.15g)\n",
i, psGCP->pszId, psGCP->pszInfo,
psGCP->dfGCPPixel, psGCP->dfGCPLine,
psGCP->dfGCPX, psGCP->dfGCPY, psGCP->dfGCPZ );
}
if(bJson)
{
json_object_object_add(poGCPs, "gcpList", poGCPList);
json_object_object_add(poJsonObject, "gcps", poGCPs);
}
}
/* -------------------------------------------------------------------- */
/* Report metadata. */
/* -------------------------------------------------------------------- */
GDALInfoReportMetadata( hDataset, bListMDD, bShowMetadata, papszExtraMDDomains, FALSE, bJson, poMetadata );
if(bJson && bShowMetadata)
json_object_object_add( poJsonObject, "metadata", poMetadata );
/* -------------------------------------------------------------------- */
/* Setup projected to lat/long transform if appropriate. */
/* -------------------------------------------------------------------- */
if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
pszProjection = GDALGetProjectionRef(hDataset);
if( pszProjection != NULL && strlen(pszProjection) > 0 )
{
OGRSpatialReferenceH hProj, hLatLong = NULL, hLatLongWGS84 = NULL;
hProj = OSRNewSpatialReference( pszProjection );
if( hProj != NULL )
{
hLatLong = OSRCloneGeogCS( hProj );
if(bJson)
{
hLatLongWGS84 = OSRNewSpatialReference( NULL );
OSRSetWellKnownGeogCS( hLatLongWGS84, "WGS84" );
}
}
if( hLatLong != NULL )
{
CPLPushErrorHandler( CPLQuietErrorHandler );
hTransform = OCTNewCoordinateTransformation( hProj, hLatLong );
}
if( hLatLongWGS84 != NULL )
{
CPLPushErrorHandler( CPLQuietErrorHandler );
hTransformWGS84 = OCTNewCoordinateTransformation( hProj, hLatLongWGS84 );
OSRDestroySpatialReference( hLatLongWGS84 );
}
if( hProj != NULL )
}
/* -------------------------------------------------------------------- */
/* Report corners. */
/* -------------------------------------------------------------------- */
if(bJson)
{
json_object *poLinearRing = json_object_new_array();
json_object *poCornerCoordinates = json_object_new_object();
json_object *poWGS84Extent = json_object_new_object();
json_object *poWGS84ExtentType = json_object_new_string("Polygon");
json_object *poWGS84ExtentCoordinates = json_object_new_array();
GDALInfoReportCorner( hDataset, hTransform, hTransformWGS84, "upperLeft",
0.0, 0.0, bJson, poCornerCoordinates, poWGS84ExtentCoordinates );
GDALInfoReportCorner( hDataset, hTransform, hTransformWGS84, "lowerLeft",
0.0, GDALGetRasterYSize(hDataset), bJson, poCornerCoordinates, poWGS84ExtentCoordinates );
GDALInfoReportCorner( hDataset, hTransform, hTransformWGS84, "upperRight",
GDALGetRasterXSize(hDataset), 0.0, bJson, poCornerCoordinates, poWGS84ExtentCoordinates );
GDALInfoReportCorner( hDataset, hTransform, hTransformWGS84, "lowerRight",
GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset),
bJson, poCornerCoordinates, poWGS84ExtentCoordinates );
GDALInfoReportCorner( hDataset, hTransform, hTransformWGS84, "center",
GDALGetRasterXSize(hDataset)/2.0, GDALGetRasterYSize(hDataset)/2.0,
bJson, poCornerCoordinates, poWGS84ExtentCoordinates );
GDALInfoReportCorner( hDataset, hTransform, hTransformWGS84, "upperLeft",
0.0, 0.0, bJson, poCornerCoordinates, poWGS84ExtentCoordinates );
json_object_object_add( poJsonObject, "cornerCoordinates", poCornerCoordinates );
json_object_object_add( poWGS84Extent, "type", poWGS84ExtentType );
json_object_array_add( poLinearRing, poWGS84ExtentCoordinates );
json_object_object_add( poWGS84Extent, "coordinates", poLinearRing );
json_object_object_add( poJsonObject, "wgs84Extent", poWGS84Extent );
}
else
{
printf( "Corner Coordinates:\n" );
GDALInfoReportCorner( hDataset, hTransform, hTransformWGS84, "Upper Left",
0.0, 0.0, bJson, NULL, NULL );
GDALInfoReportCorner( hDataset, hTransform, hTransformWGS84, "Lower Left",
0.0, GDALGetRasterYSize(hDataset), bJson, NULL, NULL );
GDALInfoReportCorner( hDataset, hTransform, hTransformWGS84, "Upper Right",
GDALGetRasterXSize(hDataset), 0.0, bJson, NULL, NULL );
GDALInfoReportCorner( hDataset, hTransform, hTransformWGS84, "Lower Right",
GDALGetRasterXSize(hDataset),
GDALGetRasterYSize(hDataset), bJson, NULL, NULL );
GDALInfoReportCorner( hDataset, hTransform, hTransformWGS84, "Center",
GDALGetRasterXSize(hDataset)/2.0,
GDALGetRasterYSize(hDataset)/2.0, bJson, NULL, NULL );
}
if( hTransform != NULL )
{
hTransform = NULL;
}
if( hTransformWGS84 != NULL )
{
hTransformWGS84 = NULL;
}
/* ==================================================================== */
/* Loop over bands. */
/* ==================================================================== */
for( iBand = 0; iBand < GDALGetRasterCount( hDataset ); iBand++ )
{
double dfMin, dfMax, adfCMinMax[2], dfNoData;
int bGotMin, bGotMax, bGotNodata, bSuccess;
int nBlockXSize, nBlockYSize, nMaskFlags;
double dfMean, dfStdDev;
CPLErr eErr;
json_object *poBand = NULL, *poBandMetadata = NULL;
if(bJson)
{
poBand = json_object_new_object();
poBandMetadata = json_object_new_object();
}
hBand = GDALGetRasterBand( hDataset, iBand+1 );
if( bSample )
{
float afSample[10000];
int nCount;
nCount = GDALGetRandomRasterSample( hBand, 10000, afSample );
if(!bJson)
printf( "Got %d samples.\n", nCount );
}
GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize );
if(bJson)
{
json_object *poBandNumber = json_object_new_int(iBand+1);
json_object *poBlock = json_object_new_array();
json_object *poType = json_object_new_string(GDALGetDataTypeName(GDALGetRasterDataType(hBand)));
json_object *poColorInterp = json_object_new_string(GDALGetColorInterpretationName(
json_object_array_add(poBlock, json_object_new_int(nBlockXSize));
json_object_array_add(poBlock, json_object_new_int(nBlockYSize));
json_object_object_add(poBand, "band", poBandNumber);
json_object_object_add(poBand, "block", poBlock);
json_object_object_add(poBand, "type", poType);
json_object_object_add(poBand, "colorInterpretation", poColorInterp);
}
else
printf( "Band %d Block=%dx%d Type=%s, ColorInterp=%s\n", iBand+1,
nBlockXSize, nBlockYSize,
if( GDALGetDescription( hBand ) != NULL
&& strlen(GDALGetDescription( hBand )) > 0 )
{
if(bJson)
{
json_object *poBandDescription = json_object_new_string(GDALGetDescription(hBand));
json_object_object_add(poBand, "description", poBandDescription);
}
else
printf( " Description = %s\n", GDALGetDescription(hBand) );
}
dfMin = GDALGetRasterMinimum( hBand, &bGotMin );
dfMax = GDALGetRasterMaximum( hBand, &bGotMax );
if( bGotMin || bGotMax || bComputeMinMax )
{
if(!bJson)
printf( " " );
if( bGotMin )
{
if(bJson)
{
json_object *poMin = json_object_new_double_with_precision(dfMin, 3);
json_object_object_add(poBand, "min", poMin);
}
else
CPLprintf( "Min=%.3f ", dfMin );
}
if( bGotMax )
{
if(bJson)
{
json_object *poMax = json_object_new_double_with_precision(dfMax, 3);
json_object_object_add(poBand, "max", poMax);
}
else
CPLprintf( "Max=%.3f ", dfMax );
}
if( bComputeMinMax )
{
GDALComputeRasterMinMax( hBand, FALSE, adfCMinMax );
if (CPLGetLastErrorType() == CE_None)
{
if(bJson)
{
json_object *poComputedMin = json_object_new_double_with_precision(adfCMinMax[0], 3);
json_object *poComputedMax = json_object_new_double_with_precision(adfCMinMax[1], 3);
json_object_object_add(poBand, "computedMin", poComputedMin);
json_object_object_add(poBand, "computedMax", poComputedMax);
}
else
CPLprintf( " Computed Min/Max=%.3f,%.3f",
adfCMinMax[0], adfCMinMax[1] );
}
}
if(!bJson)
printf( "\n" );
}
eErr = GDALGetRasterStatistics( hBand, bApproxStats, bStats,
&dfMin, &dfMax, &dfMean, &dfStdDev );
if( eErr == CE_None )
{
if(bJson)
{
json_object *poMinimum = json_object_new_double_with_precision(dfMin, 3);
json_object *poMaximum = json_object_new_double_with_precision(dfMax, 3);
json_object *poMean = json_object_new_double_with_precision(dfMean, 3);
json_object *poStdDev = json_object_new_double_with_precision(dfStdDev, 3);
json_object_object_add(poBand, "minimum", poMinimum);
json_object_object_add(poBand, "maximum", poMaximum);
json_object_object_add(poBand, "mean", poMean);
json_object_object_add(poBand, "stdDev", poStdDev);
}
else
CPLprintf( " Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f\n",
dfMin, dfMax, dfMean, dfStdDev );
}
if( bReportHistograms )
{
int nBucketCount;
GUIntBig *panHistogram = NULL;
if(bJson)
eErr = GDALGetDefaultHistogramEx( hBand, &dfMin, &dfMax,
&nBucketCount, &panHistogram,
TRUE, GDALDummyProgress, NULL );
else
eErr = GDALGetDefaultHistogramEx( hBand, &dfMin, &dfMax,
&nBucketCount, &panHistogram,
TRUE, GDALTermProgress, NULL );
if( eErr == CE_None )
{
int iBucket;
json_object *poHistogram = NULL, *poBuckets = NULL;
if(bJson)
{
json_object *poCount = json_object_new_int(nBucketCount);
json_object *poMin = json_object_new_double(dfMin);
json_object *poMax = json_object_new_double(dfMax);
poBuckets = json_object_new_array();
poHistogram = json_object_new_object();
json_object_object_add(poHistogram, "count", poCount);
json_object_object_add(poHistogram, "min", poMin);
json_object_object_add(poHistogram, "max", poMax);
}
else
printf( " %d buckets from %g to %g:\n ",
nBucketCount, dfMin, dfMax );
for( iBucket = 0; iBucket < nBucketCount; iBucket++ )
{
if(bJson)
{
json_object *poBucket = json_object_new_int64(panHistogram[iBucket]);
json_object_array_add(poBuckets, poBucket);
}
else
printf( CPL_FRMT_GUIB " ", panHistogram[iBucket] );
}
if(bJson)
{
json_object_object_add(poHistogram, "buckets", poBuckets);
json_object_object_add(poBand, "histogram", poHistogram);
}
else
printf( "\n" );
CPLFree( panHistogram );
}
}
if ( bComputeChecksum)
{
int nBandChecksum = GDALChecksumImage(hBand, 0, 0,
GDALGetRasterXSize(hDataset),
GDALGetRasterYSize(hDataset));
if(bJson)
{
json_object *poChecksum = json_object_new_int(nBandChecksum);
json_object_object_add(poBand, "checksum", poChecksum);
}
else
printf( " Checksum=%d\n", nBandChecksum );
}
dfNoData = GDALGetRasterNoDataValue( hBand, &bGotNodata );
if( bGotNodata )
{
if (CPLIsNan(dfNoData))
{
if(bJson)
{
json_object *poNoDataValue = json_object_new_string("nan");
json_object_object_add(poBand, "noDataValue", poNoDataValue);
}
else
printf( " NoData Value=nan\n" );
}
else
{
if(bJson)
{
json_object *poNoDataValue = json_object_new_double_with_precision(dfNoData, 18);
json_object_object_add(poBand, "noDataValue", poNoDataValue);
}
else
CPLprintf( " NoData Value=%.18g\n", dfNoData );
}
}
if( GDALGetOverviewCount(hBand) > 0 )
{
int iOverview;
json_object *poOverviews = NULL;
if(bJson)
poOverviews = json_object_new_array();
else
printf( " Overviews: " );
for( iOverview = 0;
iOverview < GDALGetOverviewCount(hBand);
iOverview++ )
{
GDALRasterBandH hOverview;
const char *pszResampling = NULL;
json_object *poOverview;
if(!bJson)
if( iOverview != 0 )
printf( ", " );
hOverview = GDALGetOverview( hBand, iOverview );
if (hOverview != NULL)
{
if(bJson)
{
json_object *poOverviewSize = json_object_new_array();
json_object *poOverviewSizeX = json_object_new_int( GDALGetRasterBandXSize( hOverview) );
json_object *poOverviewSizeY = json_object_new_int( GDALGetRasterBandYSize( hOverview) );
poOverview = json_object_new_object();
json_object_array_add( poOverviewSize, poOverviewSizeX );
json_object_array_add( poOverviewSize, poOverviewSizeY );
json_object_object_add( poOverview, "size", poOverviewSize );
if(bComputeChecksum)
{
int nOverviewChecksum = GDALChecksumImage(hOverview, 0, 0,
json_object *poOverviewChecksum = json_object_new_int(nOverviewChecksum);
json_object_object_add(poOverview, "checksum", poOverviewChecksum);
}
json_object_array_add(poOverviews, poOverview);
}
else
printf( "%dx%d",
GDALGetRasterBandXSize( hOverview ),
GDALGetRasterBandYSize( hOverview ) );
pszResampling =
GDALGetMetadataItem( hOverview, "RESAMPLING", "" );
if( pszResampling != NULL && !bJson
&& EQUALN(pszResampling,"AVERAGE_BIT2",12) )
printf( "*" );
}
else
if(!bJson)
printf( "(null)" );
}
if(bJson)
json_object_object_add(poBand, "overviews", poOverviews);
else
printf( "\n" );
if ( bComputeChecksum && !bJson )
{
printf( " Overviews checksum: " );
for( iOverview = 0;
iOverview < GDALGetOverviewCount(hBand);
iOverview++ )
{
GDALRasterBandH hOverview;
if( iOverview != 0 )
printf( ", " );
hOverview = GDALGetOverview( hBand, iOverview );
if (hOverview)
{
printf( "%d",
GDALChecksumImage(hOverview, 0, 0,
GDALGetRasterBandYSize(hOverview)));
}
else
{
printf( "(null)" );
}
}
printf( "\n" );
}
}
if( GDALHasArbitraryOverviews( hBand ) && !bJson )
{
printf( " Overviews: arbitrary\n" );
}
nMaskFlags = GDALGetMaskFlags( hBand );
if( (nMaskFlags & (GMF_NODATA|GMF_ALL_VALID)) == 0 )
{
GDALRasterBandH hMaskBand = GDALGetMaskBand(hBand) ;
json_object *poMask = NULL, *poFlags = NULL, *poMaskOverviews = NULL;
if(bJson)
{
poMask = json_object_new_object();
poFlags = json_object_new_array();
}
else
printf( " Mask Flags: " );
if( nMaskFlags & GMF_PER_DATASET )
{
if(bJson)
{
json_object *poFlag = json_object_new_string( "PER_DATASET" );
json_object_array_add( poFlags, poFlag );
}
else
printf( "PER_DATASET " );
}
if( nMaskFlags & GMF_ALPHA )
{
if(bJson)
{
json_object *poFlag = json_object_new_string( "ALPHA" );
json_object_array_add( poFlags, poFlag );
}
else
printf( "ALPHA " );
}
if( nMaskFlags & GMF_NODATA )
{
if(bJson)
{
json_object *poFlag = json_object_new_string( "NODATA" );
json_object_array_add( poFlags, poFlag );
}
else
printf( "NODATA " );
}
if( nMaskFlags & GMF_ALL_VALID )
{
if(bJson)
{
json_object *poFlag = json_object_new_string( "ALL_VALID" );
json_object_array_add( poFlags, poFlag );
}
else
printf( "ALL_VALID " );
}
if(bJson)
json_object_object_add( poMask, "flags", poFlags );
else
printf( "\n" );
if(bJson)
poMaskOverviews = json_object_new_array();
if( hMaskBand != NULL &&
GDALGetOverviewCount(hMaskBand) > 0 )
{
int iOverview;
if(!bJson)
printf( " Overviews of mask band: " );
for( iOverview = 0;
iOverview < GDALGetOverviewCount(hMaskBand);
iOverview++ )
{
GDALRasterBandH hOverview;
json_object *poMaskOverviewSizeX, *poMaskOverviewSizeY,
*poMaskOverview = NULL, *poMaskOverviewSize = NULL;
if(bJson)
{
poMaskOverview = json_object_new_object();
poMaskOverviewSize = json_object_new_array();
}
else
{
if( iOverview != 0 )
printf( ", " );
}
hOverview = GDALGetOverview( hMaskBand, iOverview );
if(bJson)
{
poMaskOverviewSizeX = json_object_new_int(GDALGetRasterBandXSize(hOverview));
poMaskOverviewSizeY = json_object_new_int(GDALGetRasterBandYSize(hOverview));
json_object_array_add(poMaskOverviewSize, poMaskOverviewSizeX);
json_object_array_add(poMaskOverviewSize, poMaskOverviewSizeY);
json_object_object_add(poMaskOverview, "size", poMaskOverviewSize);
json_object_array_add(poMaskOverviews, poMaskOverview);
}
else
printf( "%dx%d",
GDALGetRasterBandXSize( hOverview ),
GDALGetRasterBandYSize( hOverview ) );
}
if(!bJson)
printf( "\n" );
}
if(bJson)
{
json_object_object_add(poMask, "overviews", poMaskOverviews);
json_object_object_add(poBand, "mask", poMask);
}
}
if( strlen(GDALGetRasterUnitType(hBand)) > 0 )
{
if(bJson)
{
json_object *poUnit = json_object_new_string(GDALGetRasterUnitType(hBand));
json_object_object_add(poBand, "unit", poUnit);
}
else
printf( " Unit Type: %s\n", GDALGetRasterUnitType(hBand) );
}
if( GDALGetRasterCategoryNames(hBand) != NULL )
{
char **papszCategories = GDALGetRasterCategoryNames(hBand);
int i;
json_object *poCategories = NULL;
if(bJson)
poCategories = json_object_new_array();
else
printf( " Categories:\n" );
for( i = 0; papszCategories[i] != NULL; i++ )
{
if(bJson)
{
json_object *poCategoryName = json_object_new_string(papszCategories[i]);
json_object_array_add(poCategories, poCategoryName);
}
else
printf( " %3d: %s\n", i, papszCategories[i] );
}
if(bJson)
json_object_object_add(poBand, "categories", poCategories);
}
if( GDALGetRasterScale( hBand, &bSuccess ) != 1.0
|| GDALGetRasterOffset( hBand, &bSuccess ) != 0.0 )
{
if(bJson)
{
json_object *poOffset = json_object_new_double_with_precision(GDALGetRasterOffset(hBand, &bSuccess), 15);
json_object *poScale = json_object_new_double_with_precision(GDALGetRasterScale(hBand, &bSuccess), 15);
json_object_object_add(poBand, "offset", poOffset);
json_object_object_add(poBand, "scale", poScale);
}
else
CPLprintf( " Offset: %.15g, Scale:%.15g\n",
GDALGetRasterOffset( hBand, &bSuccess ),
GDALGetRasterScale( hBand, &bSuccess ) );
}
GDALInfoReportMetadata( hBand, bListMDD, bShowMetadata, papszExtraMDDomains, TRUE, bJson, poBandMetadata );
if(bJson && bShowMetadata)
json_object_object_add( poBand, "metadata", poBandMetadata );
&& (hTable = GDALGetRasterColorTable( hBand )) != NULL )
{
int i;
json_object *poColorTable = NULL;
if(bJson)
{
json_object *poPalette = json_object_new_string(GDALGetPaletteInterpretationName(
json_object *poCount = json_object_new_int(GDALGetColorEntryCount(hTable));
poColorTable = json_object_new_object();
json_object_object_add(poColorTable, "palette", poPalette);
json_object_object_add(poColorTable, "count", poCount);
}
else
printf( " Color Table (%s with %d entries)\n",
if (bShowColorTable)
{
json_object *poEntries = NULL;
if(bJson)
poEntries = json_object_new_array();
for( i = 0; i < GDALGetColorEntryCount( hTable ); i++ )
{
GDALGetColorEntryAsRGB( hTable, i, &sEntry );
if(bJson)
{
json_object *poEntry = json_object_new_array();
json_object *poC1 = json_object_new_int(sEntry.c1);
json_object *poC2 = json_object_new_int(sEntry.c2);
json_object *poC3 = json_object_new_int(sEntry.c3);
json_object *poC4 = json_object_new_int(sEntry.c4);
json_object_array_add(poEntry, poC1);
json_object_array_add(poEntry, poC2);
json_object_array_add(poEntry, poC3);
json_object_array_add(poEntry, poC4);
json_object_array_add(poEntries, poEntry);
}
else
printf( " %3d: %d,%d,%d,%d\n",
i,
sEntry.c1,
sEntry.c2,
sEntry.c3,
sEntry.c4 );
}
if(bJson)
{
json_object_object_add(poColorTable, "entries", poEntries);
json_object_object_add(poBand, "colorTable", poColorTable);
}
}
}
if( bShowRAT && GDALGetDefaultRAT( hBand ) != NULL )
{
if(bJson)
{
json_object *poRAT = (json_object*) GDALRATSerializeJSON( hRAT );
json_object_object_add( poJsonObject, "rat", poRAT );
}
else
{
GDALRATDumpReadable( hRAT, NULL );
}
}
if(bJson)
json_object_array_add(poBands, poBand);
}
if(bJson)
{
json_object_object_add(poJsonObject, "bands", poBands);
printf("%s\n", json_object_to_json_string_ext(poJsonObject, JSON_C_TO_STRING_PRETTY));
json_object_put(poJsonObject);
}
GDALClose( hDataset );
CSLDestroy( papszExtraMDDomains );
CSLDestroy( papszOpenOptions );
CSLDestroy( argv );
CPLCleanupTLS();
exit( 0 );
}
/************************************************************************/
/* GDALInfoReportCorner() */
/************************************************************************/
static int
GDALInfoReportCorner( GDALDatasetH hDataset,
OGRCoordinateTransformationH hTransform, OGRCoordinateTransformationH hTransformWGS84,
const char * corner_name,
double x, double y,
int bJson, json_object *poCornerCoordinates, json_object *poWGS84ExtentCoordinates )
{
double dfGeoX, dfGeoY;
double adfGeoTransform[6];
json_object *poCorner, *poX, *poY;
if(!bJson)
printf( "%-11s ", corner_name );
/* -------------------------------------------------------------------- */
/* Transform the point into georeferenced coordinates. */
/* -------------------------------------------------------------------- */
if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
{
dfGeoX = adfGeoTransform[0] + adfGeoTransform[1] * x
+ adfGeoTransform[2] * y;
dfGeoY = adfGeoTransform[3] + adfGeoTransform[4] * x
+ adfGeoTransform[5] * y;
}
else
{
if( bJson )
{
poCorner = json_object_new_array();
poX = json_object_new_double_with_precision( x, 1 );
poY = json_object_new_double_with_precision( y, 1 );
json_object_array_add( poCorner, poX );
json_object_array_add( poCorner, poY );
json_object_object_add( poCornerCoordinates, corner_name, poCorner );
}
else
CPLprintf( "(%7.1f,%7.1f)\n", x, y );
return FALSE;
}
/* -------------------------------------------------------------------- */
/* Report the georeferenced coordinates. */
/* -------------------------------------------------------------------- */
if( ABS(dfGeoX) < 181 && ABS(dfGeoY) < 91 )
{
if(bJson)
{
poCorner = json_object_new_array();
poX = json_object_new_double_with_precision( dfGeoX, 7 );
poY = json_object_new_double_with_precision( dfGeoY, 7 );
json_object_array_add( poCorner, poX );
json_object_array_add( poCorner, poY );
json_object_object_add( poCornerCoordinates, corner_name, poCorner );
}
else
CPLprintf( "(%12.7f,%12.7f) ", dfGeoX, dfGeoY );
}
else
{
if(bJson)
{
poCorner = json_object_new_array();
poX = json_object_new_double_with_precision( dfGeoX, 3 );
poY = json_object_new_double_with_precision( dfGeoY, 3 );
json_object_array_add( poCorner, poX );
json_object_array_add( poCorner, poY );
json_object_object_add( poCornerCoordinates, corner_name, poCorner );
}
else
CPLprintf( "(%12.3f,%12.3f) ", dfGeoX, dfGeoY );
}
/* -------------------------------------------------------------------- */
/* Transform to latlong and report. */
/* -------------------------------------------------------------------- */
if(bJson)
{
double dfZ = 0.0;
if( hTransformWGS84 != NULL && !EQUAL( corner_name, "center" )
&& OCTTransform(hTransformWGS84,1,&dfGeoX,&dfGeoY,&dfZ) )
{
poCorner = json_object_new_array();
poX = json_object_new_double_with_precision( dfGeoX, 7 );
poY = json_object_new_double_with_precision( dfGeoY, 7 );
json_object_array_add( poCorner, poX );
json_object_array_add( poCorner, poY );
json_object_array_add( poWGS84ExtentCoordinates , poCorner );
}
}
else
{
double dfZ = 0.0;
if( hTransform != NULL
&& OCTTransform(hTransform,1,&dfGeoX,&dfGeoY,&dfZ) )
{
printf( "(%s,", GDALDecToDMS( dfGeoX, "Long", 2 ) );
printf( "%s)", GDALDecToDMS( dfGeoY, "Lat", 2 ) );
}
printf( "\n" );
}
return TRUE;
}
/************************************************************************/
/* GDALInfoPrintMetadata() */
/************************************************************************/
static void GDALInfoPrintMetadata( GDALMajorObjectH hObject,
const char *pszDomain,
const char *pszDisplayedname,
const char *pszIndent,
int bJson,
json_object *poMetadata )
{
int i;
char **papszMetadata;
int bIsxml = FALSE;
char *pszKey = NULL;
const char *pszValue;
json_object *poDomain = NULL, *poValue = NULL;
if (pszDomain != NULL && EQUALN(pszDomain, "xml:", 4))
bIsxml = TRUE;
papszMetadata = GDALGetMetadata( hObject, pszDomain );
if( CSLCount(papszMetadata) > 0 )
{
if(bJson && !bIsxml)
poDomain = json_object_new_object();
if(!bJson)
printf( "%s%s:\n", pszIndent, pszDisplayedname );
for( i = 0; papszMetadata[i] != NULL; i++ )
{
if(bJson)
{
if(bIsxml)
{
poValue = json_object_new_string( papszMetadata[i] );
break;
}
else
{
pszKey = NULL;
pszValue = CPLParseNameValue( papszMetadata[i], &pszKey );
if( pszKey )
{
poValue = json_object_new_string( pszValue );
json_object_object_add( poDomain, pszKey, poValue );
CPLFree( pszKey );
}
}
}
else
{
if (bIsxml)
printf( "%s%s\n", pszIndent, papszMetadata[i] );
else
printf( "%s %s\n", pszIndent, papszMetadata[i] );
}
}
if(bJson)
{
if(bIsxml)
json_object_object_add( poMetadata, pszDomain, poValue );
else
{
if(pszDomain == NULL)
json_object_object_add( poMetadata, "", poDomain );
else
json_object_object_add( poMetadata, pszDomain, poDomain );
}
}
}
}
/************************************************************************/
/* GDALInfoReportMetadata() */
/************************************************************************/
static void GDALInfoReportMetadata( GDALMajorObjectH hObject,
int bListMDD,
int bShowMetadata,
char **papszExtraMDDomains,
int bIsBand,
int bJson,
json_object *poMetadata )
{
const char* pszIndent = "";
if( bIsBand )
pszIndent = " ";
/* -------------------------------------------------------------------- */
/* Report list of Metadata domains */
/* -------------------------------------------------------------------- */
if( bListMDD )
{
char** papszMDDList = GDALGetMetadataDomainList( hObject );
char** papszIter = papszMDDList;
json_object *poMDD = NULL;
json_object *poListMDD = NULL;
if( bJson )
poListMDD = json_object_new_array();
if( papszMDDList != NULL )
{
if(!bJson)
printf( "%sMetadata domains:\n", pszIndent );
}
while( papszIter != NULL && *papszIter != NULL )
{
if( EQUAL(*papszIter, "") )
{
if(bJson)
poMDD = json_object_new_string( *papszIter );
else
printf( "%s (default)\n", pszIndent);
}
else
{
if(bJson)
poMDD = json_object_new_string( *papszIter );
else
printf( "%s %s\n", pszIndent, *papszIter );
}
if(bJson)
json_object_array_add( poListMDD, poMDD );
papszIter ++;
}
if(bJson)
json_object_object_add( poMetadata, "metadataDomains", poListMDD );
CSLDestroy(papszMDDList);
}
if (!bShowMetadata)
return;
/* -------------------------------------------------------------------- */
/* Report default Metadata domain. */
/* -------------------------------------------------------------------- */
GDALInfoPrintMetadata( hObject, NULL, "Metadata", pszIndent, bJson, poMetadata );
/* -------------------------------------------------------------------- */
/* Report extra Metadata domains */
/* -------------------------------------------------------------------- */
if (papszExtraMDDomains != NULL) {
char **papszExtraMDDomainsExpanded = NULL;
int iMDD;
if( EQUAL(papszExtraMDDomains[0], "all") &&
papszExtraMDDomains[1] == NULL )
{
char** papszMDDList = GDALGetMetadataDomainList( hObject );
char** papszIter = papszMDDList;
while( papszIter != NULL && *papszIter != NULL )
{
if( !EQUAL(*papszIter, "") &&
!EQUAL(*papszIter, "IMAGE_STRUCTURE") &&
!EQUAL(*papszIter, "SUBDATASETS") &&
!EQUAL(*papszIter, "GEOLOCATION") &&
!EQUAL(*papszIter, "RPC") )
{
papszExtraMDDomainsExpanded = CSLAddString(papszExtraMDDomainsExpanded, *papszIter);
}
papszIter ++;
}
CSLDestroy(papszMDDList);
}
else
{
papszExtraMDDomainsExpanded = CSLDuplicate(papszExtraMDDomains);
}
for( iMDD = 0; iMDD < CSLCount(papszExtraMDDomainsExpanded); iMDD++ )
{
char pszDisplayedname[256];
snprintf(pszDisplayedname, 256, "Metadata (%s)", papszExtraMDDomainsExpanded[iMDD]);
if(bJson)
GDALInfoPrintMetadata( hObject, papszExtraMDDomainsExpanded[iMDD], papszExtraMDDomainsExpanded[iMDD], pszIndent, bJson, poMetadata );
else
GDALInfoPrintMetadata( hObject, papszExtraMDDomainsExpanded[iMDD], pszDisplayedname, pszIndent, bJson, poMetadata );
}
CSLDestroy(papszExtraMDDomainsExpanded);
}
/* -------------------------------------------------------------------- */
/* Report various named metadata domains. */
/* -------------------------------------------------------------------- */
GDALInfoPrintMetadata( hObject, "IMAGE_STRUCTURE", "Image Structure Metadata", pszIndent, bJson, poMetadata );
if (!bIsBand)
{
GDALInfoPrintMetadata( hObject, "SUBDATASETS", "Subdatasets", pszIndent, bJson, poMetadata );
GDALInfoPrintMetadata( hObject, "GEOLOCATION", "Geolocation", pszIndent, bJson, poMetadata );
GDALInfoPrintMetadata( hObject, "RPC", "RPC Metadata", pszIndent, bJson, poMetadata );
}
}

Generated for GDAL by doxygen 1.8.8.