问题

最近在处理地理影像时,需要使用GDAL的库用于保存包含地理信息的图像。

在使用Python验证时,使用rasterio保存GeoTiff图像,图像地理信息设置是正常的。

但是在用C++重写时,使用GDALC++库时出现了地理信息无法设置的问题。

问题分析

GDAL官方文档中使用了下面的方式设置地理信息,并保存图像。

#include "cpl_string.h"
...
const char *pszFormat = "GTiff";
GDALDriver *poDriver;
char **papszMetadata;
poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat); // 获取驱动
if( poDriver == NULL )
    exit( 1 );
papszMetadata = poDriver->GetMetadata(); // 获取元数据
if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ) )
    printf( "Driver %s supports Create() method.\n", pszFormat );
if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) )
    printf( "Driver %s supports CreateCopy() method.\n", pszFormat );

GDALDataset *poDstDS;
char **papszOptions = NULL;
poDstDS = poDriver->Create( pszDstFilename, 512, 512, 1, GDT_Byte,
                            papszOptions ); // 创建图像

double adfGeoTransform[6] = { 444720, 30, 0, 3751320, 0, -30 }; // 地理信息,图像左上角的X坐标,图像X轴分辨率,图像行旋转角度,图像左上角的Y坐标,图像行旋转角度,图像Y轴分辨率(通常是负数)
OGRSpatialReference oSRS;
char *pszSRS_WKT = NULL;
GDALRasterBand *poBand;
GByte abyRaster[512*512];
poDstDS->SetGeoTransform( adfGeoTransform ); // 设置地理信息
oSRS.SetUTM( 11, TRUE );
oSRS.SetWellKnownGeogCS( "NAD27" );
oSRS.exportToWkt( &pszSRS_WKT );
poDstDS->SetProjection( pszSRS_WKT ); // 设置投影
CPLFree( pszSRS_WKT );
poBand = poDstDS->GetRasterBand(1); // 设置波段
poBand->RasterIO( GF_Write, 0, 0, 512, 512,
                abyRaster, 512, 512, GDT_Byte, 0, 0 ); // 写入图像

GDALClose( (GDALDatasetH) poDstDS );

但是实际图像没有成功设置地理信息。使用GetGeoTransform也获取不到地理信息。

在查看了rasterio的源码时,发现rasterio的保存接口使用的是GDALC接口,所以尝试了使用GDALC接口。

所以使用下面的代码替换原本的设置地理信息部分。

GDALSetGeoTransform((GDALDatasetH)poDstDS, adfGeoTransform);

这样发现地理信息就可以正常保存了。

估计是GDALC++接口没有正确调用GDALC接口。

参考