赞
踩
转载地址:https://blog.csdn.net/hanminaaa/article/details/52204396
GDAL帮助文件中栅格工具箱里关于gdalinfo.exe的描述如下:
- gdalinfo [--help-general] [-json] [-mm] [-stats] [-hist] [-nogcp] [-nomd]
- [-norat] [-noct] [-nofl] [-checksum] [-proj4]
- [-listmdd] [-mdd domain|`all`]*
- [-sd subdataset] [-oo NAME=VALUE]* datasetname
项目 | 作用 |
---|---|
–help | 显示帮助 |
-general | 常规项目 |
-json | 标记是否以json形式输出 |
-mm | 标记是否强制计算每波段的MAX及MIN |
-stats | 标记读取图像统计信息(如果没有将从图像中计算) |
-hist | 标记报告所有波段的直方图信息 |
-nogcp | 标记不显示图像包含的地面控制点 |
-nomd | 标记不显示元数据 |
-norat | 标记不显示栅格属性表 |
-noct | 标记不显示色彩表 |
-checksum | 强制计算波段的校验码 |
-listmdd | 列出数据集可获得的所有元数据 |
-mdd domain | 获取特定所属的元数据 |
-nofl | 只显示文件列表中的第一个文件 |
-sd subdataset | 如果数据集包含了子集,该项用于指定要获取的子项。 |
-proj4 | 以PROJ4字符串形式显示图像的地理坐标系 |
-oo NAME=VALUE | 打开选项(以“选项名=选项值”进行设定) |
在命令行界面转到可执行程序目录,输入如下命令:
(Path of gdalinfo.exe)gdalinfo --help-general
- Generic GDAL utility command options:
- --version: report version of GDAL in use.
- --license: report GDAL license info.
- --formats: report all configured format drivers.
- --format [format]: details of one format.
- --optfile filename: expand an option file into the argument list.
- --config key value: set system configuration option.
- --debug [on/off/value]: set debug level.
- --pause: wait for user input, time to attach debugger
- --locale [locale]: install locale for debugging (i.e. en_US.UTF-8)
- --help-general: report detailed help on general options.
下面是使用该程序的一个典型例子:
(Path of gdalinfo.exe)>gdalinfo -proj4 -stats ~\exmaple.tif
得到输出为:
- Driver: GTiff/GeoTIFF
- Files: E:\exmaple.tif
- Size is 200, 400
- Coordinate System is:
- GEOGCS["WGS 84",
- DATUM["WGS_1984",
- SPHEROID["WGS 84",6378137,298.257223563,
- AUTHORITY["EPSG","7030"]],
- AUTHORITY["EPSG","6326"]],
- PRIMEM["Greenwich",0],
- UNIT["degree",0.0174532925199433],
- AUTHORITY["EPSG","4326"]]
- PROJ.4 string is:
- '+proj=longlat +datum=WGS84 +no_defs '
- Origin = (116.438654182485010,40.154364985586007)
- Pixel Size = (0.000018000000000,-0.000018000000000)
- Metadata:
- AREA_OR_POINT=Area
- Image Structure Metadata:
- INTERLEAVE=PIXEL
- Corner Coordinates:
- Upper Left ( 116.4386542, 40.1543650)
- Lower Left ( 116.4386542, 40.1471650)
- Upper Right ( 116.4422542, 40.1543650)
- Lower Right ( 116.4422542, 40.1471650)
- Center ( 116.4404542, 40.1507650)
- Band 1 Block=200x5 Type=UInt16, ColorInterp=Gray
- Minimum=0.000, Maximum=0.000, Mean=0.000, StdDev=0.000
- Metadata:
- STATISTICS_MAXIMUM=0
- STATISTICS_MEAN=0
- STATISTICS_MINIMUM=0
- STATISTICS_STDDEV=0
- Band 2 Block=200x5 Type=UInt16, ColorInterp=Undefined
- Minimum=0.000, Maximum=0.000, Mean=0.000, StdDev=0.000
- Metadata:
- STATISTICS_MAXIMUM=0
- STATISTICS_MEAN=0
- STATISTICS_MINIMUM=0
- STATISTICS_STDDEV=0
- Band 3 Block=200x5 Type=UInt16, ColorInterp=Undefined
- Minimum=0.000, Maximum=0.000, Mean=0.000, StdDev=0.000
- Metadata:
- STATISTICS_MAXIMUM=0
- STATISTICS_MEAN=0
- STATISTICS_MINIMUM=0
- STATISTICS_STDDEV=0
- Band 4 Block=200x5 Type=UInt16, ColorInterp=Undefined
- Minimum=0.000, Maximum=0.000, Mean=0.000, StdDev=0.000
- Metadata:
- STATISTICS_MAXIMUM=0
- STATISTICS_MEAN=0
- STATISTICS_MINIMUM=0
- STATISTICS_STDDEV=0

