GDAL源码剖析与开发指南

978-7-115-33899-0
作者: 李民录
译者:
编辑: 陈冀康

图书目录:

详情

本书作者从2008年开始使用和查看GDAL,目前为止对其使用的方式,以及实现有一个整体的了解。我个人希望能够写一本能够作为GDAL的入门到引用级别的书,对其内部的整体的架构做一个介绍。本书分为两个部分,一部分通过剖析GDAL的架构和代码,介绍其功能,一部分通过业界实例,介绍其应用开发。本书能够帮助读者快速理解和熟悉GDAL库及其功能,进而开发出有用的地理、地图和遥感应用系统。

图书摘要

GDAL源码剖析与开发指南
李民录 著
人民邮电出版社

北京

前言

GDAL全称是Geospatial Data Abstraction Library(地理空间数据抽象库),是一个在X/MIT许可协议下读写空间数据(包括栅格数据和矢量数据)的开源库,它利用抽象数据模型来表达所支持的各种文件格式,还使用一系列命令行工具来进行数据转换和处理。

由于GDAL库支持很多数据格式,目前几乎所有的GIS和RS软件底层都使用GDAL来读写空间数据。

目前国内外关于GDAL的图书非常少,比较权威的只有GDAL官网的说明文档,导致用户缺少实用的参考资料来学习GDAL。针对这一现状,本书对GDAL库进行了全面的介绍,配以详尽的实例说明,来帮助读者尽快掌握和领会GDAL强大的功能。

关于本书

本书共9章和一个附录,分为三部分:第一部分为GDAL基础说明,对应第1章到第5章;第二部分为GDAL高级使用说明,对应第6章到第8章;第三部分为GDAL库提供的工具使用说明,对应第9章。

第1章对GDAL进行了概述,主要介绍GDAL的概念、特点、支持的数据格式等,对GDAL库的编译进行了说明(Windows平台下),同时介绍如何使用SWIG工具编译生成C#、Java、Python的调用接口以及如何使用Doxygen工具生成GDAL库的帮助文档等,最后分别使用四种编程语言(C++、C#、Python和Java)编写了一个简单的、使用GDAL读取图像信息的例子。

