作者:朱金灿

来源:http://blog.csdn.net/clever101

最近使用gdal库比较多,就谈谈gdal库的一些使用心得。

第一个是GDALOpen的访问权限参数会影响图像的创建金字塔方式。比如你是这样打开图像和创建金字塔:

std::string strImgPath = _T(“C:\\1.tif”);
GDALDataset* mGdalDataset=(GDALDataset*)(GDALOpen(strImgPath.c_str(),GA_Update));
mGdalDataset ->BuildOverviews(_T("NEAREST"),nLevel,pBandList,0,NULL,GdalBuildPyramidProgress,NULL);

运行完这段代码之后你会奇怪地发现在图像文件所在的文件夹并没有ovr文件或rrd文件出现,那么究竟有没有金字塔生成呢?实际上是有的。那么图像金字塔数据究竟存储在哪里,我猜测是存储在图像文件本身去了。为何这么说呢?因为我试着把第一行代码的GA_Update改为GA_ReadOnly,结果出现了ovr文件,也就是说当设置为GA_Update,金字塔数据是有可能放在图像文件的,当然我没有确认。这里还有一些疑问:如果金字塔数据是存储在文件里,那么对于tif文件具体是存储在哪里?对于其它图像文件又是存储在哪里呢?

第二个在调用完RasterIO函数对图像进行写入操作之后只是保留在缓存,需要再调用FlushCache函数才能真正把数据写到磁盘去。

第三个是网上有一篇关于坐标转换的教程:GDAL库学习笔记(五):坐标系之间的转化。其中有一段代码是这样的:

OGRSpatialReference    oUTM, *poLatLong;
OGRCoordinateTransformation *poTransform;
oUTM.SetProjCS("UTM 17 / WGS84");
oUTM.SetWellKnownGeogCS( "WGS84" );oUTM.SetUTM( 17 );poLatLong = oUTM.CloneGeogCS();poTransform = OGRCreateCoordinateTransformation( &oUTM, poLatLong );if( poTransform == NULL ){...}...
if( !poTransform->Transform( nPoints, x, y, z ) )...

我试过多次,OGRCreateCoordinateTransformation总是执行失败。后来看了gdal的源码,发现ogr集成prj4库进行投影坐标转换颇有些坑爹的地方。我们看一些OGRCreateCoordinateTransformation函数大致是怎么做的:

OGRCreateCoordinateTransformation函数大致是怎么做的:
OGRCoordinateTransformation*
OGRCreateCoordinateTransformation( OGRSpatialReference *poSource, OGRSpatialReference *poTarget ){OGRProj4CT  *poCT;if( !LoadProjLibrary() ){CPLError( CE_Failure, CPLE_NotSupported, "Unable to load PROJ.4 library (%s), creation of\n""OGRCoordinateTransformation failed.",GetProjLibraryName() );return NULL;}poCT = new OGRProj4CT();if( !poCT->Initialize( poSource, poTarget ) ){delete poCT;return NULL;}else{return poCT;}
}

其中 LoadProjLibrary 的含义很明显,就是加载prj4库。我们再看看 LoadProjLibrary 函数