这里使用的例子数据是一份实验数据,实际上带有信息的图像的统计信息不会全为0。
那么gdalinfo是如何工作的呢,虽然有帮助的提示,我们还有很多选项不知道如何设定,比如:–oo中的NAME=VALUE存在哪些项目和可选项呢?这些选项的默认参数又是什么呢?下面我们就从源码角度来分析该应用程序是如何工作的。
- int main( int argc, char ** argv )
-
- {
- EarlySetConfigOptions(argc, argv);//预设置
-
- GDALAllRegister();//注册所有驱动
-
- argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );//命令行参数处理
- if( argc < 1 )//如果参数小于1,程序退出
- exit( -argc );
-
- for( int i = 0; argv != NULL && argv[i] != NULL; 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"));
- CSLDestroy( argv );
- return 0;
- }
- else if( EQUAL(argv[i],"--help") )
- {//打印帮助,并退出
- Usage();
- }
- }
- argv = CSLAddString(argv, "-stdout");//设置标准输出
-
- GDALInfoOptionsForBinary* psOptionsForBinary = GDALInfoOptionsForBinaryNew();//初始化二值化选项
-
- GDALInfoOptions *psOptions
- = GDALInfoOptionsNew(argv + 1, psOptionsForBinary);//**根据字符串数组初始化要显示的信息选项**
- if( psOptions == NULL )//如果选项初始化失败,退出
- Usage();
-
- if( psOptionsForBinary->pszFilename == NULL )//如果没有指定资源文件,退出
- Usage("No datasource specified.");
-
- /* -------------------------------------------------------------------- */
- /* 打开数据集. */
- /* -------------------------------------------------------------------- */
- #ifdef __AFL_HAVE_MANUAL_CONTROL
- //**配合下面**
- int iIter = 0;
- while (__AFL_LOOP(1000)) {
- iIter ++;
- #endif
-
- GDALDatasetH hDataset
- = GDALOpenEx( psOptionsForBinary->pszFilename, GDAL_OF_READONLY | GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR, NULL,
- (const char* const* )psOptionsForBinary->papszOpenOptions, NULL );//打开数据集
-
- if( hDataset == NULL )
- {
- #ifdef __AFL_HAVE_MANUAL_CONTROL
- continue;
- #else
- fprintf( stderr,
- "gdalinfo failed - unable to open '%s'.\n",
- psOptionsForBinary->pszFilename );
-
- /* -------------------------------------------------------------------- */
- /* 如果参数是一个VSI文件, 就打印其内容。 */
- /* -------------------------------------------------------------------- */
- if ( STARTS_WITH(psOptionsForBinary->pszFilename, "/vsizip/") ||
- STARTS_WITH(psOptionsForBinary->pszFilename, "/vsitar/") )
- {
- char** papszFileList = VSIReadDirRecursive( psOptionsForBinary->pszFilename );
- if ( papszFileList )
- {
- int nCount = CSLCount( papszFileList );
- fprintf( stdout,
- "Unable to open source `%s' directly.\n"
- "The archive contains %d files:\n",
- psOptionsForBinary->pszFilename, nCount );
- for ( int i = 0; i < nCount; i++ )
- {//打印内部文件列表
- fprintf( stdout, " %s/%s\n", psOptionsForBinary->pszFilename, papszFileList[i] );
- }
- CSLDestroy( papszFileList );
- }
- }
-
- CSLDestroy( argv );//释放参数
-
- GDALInfoOptionsForBinaryFree(psOptionsForBinary);//释放二值化选项
-
- GDALInfoOptionsFree( psOptions );//释放选项占用的内存
-
- GDALDumpOpenDatasets( stderr );//释放打开的数据集
-
- GDALDestroyDriverManager();//释放驱动管理
-
- CPLDumpSharedList( NULL );
-
- exit( 1 );
- #endif
- }
-
- /* -------------------------------------------------------------------- */
- /* 读取特定的文件子数据集. */
- /* -------------------------------------------------------------------- */
- if ( psOptionsForBinary->nSubdataset > 0 )
- {
- char **papszSubdatasets = GDALGetMetadata( hDataset, "SUBDATASETS" );
- int nSubdatasets = CSLCount( papszSubdatasets );
-
- if ( nSubdatasets > 0 && psOptionsForBinary->nSubdataset <= nSubdatasets )
- {
- char szKeyName[1024];
- char *pszSubdatasetName;
-
- snprintf( szKeyName, sizeof(szKeyName),
- "SUBDATASET_%d_NAME", psOptionsForBinary->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",
- psOptionsForBinary->nSubdataset, nSubdatasets );
-
- }
- }
-
- char* pszGDALInfoOutput = GDALInfo( hDataset, psOptions );//**核心函数,读取数据集信息**
-
- if( pszGDALInfoOutput )//读取成功则输出
- printf( "%s", pszGDALInfoOutput );
-
- CPLFree( pszGDALInfoOutput );//释放输出字符串
-
- GDALClose( hDataset );//关闭数据集
- #ifdef __AFL_HAVE_MANUAL_CONTROL
- }//**配合上面,组成循环**
- #endif
-
- GDALInfoOptionsForBinaryFree(psOptionsForBinary);//释放二值化选项
-
- GDALInfoOptionsFree( psOptions );//释放选项
-
- CSLDestroy( argv );//释放输入参数
-
- GDALDumpOpenDatasets( stderr );//释放打开数据集
-
- GDALDestroyDriverManager();//释放驱动管理
-
- CPLDumpSharedList( NULL );
- CPLCleanupTLS();
-
- exit( 0 );
-
- }