第2章对GDAL库中的空间参考类OGRSpatialReference和空间坐标转换类OGRCoordinateTransformation进行说明,并且分别使用四种编程语言(C++、C#、Python和Java)编写了一个简单的坐标转换的例子。

第3章对GDAL库中的OGR库进行说明,包括OGR库中对矢量数据读取和写入的相关类使用说明、OGR库支持的SQL查询说明,最后用四种编程语言(C++、C#、Python和Java)分别编写了一个简单的使用OGR读写矢量数据的例子。

第4章对GDAL库中读写栅格相关的类进行说明,包括GDAL库中对于栅格数据各个部分所对应的类,着重阐述栅格图像中的读写接口 RasterIO,此外对图像的金字塔、统计值信息也进行了说明,最后分别使用四种编程语言(C++、C#、Python和Java)编写了一个简单的读写栅格数据的例子。

第5章对 GDAL 库中支持的常用数据格式进行说明,也包括对栅格数据的创建选项和GDAL库中通用的配置项的说明。

第6章主要对GDAL库目前不支持的数据格式进行扩展,使GDAL可以支持新的数据格式,分为栅格数据扩展和矢量数据扩展两部分。

第7章主要对GDAL库中提供的算法进行说明,基本上涉及到遥感图像处理中的各个流程。每个算法都有完整的示例代码和算法原理说明。

第8章是对GDAL库中所使用的通用库CPL进行说明,涉及的内容主要有:GDAL库中常量和常用宏定义、错误处理相关函数、文件系统相关、文件读写、字符串及其转换、ZIP文件读写、HTTP网络文件访问和XML文件读写等。

第9章对GDAL库自带的命令行工具和Python脚本工具进行说明,这些命令行工具和脚本工具基本上可以完成大部分的栅格数据和矢量数据处理。

关于读者

本书适合地理信息系统(GIS)和遥感(RS)等相关的专业人员阅读,尤其适合开发GIS或RS相关的系统的人员,如果会C/C++的话更好不过了。由于GDAL库是一个专业性比较强的库,需要使用者对空间数据有一定的了解,否则对于GDAL库中空间坐标相关的内容会感到难以理解。

本书中大部分的示例代码都是使用 C/C++语言编写而成的,相比其他的语言,唯一的差别可能就在语法和GDAL库的部分接口上,其实大部分的思路都是一致的。

致谢

本书起源于作者在CSDN网站的博客http://blog.csdn.net/liminlu0314中关于GDAL库的一系列文章,之后在人民邮电出版社陈冀康编辑的联系下才有了出版的想法。

本书在编写过程中得到了很多同学和朋友的帮助和指点,提出了宝贵的意见,他们是王海、刘巍、张艮中、姜言、朱桂海、解云飞、吴炜、HONY、ミ西风゛、narut、小土豆~~、未来、古城、Don、Sunny、图比特-么玉顺、蔚蓝♪libert、流浪的关公、★如履薄冰★等;最后要特别感谢女友孙姝娟对所有的初稿进行了审阅和修订工作,并且在编写过程中给予我鼓励和支持。

父母的养育才有了我的今天,本书的出版也是父母用心教育的结果,养育之恩,没齿难忘。

借此书出版之际,谨向为此书出版做出贡献的同学和朋友们表示衷心的感谢。

如果在阅读过程中有任何疑问,读者可以在作者的CSDN博客中留言或者直接发邮件与作者联系。作者的电子邮箱是liminlu0314@163.com,博客地址为http://blog.csdn.net/liminlu0314。

由于本人水平有限,书中错误和不妥之处在所难免,恳请读者不吝批评指正。

CSDN网站对作者的专访

1.介绍自己学习和工作经历,曾开发过什么产品?之前的工作经验对你现在的工作有何帮助?

2008年7月毕业于中国矿业大学地理信息系统专业。

2008年~2009年年底任职于北京东方泰坦科技股份有限公司。

2010年~2010年10月任职于北京数字空间科技有限公司。

2010年10月至今任职于二十一世纪空间技术股份有限公司。

在这三家公司都是做遥感图像处理相关的算法和软件研发。

之前的工作经验我觉得是我现在的基石,我工作四年多都是在做遥感图像处理的相关工作,很少涉及到其他的行业。这点对我来说既是优点也是缺点。优点就是你可以对遥感图像处理的流程及其原理有比较深入的理解,缺点就是对于其他行业的知识面有些窄。一个是纵向深展,一个是横向拓展。

2.你何时开始接触计算机?是什么原因促使你走上编程的道路?最先使用的语言是哪个?

第一次接触计算机是在2001年,是去同学家接触到的,第一眼觉得很好奇,这就是传说中的电脑。之后高考填报志愿失误,调配到地理信息系统(GIS)专业,这个专业在当时(2004年)算是一个新兴的专业,简单的说就是用计算机来处理和管理地理信息的一种技术。这也就促使我走上了编程的道路。

最先使用的语言应该算是VB,当时大一学校开设的公共基础课就有VB编程。在之后学习专业课中就有C++,此后写程序就全部使用C++语言。在2010年开始接触了Python语言,这是一门解释性语言。之后在写一些简单的工具的时候使用Python,由于它不需要编译,只要安装一个 Python 的运行环境就可以,相比 C++来说,写一些小的工具还是很方便的。

3.你目前工作主要以 C++为主,从长期的使用经验来看,你是如何看待 C++语言的未来,以及C++与C#的关系?

个人觉得C++在很长的时间中还是主流的开发语言,尤其是对于算法要求较高的行业,比如我从事的遥感图像处理。随着卫星的分辨率越来越高,数据量也越来越大,只靠提升硬件来增加处理能力只能提升部分,所以还是需要从算法的角度来进行优化。从语言的执行效率来讲,C++比C#要高很多。但是C#对于界面的开发有着很大的优势,这点对于C++来说确实是一个短板。

所以,我觉得 C++和 C#的关系应该是互存互惠的一个关系,各司其职,C++开发一些对算法要求比较高的系统,而C#应该是朝着快速的这个方向来发展。

4.你怎么看待面向对象技术的发展前景?

面向对象技术是软件设计的一个主流方向,从以前的面向过程到现在的面向对象,使人们处理问题能够更符合人的思维逻辑。同时面向对象的方法可以有效的提升开发效率以及后续的维护和二次开发。

5.C++入门难,你怎么看待这个问题?

C++入门难,个人感觉不存在这个问题。现在很多人觉得C++入门难,我觉得是因为现在网络上很多文章都在说C++难学,这样就无意识的给这些想学习C++的人灌输了一个概念,那就是C++难学。如果事先没有这个概念,那么学习C++和学习其他的语言是一样的。

对于 C++难学可能还有另外一个方面的原因,就是 C++本身只是提供了一套语法规则,没有像 C#和 Java 之类的其他语言那么多自带的库,比如正则表达式等。如果用 C++实现类似的功能确实很复杂,但是比较幸运的是,目前有很多开源的 C++库提供了这些功能,比如被称为C++的准标准库的Boost库,里面提供了一百多个涵盖了各个方面的库。

任何语言的学习都离不开一个过程,那就是亲自写代码,调试程序,在调试过程中理解语法的意义和概念。

此外,对于学习C++,建议大家经常去看一些科技网站,关注一些C++的开源库,这样很多时候就避免了重复发明轮子的这个过程。而且很多的开源库都有很多商业软件在使用,在效率和可靠性上都是比较好的。所以多了解一些C++的开源库对自己的工作肯定有很大的帮助。

6.从博客中看到,你正在写关于GDAL源码剖析的系列文章。你最初的想法是什么?透露下,未来一个月你将写哪些内容?

当初我学习GDAL的时候(2008年左右),关于GDAL的学习资料很少,除了官方的API帮助文档之外,就很少了。慢慢的,发现积累的东西越来越多,但是没有记录,忘记的也快,为了以后用到的时候方便查阅,于是就开始写关于GDAL的博客。之后创建了一个GDAL的交流群,不到一月的时间,群就满了。很多人在我的博客下面留言,说是帮助他解决了问题,或者问我一些类似的问题。所以我觉得有必要把我学习到的关于GDAL的一些知识跟大家分享一下,独乐乐不如众乐乐,于是就整理了一下,形成现在的GDAL源码剖析的系列的文章。

接下来就是继续更新《GDAL源码剖析》这个系列的内容,之前主要写的都是关于GDAL的使用方面的内容,接下来想把GDAL的内部机制和实现原理进行一个说明,真正对得起这个系列的名字,好让广大的GDAL使用者能够知其然并且知其所以然。

7.GDAL在读取不同的数据时,会发生什么常见问题?有何方法能快速的解决问题?

GDAL在读取不同的数据时,最常见的问题可能有下面三个:

1、GDAL关于中文路径的问题,以及矢量数据属性中文乱码的问题;

2、对于C#语言调用会出现程序崩溃的问题;

3、关于RasterIO读写图像的问题。

这三个问题是在群里提问最多的,对于第一个问题,主要是由于GDAL在1.8之后的版本,增加了对于多字节的处理,默认的路径编码改成UTF-8的编码导致的。由于C++中文版默认的编码是GBK或者其他的,一般有两种方式解决,第一将中文路径编码专为UTF-8,第二设置GDAL的默认编码不是UTF-8即可解决。第二个问题最主要的原因有两个:一是GDAL的dll没有复制到程序的目录;二是由于编译GDAL的平台版本和C#的平台不一致导致,比如GDAL编译的是32系统的,C#在编译的时候必须选择X86平台,否则就会出现这个问题。第三个问题主要是对于RasterIO这个函数的参数没有理解清楚导致的,尤其是对于最后的三个参数。

关于这三个问题,我分别写了几篇博客,对其进行了说明。

8.现在你从事的工作主要以C++和GDAL库为主,两者搭配的优势和弊端分别是什么?

GDAL 库本身就是用 C/C++语言编写,所以对于 C++的使用,本身没有语言的差异,使用起来也非常的方便。通过最基本的包含头文件,引用库文件就可以使用。

C++和 GDAL 搭配的弊端主要还是 C++语法的一些限制吧,比如读取数据的时候内存的申请和释放等。对于这个问题只能从使用人员本身来进行避免。

同时GDAL使用SWIG来提供其他语言的API接口,比如C#、Java、Python、PHP等。所以在使用GDAL的时候,对于搭配的语言来说,根据个人的习惯来决定。

9.分享下你学习C++和GDAL的一些经验,有何好书籍或方法可以推荐给初学者?

学习C++的经验就是自己亲手写代码、调试,这样才能真正提高自己的能力,光看书是不行的,那就成了纸上谈兵,到真正用的时候就发现写不出来了。当然了,书还是必须要看的。我觉得学习任何语言都脱离不了这个规则吧。关于C++的书籍,《C++ Primer》是一本好书,不管是学习还是用来当作参考书都是很不错的选择。另外还有一本就是《深入理解计算机系统》,这本书对于学习C/C++的人来说是一本非常好的书,尤其是想理解C/C++程序是如何映射到系统上,以及程序是如何执行的,读者能够更好地理解程序的行为为什么是这样的,以及效率低下是如何造成的。这本书通过程序员的视角,让读者可以深深地体会到学习计算机系统的内部工作原理会对他们今后的工作有进一步的帮助。

对于学习GDAL的方法,第一看GDAL的官方文档。我曾经把GDAL的官方文档全部看完过,当时还准备翻译成中文的文档,后来由于种种原因没有完成。通过官方文档和官方提供的入门Demo,逐个理解每个类,每个函数的意义。或者先熟悉一下每个类里面的接口,有个印象,等用到的时候可以大致知道,然后再去文档里面找说明。

此外,学习 GDAL 首先要对遥感图像数据的基本信息有一个了解,然后才能更好的了解GDAL 库,比如遥感图像同普通的图像多了空间信息,这些空间信息主要就是投影信息和分辨率。有了这些概念,就可以很容易的和GDAL的API结合起来,比如GDALDataset类中的GetProjectionRef这个函数就是获取的遥感图像的投影信息。

由于GDAL是在2007年前后才开始广泛的应用,所以目前还没有出版的参考书来进行参考,只能去参考它的官方帮助文档。此外我整理了一个GDAL专栏,基本上也可以作为中文的一个参考文档。

10.你在学习或工作中,是怎么接触到CSDN?CSDN对于你的工作或学习有什么影响,起到过什么帮助?有什么故事可以分享?

第一次接触 CSDN 是在大学 C++的课堂上,老师推荐有问题可以去 CSDN,之后遇到问题,首先就是先看看CSDN有没有别人遇到同样或者此类的问题(基本上80%都可以找到解决问题的方式)。

很感谢CSDN提供的这样一个平台,可以让大家集合起来,尤其是对于CSDN的论坛和博客,这两个板块个人非常喜欢。在论坛可以得到别人的帮助和帮助别人,博客可以和大家分享自己的一些学习经验等。

11.你对CSDN有什么建议,以及你对CSDN的未来有什么期待?

对于 CSDN,希望可以在发布博客的时候提供客户端的工具,之前可以使用 Live Writer来发布,但是之后又不行了。对于有时候发布一些图片比较多的博客使用在线的编辑工具确实不太方便,希望能够提供一个客户端的工具。

最后祝CSDN的发展越来越好!

第1章 GDAL简介

1.1 什么是GDAL

GDAL全称是Geospatial Data Abstraction Library(地理空间数据抽象库),是一个在X/MIT许可协议下读写空间数据(包括栅格数据和矢量数据)的开源库,它利用抽象数据模型来表达所支持的各种文件格式,还使用一系列命令行工具来进行数据转换和处理。

OGR(OGR Simple Features Library)是GDAL 项目的一个分支,功能与GDAL 类似,只是它提供对矢量数据的读写支持。同时它实现了一个对空间参考信息进行处理的类,用来对空间数据的空间信息进行处理。

GDAL 最初是由Frank Warmerdam 于1998 年开始开发的,在GDAL1.3.2 版本之后,正式由开源空间信息基金会(OpenSourceGeospatialFoundation,简称OSGeo)下的GDAL/OGR项目管理委员会对其进行维护。

很多著名的GIS类产品都使用了GDAL/OGR库,包括ESRI的ArcGIS系列、Erdas2011、Google Earth和跨平台的GRASS GIS、Quantunm GIS系统等(更多使用GDAL 的软件和产品,参考GDAL网址http://trac.osgeo.org/gdal/wiki/SoftwareUsingGdal)。

1.2 GDAL特点

GDAL 提供对多种栅格数据的支持,包括Arc/Info ASCII Grid(asc),GeoTiff (tiff),Erdas Imagine Images(img),ASCII DEM(dem) 等格式。

OGR 提供对矢量数据格式的读写支持,包括 ESRI Shapefiles、S-57、SDTS、PostGIS、Oracle Spatial、Mapinfo mid/mif和Mapinfo TAB 等。

GDAL 库还提供了一系列算法接口,比如矢量栅格化、栅格矢量化、图像校正算法以及DEM相关的算法接口等;同时对这些算法提供了一系列可以运行的程序或者脚本,方便人们使用。

1.3 GDAL支持的数据格式

GDAL支持的数据格式分为两种:栅格数据格式和矢量数据格式。GDAL在每次版本更新的时候,都会加入对新的格式的支持。本书使用 GDAL1.10 版本中支持的栅格数据格式,如表1-1所示,支持的矢量数据格式如表1-2所示。

表1-1 GDAL支持的栅格数据格式
(续表)
(续表)
(续表)
(续表)
(续表)
(续表)
(续表)

注意

文件的最大存储大小不仅由文件的格式决定,而且和操作系统有关系。

表1-2 GDAL支持的矢量数据格式
(续表)
(续表)
(续表)
(续表)

1.4 GDAL源码下载

GDAL 的源码下载有两种方式。第一种是直接下载打包好的压缩包,下载地址为:http://trac.osgeo.org/gdal/wiki/DownloadSource。另外,GDAL的各个历史版本都可以在这个地址进行下载:http://download.osgeo.org/gdal/。这种下载方式很简单,此处不作说明。下载完成,使用压缩软件解压即可。

第二种下载方式是使用 SVN 源代码管理工具直接从 GDAL 的源码服务器进行下载。下载地址是:http://svn.osgeo.org/gdal/trunk。从 SVN 下载的好处是可以直接看到代码的提交者对代码做的修改信息等。需要注意的是,从这里下载的源代码不是发布的版本,而是开发版本,可能会有些bug。下面以TortoiseSVN为例对使用SVN下载做一个简单的说明,使用SVN下载之前要确保已经安装了SVN的客户端软件。

1)在电脑中新建一个文件夹用来存放GDAL的源代码。

2)在该文件夹点击右键,在弹出菜单中选择“SVN check out…”,弹出如图1-1所示的对话框。

3)对话框中的“URL of repository”中填入“http://svn.osgeo.org/gdal/trunk”,在“Checkout directory”中确定迁出的文件夹,其他选项默认,点击“OK”按钮,即开始下载GDAL的源代码。

图1-1 SVN checkout 对话框

1.5 GDAL源码目录

下载的GDAL源代码压缩包目录如图1-2所示,使用SVN迁出的GDAL源代码目录如图1-3所示。

图1-2 GDAL 源码压缩包文件目录结构

从图1-2和图1-3所示可以看出,不管用什么方式获取GDAL的源代码,它的目录结构都是一样的。下面我们就针对目录结构中的每个文件夹和文件作一个简单的说明(按照字母顺序)。

图1-3 GDAL SVN源码文件目录结构

1.5.1 文件夹说明

对于图1-3中所示的文件夹,详细说明如下。

alg:该文件夹存放的是GDAL库中提供的一些算法的源代码,这些算法包括但不限于:DEM生成等高线算法,图像纠正算法(几何纠正、TPS纠正、RPC纠正等),栅格矢量化算法,矢量栅格化算法,格网计算算法,PCT和RGB互转算法,分类图的小碎斑块去除算法等。

apps:该文件夹中存放的是GDAL库中提供的一些命令行工具集的源代码,这些工具集的介绍可以参考http://gdal.org/gdal_utilities.html。后面会对这些工具做一个简单的说明,其中有些工具非常有用,比如gdalinfo,可以用来查看图像的元数据信息等。

bridge:该文件夹中存放的是用来连接GDAL抽象类的定义与GDAL自己的结构体定义及其实现的源代码。后面涉及GDAL的实现原理时我们会对该文件夹作一个比较详细的介绍。

data:该文件夹中存放的是GDAL库中需要用到的一些“配置文件”(此处叫配置文件可能不太准确),这些文件主要有ESRI的投影文件,ESPG的投影文件,PCI的投影和椭球体文件,AutoCAD 的DXF 格式的头文件等。在使用GDAL 库的过程中可以在程序中使用函数CPLSetConfigOption("GDAL_DATA","C:\GDAL\data");来设置该文件夹的目录,如果没有设置GDAL会自动从环境变量中查找,环境变量的名字叫GDAL_DATA,该变量的值就是data文件夹的路径;如果还是没有找到,那么GDAL可能会提示错误,比如在写入AtuoCAD的dxf格式的时候如果不设置GDAL_DATA,那么就会提示创建不成功,后面遇到时我们会再进行说明。

doc:该文件夹存放的是用来生成 GDAL 帮助文档的一些 dox 文件。dox 文件是使用doxygen工具来进行生成的,后面我们会对doxygen工具作一个简单的介绍,并且说明在自己的工程中怎样使用doxygen生成程序的开发帮助文档。

frmts:这个文件夹可以说是GDAL代码中内容最多的一个文件夹了,每次更新GDAL的版本后这个文件夹中都会多出几个文件夹,同时在GDAL支持的文件格式中也会多出来几个新的文件格式。没错,这个文件夹存放的就是GDAL针对不同的特定图像格式解析的源代码,我们可以举几个简单的例子,比如bmp文件夹就是解析BMP图像的,hfa文件夹是用来解析Erdas的img图像格式,还有pcidsk文件夹是读取PCI的pix格式的文件等。所以这个文件夹存放的是解析各个文件格式的源代码。

gcore:这个文件夹是 GDAL 的灵魂所在,主要存放 GDAL 抽象类的数据集,图像、波段的读写接口等都是在这里面实现的。如果想知道GDAL的抽象类是怎么对图像格式进行抽象的,读者可以看看这个文件夹里面的代码。

html:这个文件夹主要用来存放GDAL生成的帮助文档,使用doxygen工具生成的GDAL帮助文档会出现在这个文件夹中。如果使用压缩包的话,该文件夹里面应该是空的。后面我们会和doc文件夹一起进行详细介绍。

m4:该文件夹存放的是以m4 为后缀名的文件。m4 文件叫Macro Processor Library,是编译基础中最核心的文件,这个文件主要是用autoconf来产生configure配置文件,继而自动生成Makefile文件。这个文件夹在Windows平台下没用,在此就不作细述了。

man:该文件夹是用来生成Linux或者其他平台下的帮助文件,Windows平台下也没用。

ogr:GDAL和OGR曾经是两个库,GDAL库负责读写栅格数据,OGR库负责读写矢量数据,然而GDAL的算法库中经常会用到矢量数据的读取,将这两个库分开会造成不便,现在这两个库已经整合到一起,OGR库就是GDAL库的一个子集。其实OGR库还是可以单独编译出来的。ogr文件夹就是存放OGR库源代码的文件夹。后面我们会对这个文件夹里的内容进行详细介绍。

port:该文件夹中存放的是CPL库的东西,CPL是一个GDAL的底层支持库,CPL库中定义了一些字符串的操作、文件处理、网页请求、数据库连接、哈希表、字符加密文件压缩等基础的函数。比如GDAL中所有的导出函数符号CPL_DLL就是在这个CPL文件夹中定义的;还有frmts文件夹中,打开文件、打开数据库、打开网络路径以及字符串的处理等都是用的port库。

swig:该文件夹主要是存放swig 的脚本。SWIG 全称叫Simplified Wrapper and InterfaceGenerator,官方网站是 http://www.swig.org/。SWIG 的作用就是可以将 C/C++写的库封装为Python、C#、Java、Perl和Ruby等其他语言的访问接口。GDAL的C#版本就是使用swig来编译出来实现的。

vb6:这个文件夹用来将GDAL编译成一个VB6的模块,对于里面具体的文件说明以及如何编译参考文件夹中的readme.txt,这里就不作具体说明了。

wince:顾名思义,这个文件夹中的文件就是用来编译Windows CE 平台下的GDAL 库的,具体编译请参考其中的说明文档。

1.5.2 文件说明

aclocal.m4:同1.5.1小节介绍的m4文件夹。

autogen.sh:Linux平台下的shell文件,通过调用autoconf来产生configure配置文件。

COMMITERS:该文件中的内容是GDAL开发人员的信息,包括姓名、联系邮箱以及各自负责开发的模块说明等。

config.guess、config.sub、configure、configure.in:这四个文件在Windows下没有具体作用,在此略过。

Doxyfile:Doxyfile就是前面doc文件夹说明中提到的doxygen的工程文件,用来生成帮助文档,后面我们在介绍doxygen的使用时会对该文件进行说明。

GDALmake.opt.in:这个文件是 Linux 平台下的 GDAL 库编译配置文件,在后面的nmake.opt中我们会介绍其功能。

gdalnightlysvn.sh:Linux平台下调用svn获取GDAL源代码的一个shell脚本。

GNUmakefile:GNU的make文件。

HOWTO-RELEASE:GDAL发布版本的一些说明。

install-sh:Linux平台下GDAL的安装shell脚本。

LICENSE.TXT:GDAL的许可说明文件。

ltmain.sh:Linux平台下libtool的shell脚本,Windows下没用到。

makefile.vc:GDAL的编译文件,用来将源代码编译成dll文件,后面我们会在GDAL编译中作进一步说明。

makegdal_gen.bat:一个用来生成VS的工程文件的批处理文件,后面在GDAL编译中我们会对该文件的使用方式进行说明。

makegdal10.sln:文件夹中所有的 sln 文件都是 VS 的项目文件,文件名后的数字代表的是VS的版本号。

makegdal10.vcxproj、makegdal71.vcproj:VS的工程文件,该文件可以由makegdal_gen.bat文件自动生成,后面我们会详细介绍。

mkbindist.sh、mkgdaldist.sh、mktestdist.sh:三个shell脚本文件,Windows下没用,略过。

NEWS:介绍GDAL的新增功能以及修复的bug记录等。

nmake.opt:GDAL编译选项配置文件,在编译GDAL中,可以指定GDAL绑定的其他库等都在这里进行设置。在后面的GDAL编译中我们会详细说明。

nmake-wince.opt:编译wince版本的编译选项配置文件。

PROVENANCE.TXT:GDAL目录说明文件,如果上面说明的不够清楚,可以参考这个文件。

submake.bat:一个编译的批处理文件。

svnkeywords.sh:SVN的又一个shell脚本。

VERSION:GDAL版本信息。

1.6 GDAL编译

GDAL 的编译分为三个小节,第一节是常规编译,使用微软的Visual Studio 2008进行编译,如果用微软的其他编译器,编译过程与此类似。需要注意的是,GDAL已经不再支持VisualC++6.0编译器。第二小节主要说明怎样修改GDAL的配置文件,以使GDAL支持更多的数据格式以及算法等。第三小节对编译GDAL的64位版本进行说明。

1.6.1 常规编译

1.使用Visual Studio 2008 IDE 编译

在 GDAL 的源代码目录中,有几个以 sln 为后缀的文件,比如 makegdal10.sln、makegdal80.sln、makegdal71.sln、makegdal90.sln 等。这些是 VisualStudio 的工程文件,文件名中的数字表示VS的版本号:71表示VS2003、80表示VS2005、90表示VS2008、10表示VS2010。我们根据自己电脑安装的VS版本,打开对应的文件,如图1-4所示(使用VS2008SP1版本,打开makegdal90.sln文件)。

图1-4 GDAL 源码压缩包文件目录结构

然后我们在左侧解决方案点击右键,在弹出菜单中点击“生成”或者“重新生成”命令, GDAL 就会开始编译。输出窗口中会有编译过程中的一些信息提示,直到出现生成成功等信息,就表示GDAL已经完成编译,这时在GDAL的源代码目录中会出现gdal.lib、gdal_i.lib、gdal18.dll等文件。如果没有修改GDAL中的nmake.opt文件的话,那么C盘中会出现一个名为“C:\warmerda\bld”的文件夹,里面包含三个文件夹,分别是bin、data和html。bin文件夹中存放的是编译出来的GDAL的可执行程序,包括GDAL提供的十几个工具集;data文件夹就是1.5.1小节中介绍的data文件夹;html文件夹中存放的是各种数据格式的说明文档。

2.使用Visual Studio 2008 命令行编译

使用cmd命令行编译,首先在开始菜单中找到“所有程序→Microsoft Visual Studio 2008→Visual Studio Tools→Visual Studio 2008 命令提示”,点击“Visual Studio 2008 命令提示”弹出如图1-5所示的界面。

图1-5 Visual Studio 2008命令提示

使用cd命令,切换到GDAL的源代码目录,如图1-6所示。

图1-6 切换至GDAL 源码目录

切换至GDAL的源代码目录后,依次敲入下面的命令行后回车,等待编译结束即可。

nmake -f makefile.vc

nmake -f makefile.vc install

nmake -f makefile.vc devinstall

同时还有其他的命令,如下所示。

nmake -f makefile.vc clean

nmake -f makefile.vcMSVC_VER=1400 clean

nmake -f makefile.vcMSVC_VER=1400 DEBUG = 1

以上六行的命令含义依次如下。

编译GDAL库;

编译GDAL库并安装(这里安装的意思是将生成的dll、exe等文件复制到C:\warmerda\bld目录);

编译GDAL库并安装开发者模式(安装的意思同上,开发者模式意思是将开发用的include文件夹中的头文件和lib文件一同复制到C:\warmerda\bld目录,此时会在C:\warmerda\bld目录中增加两个文件夹,分别是include和lib,分别存放GDAL的头文件和lib文件,用于调用GDAL库);

清理GDAL库,同时会删除编译GDAL库所生成的临时文件,作用相当于VS环境中的清理命令;

作用与第四行相同,但是添加了一个“MSVC_VER = 1400”,表示使用VS2005 编译;

编译GDAL库的debug模式,可以用来调试GDAL源码。

1.6.2 自定义编译

GDAL 的强大之处不单单在于可以读取栅格和矢量数据,同时还表现在以下三个方面:第一,可以进行矢量图形之间的一些常用操作,比如求交、求并、缓冲区等;第二,可以进行投影和坐标转换;第三,可以使用配置文件来对GDAL库支持的数据格式进行扩展。

如果使用GDAL默认的编译方式,那么上述的前两个功能您将不能使用,因为GDAL这两大功能是基于另外的两个开源库GEOS(Geometry Engine, Open Source)库和PROJ4 库来实现的。下面对这两大库分别做一个简单的说明,讲述如何修改编译文件,让GDAL能够拥有这两大功能。

1.集成GEOS

简单来说,GEOS提供了OGC规范中简单几何要素对象操作的C++语言的实现。更详细的说明可以在GEOS的官网http://geos.osgeo.org中找到。

GEOS 库提供了常用的空间操作,比如判断两个几何对象相互关系的函数 Contains()、Intersects()、Touches()和Crosses()等,计算两个几何对象的空间操作的函数Difference()、Union()以及Buffer()等。

我们假设已经有编译好的GEOS库,首先使用记事本或者其他的文本编辑器打开GDAL源代码目录下的nmake.opt 文件,找到“# Uncomment for GEOS support”这句(1.10版本大概在490行左右),如下面三行代码所示。

#GEOS_DIR = C:/warmerda/geos

#GEOS_CFLAGS = -I$(GEOS_DIR)/capi -I$(GEOS_DIR)/source/headers -DHAVE_GEOS

#GEOS_LIB = $(GEOS_DIR)/source/geos_c_i.lib

我们将它们修改为以下代码。

GEOS_DIR = F:\Work\3rdPart\geos-3.2.2

GEOS_CFLAGS = -I$(GEOS_DIR)/capi -I$(GEOS_DIR)/source/headers -DHAVE_GEOS

GEOS_LIB = $(GEOS_DIR)/source/geos_c_i.lib

代码中F:\Work\3rdPart\geos-3.2.2是GEOS存放的主目录,后面两行设置的是GEOS的头文件目录和lib文件路径,设置好后保存即可。对比结果如图1-7所示。

图1-7 GEOS配置修改

保存完nmake.opt之后,我们按照1.6.1小节中的编译方式进行编译即可。编译后的GDAL将会支持图形之间的操作,因为函数主要是在OGR库中,后面会在OGR库中进行详细说明。编译完成后,我们需将geos_c.dll文件复制到gdal18.dll的同级目录下,否则会提示找不到geos_c.dll文件。

2.集成PROJ.4

PROJ.4是一套开源的坐标投影转换库,它可以完成在两套不同制图投影系统之间的转换,或者不同的椭球体或大地基准面之间的转换。GDAL中用到的坐标转换、投影转换、几何纠正、正射纠正等算法,都需要 PROJ.4 库的支持。PROJ.4 的配置同 GEOS 库的配置方法相同,在nmake.opt文件中找到PROJ.4库的位置(1.10版本大概在429行左右),如下面的三行代码所示。

#PROJ_FLAGS = -DPROJ_STATIC

#PROJ_INCLUDE = -Id:\projects\proj.4\src

#PROJ_LIBRARY = d:\projects\proj.4\src\proj_i.lib

我们将它们修改为以下代码。

#PROJ_FLAGS = -DPROJ_STATIC

PROJ_INCLUDE = -IF:\Work\3rdPart\proj-4.7.0\src

PROJ_LIBRARY = F:\Work\3rdPart\proj-4.7.0\src\proj_i.lib

代码中第一行表示是否使用静态链接的方式,第二行表示PROJ.4库存放的路径,第三行为PROJ.4库的lib文件所在路径,修改后保存即可,对比结果如图1-8所示。

图1-8 PROJ库配置修改

同GEOS库一样,保存完nmake.opt之后,我们按照第一步中的编译方式进行编译即可。编译后,我们同样将proj.dll文件复制到gdal110.dll的同级目录下,否则与坐标转换相关的所有功能都不能使用。

3.集成HDF数据读取

通过上面GEOS和PROJ库的介绍,我们对于GDAL的配置文件nmake.opt已经有了一个初步的了解。下面使用GDAL读取HDF数据也是同样,我们先在HDF的官方网上下载编译好的HDF4和HDF5的库,然后修改配置文件进行编译。HDF官网提供了32位的库和64位的库,这里我们以HDF4.2.6和HDF5-1.8.7两个库为例介绍32位库的编译,对于64位库的编译后面会进行专门介绍。

我们将下载好的 HDF4.2.6 和 HDF5-1.8.7 两个库解压,然后在 nmake.opt 文件中,找到HDF的位置(1.10版本大概在330行左右),代码如下。

# Uncomment the following and update to enable NCSA HDF Release 4 support.

#HDF4_PLUGIN = NO

#HDF4_DIR =D:\warmerda\HDF41r5

#HDF4_LIB =/LIBPATH:$(HDF4_DIR)\lib Ws2_32.lib

# Uncomment the following and update to enable NCSA HDF Release 5 support.

#HDF5_PLUGIN = NO

#HDF5_DIR =c:\warmerda\supportlibs\hdf5\5-164-win

#HDF5_LIB =$(HDF5_DIR)\dll\hdf5dll.lib

我们将它们修改为下面的代码。

# Uncomment the following and update to enable NCSA HDF Release 4 support.

HDF4_PLUGIN = NO

HDF4_DIR =F:\Work\3rdPart\HDF4.2.6_win_x86

HDF4_LIB = $(HDF4_DIR)\dll\hd426m.lib $(HDF4_DIR)\dll\hm426m.lib \

$(HDF4_DIR)\lib\hd426.lib $(HDF4_DIR)\lib\hm426.lib Ws2_32.lib

# Uncomment the following and update to enable NCSA HDF Release 5 support.

HDF5_PLUGIN = NO

HDF5_DIR =F:\Work\3rdPart\HDF5-1.8.7_win_x86

HDF5_LIB =$(HDF5_DIR)\dll\hdf5dll.lib

代码修改前后的对比如图1-9所示。

图1-9 HDF库配置修改

保存,然后编译 GDAL 即可,同时我们将 HDF 库中的 dll 文件夹下的 dll 文件复制到gdal110.dll的同级目录下。

按照同样的方式,我们可以通过修改配置文件使GDAL支持NetCDF、Oracle等格式。

1.6.3 编译其他方面

1.makegdal_gen.bat使用

下面我们介绍怎样使用makegdal_gen.bat 文件生成Visual Studio 的工程文件。

首先我们打开 cmd 命令行窗口,使用 cd 命令切换到 GDAL 源代码目录,然后输入makegdal_gen.bat后回车,会得到该工具的一个简单实用帮助,如图1-10所示。

图1-10 makegdal_gen.bat使用说明

该工具是一个带有命令行参数的批处理工具(在后面对GDAL工具集的介绍中我们会对带有参数的命令行程序以及编写带有命令行的程序作一个详细说明),通过图1-10 可以看出其基本语法如下。

makegdal_gen 7.10 > makegdal71.vcproj

makegdal_gen 8.00 > makegdal80.vcproj

通过上面的示例我们可以看出,该工具的命令行参数分别是:VS的版本号(具体版本号参考1.6.1 小节)、一个大于号“>”、输出的VS的工程名字。如果要使用该命令行生成一个VS2008版本的工程文件,我们可以输入如下命令,回车即可。

makegdal_gen 9.00 > makegdal90.vcproj

2.编译64位系统下的GDAL

GDAL的64位系统的编译,和32位系统的编译基本相同,首先我们在VS的工程中打开配置管理器,然后在活动解决方案平台的下拉列表中选择“新建”,然后弹出“新建解决方案平台”对话框,选择新平台为x64(需要在安装VS时安装64位的编译环境),然后点击“确定”按钮,最后在VS中选择X64进行编译即可,如图1-11所示。

图1-11 GDAL 编译64位的工程配置

使用cmd 命令行编译基本同32 位的一样,区别在于在开始菜单选择的不是“Visual Studio 2008 命令提示”,而是“Visual Studio 2008 x64 兼容工具命令提示”。

在编译开始之前,我们还需要打开nmake.opt 文件,找到131 行处的“#WIN64 = YES”,将前面的“#”去掉,保存,然后开始编译。如果就这样编译通过的话,那么恭喜;如果不能顺利编译过去,那么我们需要按照下面的步骤进行设置。

1)我们在GDAL目录下的nmake.opt文件中找到SYM_PREFIX的定义,应该在438行左右;将“SYM_PREFIX = _”改为“SYM_PREFIX = ”,也就是将最后的下划线去掉。

