目录

上一个主题

2. 使用 GDAL 操作栅格数据

下一个主题

2.2. Python与开源GIS:开始使用GDAL

关注公众号


常见问题

  1. Windows下的安装说明
  2. Jupyter免费在线实验环境
  3. 勘误与补充


>>> # from helper import info; info()

2.1. GDAL简介

GDAL 是读写大量的栅格空间数据格式的广泛应用的开源库。该库起源于 1998年,已经大幅进化。 它支持他自己的数据模型和应用程序接口(API)。 从最初的单一发展的起源,GDAL已发展成为一个分布式的项目,开发人员的数量相对比较大。

对于 GDAL 的 概 念,可能会稍微有些混乱。 GDAL 是 Geospatial Data Abstraction Library 的缩写, 最开始的时候是一个用来处理栅格空间数据的类库,OGR 则是则是来处 理矢量数据的。 后来,这两个库合并成为合并成为一个,在下载安装的时候,都是使用GDAL 这一个名字。 因为历史的原因,两大类库是用同样一个生成系统进行维护的, 最重要的是 GDAL/OGR 的作者是同一人,该人目前也是 OSGeo 的会长 Frank Warmerdam,其在OpenSource Geospatial 领域早已大名鼎鼎。 许多程序员都是拜读他的代码理解空间信息软件精髓的。

数据是软件的血液,空间信息产业更是如此,海量数据在空间信息软件行业体现的最为明显, 没有一套高效率的数据转换模型和类库很难完成异构数据的集成和融合,正是有了 GDAL/OGR,构建在其之上的各类空间信息软件项目才有了生命力。

GDAL/OGR 使用面向对象的 C++ 语言编写,这令该库在支持百余种格式的同时,还具有很高的执行效率。 GDAL/OGR 同时还提供多种主流编程语言的绑定,除了 C 和 C++语言之外,用户还可以在 Perl、python、VB6、Ruby、Java、C# 等语言中调用 GDAL,这令 GDAL 的应用变得非常广泛。GDAL 项目维护了使用 SWIG 生成的 Python 的 GDAL/OGR 绑定。 总体看,Python 中的类与方法与C++的类大体上匹配。 在最新版的 GDAL 1.9.0 中,GDAL 支持超过 120 种栅格数据格式,而在下一版本中,支持的数据格式会达到 200 种。 在 GDAL 缺省的编译选项设置下,一部分数据格式直接创建文件,并对他们进行几何配准。

由于 GDAL 对多种栅格数据格式都提供了支持,很多软件都使用它作为底层数据处理的库。 这其中比较有名的有:ArcGIS、Google Earth、OpenEV、GRASS GIS、OSSIM、Quantum GIS、MapServer、World Wind.

2.1.1. GDAL数据模型

GDAL数据模型包括很多部分,每一部分都支持上述的库的基本设计理念。这些部分在下面的章节讨论。

在GDAL模型里面,重要的有三个概念:数据集、栅格波段与颜色表。 其中数据集、栅格波段与 颜色表则与GIS的概念无关,只是定义了栅格数据如何以颜色进行显示的。

GDAL数据集

一个数据集(GDAL数据集类为代表)是相关的栅格波段的和一些相关的信息的集合。 该数据集栅格大小适用于所有的波段。 该数据集还负责所有波段的地理参考定义和坐标系统定义。 数据集本身也有相关联的元数据,以字符串的形式存储在名称/值列表中,具体如下。

GDAL数据集和栅格波段数据模型是基于OGC格式定义的。

坐标系统

GDAL数据集坐标系统以OGC WKT字符串表示。包含:

  • 坐标系统全名

  • 地理坐标系统名称

  • 基准面

  • 椭球名,半长轴,反偏率

  • 本初子午线的名称和从格林尼治的offset

  • 投影方法的类型(例如横轴墨卡托)

  • 投影参数列表(例如中央子午线)

  • 测量单位的名称,转换成米或弧度。

  • 轴线的名称和顺序。