从以上流程图可以看出,本程序的核心函数为GDALInfo(GDALDatasetH hDataset,
const GDALInfoOptions * psOptions )
前面大量的工作用来增强程序对多种输入的适应性和构筑信息选项。
参数初始化函数GDALInfoOptionsForBinaryNew()以及GDALInfoOptionsNew()是如何设置默认选项的呢,我们定位到函数体:
- static GDALInfoOptionsForBinary *GDALInfoOptionsForBinaryNew(void)
- {
- return (GDALInfoOptionsForBinary*) CPLCalloc( 1, sizeof(GDALInfoOptionsForBinary) );
- }
很显然,二值化信息选项只是申请了内存并且返回指针。
- GDALInfoOptions *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;//默认不以PROJ4字符报告
- 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;//默认显示文件列表
-
- /* -------------------------------------------------------------------- */
- /* 传参. */
- /* -------------------------------------------------------------------- */
- for( int i = 0; papszArgv != NULL && papszArgv[i] != NULL; 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] != NULL )
- {//设定要获取的属于该文件的元数据
- psOptions->papszExtraMDDomains = CSLAddString(
- psOptions->papszExtraMDDomains, papszArgv[++i] );
- }
- else if( EQUAL(papszArgv[i], "-oo") && papszArgv[i+1] != NULL )
- {//设定属性
- 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] != NULL )
- {//子数据集
- i++;
- if( psOptionsForBinary )
- {
- psOptionsForBinary->nSubdataset = atoi(papszArgv[i]);
- }
- }
- else if( papszArgv[i][0] == '-' )
- {//错误选项处理
- CPLError(CE_Failure, CPLE_NotSupported,
- "Unknown option name '%s'", papszArgv[i]);
- GDALInfoOptionsFree(psOptions);
- return NULL;
- }
- else if( !bGotFilename )
- {//输入文件名称
- bGotFilename = true;
- if( psOptionsForBinary )
- psOptionsForBinary->pszFilename = CPLStrdup(papszArgv[i]);
- }
- else
- {
- CPLError(CE_Failure, CPLE_NotSupported,
- "Too many command options '%s'", papszArgv[i]);
- GDALInfoOptionsFree(psOptions);
- return NULL;
- }
- }
-
- return psOptions;
- }