2)在GDAL目录下的makefile.vc文件中,找到46行左右的代码,如下所示。

BASE_INCLUDE = /INCLUDE:_GDALSimpleImageWarp@36 \

/INCLUDE:_GDALReprojectImage@48 \

/INCLUDE:_GDALComputeMedianCutPCT@32 \

/INCLUDE:_GDALDitherRGB2PCT@28 \

/INCLUDE:_OCTNewCoordinateTransformation@8 $(VB6_SAFEARRAYSYM)

我们需要将它修改为如下代码。

BASE_INCLUDE = /INCLUDE:$(SYM_PREFIX)GDALSimpleImageWarp \

/INCLUDE:$(SYM_PREFIX)GDALReprojectImage \

/INCLUDE:$(SYM_PREFIX)GDALComputeMedianCutPCT \

/INCLUDE:$(SYM_PREFIX)GDALDitherRGB2PCT \

/INCLUDE:$(SYM_PREFIX)OCTNewCoordinateTransformation $(VB6_SAFEARRAYSYM)

修改完之后保存,然后重新编译生成GDAL即可。

1.7 SWIG编译

1.7.1 SWIG简介

SWIG全称是Simplified Wrapper and Interface Generator,官方网站是http://www.swig.org/。SWIG是一个开发工具,能够将使用C或者C++编写的软件与其他各种高级编程语言进行嵌入联接。SWIG能应用于各种不同类型的语言,包括常用脚本编译语言例如Perl、PHP、Python、Tcl、Ruby、PHP 等,也包括非脚本编译语言,如C#、Common Lisp (CLISP、Allegro CL、CFFI、UFFI)、Java、Modula-3、OCAML、R等。SWIG最典型的应用就是转换C/C++接口,产生高级语言需要的代码来调用 C/C++代码。SWIG 是一个免费开源软件,可以在商业或非商业中自由使用、分发、修改。

