为便于在自己的程序中使用GDAL的示例代码提供的那些强大功能,计划建立一个动态库,在动态库中模拟实现gdal的demo的功能。
初步想法是建立一个类CGdalTools,类的成员即是这些demo的名字。实现与demo一样的功能。
下面的例子是以gdal_translate为例。
找到gdal_translate_bin.cpp(该文件已经相当简单,加上各种注释仅300行出头),复制其中的main函数内容到一个单独的gdal_translate函数中,函数参数与main函数同,返回值与其核心函数GDALTranslate的返回值同,为GDALDatasetH,如下:
GDALDatasetH Gdal_Translate(int argc, char** argv) ;
复制过来的代码不同直接使用,需要做一些修改:
- 继续复制GDALTranslateOptionsForBinaryNew和GDALTranslateOptionsForBinaryFree
- Gdal驱动的注册改为在CGdalTools类的构建函数中进行,而销毁则放在析构函数中。
- 删除EarlySetConfigOptions函数调用。
- exit函数全部改为return null;
- 认为不必要的地方,可以直接删除。比如输出使用说明、帮助信息、版本信息等地方。
- 有些输出Usage函数的地方,改为return NULL;
- 函数最后删除GDALClose(hOutDS); return nRetCode;改为return hOutDS;
- 找不到GDALTranslateOptionsForBinary类,经检查,该类其实定义于gdal_utils_priv.h中,该定义主要是用来演示DEMO的使用而添加,并不是GDAL的核心功能,因此,GDAL的编译并没有将它导出。为便于开发,最简单的方法是将该文件复制到gdal开发版本的include目录下,然后在所有结构体的定义前加CPL_DLL即可。
修改后的代码已经可以运行了,其输入参数与在命令行中调用gdal_translate完全相同。代码示例如下,需要注意的是输出的GDALDatasetH须在外面关闭,也就是调用在上面的第7步中删除的GDALClose(hOutDS);
GDALDatasetH CGdalTools::Gdal_Translate(int argc, char** argv)
{
GDALDatasetH hDataset, hOutDS;
int bUsageError;
argc = GDALGeneralCmdLineProcessor(argc, &argv, 0);
if (argc < 1)
return NULL;
if (CPLGetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", NULL) == NULL)
{
CPLSetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", "450");
}
GDALTranslateOptionsForBinary* psOptionsForBinary = GDALTranslateOptionsForBinaryNew();
GDALTranslateOptions *psOptions = GDALTranslateOptionsNew(argv + 1, psOptionsForBinary);
CSLDestroy(argv);
if (psOptions == NULL)
{
return NULL;
}
if (psOptionsForBinary->pszSource == NULL)
{
return NULL;
}
if (psOptionsForBinary->pszDest == NULL)
{
return NULL;
}
if (strcmp(psOptionsForBinary->pszDest, "/vsistdout/") == 0)
{
psOptionsForBinary->bQuiet = TRUE;
}
if (!(psOptionsForBinary->bQuiet))
{
GDALTranslateOptionsSetProgress(psOptions, GDALTermProgress, NULL);
}
if (!psOptionsForBinary->bQuiet && !psOptionsForBinary->bFormatExplicitlySet)
CheckExtensionConsistency(psOptionsForBinary->pszDest, psOptionsForBinary->pszFormat);
/* -------------------------------------------------------------------- */
/* Attempt to open source file. */
/* -------------------------------------------------------------------- */
hDataset = GDALOpenEx(psOptionsForBinary->pszSource, GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR, NULL,
(const char* const*)psOptionsForBinary->papszOpenOptions, NULL);
if (hDataset == NULL)
{
return NULL;
}
/* -------------------------------------------------------------------- */
/* Handle subdatasets. */
/* -------------------------------------------------------------------- */
if (!psOptionsForBinary->bCopySubDatasets
&& CSLCount(GDALGetMetadata(hDataset, "SUBD