上述预定义的坐标系统方面大部分代码来自欧洲石油调查组(EPSG)( http://www.epsg.org/ )。

一个空的坐标系统字符串表示不知道正在使用的地理参考坐标系统是什么。

2.1.2. 仿射地理转换

GDAL数据集在表示栅格位置(像素或者是行坐标)和地理参考坐标之间的关系有两种方法。 最常使用的仿射变换。 仿射变换包括六个参数,由GDALDataset::GetGeoTransform()返回, 采用下面的关系把像素/行坐标转换到地理参考空间:

\[\begin{split}Xgeo = GT(0)+Xpixel{\cdot}GT(1)+Yline{\cdot}GT(2) \\\\ Ygeo = GT(3)+Xpixel{\cdot}GT(4)+Yline{\cdot}GT(5)\end{split}\]

在“向北”的图像中,GT(2) and GT(4) 系数为0, GT(1) 是像素宽度, GT(5) 是像素高度。 (GT(0),GT(3)) 位置是栅格左上角像素的左上角。

请注意,上面的像素/行坐标是从左上角像素的左上角 (0.0, 0.0) 到右下角像素的右下角。 例如,左上角像素的中心位置是 (0.5, 0.5) 。

2.1.3. 地理控制点

GDAL描述栅格数据集地理参考的其中一种方法是使用地理控制点(GCP)。 使用这种方法,一个数据集将会有一套控制点,关联栅格位置和地理参考系统的一个或者多个位置。 所有的控制点共享一个地理参考坐标系统(由GDALDataset::GetGCPProjection()返回)。 每个控制点(GDAL-GCP类描述)包括下面的部分(C语言中):

  • Char pszId

  • Char pszInfo

  • double dfGCPPixel

  • double dfGCPLine

  • double dfGCPX

  • double dfGCPY

  • double dfGCPZ

pszid字符串是数据集中控制点集中GCP的唯一标识符(通常但非总是数值)。 通常pszinfo是一个空串,但可以包含任何与控制点相关的用户定义的文本。 潜在的,这也可以包含对GCP状态机的机器可分析信息, 虽然这是个功能目前尚未实现。像素,线的位置是控制点在栅格的位置。 X,Y,Z的位置是相关的地理参考位置(Z值往往是零)。

GDAL数据模型并不意味着转换机制必须从控制点产生, 而是留给应用程序。 然而,1到5阶多项式是常用的方法。 通常情况下,数据集包含仿射变换或者地理控制点或者都不包含。 两者都有的情况是比较少的,还没有确定哪种方法更权威一些。

2.1.4. 元数据

GDAL的元数据是辅助的格式,应用程序特定的文本数据保存为名称/值对列表。 名称需要标记好(没有空格或者奇怪的字符)。 值可以是任意长度,可以包含除了嵌入的null(ASCII0)之外的任何值。

一些格式支持一些用户定义的的元数据, 而其他格式的驱动器将会把特殊格式的字段映射到元数据名称中。 例如,TIFF驱动器会返回一些信息标签,因为元数据包括日期/时间字段,是这样返回的:

TIFFTAG DATETIME=1999:05:11 11:29:56

元数据还可以被分成成为域的组,默认的域没有名称(NULL或者 "")。 一些具体的域的存在是有特殊目的的。 需要注意的是,虽然目前没有办法列举给定对象的所有域, 但是程序可以测试任何它们知道如何解释的域。一个例子就是SUBDATASETS域,在下节讲述。

2.1.5. 子数据集域

子数据集域包含一系列的子集。 通常这是用来提供那些多图像文件(HDF或者NITF)存储的图像序列的指针。 例如,一个含有四副影像的NITF可能含有下面的子集列表:

SUBDATASET_1_NAME=NITF_IM:0:multi_1b.ntf
SUBDATASET_1_DESC=Image 1 of multi_1b.ntf
SUBDATASET_2_NAME=NITF IM:1:multi_1b.ntf
SUBDATASET_2_DESC=Image 2 of multi_1b.ntf
SUBDATASET_3_NAME=NITF IM:2:multi_1b.ntf
SUBDATASET_3_DESC=Image 3 of multi_1b.ntf
SUBDATASET_4_NAME=NITF IM:3:multi_1b.ntf
SUBDATASET_4_DESC=Image 4 of multi_1b.ntf
SUBDATASET_5_NAME=NITF IM:4:multi_1b.ntf
SUBDATASET_5_DESC=Image 5 of multi_1b.ntf

以NAME结尾的字符串可以传递到GDALOpen()来访问这些文件。 以DESC结尾的值是用户友好的字符串,可以向用户显示一个选择的列表。

2.1.6. 栅格波段

GDAL栅格波段的表达是用GDALRasterBand类。 它代表一个栅格波段,通道或者是层。 它通常不代表一整幅影像。 例如一个24位的RGB图像通常被表示为三个波段,红、绿、蓝。一个栅格波段具有以下属性:

  • 像元的高度、宽度和行数。如果是全分辨率波段的话,数据集的定义是相同的。

  • 数据类型(GDALDataType)。一个字节,UInt16, Int16, UInt32, Int32, Float32,Float64, 复杂类型 CInt16, CInt32, CFloat32, and CFloat64。

  • 块大小。这是首选的访问块大小。对于平铺的图像这是一片。对于扫描线图像,这通常是一个扫描线。

  • 元数据的名称/值对列表和数据集是相同的格式,但是信息是针对每个波段的。

  • 可选的描述字符串。

  • 可选的类别名称列表(主题图像的有效类名)。

  • 可选的最大值和最小值。

  • 可选的偏移量和把栅格值转化为有意义的值的尺度(例如,转换高度为米)。

  • 栅格单位的名称。例如高程数据可能是线性单位。

  • 波段的颜色解释。这可以是未定义的,灰色的,调色板索引, 红,绿,蓝, α ,色调,饱和度明度,青色,洋红色,黄色和黑色。

  • 一个颜色表,在下一节中详细介绍。

  • 降低分辨率概述(金字塔)的知识,如果可用。

2.1.7. 颜色表

一个颜色表包含0个或者多个颜色,在C代码中用结构表示:

  • short C1; /* 灰色,红色,青色或色调 */

  • short C2; /* 绿色,洋红,或轻盈 */

  • short C3; /* 蓝色,黄色,或饱和 */

  • short C4; /* αblackband */

颜色表中显示了一个调色板解释值(GDAL PaletteInterp), 是下面的值之一,表示颜色表中的值如何解释。值是灰色,RGB,CMYK和HLS。

让栅格像素与颜色相连,像素值被用作颜色表的下标。这意味着,颜色总是从零开始,升序。在查看颜色表之前没有提供预调整机制。

2.1.8. 快视图

一个波段可能含有一个或者多个快视图(Overviews)。 每个都代表一个相对独立的GDALRasterBand。 快视图的大小与底层的栅格不同, 但是快视图的地理区域参考和全分辨率波段是相同的。 Overviws能够更快速的展示较低分辨率降的图像, 相比读取全分辨率图像然后再采样要快得多。

2.1.9. 设计理念

GDAL的起源是高效灵活的文件格式转换的需要, GDAL将扩展引入到新的格式, 也没有排除任何具体的设计决策经常遇到的空间数据格式。 因此,设计目的一开始是通过一个统一的抽象数据模型和正在审议的标准, 或者由组织发布,如放地理空间联盟(OGC),实现无处不在的覆盖。 这些和其他的设计原则将在下面的章节讨论。

2.1.10. 一个统一的抽象数据模型

在PCI与GDB的经验中学到的一个重要的教训是要有一个实施GDAL定义良好的抽象数据模型。 对于GDAL,这是一个抽象的模型: 可能包括栅格数据集,即像素数据类型,元数据模型,颜色模型,地理参考机制等等。

然而不是所有的数据格式驱动程序都能落实抽象数据模型的各个方面, 而是数据模型本身应用到所有格式适合的数据集的广义虚拟模型, 数据模型将在下接中有更详细的介绍。

2.1.11. 配合开放地理空间联盟

在实际的情况下,GDAL采用OCG标准一致。由于OGC未指定C++ API标准, 所以通常没有采取直接实施OGC规范的形式, 而是采用调整后的OGC数据模型和数据类型:

OGC简单要素几何:OGC简单特征规范,如SQL简单特征, 描述了一个地理信息系统(GIS)向量几何以及众所周知的文本(WKT的) 还有熟知的二进制(WKB)编码模型。

OGC的空间参考系统:OGC简单的特点也描述一个WKT机制, 用于描述坐标或投影系统。 这种表示被GDAL采用,作为其坐标系统的内部表示。 这个标准和ESRI的shapefile.Prj文件的投影引擎字符串是相似的。

网格覆盖范围:OGC网格覆盖规范中为栅格数据集定义了一个模型。 在一定程度上,它被用来作为在GDAL API方面的典范。 GetCategoryNames的getOffset()GetScale()GetColorInterpretation() 方法可以追溯到OGC覆盖规范。

2.1.12. 零配置 - 点和开放

从GDB经验中得到的进一步设计师尝试和确保数据集的开放式尽可能简单。 特别是,用户不应该事先就知道文件的格式,或者是在打开数据集之前就需要设置选项。 应该是很简单的,就像选择一个文件,然后看看它是否能被软件识别。

在GDAL中,是这样进行的,它有一系列的格式驱动器,每个(按顺序)都用来尝试打来一个数据集。 首次成功的就用来打开文件。 个别的驱动可能通过文件头公认的字符串、 扩展名或者某些情况下嵌入到数据集的特殊前缀来识别格式。 然而,关键的一点是,用户通常可以使用菜单中“文件>打开”的方式打开文件, 用户可能对要打开的文件没有先验知识。