下载安装Swig的时候我们注意要下载Swigwin文件而不是下载源代码。以swigwin-2.0.4为例,我们下载swigwin-2.0.4.zip文件后解压,将解压目录也添加到环境变量Path中去,否则后面需要设置swig的所在目录。检验swig是否成功设置到环境变量Path中的最简单的办法就是在运行中输入swig后回车,如果提示windows找不到swig,那么说明没有设置成功;如果出现一个黑屏一闪而过,那么说明已经设置成功了。

下面三小节需要在安装完SWIG之后才能进行编译。需要注意的是,编译下面三种语言的GDAL之前,我们首先要编译C++版本的,就是1.6节的内容。

1.7.2 编译C#版本GDAL

首先,我们打开 nmake.opt 文件,找到 SWIG = swig.exe 这一句,假如没有将 swig 的目录添加到环境变量中,那么将这句后面的 swig.exe 修改为 swig.exe 的全路径,如F:\Work\3rdPart\swigwin-2.0.4\swig.exe;如果设置了环境变量,那么就不需要进行修改了。

然后,我们按照1.6节中的使用cmd命令编译GDAL的方式来进行编译,打开“Visual Studio2008 命令提示”并定位到 GDAL 源代码目录,然后依次执行如下三行命令,其实就是编译C++版本的GDAL。