static int LoadProjLibrary(){CPLMutexHolderD( &hPROJMutex );static int  bTriedToLoad = FALSE;const char *pszLibName;if( bTriedToLoad )return( pfn_pj_transform != NULL );bTriedToLoad = TRUE;pszLibName = GetProjLibraryName();#ifdef PROJ_STATICpfn_pj_init = pj_init;pfn_pj_init_plus = pj_init_plus;pfn_pj_fwd = pj_fwd;pfn_pj_inv = pj_inv;pfn_pj_free = pj_free;pfn_pj_transform = pj_transform;pfn_pj_get_errno_ref = (int *(*)(void)) pj_get_errno_ref;pfn_pj_strerrno = pj_strerrno;pfn_pj_dalloc = pj_dalloc;
#if PJ_VERSION >= 446pfn_pj_get_def = pj_get_def;
#endif
#elseCPLPushErrorHandler( CPLQuietErrorHandler );pfn_pj_init = (projPJ (*)(int, char**)) CPLGetSymbol( pszLibName,"pj_init" );CPLPopErrorHandler();if( pfn_pj_init == NULL )return( FALSE );pfn_pj_init_plus = (projPJ (*)(const char *)) CPLGetSymbol( pszLibName, "pj_init_plus" );pfn_pj_fwd = (projUV (*)(projUV,projPJ)) CPLGetSymbol( pszLibName, "pj_fwd" );pfn_pj_inv = (projUV (*)(projUV,projPJ)) CPLGetSymbol( pszLibName, "pj_inv" );pfn_pj_free = (void (*)(projPJ)) CPLGetSymbol( pszLibName, "pj_free" );pfn_pj_transform = (int (*)(projPJ,projPJ,long,int,double*,double*,double*))CPLGetSymbol( pszLibName, "pj_transform" );pfn_pj_get_errno_ref = (int *(*)(void))CPLGetSymbol( pszLibName, "pj_get_errno_ref" );pfn_pj_strerrno = (char *(*)(int))CPLGetSymbol( pszLibName, "pj_strerrno" );CPLPushErrorHandler( CPLQuietErrorHandler );pfn_pj_get_def = (char *(*)(projPJ,int))CPLGetSymbol( pszLibName, "pj_get_def" );pfn_pj_dalloc = (void (*)(void*))CPLGetSymbol( pszLibName, "pj_dalloc" );CPLPopErrorHandler();#endifif( pfn_pj_transform == NULL ){CPLError( CE_Failure, CPLE_AppDefined, "Attempt to load %s, but couldn't find pj_transform.\n""Please upgrade to PROJ 4.1.2 or later.", pszLibName );return FALSE;}return( TRUE );
}

gdal库集成prj4库有两种方式:静态库集成和动态库集成,使用预处理器PROJ_STATIC。首先看看静态库集成:

    pfn_pj_init = pj_init;pfn_pj_init_plus = pj_init_plus;pfn_pj_fwd = pj_fwd;pfn_pj_inv = pj_inv;pfn_pj_free = pj_free;pfn_pj_transform = pj_transform;pfn_pj_get_errno_ref = (int *(*)(void)) pj_get_errno_ref;pfn_pj_strerrno = pj_strerrno;pfn_pj_dalloc = pj_dalloc;

这里只是函数指针的赋值,那么函数调用的地方在哪里呢?我并没有找到。动态库集成就更扯淡了,首先通过GetProjLibraryName函数获取prj4库的动态库名字,这里名字规定为:

#if (defined(WIN32) || defined(WIN32CE)) && !defined(__MINGW32__)
#  define LIBNAME      "proj.dll"
#elif defined(__CYGWIN__) || defined(__MINGW32__)
// XXX: If PROJ.4 library was properly built using libtool in Cygwin or MinGW
// environments it has the interface version number embedded in the file name
// (it is CURRENT-AGE number). If DLL came somewhere else (e.g. from MSVC
// build) it can be named either way, so use PROJSO environment variable to
// specify the right library name. By default assume that in Cygwin/MinGW all
// components were buit in the same way.
#  define LIBNAME      "libproj-0.dll"
#elif defined(__APPLE__)
#  define LIBNAME      "libproj.dylib"
#else
#  define LIBNAME      "libproj.so"
#endif

也就是说假如在windows平台下不叫proj.dll,压根加载不了prj4库,还有致命一条:proj.dll究竟放在哪个路径下呢?据我经验,LoadLibrary没有指定路径的话,在Windows平台只能在当前目录和在系统环境变量路径中找到,具体见:关于DLL搜索路径的顺序问题。动态库集成和静态库集成存在一样的问题,只找到函数地址,并不见调用的地方。

转载于:https://www.cnblogs.com/suncoolcat/p/3324905.html

