GDAL
Simple C Example: gdalinfo_lib.cpp
/******************************************************************************
*
* Project: GDAL Utilities
* Purpose: Command line application to list info about a file.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
* ****************************************************************************
* Copyright (c) 1998, Frank Warmerdam
* Copyright (c) 2007-2015, Even Rouault <even.rouault at spatialys.com>
* Copyright (c) 2015, Faza Mahamood
*
* 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 "cpl_port.h"
#include "gdal_utils.h"
#include "gdal_utils_priv.h"
#include <cmath>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <new>
#include <string>
#include <vector>
#include "commonutils.h"
#include "cpl_conv.h"
#include "cpl_error.h"
#include "cpl_json_header.h"
#include "cpl_minixml.h"
#include "cpl_progress.h"
#include "cpl_string.h"
#include "cpl_vsi.h"
#include "gdal.h"
#include "gdal_alg.h"
#include "gdal_priv.h"
#include "gdal_rat.h"
#include "ogr_api.h"
#include "ogr_srs_api.h"
#include "ogr_spatialref.h"
#include "ogrgeojsonreader.h"
#include "ogrgeojsonwriter.h"
using std::vector;
CPL_CVSID("$Id: gdalinfo_lib.cpp ee6581953a7041956a6655c1656830f35a6739e5 2018-08-08 23:38:59 +0200 Even Rouault $")
typedef enum { GDALINFO_FORMAT_TEXT = 0, GDALINFO_FORMAT_JSON = 1
} GDALInfoFormat;
/************************************************************************/
/* GDALInfoOptions */
/************************************************************************/
{
GDALInfoFormat eFormat;
int bComputeMinMax;
int bReportHistograms;
int bReportProj4;
int bStats;
int bApproxStats;
int bSample;
int bComputeChecksum;
int bShowGCPs;
int bShowMetadata;
int bShowRAT;
int bShowColorTable;
int bListMDD;
int bShowFileList;
char **papszExtraMDDomains;
bool bStdoutOutput;
};
static int
GDALInfoReportCorner( const GDALInfoOptions* psOptions,
GDALDatasetH hDataset,
const char * corner_name,
double x,
double y,
bool bJson,
json_object *poCornerCoordinates,
json_object *poLongLatExtentCoordinates,
CPLString& osStr );
static void
GDALInfoReportMetadata( const GDALInfoOptions* psOptions,
bool bIsBand,
bool bJson,
json_object *poMetadata,
CPLString& osStr );
static void Concat( CPLString& osRet, bool bStdoutOutput,
const char* pszFormat, ... ) CPL_PRINT_FUNC_FORMAT (3, 4);
static void Concat( CPLString& osRet, bool bStdoutOutput,
const char* pszFormat, ... )
{
va_list args;
va_start( args, pszFormat );
if( bStdoutOutput )
{
vfprintf(stdout, pszFormat, args );
}
else
{
try
{
CPLString osTarget;
osTarget.vPrintf( pszFormat, args );
osRet += osTarget;
}
catch( const std::bad_alloc& )
{
CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory");
}
}
va_end( args );
}
/************************************************************************/
/* GDALInfo() */
/************************************************************************/
char *GDALInfo( GDALDatasetH hDataset, const GDALInfoOptions *psOptions )
{
if( hDataset == nullptr )
return nullptr;
GDALInfoOptions* psOptionsToFree = nullptr;
if( psOptions == nullptr )
{
psOptionsToFree = GDALInfoOptionsNew(nullptr, nullptr);
psOptions = psOptionsToFree;
}
CPLString osStr;
json_object *poJsonObject = nullptr;
json_object *poBands = nullptr;
json_object *poMetadata = nullptr;
const bool bJson = psOptions->eFormat == GDALINFO_FORMAT_JSON;
/* -------------------------------------------------------------------- */
/* Report general info. */
/* -------------------------------------------------------------------- */
GDALDriverH 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
{
Concat( osStr, psOptions->bStdoutOutput, "Driver: %s/%s\n",
GDALGetDriverLongName( hDriver ) );
}
char **papszFileList = GDALGetFileList( hDataset );
if( papszFileList == nullptr || *papszFileList == nullptr )
{
if( bJson )
{
json_object *poFiles = json_object_new_array();
json_object_object_add(poJsonObject, "files", poFiles);
}
else
{
Concat( osStr, psOptions->bStdoutOutput,
"Files: none associated\n" );
}
}
else
{
if( bJson )
{
if( psOptions->bShowFileList )
{
json_object *poFiles = json_object_new_array();
for( int i = 0; papszFileList[i] != nullptr; i++ )
{
json_object *poFile =
json_object_new_string(papszFileList[i]);
json_object_array_add(poFiles, poFile);
}
json_object_object_add(poJsonObject, "files", poFiles);
}
}
else
{
Concat(osStr, psOptions->bStdoutOutput,
"Files: %s\n", papszFileList[0] );
if( psOptions->bShowFileList )
{
for( int i = 1; papszFileList[i] != nullptr; i++ )
Concat(osStr, psOptions->bStdoutOutput,
" %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
{
Concat(osStr, psOptions->bStdoutOutput,
"Size is %d, %d\n",
GDALGetRasterXSize( hDataset ),
GDALGetRasterYSize( hDataset ) );
}
/* -------------------------------------------------------------------- */
/* Report projection. */
/* -------------------------------------------------------------------- */
if( GDALGetProjectionRef( hDataset ) != nullptr )
{
json_object *poCoordinateSystem = nullptr;
if( bJson )
poCoordinateSystem = json_object_new_object();
char *pszProjection =
const_cast<char *>( GDALGetProjectionRef( hDataset ) );
if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None )
{
char *pszPrettyWkt = nullptr;
OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE );
if( bJson )
{
json_object *poWkt = json_object_new_string(pszPrettyWkt);
json_object_object_add(poCoordinateSystem, "wkt", poWkt);
}
else
{
Concat( osStr, psOptions->bStdoutOutput,
"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
{
Concat( osStr, psOptions->bStdoutOutput,
"Coordinate System is `%s'\n",
GDALGetProjectionRef( hDataset ) );
}
}
if ( psOptions->bReportProj4 )
{
char *pszProj4 = nullptr;
OSRExportToProj4( hSRS, &pszProj4 );
if( bJson )
{
json_object *proj4 = json_object_new_string(pszProj4);
json_object_object_add(poCoordinateSystem, "proj4", proj4);
}
else
Concat(osStr, psOptions->bStdoutOutput,
"PROJ.4 string is:\n\'%s\'\n",pszProj4);
CPLFree( pszProj4 );
}
if( bJson )
json_object_object_add(poJsonObject, "coordinateSystem",
poCoordinateSystem);
}
/* -------------------------------------------------------------------- */
/* Report Geotransform. */
/* -------------------------------------------------------------------- */
double adfGeoTransform[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
{
if( bJson )
{
json_object *poGeoTransform = json_object_new_array();
for( int 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 )
{
Concat( osStr, psOptions->bStdoutOutput,
"Origin = (%.15f,%.15f)\n",
adfGeoTransform[0], adfGeoTransform[3] );
Concat( osStr, psOptions->bStdoutOutput,
"Pixel Size = (%.15f,%.15f)\n",
adfGeoTransform[1], adfGeoTransform[5] );
}
else
{
Concat( osStr, psOptions->bStdoutOutput, "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( psOptions->bShowGCPs && GDALGetGCPCount( hDataset ) > 0 )
{
json_object * const poGCPs = bJson ? json_object_new_object() : nullptr;
if (GDALGetGCPProjection(hDataset) != nullptr)
{
json_object *poGCPCoordinateSystem = nullptr;
char *pszProjection =
const_cast<char *>( GDALGetGCPProjection( hDataset ) );
if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None )
{
char *pszPrettyWkt = nullptr;
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
{
Concat(osStr, psOptions->bStdoutOutput,
"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
{
Concat(osStr, psOptions->bStdoutOutput,
"GCP Projection = %s\n",
GDALGetGCPProjection( hDataset ) );
}
}
if(bJson)
json_object_object_add(poGCPs, "coordinateSystem",
poGCPCoordinateSystem);
}
json_object * const poGCPList = bJson ? json_object_new_array() : nullptr;
for( int i = 0; i < GDALGetGCPCount(hDataset); i++ )
{
const GDAL_GCP *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
{
Concat(osStr, psOptions->bStdoutOutput,
"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( psOptions, hDataset, false,
bJson, poMetadata, osStr );
if( bJson )
{
if( psOptions->bShowMetadata )
json_object_object_add( poJsonObject, "metadata", poMetadata );
else
json_object_put(poMetadata);
}
/* -------------------------------------------------------------------- */
/* Setup projected to lat/long transform if appropriate. */
/* -------------------------------------------------------------------- */
const char *pszProjection = nullptr;
if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
pszProjection = GDALGetProjectionRef(hDataset);
OGRCoordinateTransformationH hTransform = nullptr;
bool bTransformToWGS84 = false;
if( pszProjection != nullptr && strlen(pszProjection) > 0 )
{
OGRSpatialReferenceH hLatLong = nullptr;
OGRSpatialReferenceH hProj = OSRNewSpatialReference( pszProjection );
if( hProj != nullptr )
{
// Check that it looks like Earth before trying to reproject to wgs84...
if(bJson &&
fabs( OSRGetSemiMajor(hProj, &eErr) - 6378137.0) < 10000.0 &&
eErr == OGRERR_NONE )
{
bTransformToWGS84 = true;
hLatLong = OSRNewSpatialReference( nullptr );
OSRSetWellKnownGeogCS( hLatLong, "WGS84" );
}
else
{
hLatLong = OSRCloneGeogCS( hProj );
if( hLatLong )
{
// Drop GEOGCS|UNIT child to be sure to output as degrees
OGRSpatialReference* poLatLong = reinterpret_cast<
OGRSpatialReference*>(hLatLong);
OGR_SRSNode *poGEOGCS = poLatLong->GetRoot();
if( poGEOGCS )
{
const int iUnitChild =
poGEOGCS->FindChild("UNIT");
if( iUnitChild != -1 )
poGEOGCS->DestroyChild(iUnitChild);
}
}
}
}
if( hLatLong != nullptr )
{
hTransform = OCTNewCoordinateTransformation( hProj, hLatLong );
}
if( hProj != nullptr )
}
/* -------------------------------------------------------------------- */
/* Report corners. */
/* -------------------------------------------------------------------- */
if( bJson && GDALGetRasterXSize(hDataset) )
{
json_object *poLinearRing = json_object_new_array();
json_object *poCornerCoordinates = json_object_new_object();
json_object *poLongLatExtent = json_object_new_object();
json_object *poLongLatExtentType = json_object_new_string("Polygon");
json_object *poLongLatExtentCoordinates = json_object_new_array();
GDALInfoReportCorner( psOptions, hDataset, hTransform,
"upperLeft",
0.0, 0.0, bJson, poCornerCoordinates,
poLongLatExtentCoordinates, osStr );
GDALInfoReportCorner( psOptions, hDataset, hTransform,
"lowerLeft",
0.0, GDALGetRasterYSize(hDataset), bJson,
poCornerCoordinates, poLongLatExtentCoordinates,
osStr );
GDALInfoReportCorner( psOptions, hDataset, hTransform,
"lowerRight",
GDALGetRasterXSize(hDataset),
GDALGetRasterYSize(hDataset),
bJson, poCornerCoordinates,
poLongLatExtentCoordinates, osStr );
GDALInfoReportCorner( psOptions, hDataset, hTransform,
"upperRight",
GDALGetRasterXSize(hDataset), 0.0, bJson,
poCornerCoordinates, poLongLatExtentCoordinates,
osStr );
GDALInfoReportCorner( psOptions, hDataset, hTransform,
"center",
GDALGetRasterXSize(hDataset) / 2.0,
GDALGetRasterYSize(hDataset) / 2.0,
bJson, poCornerCoordinates,
poLongLatExtentCoordinates, osStr );
GDALInfoReportCorner( psOptions, hDataset, hTransform,
"upperLeft",
0.0, 0.0, bJson, poCornerCoordinates,
poLongLatExtentCoordinates, osStr );
json_object_object_add( poJsonObject, "cornerCoordinates",
poCornerCoordinates );
json_object_object_add( poLongLatExtent, "type", poLongLatExtentType );
json_object_array_add( poLinearRing, poLongLatExtentCoordinates );
json_object_object_add( poLongLatExtent, "coordinates", poLinearRing );
json_object_object_add( poJsonObject,
bTransformToWGS84 ? "wgs84Extent": "extent", poLongLatExtent );
}
else if( GDALGetRasterXSize(hDataset) )
{
Concat(osStr, psOptions->bStdoutOutput, "Corner Coordinates:\n" );
GDALInfoReportCorner( psOptions, hDataset, hTransform,
"Upper Left",
0.0, 0.0, bJson, nullptr, nullptr, osStr );
GDALInfoReportCorner( psOptions, hDataset, hTransform,
"Lower Left",
0.0, GDALGetRasterYSize(hDataset), bJson,
nullptr, nullptr, osStr );
GDALInfoReportCorner( psOptions, hDataset, hTransform,
"Upper Right",
GDALGetRasterXSize(hDataset), 0.0, bJson,
nullptr, nullptr, osStr );
GDALInfoReportCorner( psOptions, hDataset, hTransform,
"Lower Right",
GDALGetRasterXSize(hDataset),
GDALGetRasterYSize(hDataset), bJson,
nullptr, nullptr, osStr );
GDALInfoReportCorner( psOptions, hDataset, hTransform,
"Center",
GDALGetRasterXSize(hDataset)/2.0,
GDALGetRasterYSize(hDataset)/2.0, bJson,
nullptr, nullptr, osStr );
}
if( hTransform != nullptr )
{
hTransform = nullptr;
}
/* ==================================================================== */
/* Loop over bands. */
/* ==================================================================== */
for( int iBand = 0; iBand < GDALGetRasterCount( hDataset ); iBand++ )
{
json_object *poBand = nullptr;
json_object *poBandMetadata = nullptr;
if( bJson )
{
poBand = json_object_new_object();
poBandMetadata = json_object_new_object();
}
GDALRasterBandH const hBand = GDALGetRasterBand( hDataset, iBand+1 );
if( psOptions->bSample )
{
vector<float> ofSample(10000, 0);
float * const pafSample = &ofSample[0];
const int nCount =
GDALGetRandomRasterSample( hBand, 10000, pafSample );
if( !bJson )
Concat( osStr, psOptions->bStdoutOutput,
"Got %d samples.\n", nCount );
}
int nBlockXSize = 0;
int nBlockYSize = 0;
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(
json_object *poColorInterp =
json_object_new_string(
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
{
Concat( osStr, psOptions->bStdoutOutput,
"Band %d Block=%dx%d Type=%s, ColorInterp=%s\n",
iBand + 1,
nBlockXSize, nBlockYSize,
}
if( GDALGetDescription( hBand ) != nullptr
&& strlen(GDALGetDescription( hBand )) > 0 )
{
if(bJson)
{
json_object *poBandDescription =
json_object_new_string(GDALGetDescription(hBand));
json_object_object_add(poBand, "description",
poBandDescription);
}
else
{
Concat( osStr, psOptions->bStdoutOutput, " Description = %s\n",
}
}
{
int bGotMin = FALSE;
int bGotMax = FALSE;
const double dfMin = GDALGetRasterMinimum( hBand, &bGotMin );
const double dfMax = GDALGetRasterMaximum( hBand, &bGotMax );
if( bGotMin || bGotMax || psOptions->bComputeMinMax )
{
if( !bJson )
Concat(osStr, psOptions->bStdoutOutput, " " );
if( bGotMin )
{
if( bJson )
{
json_object *poMin =
json_object_new_double_with_precision(dfMin, 3);
json_object_object_add(poBand, "min", poMin);
}
else
{
Concat(osStr, psOptions->bStdoutOutput,
"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
{
Concat(osStr, psOptions->bStdoutOutput,
"Max=%.3f ", dfMax );
}
}
if( psOptions->bComputeMinMax )
{
double adfCMinMax[2] = {0.0, 0.0};
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
{
Concat(osStr, psOptions->bStdoutOutput,
" Computed Min/Max=%.3f,%.3f",
adfCMinMax[0], adfCMinMax[1] );
}
}
}
if(!bJson)
Concat(osStr, psOptions->bStdoutOutput, "\n" );
}
}
double dfMinStat = 0.0;
double dfMaxStat = 0.0;
double dfMean = 0.0;
double dfStdDev = 0.0;
CPLErr eErr = GDALGetRasterStatistics( hBand, psOptions->bApproxStats,
psOptions->bStats,
&dfMinStat, &dfMaxStat,
&dfMean, &dfStdDev );
if( eErr == CE_None )
{
if( bJson )
{
json_object *poMinimum =
json_object_new_double_with_precision(dfMinStat, 3);
json_object *poMaximum =
json_object_new_double_with_precision(dfMaxStat, 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
{
Concat(osStr, psOptions->bStdoutOutput,
" Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f\n",
dfMinStat, dfMaxStat, dfMean, dfStdDev );
}
}
if( psOptions->bReportHistograms )
{
int nBucketCount = 0;
GUIntBig *panHistogram = nullptr;
if( bJson )
eErr = GDALGetDefaultHistogramEx( hBand, &dfMinStat, &dfMaxStat,
&nBucketCount, &panHistogram,
TRUE, GDALDummyProgress,
nullptr );
else
eErr = GDALGetDefaultHistogramEx( hBand, &dfMinStat, &dfMaxStat,
&nBucketCount, &panHistogram,
TRUE, GDALTermProgress,
nullptr );
if( eErr == CE_None )
{
json_object *poHistogram = nullptr;
json_object *poBuckets = nullptr;
if( bJson )
{
json_object *poCount = json_object_new_int(nBucketCount);
json_object *poMin = json_object_new_double(dfMinStat);
json_object *poMax = json_object_new_double(dfMaxStat);
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
{
Concat(osStr, psOptions->bStdoutOutput,
" %d buckets from %g to %g:\n ",
nBucketCount, dfMinStat, dfMaxStat );
}
for( int iBucket = 0; iBucket < nBucketCount; iBucket++ )
{
if(bJson)
{
json_object *poBucket =
json_object_new_int64(panHistogram[iBucket]);
json_object_array_add(poBuckets, poBucket);
}
else
Concat(osStr, psOptions->bStdoutOutput,
CPL_FRMT_GUIB " ", panHistogram[iBucket] );
}
if( bJson )
{
json_object_object_add(poHistogram, "buckets", poBuckets);
json_object_object_add(poBand, "histogram", poHistogram);
}
else
{
Concat(osStr, psOptions->bStdoutOutput, "\n" );
}
CPLFree( panHistogram );
}
}
if ( psOptions->bComputeChecksum)
{
const 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
{
Concat(osStr, psOptions->bStdoutOutput,
" Checksum=%d\n", nBandChecksum );
}
}
int bGotNodata = FALSE;
const double 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
{
Concat(osStr, psOptions->bStdoutOutput,
" 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
{
Concat(osStr, psOptions->bStdoutOutput,
" NoData Value=%.18g\n", dfNoData );
}
}
}
if( GDALGetOverviewCount(hBand) > 0 )
{
json_object *poOverviews = nullptr;
if( bJson )
poOverviews = json_object_new_array();
else
Concat(osStr, psOptions->bStdoutOutput, " Overviews: " );
for( int iOverview = 0;
iOverview < GDALGetOverviewCount(hBand);
iOverview++ )
{
if( !bJson )
if( iOverview != 0 )
Concat(osStr, psOptions->bStdoutOutput, ", " );
GDALRasterBandH hOverview = GDALGetOverview( hBand, iOverview );
if (hOverview != nullptr)
{
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) );
json_object *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(psOptions->bComputeChecksum)
{
const int nOverviewChecksum =
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
{
Concat(osStr, psOptions->bStdoutOutput, "%dx%d",
GDALGetRasterBandXSize( hOverview ),
GDALGetRasterBandYSize( hOverview ) );
}
const char *pszResampling =
GDALGetMetadataItem( hOverview, "RESAMPLING", "" );
if( pszResampling != nullptr && !bJson
&& STARTS_WITH_CI(pszResampling, "AVERAGE_BIT2") )
Concat(osStr, psOptions->bStdoutOutput, "*" );
}
else
{
if(!bJson)
Concat(osStr, psOptions->bStdoutOutput, "(null)" );
}
}
if(bJson)
json_object_object_add(poBand, "overviews", poOverviews);
else
Concat(osStr, psOptions->bStdoutOutput, "\n" );
if ( psOptions->bComputeChecksum && !bJson )
{
Concat(osStr, psOptions->bStdoutOutput,
" Overviews checksum: " );
for( int iOverview = 0;
iOverview < GDALGetOverviewCount(hBand);
iOverview++ )
{
GDALRasterBandH hOverview;
if( iOverview != 0 )
Concat(osStr, psOptions->bStdoutOutput, ", " );
hOverview = GDALGetOverview( hBand, iOverview );
if (hOverview)
{
Concat(osStr, psOptions->bStdoutOutput, "%d",
GDALChecksumImage(hOverview, 0, 0,
GDALGetRasterBandYSize(hOverview)));
}
else
{
Concat(osStr, psOptions->bStdoutOutput, "(null)" );
}
}
Concat(osStr, psOptions->bStdoutOutput, "\n" );
}
}
if( GDALHasArbitraryOverviews( hBand ) && !bJson )
{
Concat(osStr, psOptions->bStdoutOutput,
" Overviews: arbitrary\n" );
}
const int nMaskFlags = GDALGetMaskFlags( hBand );
if( (nMaskFlags & (GMF_NODATA|GMF_ALL_VALID)) == 0 ||
nMaskFlags == (GMF_NODATA | GMF_PER_DATASET) )
{
GDALRasterBandH hMaskBand = GDALGetMaskBand(hBand) ;
json_object *poMask = nullptr;
json_object *poFlags = nullptr;
json_object *poMaskOverviews = nullptr;
if(bJson)
{
poMask = json_object_new_object();
poFlags = json_object_new_array();
}
else
Concat(osStr, psOptions->bStdoutOutput, " 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
Concat(osStr, psOptions->bStdoutOutput, "PER_DATASET " );
}
if( nMaskFlags & GMF_ALPHA )
{
if(bJson)
{
json_object *poFlag = json_object_new_string( "ALPHA" );
json_object_array_add( poFlags, poFlag );
}
else
Concat(osStr, psOptions->bStdoutOutput, "ALPHA " );
}
if( nMaskFlags & GMF_NODATA )
{
if(bJson)
{
json_object *poFlag = json_object_new_string( "NODATA" );
json_object_array_add( poFlags, poFlag );
}
else
{
Concat(osStr, psOptions->bStdoutOutput, "NODATA " );
}
}
if(bJson)
json_object_object_add( poMask, "flags", poFlags );
else
Concat(osStr, psOptions->bStdoutOutput, "\n" );
if(bJson)
poMaskOverviews = json_object_new_array();
if( hMaskBand != nullptr &&
GDALGetOverviewCount(hMaskBand) > 0 )
{
if(!bJson)
Concat(osStr, psOptions->bStdoutOutput,
" Overviews of mask band: " );
for( int iOverview = 0;
iOverview < GDALGetOverviewCount(hMaskBand);
iOverview++ )
{
GDALRasterBandH hOverview = GDALGetOverview( hMaskBand, iOverview );
if( !hOverview )
break;
json_object *poMaskOverview = nullptr;
json_object *poMaskOverviewSize = nullptr;
if(bJson)
{
poMaskOverview = json_object_new_object();
poMaskOverviewSize = json_object_new_array();
}
else
{
if( iOverview != 0 )
Concat(osStr, psOptions->bStdoutOutput, ", " );
}
if(bJson)
{
json_object *poMaskOverviewSizeX =
json_object_new_int(
json_object *poMaskOverviewSizeY =
json_object_new_int(
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
{
Concat( osStr, psOptions->bStdoutOutput, "%dx%d",
GDALGetRasterBandXSize( hOverview ),
GDALGetRasterBandYSize( hOverview ) );
}
}
if( !bJson )
Concat(osStr, psOptions->bStdoutOutput, "\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
{
Concat(osStr, psOptions->bStdoutOutput,
" Unit Type: %s\n", GDALGetRasterUnitType(hBand) );
}
}
if( GDALGetRasterCategoryNames(hBand) != nullptr )
{
char **papszCategories = GDALGetRasterCategoryNames(hBand);
json_object *poCategories = nullptr;
if( bJson )
poCategories = json_object_new_array();
else
Concat(osStr, psOptions->bStdoutOutput, " Categories:\n" );
for( int i = 0; papszCategories[i] != nullptr; i++ )
{
if(bJson)
{
json_object *poCategoryName =
json_object_new_string(papszCategories[i]);
json_object_array_add(poCategories, poCategoryName);
}
else
Concat(osStr, psOptions->bStdoutOutput,
" %3d: %s\n", i, papszCategories[i] );
}
if(bJson)
json_object_object_add(poBand, "categories", poCategories);
}
int bSuccess = FALSE;
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
{
Concat(osStr, psOptions->bStdoutOutput,
" Offset: %.15g, Scale:%.15g\n",
GDALGetRasterOffset( hBand, &bSuccess ),
GDALGetRasterScale( hBand, &bSuccess ) );
}
}
GDALInfoReportMetadata( psOptions, hBand, true, bJson,
poBandMetadata, osStr );
if( bJson )
{
if (psOptions->bShowMetadata)
json_object_object_add( poBand, "metadata", poBandMetadata );
else
json_object_put(poBandMetadata);
}
&& (hTable = GDALGetRasterColorTable( hBand )) != nullptr )
{
if( !bJson )
Concat( osStr, psOptions->bStdoutOutput,
" Color Table (%s with %d entries)\n",
if (psOptions->bShowColorTable)
{
json_object *poEntries = nullptr;
if( bJson )
{
json_object *poPalette =
json_object_new_string(GDALGetPaletteInterpretationName(
json_object *poCount =
json_object_new_int(GDALGetColorEntryCount(hTable));
json_object *poColorTable = json_object_new_object();
json_object_object_add(poColorTable, "palette", poPalette);
json_object_object_add(poColorTable, "count", poCount);
poEntries = json_object_new_array();
json_object_object_add(poColorTable, "entries", poEntries);
json_object_object_add(poBand, "colorTable", poColorTable);
}
for( int 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
{
Concat(osStr, psOptions->bStdoutOutput,
" %3d: %d,%d,%d,%d\n",
i,
sEntry.c1,
sEntry.c2,
sEntry.c3,
sEntry.c4 );
}
}
}
}
if( psOptions->bShowRAT && GDALGetDefaultRAT( hBand ) != nullptr )
{
if( bJson )
{
json_object *poRAT =
static_cast<json_object*>(GDALRATSerializeJSON( hRAT ));
json_object_object_add( poJsonObject, "rat", poRAT );
}
else
{
CPLXMLNode *psTree =
static_cast<GDALRasterAttributeTable *>(hRAT)->Serialize();
char *pszXMLText = CPLSerializeXMLTree( psTree );
CPLDestroyXMLNode( psTree );
Concat(osStr, psOptions->bStdoutOutput, "%s\n", pszXMLText );
CPLFree( pszXMLText );
}
}
if(bJson)
json_object_array_add(poBands, poBand);
}
if(bJson)
{
json_object_object_add(poJsonObject, "bands", poBands);
Concat(osStr, psOptions->bStdoutOutput, "%s",
json_object_to_json_string_ext(poJsonObject,
JSON_C_TO_STRING_PRETTY));
json_object_put(poJsonObject);
}
if( psOptionsToFree != nullptr )
GDALInfoOptionsFree(psOptionsToFree);
return VSI_STRDUP_VERBOSE(osStr);
}
/************************************************************************/
/* GDALInfoReportCorner() */
/************************************************************************/
static int
GDALInfoReportCorner( const GDALInfoOptions* psOptions,
GDALDatasetH hDataset,
const char * corner_name,
double x,
double y,
bool bJson,
json_object *poCornerCoordinates,
json_object *poLongLatExtentCoordinates,
CPLString& osStr )
{
if(!bJson)
Concat(osStr, psOptions->bStdoutOutput, "%-11s ", corner_name );
/* -------------------------------------------------------------------- */
/* Transform the point into georeferenced coordinates. */
/* -------------------------------------------------------------------- */
double adfGeoTransform[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
double dfGeoX = 0.0;
double dfGeoY = 0.0;
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 )
{
json_object * const poCorner = json_object_new_array();
json_object * const poX =
json_object_new_double_with_precision( x, 1 );
json_object * const 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
{
Concat(osStr, psOptions->bStdoutOutput, "(%7.1f,%7.1f)\n", x, y );
}
return FALSE;
}
/* -------------------------------------------------------------------- */
/* Report the georeferenced coordinates. */
/* -------------------------------------------------------------------- */
if( std::abs(dfGeoX) < 181 && std::abs(dfGeoY) < 91 )
{
if(bJson)
{
json_object * const poCorner = json_object_new_array();
json_object * const poX =
json_object_new_double_with_precision( dfGeoX, 7 );
json_object * const 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
{
Concat(osStr, psOptions->bStdoutOutput,
"(%12.7f,%12.7f) ", dfGeoX, dfGeoY );
}
}
else
{
if(bJson)
{
json_object * const poCorner = json_object_new_array();
json_object * const poX =
json_object_new_double_with_precision( dfGeoX, 3 );
json_object * const 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
{
Concat(osStr, psOptions->bStdoutOutput,
"(%12.3f,%12.3f) ", dfGeoX, dfGeoY );
}
}
/* -------------------------------------------------------------------- */
/* Transform to latlong and report. */
/* -------------------------------------------------------------------- */
if(bJson)
{
double dfZ = 0.0;
if( hTransform != nullptr && !EQUAL( corner_name, "center" )
&& OCTTransform(hTransform,1,&dfGeoX,&dfGeoY,&dfZ) )
{
json_object * const poCorner = json_object_new_array();
json_object * const poX =
json_object_new_double_with_precision( dfGeoX, 7 );
json_object * const 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( poLongLatExtentCoordinates , poCorner );
}
}
else
{
double dfZ = 0.0;
if( hTransform != nullptr
&& OCTTransform(hTransform,1,&dfGeoX,&dfGeoY,&dfZ) )
{
Concat(osStr, psOptions->bStdoutOutput,
"(%s,", GDALDecToDMS( dfGeoX, "Long", 2 ) );
Concat(osStr, psOptions->bStdoutOutput,
"%s)", GDALDecToDMS( dfGeoY, "Lat", 2 ) );
}
Concat(osStr, psOptions->bStdoutOutput, "\n" );
}
return TRUE;
}
/************************************************************************/
/* GDALInfoPrintMetadata() */
/************************************************************************/
static void GDALInfoPrintMetadata( const GDALInfoOptions* psOptions,
const char *pszDomain,
const char *pszDisplayedname,
const char *pszIndent,
int bJsonOutput,
json_object *poMetadata,
CPLString& osStr )
{
const bool bIsxml =
pszDomain != nullptr &&
STARTS_WITH_CI(pszDomain, "xml:");
const bool bMDIsJson =
pszDomain != nullptr &&
STARTS_WITH_CI(pszDomain, "json:");
char **papszMetadata = GDALGetMetadata( hObject, pszDomain );
if( papszMetadata != nullptr && *papszMetadata != nullptr )
{
json_object *poDomain =
(bJsonOutput && !bIsxml && !bMDIsJson) ?
json_object_new_object() : nullptr;
if( !bJsonOutput )
Concat( osStr, psOptions->bStdoutOutput, "%s%s:\n", pszIndent,
pszDisplayedname );
json_object *poValue = nullptr;
for( int i = 0; papszMetadata[i] != nullptr; i++ )
{
if( bJsonOutput )
{
if( bIsxml )
{
poValue = json_object_new_string( papszMetadata[i] );
break;
}
else if( bMDIsJson )
{
OGRJSonParse(papszMetadata[i], &poValue, true);
break;
}
else
{
char *pszKey = nullptr;
const char *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 || bMDIsJson)
Concat(osStr, psOptions->bStdoutOutput,
"%s%s\n", pszIndent, papszMetadata[i] );
else
Concat(osStr, psOptions->bStdoutOutput,
"%s %s\n", pszIndent, papszMetadata[i] );
}
}
if(bJsonOutput)
{
if(bIsxml || bMDIsJson)
{
json_object_object_add( poMetadata, pszDomain, poValue );
}
else
{
if(pszDomain == nullptr)
json_object_object_add( poMetadata, "", poDomain );
else
json_object_object_add( poMetadata, pszDomain, poDomain );
}
}
}
}
/************************************************************************/
/* GDALInfoReportMetadata() */
/************************************************************************/
static void GDALInfoReportMetadata( const GDALInfoOptions* psOptions,
bool bIsBand,
bool bJson,
json_object *poMetadata,
CPLString& osStr )
{
const char* const pszIndent = bIsBand ? " " : "";
/* -------------------------------------------------------------------- */
/* Report list of Metadata domains */
/* -------------------------------------------------------------------- */
if( psOptions->bListMDD )
{
char** papszMDDList = GDALGetMetadataDomainList( hObject );
char** papszIter = papszMDDList;
json_object *poMDD = nullptr;
json_object * const poListMDD = bJson ? json_object_new_array() : nullptr;
if( papszMDDList != nullptr )
{
if( !bJson )
Concat(osStr, psOptions->bStdoutOutput,
"%sMetadata domains:\n", pszIndent );
}
while( papszIter != nullptr && *papszIter != nullptr )
{
if( EQUAL(*papszIter, "") )
{
if( bJson )
poMDD = json_object_new_string( *papszIter );
else
Concat(osStr, psOptions->bStdoutOutput,
"%s (default)\n", pszIndent);
}
else
{
if( bJson )
poMDD = json_object_new_string( *papszIter );
else
Concat(osStr, psOptions->bStdoutOutput,
"%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 (!psOptions->bShowMetadata)
return;
/* -------------------------------------------------------------------- */
/* Report default Metadata domain. */
/* -------------------------------------------------------------------- */
GDALInfoPrintMetadata( psOptions, hObject, nullptr, "Metadata",
pszIndent, bJson, poMetadata, osStr );
/* -------------------------------------------------------------------- */
/* Report extra Metadata domains */
/* -------------------------------------------------------------------- */
if( psOptions->papszExtraMDDomains != nullptr )
{
char **papszExtraMDDomainsExpanded = nullptr;
if( EQUAL(psOptions->papszExtraMDDomains[0], "all") &&
psOptions->papszExtraMDDomains[1] == nullptr )
{
char ** papszMDDList = GDALGetMetadataDomainList( hObject );
char * const * papszIter = papszMDDList;
while( papszIter != nullptr && *papszIter != nullptr )
{
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(psOptions->papszExtraMDDomains);
}
for( int iMDD = 0; papszExtraMDDomainsExpanded != nullptr &&
papszExtraMDDomainsExpanded[iMDD] != nullptr; iMDD++ )
{
if(bJson)
{
GDALInfoPrintMetadata(
psOptions, hObject, papszExtraMDDomainsExpanded[iMDD],
papszExtraMDDomainsExpanded[iMDD], pszIndent, bJson,
poMetadata, osStr );
}
else
{
CPLString osDisplayedname =
"Metadata (" +
CPLString(papszExtraMDDomainsExpanded[iMDD]) + ")";
GDALInfoPrintMetadata(
psOptions, hObject, papszExtraMDDomainsExpanded[iMDD],
osDisplayedname.c_str(), pszIndent, bJson, poMetadata,
osStr );
}
}
CSLDestroy(papszExtraMDDomainsExpanded);
}
/* -------------------------------------------------------------------- */
/* Report various named metadata domains. */
/* -------------------------------------------------------------------- */
GDALInfoPrintMetadata( psOptions, hObject, "IMAGE_STRUCTURE",
"Image Structure Metadata", pszIndent, bJson,
poMetadata, osStr );
if (!bIsBand)
{
GDALInfoPrintMetadata( psOptions, hObject, "SUBDATASETS", "Subdatasets",
pszIndent, bJson, poMetadata, osStr );
GDALInfoPrintMetadata( psOptions, hObject, "GEOLOCATION", "Geolocation",
pszIndent, bJson, poMetadata, osStr );
GDALInfoPrintMetadata( psOptions, hObject, "RPC", "RPC Metadata",
pszIndent, bJson, poMetadata, osStr );
}
}
/************************************************************************/
/* GDALInfoOptionsNew() */
/************************************************************************/
char** papszArgv,
GDALInfoOptionsForBinary* psOptionsForBinary )
{
bool bGotFilename = false;
GDALInfoOptions *psOptions = static_cast<GDALInfoOptions *>(
CPLCalloc( 1, sizeof(GDALInfoOptions) ) );
psOptions->eFormat = GDALINFO_FORMAT_TEXT;
psOptions->bComputeMinMax = FALSE;
psOptions->bReportHistograms = FALSE;
psOptions->bReportProj4 = FALSE;
psOptions->bStats = FALSE;
psOptions->bApproxStats = TRUE;
psOptions->bSample = FALSE;
psOptions->bComputeChecksum = FALSE;
psOptions->bShowGCPs = TRUE;
psOptions->bShowMetadata = TRUE;
psOptions->bShowRAT = TRUE;
psOptions->bShowColorTable = TRUE;
psOptions->bListMDD = FALSE;
psOptions->bShowFileList = TRUE;
/* -------------------------------------------------------------------- */
/* Parse arguments. */
/* -------------------------------------------------------------------- */
for( int i = 0; papszArgv != nullptr && papszArgv[i] != nullptr; i++ )
{
if( EQUAL(papszArgv[i],"-json") )
psOptions->eFormat = GDALINFO_FORMAT_JSON;
else if( EQUAL(papszArgv[i], "-mm") )
psOptions->bComputeMinMax = TRUE;
else if( EQUAL(papszArgv[i], "-hist") )
psOptions->bReportHistograms = TRUE;
else if( EQUAL(papszArgv[i], "-proj4") )
psOptions->bReportProj4 = TRUE;
else if( EQUAL(papszArgv[i], "-stats") )
{
psOptions->bStats = TRUE;
psOptions->bApproxStats = FALSE;
}
else if( EQUAL(papszArgv[i], "-approx_stats") )
{
psOptions->bStats = TRUE;
psOptions->bApproxStats = TRUE;
}
else if( EQUAL(papszArgv[i], "-sample") )
psOptions->bSample = TRUE;
else if( EQUAL(papszArgv[i], "-checksum") )
psOptions->bComputeChecksum = TRUE;
else if( EQUAL(papszArgv[i], "-nogcp") )
psOptions->bShowGCPs = FALSE;
else if( EQUAL(papszArgv[i], "-nomd") )
psOptions->bShowMetadata = FALSE;
else if( EQUAL(papszArgv[i], "-norat") )
psOptions->bShowRAT = FALSE;
else if( EQUAL(papszArgv[i], "-noct") )
psOptions->bShowColorTable = FALSE;
else if( EQUAL(papszArgv[i], "-listmdd") )
psOptions->bListMDD = TRUE;
/* Not documented: used by gdalinfo_bin.cpp only */
else if( EQUAL(papszArgv[i], "-stdout") )
psOptions->bStdoutOutput = true;
else if( EQUAL(papszArgv[i], "-mdd") && papszArgv[i+1] != nullptr )
{
psOptions->papszExtraMDDomains = CSLAddString(
psOptions->papszExtraMDDomains, papszArgv[++i] );
}
else if( EQUAL(papszArgv[i], "-oo") && papszArgv[i+1] != nullptr )
{
i++;
if( psOptionsForBinary )
{
psOptionsForBinary->papszOpenOptions = CSLAddString(
psOptionsForBinary->papszOpenOptions, papszArgv[i] );
}
}
else if( EQUAL(papszArgv[i], "-nofl") )
psOptions->bShowFileList = FALSE;
else if( EQUAL(papszArgv[i], "-sd") && papszArgv[i+1] != nullptr )
{
i++;
if( psOptionsForBinary )
{
psOptionsForBinary->nSubdataset = atoi(papszArgv[i]);
}
}
else if( papszArgv[i][0] == '-' )
{
"Unknown option name '%s'", papszArgv[i]);
GDALInfoOptionsFree(psOptions);
return nullptr;
}
else if( !bGotFilename )
{
bGotFilename = true;
if( psOptionsForBinary )
psOptionsForBinary->pszFilename = CPLStrdup(papszArgv[i]);
}
else
{
"Too many command options '%s'", papszArgv[i]);
GDALInfoOptionsFree(psOptions);
return nullptr;
}
}
return psOptions;
}
/************************************************************************/
/* GDALInfoOptionsFree() */
/************************************************************************/
{
if( psOptions != nullptr )
{
CSLDestroy( psOptions->papszExtraMDDomains );
CPLFree(psOptions);
}
}

Generated for GDAL by doxygen 1.8.13.