nmake /f makefile.vc

nmake /f makefile.vc install

nmake /f makefile.vc devinstall

执行以上三句之后,接下来我们使用 cd 命令,进入 swig\csharp 文件夹中并使用 nmake工具编译,命令如下所示。

cd swig\csharp

nmake /f makefile.vc

nmake /f makefile.vc install

执行完以上两句命令后,系统会在csharp文件夹下生成8个dll文件,并将这8个dll文件复制到GDAL输出目录下的csharp文件夹中。

这8个dll分别如下。

gdal_csharp.dll

gdal_wrap.dll

gdalconst_csharp.dll

gdalconst_warp.dll

ogr_csharp.dll

ogr_wrap.dll

osr_csharp.dll

osr_wrap.dll

在C#工程中引用GDAL的时候,我们只需要把上面8个dll中后面以_csharp.dll结尾的四个dll加入到C#工程中即可。需要注意的是,在使用这几个dll的时候我们需要将gdal110.dll以及它依赖的其他dll都复制到同一个目录中,才能使C#程序正常运行。

1.7.3 编译Python 版本GDAL

在编译Python版本之前,我们要确保自己的电脑中已经安装了Python。如果我们安装了ArcGIS软件,那么就不用再安装Python了,因为在安装ArcGIS的时候必须要安装Python。将Python的bin目录添加到环境变量Path中去,然后我们就可以开始编译Python版本的GDAL了。