gdal库的三个使用心得相关推荐

  1. gdal库中设置prj4库全路径的用法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 gdal库实现投影转换之类的功能实际上底层都是调用prj4库的功能.如果gdal使用非静态的方式集成prj4库,实际上 ...

  2. GDAL库三个读取Jpeg2000格式驱动测试

    0.目的 GDAL库中提供了四五种读取Jpeg2000的驱动,但是各个驱动读取数据的效率各不相同,下面就针对三种读取jpeg2000的效率进行测试. GDAL库中提供的读取Jpeg2000的驱动有下面 ...

  3. GDAL库简介以及在Windows下编译过程

    GDAL(Geospatial Data Abstraction Library,地理空间数据抽象库)是一个在X/MIT许可协议下的开源栅格空间数据转换库.官网http://www.gdal.org/ ...

  4. 基于GDAL库,读取海洋风场数据(.nc格式)c++版

    经过这一段时间的对海洋数据的处理,接触了大量的与海洋相关的数据,例如海洋地形.海洋表面温度.盐度.湿度.云场.风场等数据,除了地形数据是grd格式外,其他的都是nc格式的数据.本文将以海洋风场数据为例 ...

  5. python 读取geotiff_科学网—利用python GDAL库读写geotiff格式的遥感影像方法 - 张伟的博文...

    (1)利用python GDAL库读写geotiff格式的遥感影像方法,具有很好的参考价值,不错! from osgeo import gdal import numpy as np def read ...

  6. GDAL库进度信息编写示例

    GDAL进度信息编写 GDAL库中的算法以及读写数据的时候一般都会提供两个与进度信息相关的参数,下面分别进行描述: GDALProgressFunc pfnProgress void * pProgr ...

  7. 使用GDAL库中的RPC校正问题

    最近将GDAL库更新至1.11版本之后,发现之前写的RPC像方改正模型校正的结果偏差特别大(更新版本之前结果和PCI处理的结果一致).所以初步判断是GDAL库的bug,经过各个参数修改发现原来是指定的 ...

  8. GDAL库中WFS服务中含有中文不能获取数据的问题

    GDAL库中目前提供了对WFS服务发布的数据进行获取,目前发现对于中文的服务名称或者图层名为中文,GDAL不能正确识别.通过调试发现,其原因有下面两点: 1.输入的URL路径没有使用UTF8编码而从网 ...

  9. 浅析GDAL库C#版本支持中文路径问题(续)

    上篇博客中主要说了GDAL库C#版本中存在的问题,其表现形式主要是:"文件名中的汉字个数是偶数,完全没有影响,读取和创建都正常,如果文件名中的汉字个数是奇数,读取和创建都会报错." ...

最新文章

  1. Codeforces Global Round 13 E. Fib-tree
  2. Spark编程模型几大要素
  3. 有些事儿,工程师可能今生仅此一次
  4. mysql dms_关于MySQL与DMsql探寻
  5. 阿里云rds mysql 并发_干货 | 浅析RDS MySQL 8.0语句级并发控制-阿里云开发者社区
  6. 一次解决DB2接口文件到Oracle无法导入问题的经历
  7. linux搜索命令有哪些,linux五大搜索命令学习
  8. SwiftyJSON解析本地JSON文件
  9. 如何在android上编程,如何在Android中以编程方式与USSD对话框进行交互
  10. 百度2014移动研发笔试题目
  11. cpu飙升 死循环_CPU飙升问题的解决实例
  12. iOS 单例模式详解/避免滥用单例
  13. 3GPP 资源 使用、查找 教程
  14. inherits在java中是什么属性_在Java中,要想让一个类继承另一个类,可以使用哪个关键字?()...
  15. 商标注册计算机软件app属于第几类,软件商标属于第几类?
  16. 同心拼图(concentric mosaics)
  17. 线性加权平均 c语言程序,【求助】编的一个加权平均分计算程序,总是出错。求高手指点~...
  18. Qt Quick - Slider
  19. 华米手表2 是android,手表 | 续航怪兽 华米AMAZFIT智能运动手表2代深度评测(二)...
  20. 三、12.13.14.15.编写三角形类Triangle

热门文章

  1. [转]如何使用 DirectX 診斷工具判斷 DirectX 的版本
  2. 计算机网络—路由器(Cisco Packet Tracer)常用的命令总结
  3. HTML+CSS制作3D步数统计界面
  4. iPhone8用的全面屏是什么屏幕?
  5. 川菜中,你觉得哪道菜能称为“经典之菜”呢?
  6. 小舅子的工作每周轮换一次
  7. “云手机”是否会成为未来的主流?
  8. 没有任何一个行业是没有竞争的
  9. 新零售时代,美妆行业如何打造新主场?
  10. 穷的时候要记住这5点,才能有机会翻身