从上面的源码我们可以得到一些处理命令行程序参数输入的小技巧,如-oo和文件名的指定,也清楚了默认文件打开参数和信息显示选项值。但必须注意的是,这里对于-oo的处理仅是将NMAE=VALUE加入OpenOptions字符串数组中,那么问题就转变成了如何根据这个字符串数组进行有效性判断!
没错,再次将视线转向GDALOpenEx(const char* pszFilename,unsigned int nOpenFlags, const char* const* papszAllowedDrivers, const char* const* papszOpenOptions,const char* const* papszSiblingFiles)函数。注意到帮助里的描述:
- * @param papszOpenOptions NULL, or a NULL terminated list of strings with open
- * options passed to candidate drivers. An option exists for all drivers,
- * OVERVIEW_LEVEL=level, to select a particular overview level of a dataset.
- * The level index starts at 0. The level number can be suffixed by "only" to specify that
- * only this overview level must be visible, and not sub-levels.
- * Open options are validated by default, and a warning is emitted in case the
- * option is not recognized. In some scenarios, it might be not desirable (e.g.
- * when not knowing which driver will open the file), so the special open option
- * VALIDATE_OPEN_OPTIONS can be set to NO to avoid such warnings. Alternatively,
- * since GDAL 2.1, an option name can be preceded by the @ character to indicate
- * that it may not cause a warning if the driver doesn't declare this option.
经过几步,最后定义到有效性检验函数体:
- int GDALValidateOpenOptions( GDALDriverH hDriver,
- const char* const* papszOpenOptions)
- {
- VALIDATE_POINTER1( hDriver, "GDALValidateOpenOptions", FALSE );
- const char *pszOptionList =
- ((GDALDriver *) hDriver)->GetMetadataItem( GDAL_DMD_OPENOPTIONLIST );
- CPLString osDriver;
- osDriver.Printf("driver %s", ((GDALDriver *) hDriver)->GetDescription());
- return GDALValidateOptions( pszOptionList, papszOpenOptions,
- "open option",
- osDriver);
- }
可以看出该打开选项依赖于图像驱动的不同而变化,通过该驱动的GetMetadataItem()方法可以得到驱动所支持的打开选项列表。
这里还存在一个问题,GDAL_DMD_OPENOPTIONLIST
是一个定义项,其值为"DMD_OPENOPTIONLIST"
,然而在内部进行跟踪时别没有发现它是如何获得选项列表的。不过对帮助进行查看我们发现存在 char ** VRTDriver::GetMetadata ( const char * pszDomain = "" )
可以获得驱动的元数据列表,但同样是虚方法,根据具体驱动实现不同。
先上源码:
- char *GDALInfo( GDALDatasetH hDataset, const GDALInfoOptions *psOptions )
- {
- if( hDataset == NULL )
- return NULL;
-
- GDALInfoOptions* psOptionsToFree = NULL;
- if( psOptions == NULL )
- {//初始化信息选项
- psOptionsToFree = GDALInfoOptionsNew(NULL, NULL);
- psOptions = psOptionsToFree;
- }
-
- CPLString osStr;
- json_object *poJsonObject = NULL, *poBands = NULL, *poMetadata = NULL;
-
- const bool bJson = psOptions->eFormat == GDALINFO_FORMAT_JSON;//先判断后赋值
-
- /* -------------------------------------------------------------------- */
- /* 报告通常信息. */
- /* -------------------------------------------------------------------- */
- 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",
- GDALGetDriverShortName( hDriver ),
- GDALGetDriverLongName( hDriver ) );
- }//这是一个链接输出项目形成输出字符串的函数
-
- char **papszFileList = GDALGetFileList( hDataset );
-
- if( papszFileList == NULL || *papszFileList == NULL )
- {
- if(bJson)
- {
- json_object *poFiles = json_object_new_array();
- json_object_object_add(poJsonObject, "files", poFiles);//文件列表json
- }
- 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] != 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
- {
- Concat(osStr, psOptions->bStdoutOutput, "Files: %s\n", papszFileList[0] );
- if( psOptions->bShowFileList )
- {
- for( int i = 1; papszFileList[i] != NULL; 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 ) );//栅格图像大小
-
- /* -------------------------------------------------------------------- */
- /* 报告投影信息. */
- /* -------------------------------------------------------------------- */
- if( GDALGetProjectionRef( hDataset ) != NULL )
- {
- json_object *poCoordinateSystem = NULL;
-
- if(bJson)
- poCoordinateSystem = json_object_new_object();
-
- char *pszProjection
- = const_cast<char *>( GDALGetProjectionRef( hDataset ) );
-
- OGRSpatialReferenceH hSRS
- = OSRNewSpatialReference(NULL);
- if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None )//尝试转化OGR参考系
- {
- 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
- 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 = NULL;
- OSRExportToProj4( hSRS, &pszProj4 );//转换为PROJ4格式
-
- 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);
-
- OSRDestroySpatialReference( hSRS );
- }
-
- /* -------------------------------------------------------------------- */
- /* 报告地理转换参数. */
- /* -------------------------------------------------------------------- */
- 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] );//顺序输出
- }
-
- }
-
- /* -------------------------------------------------------------------- */
- /* 报告地面控制点. */
- /* -------------------------------------------------------------------- */
- if( psOptions->bShowGCPs && GDALGetGCPCount( hDataset ) > 0 )
- {
- json_object * const poGCPs = bJson ? json_object_new_object() : NULL;
-
- if (GDALGetGCPProjection(hDataset) != NULL)//获取地面控制点投影
- {
- json_object *poGCPCoordinateSystem = NULL;
-
- char *pszProjection
- = const_cast<char *>( GDALGetGCPProjection( hDataset ) );
-
- OGRSpatialReferenceH 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
- 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);
- OSRDestroySpatialReference( hSRS );
- }
-
- json_object * const poGCPList = bJson ? json_object_new_array() : NULL;
-
- 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);
- }
- }
-
- /* -------------------------------------------------------------------- */
- /* 报告数据集元数据. */
- /* -------------------------------------------------------------------- */
-
- GDALInfoReportMetadata( psOptions, hDataset, false, bJson, poMetadata, osStr );//元数据信息获取函数(数据集)
- if(bJson)
- {
- if( psOptions->bShowMetadata )
- json_object_object_add( poJsonObject, "metadata", poMetadata );
- else
- json_object_put(poMetadata);
- }
-
- /* -------------------------------------------------------------------- */
- /* 如果合适,设置经纬度投影转换. */
- /* -------------------------------------------------------------------- */
- const char *pszProjection = NULL;
- if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
- pszProjection = GDALGetProjectionRef(hDataset);
-
- OGRCoordinateTransformationH hTransform = NULL;
- OGRCoordinateTransformationH hTransformWGS84 = NULL;
-
- 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 );//坐标转换信息
- CPLPopErrorHandler();
-
- OSRDestroySpatialReference( hLatLong );
- }
-
- if( hLatLongWGS84 != NULL )
- {
- CPLPushErrorHandler( CPLQuietErrorHandler );
- hTransformWGS84 = OCTNewCoordinateTransformation( hProj, hLatLongWGS84 );
- CPLPopErrorHandler();
-
- OSRDestroySpatialReference( hLatLongWGS84 );
- }
-
- if( hProj != NULL )
- OSRDestroySpatialReference( hProj );
- }
-
- /* -------------------------------------------------------------------- */
- /* 报告边角信息. */
- /* -------------------------------------------------------------------- */
- 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( psOptions, hDataset, hTransform, hTransformWGS84, "upperLeft",
- 0.0, 0.0, bJson, poCornerCoordinates, poWGS84ExtentCoordinates, osStr );//边角报告函数
- GDALInfoReportCorner( psOptions, hDataset, hTransform, hTransformWGS84, "lowerLeft",
- 0.0, GDALGetRasterYSize(hDataset), bJson, poCornerCoordinates, poWGS84ExtentCoordinates, osStr );
- GDALInfoReportCorner( psOptions, hDataset, hTransform, hTransformWGS84, "upperRight",
- GDALGetRasterXSize(hDataset), 0.0, bJson, poCornerCoordinates, poWGS84ExtentCoordinates, osStr );
- GDALInfoReportCorner( psOptions, hDataset, hTransform, hTransformWGS84, "lowerRight",
- GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset),
- bJson, poCornerCoordinates, poWGS84ExtentCoordinates, osStr );
- GDALInfoReportCorner( psOptions, hDataset, hTransform, hTransformWGS84, "center",
- GDALGetRasterXSize(hDataset)/2.0, GDALGetRasterYSize(hDataset)/2.0,
- bJson, poCornerCoordinates, poWGS84ExtentCoordinates, osStr );
- GDALInfoReportCorner( psOptions, hDataset, hTransform, hTransformWGS84, "upperLeft",
- 0.0, 0.0, bJson, poCornerCoordinates, poWGS84ExtentCoordinates, osStr );
-
- 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
- {
- Concat(osStr, psOptions->bStdoutOutput, "Corner Coordinates:\n" );
- GDALInfoReportCorner( psOptions, hDataset, hTransform, hTransformWGS84, "Upper Left",
- 0.0, 0.0, bJson, NULL, NULL, osStr );
- GDALInfoReportCorner( psOptions, hDataset, hTransform, hTransformWGS84, "Lower Left",
- 0.0, GDALGetRasterYSize(hDataset), bJson, NULL, NULL, osStr );
- GDALInfoReportCorner( psOptions, hDataset, hTransform, hTransformWGS84, "Upper Right",
- GDALGetRasterXSize(hDataset), 0.0, bJson, NULL, NULL, osStr );
- GDALInfoReportCorner( psOptions, hDataset, hTransform, hTransformWGS84, "Lower Right",
- GDALGetRasterXSize(hDataset),
- GDALGetRasterYSize(hDataset), bJson, NULL, NULL, osStr );
- GDALInfoReportCorner( psOptions, hDataset, hTransform, hTransformWGS84, "Center",
- GDALGetRasterXSize(hDataset)/2.0,
- GDALGetRasterYSize(hDataset)/2.0, bJson, NULL, NULL, osStr );
-
- }
-
- if( hTransform != NULL )
- {
- OCTDestroyCoordinateTransformation( hTransform );
- hTransform = NULL;
- }
-
- if( hTransformWGS84 != NULL )
- {
- OCTDestroyCoordinateTransformation( hTransformWGS84 );
- hTransformWGS84 = NULL;
- }
-
- /* ==================================================================== */
- /* 循环处理波段. */
- /* ==================================================================== */
- for( int iBand = 0; iBand < GDALGetRasterCount( hDataset ); iBand++ )
- {
- json_object *poBand = NULL;
- json_object *poBandMetadata = NULL;
-
- 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(GDALGetDataTypeName(GDALGetRasterDataType(hBand)));//获取数据类型说明
- json_object *poColorInterp = json_object_new_string(GDALGetColorInterpretationName(
- GDALGetRasterColorInterpretation(hBand)));//获取波段说明
-
- 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,
- GDALGetDataTypeName(
- GDALGetRasterDataType(hBand)),
- GDALGetColorInterpretationName(
- GDALGetRasterColorInterpretation(hBand)) );
-
- 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
- Concat( osStr, psOptions->bStdoutOutput, " Description = %s\n",
- GDALGetDescription(hBand) );//波段说明
- }
-
- {
- 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 )
- {
- CPLErrorReset();
- 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;
- GUIntBig *panHistogram = NULL;
-
- if(bJson)
- eErr = GDALGetDefaultHistogramEx( hBand, &dfMinStat, &dfMaxStat,
- &nBucketCount, &panHistogram,
- TRUE, GDALDummyProgress,
- NULL );//获得默认直方图
- else
- eErr = GDALGetDefaultHistogramEx( hBand, &dfMinStat, &dfMaxStat,
- &nBucketCount, &panHistogram,
- TRUE, GDALTermProgress,
- NULL );
- if( eErr == CE_None )
- {
- json_object *poHistogram = NULL, *poBuckets = NULL;
-
- 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)
- {
- 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 = NULL;
-
- 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 != 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) );
-
- 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)
- {
- int nOverviewChecksum = GDALChecksumImage(hOverview, 0, 0,
- GDALGetRasterBandXSize(hOverview),
- GDALGetRasterBandYSize(hOverview));
- 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 != NULL && !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,
- GDALGetRasterBandXSize(hOverview),
- 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 )
- {
- 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
- 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( nMaskFlags & GMF_ALL_VALID )
- {
- if(bJson)
- {
- json_object *poFlag = json_object_new_string( "ALL_VALID" );
- json_object_array_add( poFlags, poFlag );
- }
- else
- Concat(osStr, psOptions->bStdoutOutput, "ALL_VALID " );
- }
- if(bJson)
- json_object_object_add( poMask, "flags", poFlags );
- else
- Concat(osStr, psOptions->bStdoutOutput, "\n" );
-
- if(bJson)
- poMaskOverviews = json_object_new_array();
-
- if( hMaskBand != NULL &&
- GDALGetOverviewCount(hMaskBand) > 0 )
- {//获取掩膜预览
- if(!bJson)
- Concat(osStr, psOptions->bStdoutOutput, " Overviews of mask band: " );
-
- for( int iOverview = 0;
- iOverview < GDALGetOverviewCount(hMaskBand);
- iOverview++ )
- {
- GDALRasterBandH hOverview;
- json_object *poMaskOverview = NULL;
- json_object *poMaskOverviewSize = NULL;
-
- if(bJson)
- {
- poMaskOverview = json_object_new_object();
- poMaskOverviewSize = json_object_new_array();
- }
- else
- {
- if( iOverview != 0 )
- Concat(osStr, psOptions->bStdoutOutput, ", " );
- }
-
- hOverview = GDALGetOverview( hMaskBand, iOverview );
- if(bJson)
- {
- json_object *poMaskOverviewSizeX =
- json_object_new_int(GDALGetRasterBandXSize(hOverview));
- json_object *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
- 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) != NULL )
- {//获取栅格种类名
- char **papszCategories = GDALGetRasterCategoryNames(hBand);
- json_object *poCategories = NULL;
-
- if(bJson)
- poCategories = json_object_new_array();
- else
- Concat(osStr, psOptions->bStdoutOutput, " Categories:\n" );
-
- for( int i = 0; papszCategories[i] != NULL; 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);
- }
-
- GDALColorTableH hTable;
- if( GDALGetRasterColorInterpretation(hBand) == GCI_PaletteIndex
- && (hTable = GDALGetRasterColorTable( hBand )) != NULL )//获得颜色索引及色彩表
- {
- if(!bJson)
- Concat( osStr, psOptions->bStdoutOutput,
- " Color Table (%s with %d entries)\n",
- GDALGetPaletteInterpretationName(
- GDALGetPaletteInterpretation( hTable )),
- GDALGetColorEntryCount( hTable ) );
-
- if (psOptions->bShowColorTable)
- {
- json_object *poEntries = NULL;
-
- if(bJson)
- {
- json_object *poPalette = json_object_new_string(GDALGetPaletteInterpretationName(
- GDALGetPaletteInterpretation(hTable)));
- 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++ )//获取颜色记录
- {
- GDALColorEntry sEntry;
-
- 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 ) != NULL )
- {
- GDALRasterAttributeTableH hRAT = GDALGetDefaultRAT( hBand );//获取栅格属性表
-
- if(bJson)
- {
- json_object *poRAT = (json_object*) GDALRATSerializeJSON( hRAT );
- json_object_object_add( poJsonObject, "rat", poRAT );
- }
- else
- {//获取属性表并转化为xml树状信息
- CPLXMLNode *psTree = ((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 != NULL )
- GDALInfoOptionsFree(psOptionsToFree);
-
- return VSI_STRDUP_VERBOSE(osStr);
- }

根据函数名称,我们基本能够推断出函数的作用,从获取关联文件到栅格属性表等等。研究本源码文件更多地是向我们展示了GDAL库设计者们对于库函数的使用范本。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。