打开nmake.opt文件(1.10版本大概76行左右),将PYDIR后面的路径修改为本机Python的路径。

PYDIR ="C:\Python26"

修改完之后,保存nmake.opt文件。接下来使用cd命令将命令行定位到swig\python目录后,依次输入如下命令。

python setup.py build

python setup.py install

执行完上述命令后,我们会在python的site-packages目录看到多了GDAL和OGR的文件以及一个osgeo的文件夹。我们将编译出来的gdal110.dll以及它依赖的所有DLL都复制到site-packages文件夹中的osgeo 文件夹中,最后就可以在Python 中用imort gdal 来使用GDAL了。测试Python版本的gdal是否安装成功,可以使用如下Python代码。

from osgeo import gdal

from osgeo.gdalconst import *

dataset = gdal.Open("F:\Work\Data\envi.img",GA_ReadOnly)

dataset.GetDriver().ShortName

#'ENVI' #图像格式

dataset.GetProjectionRef()

#'PROJCS["unnamed",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHERO ID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4269"] ],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",30],PARAMET ER["central_meridian",-84.16666666666667],PARAMETER["scale_factor",0.9999],PAR AMETER["false_easting",2296587.926509186],PARAMETER["false_northing",0],UNIT["Foot (International)",0.3048]]' #图像投影信息

1.7.4 编译Java 版本GDAL

在编译Java版本的GDAL时,除SWIG之外,我们还需要JRE和Ant这两个工具,没有的话需要先下载安装,其中 ANT 只需直接解压,不用安装。接下来我们用记事本打开nmake.opt,找到第86行左右位置(1.10版本),将文件中的JAVA_HOME和ANT_HOME修改为本机的路径,只要修改到主文件夹即可(就是bin文件夹所在的文件夹);如果文件夹路径有空格的话,把路径用双引号引起来,修改后的内容与以下代码类似。

# SWIG Java settings

!IFNDEF JAVA_HOME

JAVA_HOME = "C:\Program Files\Java\jdk1.6.0_26"

!ENDIF

!IFNDEF ANT_HOME

ANT_HOME = F:\Work\GDAL\gdal_need\apache-ant-1.8.4

!ENDIF

JAVADOC = $(JAVA_HOME)\bin\javadoc

JAVAC = $(JAVA_HOME)\bin\javac

JAVA = $(JAVA_HOME)\bin\java

JAR = $(JAVA_HOME)\bin\jar

JAVA_INCLUDE = -I$(JAVA_HOME)\include -I$(JAVA_HOME)\include\win32

修改保存之后,我们就可以编译 Java 版本的 GDAL 了,首先还是要先编译 C++版本的GDAL,然后使用cd命令切换到swig文件夹中,开始编译Java版本GDAL。

nmake /f makefile.vc

nmake /f makefile.vc install

nmake /f makefile.vc devinstall

cd swig

nmake /f makefile.vc java

正常情况下,执行完上面的命令后Java版本的GDAL应该就编译完成了。编译出来的文件存放在swig\java目录中,主要有以下五个文件。

gdalconstjni.dll

gdaljni.dll

ogrjni.dll

osrjni.dll

gdal.jar

如果目录中有上面的五个文件,那就说明编译成功,如果没有,则要根据命令行编译的输出信息排除错误重新生成。我们将上面五个文件以及编译GDAL时生成的gdal110.dll复制到一个新建的文件夹,用于Java程序调用。

1.8 GDAL帮助文档生成

1.8.1 Doxygen 简介

Doxygen是生成C++注释文档的标准工具,也支持其他语言,如C、Objective-C、C#、PHP、Java、Python、IDL (Corba and Microsoft flavors)、Fortran、VHDL、Tcl 等。

我们可以通过三种方式来使用Doxygen。

1.从源文件中以HTML形式生成在线文档浏览器,或者以LATEX形式生成非在线的参考手册,也支持RTF (MS-Word)、PostScript、超链接PDF、压缩HTML 等格式。注释文档是直接从源文件中提取的,这样可以保持与源代码的一致性。

2.安装Doxygen从源文件中提取代码结构。Doxygen也可以通过依赖图、继承图等将不同元素之间的关系可视化显示出来,这些图都是自动生成的。但是生成这些图需要借助另外一个强大的开源库Graphviz(Graph Visualization Software)。Graphviz 是一个由AT&T 实验室启动的开源工具包,用于绘制DOT语言脚本描述的图形,官方网站是http://www.graphviz.org/。

