GDAL工具箱详解之gdalinfo.exe

本文详细介绍了GDAL工具箱中的gdalinfo.exe,包括其使用方法、典型例子和源码分析。gdalinfo用于获取GDAL数据集的详细信息,源码分析部分探讨了参数初始化和核心函数,揭示了GDALOpenEx函数在处理-oo选项时的工作原理。

GDAL工具箱详解之gdalinfo.exe

GDAL自带的工具包含了众多的功能,可以看做是利用该开源库进行的典型开发案例。本节主要介绍其中基本的一项工具——gdalinfo.exe。

  • 该工具箱位于GDAL文件夹下的apps文件夹中,属于命令行可执行程序。

目录


使用方法

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();
<think>我们正在处理一个关于GDAL数据目录配置错误的问题。用户遇到了"GDAL data directory not containing correct data files"错误,需要修复方法。 根据GDAL的文档和常见问题,这个错误通常发生在GDAL无法找到其数据文件(如各种投影定义文件、EPSG代码文件等)时。数据目录通常包含gcs.csv、pcs.csv、epsg.wkt等文件。 解决方法通常包括: 1. 确认GDAL数据目录的位置 2. 设置正确的环境变量GDAL_DATA指向该目录 3. 确保目录中包含所需的数据文件 引用[1]提到安装文件到指定目录的规则,这提醒我们GDAL的数据文件需要被正确安装到指定目录。引用[2]提到编译和安装过程中可能出现的问题,但用户的问题可能不是编译问题,而是配置问题。引用[3]提到合并和照片对齐,与当前问题无关。 因此,我们主要关注如何正确设置GDAL_DATA环境变量以及验证数据文件的存在。 具体步骤: 1. 确定GDAL数据目录的位置: - 在Windows上,如果通过安装程序安装,通常在`C:\Program Files\GDAL\gdal-data`(或类似路径)。 - 在Linux上,如果通过包管理器安装,可能在`/usr/share/gdal`或`/usr/local/share/gdal`。 - 也可以通过命令查找:`gdalinfo --version`会输出GDAL版本,同时可能包含数据路径;或者使用`gdalinfo --license`也可能显示数据路径。 2. 设置环境变量: - Windows:在系统环境变量中添加`GDAL_DATA`,值为数据目录的路径(例如`C:\Program Files\GDAL\gdal-data`),然后重启命令行或应用程序。 - Linux/macOS:在shell配置文件(如.bashrc或.zshrc)中添加: ```bash export GDAL_DATA=/usr/share/gdal ``` 然后运行`source ~/.bashrc`(或相应配置文件)。 3. 验证数据目录内容: - 检查数据目录下是否有必要的文件,例如`gcs.csv`, `pcs.csv`, `epsg.wkt`等。如果这些文件缺失,可能需要重新安装GDAL或手动复制这些文件到该目录。 4. 如果数据文件缺失,可以: - 重新安装GDAL,并确保安装包包含数据文件。 - 从GDAL源代码仓(如https://github.com/OSGeo/gdal/tree/master/data)下载所需数据文件,并复制到数据目录中。 5. 在代码中设置(备选): 如果无法设置环境变量,可以在代码中设置(例如在Python中): ```python import os os.environ['GDAL_DATA'] = '/path/to/gdal-data' ``` 注意:如果用户是在特定环境中(如Anaconda)使用GDAL,可能需要通过conda安装`gdal-data`包(如果单独存在),或者重新安装`libgdal`包,确保数据文件被正确安装。 根据上述分析,我们给出回答。</think>### GDAL数据目录配置错误的解决方法 当出现"GDAL data directory not containing correct data files"错误时,通常是因为GDAL无法找到或识别其核心数据文件(如投影定义文件、EPSG代码文件等)。以下是系统性的解决方法: #### 1. **验证数据文件存在性** - 检查GDAL数据目录(默认路径): - Windows: `C:\Program Files\GDAL\gdal-data` - Linux: `/usr/share/gdal` 或 `/usr/local/share/gdal` - 确认目录包含以下关键文件: - `gcs.csv`(地理坐标系定义) - `pcs.csv`(投影坐标系定义) - `epsg.wkt`(EPSG代码定义) - `gdalvrt.xsd`(虚拟数据集模板) - 如果文件缺失,需重新获取完整数据包[^1]。 #### 2. **正确设置环境变量** - **Windows**: 1. 右键"此电脑" → 属性 → 高级系统设置 → 环境变量 2. 新建系统变量: - 变量名:`GDAL_DATA` - 变量值:`C:\Program Files\GDAL\gdal-data`(根据实际路径修改) 3. 重启所有命令行和应用程序 ```cmd :: 命令行临时设置 set GDAL_DATA=C:\Program Files\GDAL\gdal-data ``` - **Linux/macOS**: 在终端配置文件(`.bashrc`或`.zshrc`)中添加: ```bash export GDAL_DATA=/usr/share/gdal ``` 执行 `source ~/.bashrc` 生效 #### 3. **代码中硬编码路径(备选方案)** ```python import os os.environ['GDAL_DATA'] = '/custom/path/to/gdal-data' # Python示例 ``` #### 4. **重新安装数据文件** - 从官方源获取数据包: ```bash # Ubuntu/Debian sudo apt-get install gdal-data # Conda环境 conda install -c conda-forge gdal-data ``` - 或手动下载最新数据: ```bash wget https://github.com/OSGeo/gdal/raw/master/data/gdal-data.zip unzip -d /target/directory gdal-data.zip ``` #### 5. **验证修复结果** - 执行诊断命令: ```bash gdalinfo --version # 应显示"GDAL_DATA"路径 gdalsrsinfo EPSG:4326 # 测试坐标系统加载 ``` - 若仍报错,检查路径权限: ```bash ls -l /usr/share/gdal # Linux权限检查 icacls "C:\GDAL\data" # Windows权限检查 ``` #### 常见陷阱排查 1. **路径分隔符问题**:Windows使用`\`需转义为`\\`,推荐使用`/`替代 2. **多版本冲突**:卸载冗余GDAL版本,确保环境变量指向单一版本 3. **虚拟环境隔离**:在Docker/VenV中需显式设置变量 4. **文件编码错误**:确保CSV文件为UTF-8编码(用`file -i gcs.csv`验证) > **关键提示**:安装过程中若遇中断,需根据错误日志定位失败点后重新执行安装[^2]。对于大型GIS项目,建议使用容器化部署保证环境一致性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值