3.可以用Doxygen来创建标准文档。

Doxygen 是免费软件,其发布遵守GNU General Public License。Doxygen是在Mac OS X和 Linux 平台开发的,但是具有很高的移植性,在大多数类 Unix 平台上可以运行,也支持Windows系统。

1.8.2 生成GDAL 开发帮助文档

首先我们下载安装Doxygen和Graphviz,安装完之后最好将Doxygen和Graphviz的bin目录添加到系统环境变量Path中去,否则需要设置一些参数,比较麻烦。

安装完 Doxygen 后,在开始菜单中有个 doxywizard.exe 的程序,我们打开程序然后在“File->Open…”菜单中选择GDAL源代码目录下的Doxyfile文件,然后切换到“Run”标签,点击Run Doxygen 按钮,如图1-12所示。

图1-12 Doxygen界面

接下来系统就会自动提取源代码中的注释生成一份GDAL的帮助文档,默认的输出目录是GDAL 目录下的html 目录;生成结束后,点击左下角的Show Html Output按钮就可以打开生成的帮助文档。

这样生成的帮助文档和GDAL的官方网站一模一样,但这里生成的只是GDAL的帮助文档,没有 OGR 的帮助文档。同样按照上述步骤,我们打开 GDAL 目录下 OGR 文件夹下的Doxyfile,然后点击“生成”,生成的目录默认为ogr文件夹下的html文件夹。我们将该文件夹重命名为ogr,全部复制到上一层的html中,同时将GDAL目录中的doc文件夹中除dox文件以外的文件全部复制到html文件夹中,然后将编译GDAL后生成的html文件夹的内容与 ogr 文件夹进行合并,就可以得到一份完整的 GDAL 帮助文档,首页是 html 文件夹下的index.html,如图1-13所示。

图1-13 Doxygen生成的GDAL 帮助

1.9 简单的调用

关于GDAL的使用,关键是要熟悉GDAL的组织结构、类以及类的函数等。最常用的就是动态库的GDAL,当然我们也可以使用静态库,这里只是简单地介绍使用动态GDAL库来做开发。

下面我们简单地使用C++、C#、Python 和Java 4 种语言分别进行示例,来说明如何使用GDAL进行开发。

1.9.1 C ++使用GDAL

首先我们打开Visual Studio2008,新建一个Win32的控制台工程(名字叫GDALCppTest),然后在工程的属性对话框中,找到“配置属性”→“C/C++”→“常规”,在右侧的“附加包含目录”中将GDAL的include文件夹路径填写到输入框,如图1-14所示。

图1-14 Visual Studio C ++使用GDAL 头文件配置

我们继续在属性对话框中找到“配置属性”→“链接器”→“常规”,在右侧的“附加库目录”中将GDAL的lib文件夹路径填写完整,如图1-15所示。

图1-15 Visual Studio C++使用GDAL 库文件配置

最后在“配置属性”→“链接器”→“输入”,在右侧的“附加依赖项”中将 gdal_i.lib填写完整。然后点击“确定”按钮即可。至此,使用GDAL的环境全部搭建完成,剩下的就是在代码中使用GDAL了。

我们将以下代码复制到刚才新建工程中的 cpp 文件中,保存后编译。正常情况下系统会提示生成成功,然后我们将GDAL编译出来的gdal110.dll及其依赖的dll文件复制到编译出来的exe所在目录,最后运行,会在控制台上输出图像的一些信息。

#include "gdal_priv.h"

int main()

{

//注册文件格式

GDALAllRegister();

const char* pszFile = "C:\\Test.img";

//使用只读方式打开图像

GDALDataset *poDataset = (GDALDataset*) GDALOpen( pszFile, GA_ReadOnly );

if( poDataset == NULL )

{

printf( "File: %s不能打开!\n",pszFile);

return 0;

}

//输出图像的格式信息

printf( "Driver:%s/%s\n",

poDataset->GetDriver()->GetDescription(),

poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME) );

//输出图像的大小和波段个数

printf( "Size is%dx%dx%d\n",

poDataset->GetRasterXSize(),poDataset->GetRasterYSize(),

poDataset->GetRasterCount());

//输出图像的投影信息

if( poDataset->GetProjectionRef() != NULL )

printf( "Projectionis `%s'\n", poDataset->GetProjectionRef() );

//输出图像的坐标和分辨率信息

double adfGeoTransform[6];

if( poDataset->GetGeoTransform( adfGeoTransform) == CE_None )

{

printf( "Origin =(%.6f,%.6f)\n",

adfGeoTransform[0], adfGeoTransform[3]);

printf( "PixelSize = (%.6f,%.6f)\n",

adfGeoTransform[1], adfGeoTransform[5]);

}

//读取第一个波段

GDALRasterBand *poBand = poDataset->GetRasterBand( 1 );

//获取该波段的最大值最小值,如果获取失败,则进行统计

int   bGotMin, bGotMax;

double  adfMinMax[2];

adfMinMax[0] = poBand->GetMinimum( &bGotMin);

adfMinMax[1] = poBand->GetMaximum( &bGotMax);

if( ! (bGotMin&& bGotMax) )

GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);

printf( "Min=%.3fd,Max=%.3f\n", adfMinMax[0], adfMinMax[1] );

int nXSize = poBand->GetXSize();

float *pafScanline = new float[nXSize];

//读取图像的第一行数据

poBand->RasterIO(GF_Read, 0, 0, nXSize,1, pafScanline, nXSize,1, GDT_Float32, 0, 0 );

delete []pafScanline;

//关闭文件

GDALClose((GDALDatasetH)poDataset);

}

执行的结果如图1-16所示。

图1-16 C++使用GDAL 的运行结果

1.9.2 C#使用GDAL

我们首先打开 Visual Studio 2008,新建一个 Visual C#的控制台应用程序(名字叫GDALCSTest),然后在工程的“引用”点击右键,打开“添加引用”对话框,找到浏览标签页,将GDAL以_cshrp.dll结尾的四个dll添加到工程中,如图1-17所示。

图1-17 C#使用GDAL 引用配置

接下来我们将下面的代码复制到刚才新建工程中的Program.cs文件中,保存后编译。正常情况下系统会提示生成成功,然后我们将GDAL编译出来的gdal110.dll及其依赖的dll文件复制到编译出来的exe所在目录,最后运行,会在控制台上输出图像的一些信息。

需要值得注意的是,在64位的系统下,如果GDAL编译的时候是32位的,那么选择编译C#工程的时候,我们要使用X86编译才能正常运行,否则会报错。

using System;

using OSGeo.GDAL;

using OSGeo.OSR;

namespace GDALCSTest

{

class Program

{

static void Main(string[] args)

{

Console.WriteLine("");

try

{

//注册文件格式

Gdal.AllRegister();

string strFile = "F:\\Work\\GDAL 源码剖析\\GDALTest\\Test.tif";

//使用只读方式打开图像

Dataset ds = Gdal.Open(strFile, Access.GA_ReadOnly);

if (ds == null)

{

Console.WriteLine("不能打开:" + strFile);

System.Environment.Exit(-1);

}

Driver drv = ds.GetDriver();

if (drv == null)

{

Console.WriteLine("Can't get driver.");

System.Environment.Exit(-1);

}

//输出图像的格式信息

Console.WriteLine("Dirver :" + drv.GetDescription());

Console.WriteLine("Using driver " + drv.LongName);

//输出图像的大小和波段个数

Console.WriteLine(" RasterCount: " + ds.RasterCount);

Console.WriteLine(" RasterSize (" + ds.RasterXSize + "," + ds.RasterYSize + ")");

//输出图像的投影信息

Console.WriteLine(" Projection: " + ds.GetProjectionRef());

//输出图像的坐标和分辨率信息

double[] adfGeoTransform = new double[6];

ds.GetGeoTransform(adfGeoTransform);

Console.WriteLine("Origin =(" + adfGeoTransform[0] + "," + adfGeoTransform[3] + ")");

Console.WriteLine("PixelSize = (" + adfGeoTransform[1] + "," + adfGeoTransform[5] + ")");

Console.WriteLine("");

//读取第一个波段

Band band = ds.GetRasterBand(1);

double val;

int hasval;

band.GetMinimum(out val, out hasval);

if (hasval != 0)

Console.WriteLine(" Minimum: " + val.ToString());

band.GetMaximum(out val, out hasval);

if (hasval != 0)

Console.WriteLine(" Maximum: " + val.ToString());

int nXSize = ds.RasterXSize;

float[] pafScanLine;

pafScanLine = new float[nXSize];

band.ReadRaster(0,0, nXSize, 1, pafScanLine, nXSize, 1, 0, 0);

}

catch (Exception e)

{

Console.WriteLine("Application error: " + e.Message);

}

}

}

}

1.9.3 Python 使用GDAL

在使用Python版本GDAL之前,我们首先要确保GDAL的Python版本安装成功,否则无法按照下面的步骤进行安装。

按照1.7.3小节的python编译步骤进行编译,之后我们将GDAL所有的dll文件复制到python版本的GDAL安装目录中,如图1-18所示。

图1-18 Python使用GDAL 的安装路径

接下来我们使用记事本等工具,将以下代码复制进去,保存为GDALPythonTest.py。

from osgeo import gdal

from osgeo.gdalconst import *

gdal.AllRegister()

#使用只读方式打开图像

ds = gdal.Open("F:\Work\GDAL 源码剖析\GDALTest\Test.tif",GA_ReadOnly)

#输出图像的格式信息

print ds.GetDriver().ShortName

#输出图像的大小和波段个数

print ds.RasterXSize

print ds.RasterYSize

print ds.RasterCount

#输出图像的投影信息

print ds.GetProjectionRef()

#输出图像的坐标和分辨率信息

adfGeoTransform = ds.GetGeoTransform()

print adfGeoTransform[0]

print adfGeoTransform[3]

print adfGeoTransform[1]

print adfGeoTransform[5]

band = ds.GetRasterBand(1)

#读取图像的第一行数据

data = band.ReadRaster( 0, 0, ds.RasterXSize, 1,

ds.RasterXSize, 1, band.DataType )

我们在开始菜单中的Python 目录中打开“IDLE(Python GUI)”,在弹出的程序中,使用文件菜单中的打开命令打开刚才保存的GDALPythonTest.py文件,如图1-19所示,然后按“F5”运行,即可输出影像的一些信息,如图1-20所示。

图1-19 Python GUI 打开GDALPythonTest.py
图1-20 运行GDALPythonTest.py 输出的结果

1.9.4 Java 使用GDAL

Java使用GDAL,这里使用的IDE是Eclipse。我们使用Eclipse新建一个工程,名字叫GDALJavaTest,然后在这个工程中新建一个名为GDALTestApp的类,打开GDALTestApp.java,将里面的代码修改为以下代码内容,然后保存,如图1-21所示。

图1-21 Eclipse 使用GDAL

import org.gdal.gdal.Band;

import org.gdal.gdal.Dataset;

import org.gdal.gdal.Driver;

import org.gdal.gdal.gdal;

import org.gdal.gdalconst.gdalconstConstants;

public class GDALTestApp {

/**

* @param args

*/

public static void main(String[] args)

{

gdal.AllRegister();

String fileName_tif = "F:\\Work\\GDAL源码剖析\\GDALTest\\Test.tif";

//使用只读方式打开图像

Dataset hDataset = gdal.Open(fileName_tif, gdalconstConstants.GA_ReadOnly);

if (hDataset == null)

{

System.err.println("GDALOpen failed - " + gdal.GetLastErrorNo());

System.err.println(gdal.GetLastErrorMsg());

System.exit(1);

}

//输出图像的格式信息

Driver hDriver = hDataset.GetDriver();

System.out.println("Driver: " + hDriver.getShortName() + "/" +hDriver.getLongName());

//输出图像的大小和波段个数

int iXSize = hDataset.getRasterXSize();

int iYSize = hDataset.getRasterYSize();

int iBandCount = hDataset.getRasterCount();

System.out.println("Size is " + iXSize + ", " + iYSize + "," +iBandCount);

Band band = hDataset.GetRasterBand(1);

int itype = band.GetRasterDataType();

System.out.println(itype + "\n");

//读取一行数据

int buf[] = new int[iXSize];

band.ReadRaster(0, 0, iXSize, 1, buf);

hDataset.delete();

// 可选

gdal.GDALDestroyDriverManager();

}

}

我们将之前编译Java版本GDAL时生成的五个文件(dll和jar文件)复制到工程所在文件夹中,然后点击“工程”右键,选择“Build Path->configure build path”,弹出“属性”对话框,然后切换到“libraries”标签,点击“Add Jars…”,选择 gdal.jar 和名字中有 ini 的 dll文件,添加到lib中,如图1-22所示,然后确定,编译运行即可。

图1-22 Eclispe 配置GDAL

1.9.5 调试GDAL 源代码

很多时候我们需要查看GDAL的源代码以了解它的内部实现,为了更好地理解源代码,可以通过调试查看源代码中变量的内容。

调试GDAL的源代码,需要GDAL的debug版本以及编译GDAL的时候生成的pdb等调试文件。此外我们也可以把GDAL的源代码加入到自己的工程中,但是这样太费时费力。

这里介绍一个很简单的方法:首先编译一下GDAL的debug版本(具体步骤可以参考1.6节的内容),将编译生成的文件(主要有gdal110.dll,gdal_i.exp,gdal_i.lib,gdal.lib,gdal110.pdb, gdal110.ilk,gdal110.exp等)复制到自己工程的生成目录中,然后调试自己的程序,在执行到GDALOpen函数(或者其他GDAL的函数)时按“F11”键,就可以进入到GDAL的源代码中进行调试。

对于使用C#语言来说,也可以跨语言来对GDAL进行调试。首先我们要确保GDAL库编译时使用debug版本,同时编译的C#版本也是debug版本。在执行调试时我们需要将GDAL的C#版本中八个dll文件及其对应的pdf等文件全部复制到测试程序输出目录,然后在测试目录的属性中勾选“启用非托管代码调试”,最后启动,按“F11”键即可进入GDAL源码。

图书在版编目(CIP)数据

GDAL源码剖析与开发指南/李民录著.--北京:人民邮电出版社,2014.3

ISBN 978-7-115-33899-0

Ⅰ.①G… Ⅱ.①李… Ⅲ.①数据转换—源代码—指南 Ⅳ.①TP274-62②TP311.52

中国版本图书馆CIP数据核字(2013)第284140号

内容提要

GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。由于GDAL库支持很多的数据格式,目前几乎所有的GIS和RS软件底层都使用GDAL来读写空间数据。

本书是基于GDAL源码剖析的编程开发指南,共9章,分为三部分。第一部分是前5章,介绍了GDAL的基本功能,包括GDAL简介、ORG库、GDAL库以及GDAL的数据格式和配置项等;第二部分是第6章到第8章,是GDAL的高级使用说明,包括GDAL格式扩展、GDAL算法和CPL库;第三部分是第9章,介绍GDAL工具的使用。

本书适合地理信息系统和遥感等相关专业应用的开发人员阅读参考。本书中大部分的示例代码都是使用C/C++语言编写,有一定C/C++语言基础的读者能够快速上手开发相关应用。

◆著 李民录

责任编辑 陈冀康

责任印制 程彦红 杨林杰

◆人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

三河市海波印务有限公司印刷

◆开本:800×1000 1/16

印张:40.25

字数:781千字  2014年3月第1版

印数:1-3000册  2014年3月河北第1次印刷

定价:89.00元

读者服务热线:(010)81055410 印装质量热线:(010)81055316

反盗版热线:(010)81055315

相关图书

GeoTools 地理信息系统开发
GeoTools 地理信息系统开发
Python地理空间分析指南(第2版)
Python地理空间分析指南(第2版)

相关文章

相关课程