1. 概述
数字化地图、卫星影像和航空影像等图像文件可以采用不同的格式,为了在 GIS 软件中能够使用此类图像,就必须包含地理配准信息。对于许多图像类型(例如:TIFF 和 JPEG),地理配准信息包含在额外的文件中,例如:.tfw 文件或者 .jfw 文件。
GeoTIFF,英文全称是 Geographic Tagged Image File Format,是开放地理空间联盟(Open Geospatial Consortium, OGC)实施标准,是 TIFF 的一种扩展,用作地理参考栅格图像的交换格式,航空图像、卫星图像、数字高程模型等都是 GeoTIFF 文件的一些示例。GeoTIFF 在 TIFF 的基础上定义了一些 GeoTag(地理标签),从而实现对各种坐标系统、椭球基准、投影信息等进行定义和存储,使得图像数据和地理数据存储在同一图像文件中。
GeoTIFF 文件可能附带其他文件:
- *.tfw 文件:提供地理位置,但绝大多数情况下不再需要该文件
- *.xml 文件:GeoTIFF 文件的元数据,大多出现在原始影像中
- *.aux 文件:存储投影和其他信息的辅助文件
- *.ovr:金字塔文件,可以提供影像文件的显示速度
2. TIFF 和 JPEG 图像文件存储地理配准信息的方式
以 JPEG 图像文件为例
在光学原始卫星影像中,一般都会提供*.jpw
文件,以 GF1B_PMS 原始影像为例,它除了提供<文件名>_MUX.tiff
文件以外,也提供了<文件名_MUX.jpg>
、<文件名_MUX.jpw>
文件。如果在 ArcMap 中依次打开 TIFF 文件和 JPG 文件,你会发现,它们基本可以重合在一起;如果删除<文件名>_MUX.jpw
文件,则会发现 JPG 文件不能正确的定位。
打开 JPW 文件,其内容如下:
0.000299184071201538
-0.0000585703287133816
-0.0000639702633068812
-0.000272718634182381
105.020989957873
24.9829246988689
其中:
2.1 原始卫星影像
光学遥感原始卫星影像压缩包中 TIFF 文件通常不是 GeoTIFF 格式而是一张单纯的 TIFF 图像,不同厂家的卫星存储坐标信息的文件格式也是不同的,例如,对于高分系列,通常是从 rpb 或者 rpc 文件中读取坐标信息,其中,对于高分6号卫星影像,TIFF 文件中包含了一些无效的位置信息,但准确的位置信息还是在 rpb 文件中;而对于 Landsat 5 是从 *_GCP.txt 文档中读取坐标信息的。
3. GeoTFF 文件结构
GeoTIFF 文件结构与 TIFF 文件结构是一致的,GeoTIFF 特定信息都编码在集合额外的保留的 TIFF TAG 中,主要包括了 GeoKeyDirectoryTag、GeoDoubleParamsTag、GeoAsciiParamsTag。
3.1 GeoKeyDirectoryTag
TIFF TAG 值为34735,对应的数据类型为 SHORT,值的个数:至少4个
GeoTIFF 文件将投影参数保存在一组“键”中,这些键在功能上与 TIFF TAG 几乎相同,与 TAG 一样,一个键有一个 ID,范围从0~65535。为了节省 TIFF 预留的标签资源,GeoTIFF 使用了 GeoKeys 来组织众多空间参数,所有的 GeoKeys 由 GeoKeyDirectoryTag 来索引。
GeoKeyDirectoryTag 又可成为 ProjectionTag、CoorSystemInfoTag,主要用于存储 GeoKey 目录,该目录定义和引用了 GeoTIFF 中的键(也称为 GeoKeys)。该标签的值是一个无符号 SHORT 类型的数组,前4个值是特殊的,它们构成了 GeoKey 目录头的基本信息,按顺序由以下信息组成:
- KeyDirectoryVersion:表示键的实现版本号,并且只有当前 TAG 的键的结果发生变化时值才会更改,当前这个值为1,可能永远不会改变,并且用来确保这是一个有效的键的实现。
- KeyRevision、MinorRevision:表示使用的键集(Key-Sets)的修订版本。
- NumberOfKeys:表示键的数目
GeoKeyDirectorTag 后面紧跟着NumberOfKeys
个键条目(Key Entry),每个条目由4个值组成:
- KeyID:键对应的 ID,在功能上与 TIFF TAG 的 ID 相同,但是完全独立于 TIFF TAG 空间。
- TIFFTagLocation:表示哪个 TIFF 标签包含键的值。如果值为0,则表示该值类型为 SHORT,并且包含在 ValueOffset 条目中。否则,该值的类型(格式)为包含该值的 TAG 的 TIFF 类型指定。
- Count:表示当前键中的值的数量
- ValueOffset:如果 TIFFTagLocation 为0,则 ValueOffset 的值就是当前键的值(只有1个)。如果 TIFFTagLocation 不为0,则 ValueOffset 的值表示索引偏移量。这里的偏移是在在 TIFFTagLocation 指定的 TAG 的值的偏移量,具体可以查看3.4小节的示例。
在 Key-Entry 定义之后,GeoKeyDirectoryTag 还可以包含其他的值。例如,如果一个键需要多个 SHORT 值,则可以将它们放在当前 TAG 的末尾,并且将 Key-Entry 的 TIFFTagLocation 设置 GeoKeyDirectoryTag,将 ValueOffset 指向值的位置。
GeoKeyDirectoryTag 中的 Key-Entry 仅存储 SHORT 类型的键值,所有的非 SHORT 类型的键值都将根据其格式存储在 GeoDoubleParamsTag 或者 GeoAsciiParamsTag 标签中。
另外,该标签中如何存储 Key-Etnry 也是有要求的。TIFF 规范要求 TAG 按照对应的 ID 排序顺序写入文件,目的是为了避免在读取和写入过程中出现耗时的排序操作。为了遵循 TIFF 的理念,生成 GeoTIFF 文件时应将 GeoKey 条目按照键的排序顺序存储在 GeoKeyDirectoryTag 中。
3.1.1 键ID
GeoTIFF GeoKey ID 可以采用 0 到 65535 之间的任何值。按照 TIFF 通用做法,32768 及以上的 GeoKey ID 可用于私有实现,但是不会为这些 Key 或者代码建立注册表。从0到32767的 Key ID保留供 GeoTIFF 官方规范使用,并分为以下子域:
- 0 - 1023:保留的
- 1024 - 2047:GeoTIFF 配置键
- 2048 - 3071:地理或者地心坐标系统参数键
- 3072 - 4095:投影坐标系统参数键
- 4096 - 5119:垂直坐标系统参数键
- 5120 - 32767:保留的
- 32768 - 65535:私有的
3.1.1.1 GeoTIFF 的配置键
- 1024:GTModelTypeGeoKey,定义习惯的模型坐标系的一般类型。值为1表示投影坐标系,值为2表示地理经纬系,值为3表示地心(X,Y,Z)坐标系;
- 1025:GTRasterTypeGeoKey,建立习惯的光栅空间坐标系统。值为1表示光栅像素是区域(RasterPixelIsArea),值为2表示光散像素是点(RasterPixelIsPoint);
- 1026:GTCitationGeoKey,和所有的“引证”键一起,该键只要给出一个ASCII参考到基于这个文件的全部配置的发表文档。
3.1.1.2 地理坐标系参数键
- 2048:GeographicTypeGeoKey,地理类型代码,指出采用哪一个地理坐标系统;
- 2049:GeogCitationGeoKey,文档,适用于所有的地理坐标系参数的一般的引文和参考;
- 2050:GeogGeodeticDatumGeoKey,大地基准点代码;
- 2051:GeogPrimeMeridianGeoKey,本初子午线代码;
- 2052:GeogLinearUnitsGeoKey,线性单位代码;
- 2053:GeogLinearUnitSizeGeoKey,线性单位大小,单位为米;
- 2054:GeogAngularUnitsGeoKey,有角的单位代码,允许定义自定义的GCS和椭圆体的地心坐标系线性单位;
- 2055:GeogAngularUnitSizeGeoKey,用于定义自定义的角度地理单位(以弧度为单位)。
- 2056:GeogEllipsoidGeoKey,椭圆体代码,这个键可以用来指定地理坐标系的大地基准点里的椭圆体的编码;
- 2057:GeogSemiMajorAxisGeoKey,提供自定义椭圆体Semi-Major轴(a)的规格;
- 2058:GeogSemiMinorAxisGeoKey,提供自定义椭圆体Semi-Major轴(b)的规格;
- 2059:GeogInvFlatteningGeoKey,提供自定义的椭圆体的扁率参数(f)的Inverse的规格,值为比率;
- 2060:GeogAzimuthUnitsGeoKey,可用于指定在地理坐标系中用于定义方位角的角度测量单位;
- 2061:GeogPrimeMeridianLongGeoKey,本初子午线长。这个键提供自定义的本初子午线的定义,位置由他的相对于格林威治的经度定义。
3.1.1.3 投影坐标系参数键
- 3072:ProjectedCSTypeGeoKey,投影坐标系类型代码;
- 3073:PCSCitationGeoKey,文档,和所有的“引证”键一起,该键只要给出一个ASCII参考到投影坐标系上的发表文档,特别的如果这是一个自定义的PCS。
3.1.1.4 投影定义的键
- 2060:GeogAzimuthUnitsGeoKey,可用于指定在地理坐标系中用于定义方位角的角度测量单位;
- 3074:ProjectionGeoKey,投影编码;
- 3075:ProjCoordTransGeoKey,坐标转换编码;
- 3076:ProjLinearUnitsGeoKey,线性单位编码;
- 3077:ProjLinearUnitSizeGeoKey,定义自定义线性单位的尺寸,单位为米;
- 3078:ProjStdParallel1GeoKey,首要标准纬线的维度;
- 3079:ProjStdParallel2GeoKey,第二标准纬线的维度;
- 3080:ProjNatOriginLongGeoKey,地图投影自然原点的经度;
- 3081:ProjNatOriginLatGeoKey,地图投影自然原点的纬度;
- 3082:ProjFalseEastingGeoKey,给出地图投影自然原点的东向坐标;
- 3083:ProjFalseNorthingGeoKey,给出地图投影自然原点的北向坐标;
- 3084:ProjFalseOriginLongGeoKey,给出伪原点的经度;
- 3085:ProjFalseOriginLatGeoKey,给出伪原点的纬度;
- 3086:ProjFalseOriginEastingGeoKey,给出伪原点的东向坐标;
- 3087:ProjFalseOriginNorthingGeoKey,给出伪原点的北向坐标;
- 3088:ProjCenterLongGeoKey,投影的中心的经度;
- 3089:ProjCenterLatGeoKey,投影的中心的纬度;
- 3090:ProjCenterEastingGeoKey,给出中心的东向坐标;
- 3091:ProjFalseOriginNorthingGeoKey,给出中心的北向坐标;
- 3092:ProjScaleAtNatOriginGeoKey,自然原点的比率;
- 3093:ProjScaleAtCenterGeoKey,在中心的比率;
- 3094:ProjAzimuthAngleGeoKey,经过投影中心的中心线的真北的东方的方位角;
- 3095:ProjStraightVertPoleLongGeoKey,在直线垂直极点的经度。
3.1.1.5 垂直坐标系的键
- 4096:VerticalCSTypeGeoKey,垂直坐标系类型代码;
- 4097:VerticalCitationGeoKey,文档,该键用于垂直坐标系统和它的参数的文档;
- 4098:VerticalDatumGeoKey,垂直坐标系数据编码;
- 4099:VerticalUnitsGeoKey,线性单位编码。
3.1.2 标记位置
- 如果值为0,则 ValueOffset 的值就是当前键的值;
- 如果值为34736,则表示值的类型为 DOUBLE,具体值为 GeoDoubleParamsTag 标记的第_ValueOffset_值;
- 如果值为34737,则表示值的类型为字符串,具体值为 GeoAsciiParamsTag 标记的值,从_ValueOffset_开始,长度为_Count_。
3.2 GeoDoubleParamsTag
TIFF TAG 值为34736,对应的数据类型为 DOUBLE
GeoDoubleTag 用于存储 GeoKeyDirectoryTag 中引用的所有 Double 类型的 GeoKey。FLOAT 类型的值应该先转为 DOUBLE 类型存储在这里。该值的含义有 GeoKyeDirectoryTag 中引用它的 Key-Entry 确定。
3.3 GeoAsciiParamsTag
TIFF TAG 值为34737,对应的数据类型为 ASCII
GeoAsciiParamsTag 标记的值为字符串,样式为xxxx|xxxx|xxxx
,用于存储 GeoKeyDirectoryTag 中引用的所有 ASCII 类型的 GeoKey。GeoKeyDirectorTag 通过_计数_和_偏移量_确定具体的字符串,末尾的|
符号表示结束符,需要由读取程序编写相关的转换逻辑。
3.4 示例数据
GeoKeyDirectoryTag=( 1, 1, 2, 6,
1024, 0, 1, 2,
1026, 34737,12, 0,
2048, 0, 1, 32767,
2049, 34737,14, 12,
2050, 0, 1, 6,
2051, 34736, 1, 0 )
GeoDoubleParamsTag(34736)=(1.5)
GeoAsciiParamsTag(34737)=("Custom File|My Geographic|")
- GeoKeyDirectoryTag 第1行表示当前版本为1,使用的 Key-Set 版本为1.2,并有6个 Key-Entry。
- 第1个 Key-Entry 的 ID 为 1024,TIFFTagLocation 为0,Count 为 1,ValueOffset 为 2,表示使用地理坐标系。
- 第2个 Key-Entry 的 ID 为 1026,TIFFTagLocation 为34737(对应的值存储在 GeoAsciiParamsTag 里面),Count 为12,ValueOffset 为0。该条目的值从 GeoAsciiParamsTag 标签的值中读取,起始位置为0,总共包含12个ASCII值(|也占一位),即为“Custom File|”。
- 第3个 Key-Entry 的 ID 为 2048,TIFFTagLocation 为0,Count 为1,ValueOffset 为32767,。
- 第4个 Key-Entry 的 ID 为 2049,TIFFTagLocation 为34737(对应的值存储在 GeoAsciiParamsTag 里面),Count 为14,ValueOffset 为12。该条目的值从 GeoAsciiParamsTag 标签的值中读取,起始位置为12,总共包含14个ASCII值(|也占一位),即为“My Geographic|”。
- 第5个 Key-Entry 的 ID 为 2050,TIFFTagLocation 为0,Count 为1,ValueOffset 为6。
- 第6个 Key-Entry 的 ID 为 2051,TIFFTagLocation 为34736(对应的值存储在 GeoDoubleParamsTag 里面),Count 为1,ValueOffset 为0。该条目的值从 GeoDoubleParamsTag 标签的值中读取,值为1.5。
4. GeoTIFF 中的坐标系
GeoTIFF 的设计使得标准地图坐标系的定义可以很容易地存储在 TIFF TAG 中,它还可以通过3个或者4个额外的 TIFF 标记来描述非标准的坐标系的定义,以及描述坐标系之间的转换。为了在 GeoTIFF 的提供者和各种客户端之间正确地交换信息,需要建立一个描述地图投影的通用系统。
在 TIFF/GeoTIFF 框架中,基本上有一个不同的空间,可以在这些空间上定义坐标系:
4.1 设备空间和 GeoTIFF
在 TIFF 标准中,存在将栅格空间 R 与设备空间 D (例如:监视器、扫描仪或者打印机)相关联的 TAG,主要包括:
- Orientation(274),描述图像的方向
- XResolution(282),表示在 ImageWidth 方向上每个分辨率单位(ResolutionUnit)上像素的个数,通常为96
- YResolution(283),表示在 ImageLength 方向上每个分辨率单位(ResolutionUnit)上像素的个数,通常为96
- XPosition(286),图像左侧相对于页面左侧的X偏移量(以分辨率为单位)
- YPosition(287),图像顶部相对于页面顶部的Y偏移量(以分辨率为单位)。在TIFF坐标系中,正Y方向向下,因此YPosition始终为正。
- ResolutionUnit(296),用于指定 XResolution、YResolution 的测量单位,可选值有英寸、厘米等。
在 GeoTIFF 中,规定识别以地球为基准的坐标(模型空间 M),并将 M 空间与 R 空间联系起来。这一个规定独立于设备空间和栅格空间之间的关系,并且可以与之共存。为了强调区别,在 GeoTIFF 规范中不提及 X 和 Y 栅格坐标,而是统一使用栅格 J (行)和 I (列)表示。
4.2 栅格坐标系统
4.2.1 栅格数据
栅格数据由空间相干、数字存储的数值数据组成,这些数据是从传感器或者扫描仪中收集的,或者以其他方式导出的。TIFF 标准中描述了在 TIFF 文件中实现此存储的方式。从文件中读取的栅格数据值由软件组织成二维数据,数组的索引用作坐标。多光谱数据还可能有其他索引,但这些索引不是值空间坐标而是指光谱。
许多不同类型的栅格数据都可以进行地理配准,并且数据本身的性质可能会以微妙的方式影像栅格数据的坐标系(栅格空间)的定义方式。例如,从成像设备和传感器导出的像素数据表示在小而有限的地理区域内收集的聚合值,因此很自然地定义坐标系,其中像素值被认为填充了一个区域。 另一方面,数字高程模型可能由离散的“postings”(可以理解为网格)组成,最好将其视为网格顶点处的点测量,而不是单元内部的点测量。
4.2.2 栅格空间
栅格空间的原点选择并不完全是任意选择的,并且应取决于收集数据的性质。栅格空间坐标应通过其像素类型来引用,即“PixelIsArea”或“PixelIsPoint”。
注意:为了简单起见,下面记录的两个栅格空间都使用固定的像素大小和间距 1。有关该数据的视觉表示的信息,例如具有非单位长宽比、比例、方向等的像素,最好查看 TIFF 6.0 标准中的 TAG。
4.2.2.1 PixellsArea 栅格空间
默认的 PixellsArea 栅格网格空间 R 使用坐标 I 和 J,其中(0,0)表示图像的左上角,并且向右增加 I,向下增加 J。第一个像素值用边界填充方形网格单元top-left=(0, 0), bottom-right=(1, 1)
。通过扩展,这个一对一的网格单位也称为像素。N x M 像素图像覆盖具有数据定义编辑(0,0)、(N,M)
的区域。
4.2.2.2 PixellsPoint 栅格空间
PixellsPoint 栅格网格空间 R 使用与 PixellsArea 栅格空间中使用的坐标轴相同的名称,其中 I 向右增加,J 向下增加。然而,第一个像素值被实现为位于(0,0)的点值。N x M 像素图像有填充数据定义的边界(0,0)、(N-1,M-1)
的点组成。
如果点像素图像要显示在与栅格间距相同大小的像素单元的显示设备上,则显示图像的左上角将位于栅格空间中的(-0.5, -0.5)处。
4.2.3 模型坐标系统
GeoTIFF 识别了以下描述空间模型位置的方法(与栅格相反):
- Geographic Coordinates(地理坐标)
- Geocentric Coordinates(地心坐标)
- Projected Coordinates(投影坐标)
- Vertical Coordinates(垂直坐标)
地理坐标、地心坐标和投影坐标都被强加在地球模型上。为了唯一地描述一个位置,坐标集必须参考定义的坐标系。如果坐标系来自 Geotiff 标准定义,则唯一需要的参考是标准坐标系代码/名称。如果坐标系是非标准的,则必须对其进行定义。投影坐标、局部网格坐标和(通常)地理坐标形成二维水平坐标系(即相对于地球表面的水平坐标系)。高度不是这些系统的一部分。为了在三维中描述位置,有必要将高度视为第二个一维垂直坐标系。要在 GeoTIFF 中对图像进行地理参考,必须指定栅格空间坐标系,选择水平模型坐标系,以及这两者之间的转换,如第5小节所述。
4.3 参考参数
大多数数字编码系统和坐标系定义都是基于 EPSG/POSC 中定义的标准,GeoTIFF 中使用的一整套 ESPG 编码可以查看下面的地址。
Index of /geotiff/tables/
5. 坐标转换
GeoTIFF 的目的是允许在栅格数据集中确定地理参考位置。当不需要进一步的信息时,这通常是通过将栅格空间坐标系绑定到模型空间坐标系来实现。在 GeoTIFF 术语中,“地理配准(Georeferencing)”是指将栅格空间 R 与模型空间 M 联系起来,而“地理编码(Geocoding)”是指定义模型空间 M 如何将坐标分配给地球上的点。
下面定义的三个标签可以用于定义 R 和 M 之间的关系:
5.1 用于坐标转换的 GeoTIFF Tag
对于大多数常见应用,栅格和模型空间之间的转换可以使用一组栅格到模型的连接点和缩放参数来定义。下面的2个标签可以用于实现该目的。
别名 GeoreferenceTag,TAG 编号 33922,数据类型 DOUBLE,按顺序存储了栅格->模型的连接点对,数据格式为ModelTiepointTag=(…,I,J,K,X,Y,Z…)
,其中,(I, J, K) 是栅格空间像素位置为(I, J)的像素,其值(表示高度值)为 K;(X, Y, Z) 是模型空间中的矢量,K 和 Z 是支持 3D 数字高程模型和垂直坐标系。在大多数情况下,模型空间只是二维的,K 和 Z 的值都应该设置为0。
可以简单地通过指定其在模型坐标空间 M 中的位置、大小和方向来对光栅图像进行地理配准。这可以通过指定四个边界角点中的三个的位置来完成。 然而,连接点仅在指定的点处才被认为是精确的; 因此,定义这样一组边界连接点并不意味着图像内部的模型空间位置可以通过这些连接点的线性插值来精确计算。
然而,由于栅格空间和模型空间之间的关系通常是精确的仿射变换,因此可以使用一组连接点和下面描述的“ModelPixelScaleTag”来定义这种关系,该标记给出以模型单位指定的垂直和水平光栅网格单元大小。
如果可能,放置在该标签中的第一个连接点应为在栅格空间中确定点(0,0)位置的连接点。然而,如果这是不可能的(例如,如果(0,0)进入模型空间中投影定义不明确的部分),则不需要列出连接点的特定顺序。
对于正射校正或镶嵌应用,可以在栅格图像上的网格上指定大量的连接点。但是,关联网格插值方法的定义不在当前 GeoTIFF 规范的范围内。
接下来的两个标签是可选的标签,用于定义栅格和模型空间之间的精确仿射变换;基准 GeoTIFF 文件可以使用其中一种,但决不能在同一TIFF图像目录中同时使用这两种。
TAG 编号 33550,数据类型 DOUBLE。当栅格空间可以嵌入模型空间坐标系而不用旋转时,该标签可用于指定模型空间单位中栅格像素间距的大小,并由以下3个值组成:ModelPixelScaleTag = (ScaleX, ScaleY, ScaleZ)
。其中 ScaleX 和 ScaleY 给出栅格像素的水平和垂直间距,ScaleZ 主要用于将数字高程模型的像素值映射到正确的 Z 值,因此对于二维模型空间,Z=0。
ModelTiepointTag 中的单个连接点与该标签一起,完全确定了栅格和模型空间之间的关系; 因此,标准 GeoTIFF 文件最常使用这两个标签将光栅图像放置到模型空间中的“标准位置”。
与 Tiepoint 标签一样,此标签信息独立于TIFF 6.0 标准规范的 XPosition、YPosition、Resolution 和 Orientation 标签。 然而,栅格和模型空间之间方向的简单反转(例如水平或垂直翻转)可以通过 ModelPixelScaleTag 的相应组件中的符号反转来指示。 符合 GeoTIFF 标准的读取器必须遵守此符号反转约定。
如果栅格图像需要旋转或剪切才能将其放入标准模型空间,则不得使用此标签,应该使用更通用的 ModelTransformationTag 来定义转换。
TAG 编号 34264,数据类型为 DOUBLE。该标记可用于指定栅格空间(即相关的像素值)和(可能是 3D)模型空间之间的变换矩阵,组织结果如下:ModelTransformationTag=(a,b,c,d,e…m,n,o,p)
。
5.2 坐标转换数据流
各种 GeoTIFF 参数数据集的数据流基于 EPSG/POSC 配置,下图是 EPSG 参数表附带的坐标转换数据流图。
5.3 定义坐标转换步骤
这里提供了一个定义坐标转换的4步指南,用来生成一组用于定义栅格数据集的坐标变换信息的标准 GeoTIFF TAG。
- 步骤1:建立所使用的栅格空间坐标系:RasterPixellsArea 或者 RasterPixellsPoint
- 步骤2:建立/定义要对图像进行地理参考的模型空间类型。通常这将是一个投影坐标系。如果你对数据集进行地理编码,则模型空间被定义为相应的地理、地心或投影坐标系。
- 步骤3:确定将栅格数据绑定到模型空间坐标系所需的转换的性质。
- 情况1:栅格点(x, y)的模型位置已知,但未知比例和方向,使用 ModelTiepointTag 定义已知栅格点的 (X,Y,Z) 坐标;
- 情况2:3个不共线栅格点的位置是精确且已知的,但变换的线性度未知。使用 ModelTiepointTag 定义所有3个已知栅格点的 (X,Y,Z) 坐标。不要计算或定义 ModelPixelScale 或 ModelTransformation TAG;
- 情况3:数据的位置和比例是准确已知的,不需要旋转或剪切来适应模型空间。使用 ModelTiepointTag 定义已知栅格点的 (X,Y,Z) 坐标,并使用 ModelPixelScaleTag 指定比例;
- 情况4:栅格数据需要旋转和/或横向剪切才能适应定义的模型空间。使用 ModelTransformation 矩阵定义变换;
- 情况5:栅格数据无法通过简单的仿射变换到模型空间。仅使用 ModelTiepoint 标记,并根据应用程序需要指定尽可能多的连接点。 但请注意,这不是标准 GeoTIFF 实现,并且不应用于交换; 建议先对图像进行几何校正,并放入标准投影坐标系中。
- 在 TIFF 文件中保存定义的 TAG 值并输出 TIFF 图像。
6. 栅格数据地理编码
6.1 通用方法
地理编码图像是第5小节中描述的地理参考图像,它还指定模型空间 M(栅格空间已绑定到的模型空间)和地球之间的模型空间坐标系 (CS),转换关系图如下。
地理编码坐标系由 GeoKeyDirectoryTag 定义,而地理配准信息 (T) 由 ModelTiepointTag 和 ModelPixelScale 或 ModelTransformationTag 定义。 由于这两个系统彼此独立,因此在 GeoTIFF 文件中用于存储参数的标签彼此分开。
6.2 地理编码相关的 GeoKey
正如6.1小节所述,有关栅格数据中使用的模型坐标系的所有信息均从存储所有 GeoKey 条目的 GeoKeyDirectoryTag 引用,在第3小节中总结了常用的 GeoKey。
7. 实例说明
7.1 示例文件及代码说明
7.1.1 示例代码获取
从 Gitee 上克隆示例代码,访问地址:gitee.com/shixxa/tiff…。安装 POM 依赖后,运行 Main.java 文件即可。
示例代码所用的内容及版本如下:
7.1.2 示例文件说明
示例文件存放在src/main/resource
文件中,名称为GeoTIFF.tif
,示意图如下:
7.2 IFH 解析结果分析
IFH 内容的打印结果如下:
IFH中的字节顺序:4949
IFH中的标识符:2A00
IFH中第一个IFD的偏移量(十六进制,大端字节序):08000000
根据第2.1内容分析:
- 十六进制的
4949
转为 Word 类型(字符串类型)为II
,即表示小端字节序,也就说后,后续所有的读取顺序与打印的顺序是相反的; - 标识符值为
2A00
,读取结果为002A
,对应的十进制值为42
- 第一个 IFD 的偏移量为
08000000
,读取结果为000000CA
,对应的十进制值为8
,表示第一个 IFD 的内容从读取结果的第8位开始。
7.3 IFD及DE解析结果分析
7.3.1 IFD 中 DE 的数量
第一个 IFD 中的 DE 的数量打印结果如下:
第一个IFD中的DE的数量(十六进制,大端字节序):1000
打印结果对应的读取顺序为0010
,对应的十进制值为16
,表示该 IFD 共有16个DE。
7.3.2 IFD 中的 DE 解析结果
从上一步可以得到,第一个 IFD 共有16个 DE,接下来逐个分析其中的内容。
7.3.2.1 第0个DE
-第0个DE的内容:
--DE中的TAG标识:0001
--DE中的数据类型:0300
--DE中的数据数量:01000000
--DE中的ValueOffset:E9030000
- TAG 的读取结果为
0100
,该 TAG 表示 ImageWidth,图像中的列数,即每行的像素数; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
00000001
,表示共1条数据; - 数据值的偏移量读取结果为
000003E9
,十进制值为1001,即该文件每行有1001个像素。
7.3.2.2 第1个DE
-第1个DE的内容:
--DE中的TAG标识:0101
--DE中的数据类型:0300
--DE中的数据数量:01000000
--DE中的ValueOffset:E9030000
- TAG 的读取结果为
0100
,该 TAG 表示 ImageLength,图像中像素的行数; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
00000001
,表示共1条数据; - 数据值的偏移量读取结果为
000003E9
,十进制值为1001,即该文件有1001行。
7.3.2.3 第2个DE
-第2个DE的内容:
--DE中的TAG标识:0201
--DE中的数据类型:0300
--DE中的数据数量:03000000
--DE中的ValueOffset:CE000000
- TAG 的读取结果为
0102
,该 TAG 表示 BitsPerSample,每个分量的Bit数; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
00000003
,表示共3条数据; - 数据值的偏移量读取结果为
000000CE
,十进制值为206。因为该 DE 中共有3条 SHORT 类型的数据,共占用了6个字节,大于4个字节,因此该部分表示的数据值的偏移量,偏移量为206。
SHORT 类型占用2个字节,所以代码中获取了206-212的内容,打印结果如下:
第3个DE中BitsPerSample的值:100010001000
打印结果解析:
7.3.2.4 第3个DE
-第3个DE的内容:
--DE中的TAG标识:0301
--DE中的数据类型:0300
--DE中的数据数量:01000000
--DE中的ValueOffset:01000000
- TAG 的读取结果为
0103
,表示 Compression,压缩属性; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
00000001
,表示共1条数据; - 数据值的偏移量读取结果为
00000001
,十进制值为1,表示没有压缩。
7.3.2.5 第4个DE
-第4个DE的内容:
--DE中的TAG标识:0601
--DE中的数据类型:0300
--DE中的数据数量:01000000
--DE中的ValueOffset:01000000
- TAG 的读取结果为
0106
,表示 PhotometricInterpretation,颜色空间; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
00000001
,表示共1条数据; - 数据值的偏移量读取结果为
00000001
,十进制值为1,表示当前颜色空间为 BlacklsZero,即:0表示黑色。
7.3.2.6 第5个DE
-第5个DE的内容:
--DE中的TAG标识:1101
--DE中的数据类型:0400
--DE中的数据数量:E9030000
--DE中的ValueOffset:A6080000
- TAG 的读取结果为
0111
,表示 StripOffsets,对于每个条带,该条带的字节偏移量; - 数据类型的读取结果为
0004
,对应的数据类型为 LONG; - 数据数量的读取结果为
000003E9
,表示共1001条数据; - 数据值的偏移量读取结果为
000008A6
,十进制为2214,显然这个值表示的是偏移量。考虑到该值内容太长,不在文档中展示了,可以在代码中查看。
**PS: **2214 + 1001*4 = 6218,正好是第11个 DE 值的偏移量。
7.3.2.7 第6个DE
-第6个DE的内容:
--DE中的TAG标识:1501
--DE中的数据类型:0300
--DE中的数据数量:01000000
--DE中的ValueOffset:03000000
- TAG 的读取结果为
0115
,表示 SamplesPerPixel,每个像素的通道数; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
00000001
,表示共1条数据; - 数据值的偏移量读取结果为
00000003
,十进制为3,表示每个像素有3个通道。
7.3.2.8 第7个DE
-第7个DE的内容:
--DE中的TAG标识:1601
--DE中的数据类型:0300
--DE中的数据数量:01000000
--DE中的ValueOffset:01000000
- TAG 的读取结果为
0116
,表示 RowsPerStrip,每个条带有多少行; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
00000001
,表示共1条数据; - 数据值的偏移量读取结果为
00000001
,十进制为1,表示每个条带有1行。
7.3.2.9 第8个DE
-第8个DE的内容:
--DE中的TAG标识:1701
--DE中的数据类型:0300
--DE中的数据数量:E9030000
--DE中的ValueOffset:D4000000
- TAG 的读取结果为
0117
,表示 StripByteCounts,每个条带的长度; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
000003E9
,表示共1001条数据; - 数据值的偏移量读取结果为
000000D4
,十进制为212,该值代表的是一个偏移量。考虑到该值内容太长,不在文档中展示了,可以在代码中查看。
**PS: **212 + 1001*2 = 2214,正好是第5个 DE 值的偏移量。
7.3.2.10 第9个DE
-第9个DE的内容:
--DE中的TAG标识:1C01
--DE中的数据类型:0300
--DE中的数据数量:01000000
--DE中的ValueOffset:01000000
- TAG 的读取结果为
011C
,表示 PlanarConfiguration,如何存储每个像素的分量; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
00000001
,表示共1条数据; - 数据值的偏移量读取结果为
00000001
,十进制为1,表示 Chunky 格式,即:每个像素的分量值是连续存储的。 例如,对于RGB数据,数据存储为RGBRGBRGB。
7.3.2.11 第10个DE
-第10个DE的内容:
--DE中的TAG标识:5201
--DE中的数据类型:0300
--DE中的数据数量:02000000
--DE中的ValueOffset:00000000
- TAG 的读取结果为
0152
,表示 ExtraSamples,表示额外的描述; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
00000002
,表示共2条数据; - 数据值的偏移量读取结果为
00000000
,十进制为0,表示未指定数据。
7.3.2.12 第11个DE
-第11个DE的内容:
--DE中的TAG标识:5301
--DE中的数据类型:0300
--DE中的数据数量:03000000
--DE中的ValueOffset:4A180000
- TAG 的读取结果为
0153
,表示 SampleFormat,指定如何解释像素中的每个数据样本; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
00000003
,表示共3条数据; - 数据值的偏移量读取结果为
0000184A
,十进制为6218,很显然该值表示一个偏移量。
SHORT 类型占用2个字节,所以代码中获取了6218-6224的内容,打印结果如下:
第11个DE中SampleFormat的值:010001000100
打印结果解析:
- 每个通道的SampleFormat的值
0001
(十六进制,十进制为1),unsigned integer data
,即无符号整型数据。
**PS:**6218 + 3*2 = 6224,正好是第12个 DE 的偏移量。
7.3.2.13 第12个DE
-第12个DE的内容:
--DE中的TAG标识:0E83
--DE中的数据类型:0C00
--DE中的数据数量:03000000
--DE中的ValueOffset:50180000
- TAG 的读取结果为
830E
,表示 ModelPixelScaleTag,用于定义栅格和模型空间之间的精确仿射变换,主要用于 GeoTIFF 文件; - 数据类型的读取结果为
000C
,十进制为12,对应的数据类型为 DOUBLE; - 数据数量的读取结果为
00000003
,表示共3条数据; - 数据值的偏移量读取结果为
00001850
,十进制为6224,很显然该值表示一个偏移量。
DOUBLE 类型占用8个字节,所以代码中获取了6224-6248的内容,打印结果如下:
第12个DE中ModelPixelScaleTag的值:000000000000244000000000000024400000000000000000
打印结果解析:
- ScaleX、SacleY 的值均为
0000000000002440
,读取值为4024000000000000
,转为 Double 类型的值为10
,在 ArcMap 中验证结果如下;ScaleZ 值为0000000000000000
,Double 类型的值为 0。
**PS:**6224 + 8*3 = 6248,正好对应第13个 DE 值的偏移量。
7.3.2.14 第13个DE
-第13个DE的内容:
--DE中的TAG标识:8284
--DE中的数据类型:0C00
--DE中的数据数量:06000000
--DE中的ValueOffset:68180000
- TAG 的读取结果为
8482
,表示 ModelTiepointTag,该标签也称为 GeoreferenceTag,按顺序存储栅格->模型连接点对,模型连接点标签 =(...,I,J,K, X,Y,Z...)
,其中(I,J,K)
是栅格空间中位置(I,J)
处像素值为K
的点,(X,Y,Z)
是模型空间中的向量。 大多数情况下模型空间只是二维的,在这种情况下 K 和 Z 都应该设置为零; 提供第三个维度是为了将来支持 3D 数字高程模型和垂直坐标系; - 数据类型的读取结果为
000C
,十进制为12,对应的数据类型为 DOUBLE; - 数据数量的读取结果为
00000006
,表示共6条数据; - 数据值的偏移量读取结果为
00001868
,十进制为6248,很显然该值表示一个偏移量,具体解析详见4.4小节。
7.3.2.15 第14个DE
-第14个DE的内容:
--DE中的TAG标识:AF87
--DE中的数据类型:0300
--DE中的数据数量:20000000
--DE中的ValueOffset:98180000
- TAG 的读取结果为
87AF
,表示 GeoKeyDirectoryTag,该标签也称为 ProjectionInfoTag 或者 CoordSystemInfoTag,用于存储 GeoKey 目录,该目录定义并引用“GeoKey”; - 数据类型的读取结果为
0003
,对应的数据类型为 SHORT; - 数据数量的读取结果为
00000020
,表示共32条数据; - 数据值的偏移量读取结果为
00001898
,十进制为6296,很显然该值表示一个偏移量,具体解析详见4.5小节。
7.3.2.16 第15个DE
-第15个DE的内容:
--DE中的TAG标识:B187
--DE中的数据类型:0200
--DE中的数据数量:1E000000
--DE中的ValueOffset:D8180000
- TAG 的读取结果为
87B1
,表示 GeoAsciiParamsTag,用于存储由 GeoKeyDirectoryTag 引用的所有 ASCII 值 GeoKey。 由于键使用标签的偏移量,因此任何特殊注释都可以放置在该标签的开头。 在大多数情况下,唯一具有 ASCII 值的键是“引文”键,为晦涩的投影、数据等提供文档和参考; - 数据类型的读取结果为
0002
,对应的数据类型为 ASCII; - 数据数量的读取结果为
0000001E
,表示共30条数据; - 数据值的偏移量读取结果为
000018D8
,十进制为6360,很显然该值表示一个偏移量。
7.4 GeoKeyDirectoryTag 信息分析
该信息在第14个 DE 中
首先来看该信息的打印结果。因为有32条数据,每条数据都是 SHORT 类型(2字节),因此共占用了32 * 2=64个字节,所以该信息的偏移量为6296~(6296 + 64),具体打印结果为:
0100010000000700000400000100010001040000010001000204B187160000000108B187070016000608000001008E23000C00000100777F040C000001002923
- GeoKeyDirectory 标头分析
根据3.1节内容,标头共有4个值,每个值都是 SHORT 类型,共占8个字节,因此其内容为0100,0100,0000,0700
(其中,
只是为了更好区分),其中:
- 第1个值为版本号,读取的值为
0001
,十进制为1; - 第2个值为键集修订版本号,读取的值为
0001
; - 第3个值为键码修订版本号,读取的值为
0000
; - 第4个值为键的数目,读取值为
0007
,十进制为7,表示共有7组键的记录集。
- 第1组键的记录集
根据3.1节内容,每组记录集共有4个值,每个值都是 SHORT 类型,共占8个字节,因此第1组键的记录集为0004,0000,0100,0100
,其中:
- 第1个值为_键 ID_,读取的值为
0400
,十进制为1024,具体描述参照3.1.1.1小节; - 第2个值为_标记位置_,读取的值为
00000
,十进制为0,也就说,该记录的值就为_偏移_; - 第3个值为_计数_,读取的值为
0001
,十进制为1; - 第4个值为_偏移_,读取的值为
0001
,十进制为1,参照3.1.1.1的描述,该值表述的为投影坐标系,可以在 ArcMap 中确认一下。
- 第2组键的记录集
第2组键的记录集为0104,0000,0100,0100
,其中:
- 第1个值为_键 ID_,读取的值为
0401
,十进制为1025,具体描述参照3.1.1.1小节; - 第2个值为_标记位置_,读取的值为
00000
,十进制为0,也就说,该记录的值就为_偏移_; - 第3个值为_计数_,读取的值为
0001
,十进制为1; - 第4个值为_偏移_,读取的值为
0001
,十进制为1,参照3.1.1.1的描述,该值表示光栅像素是区域(不太明白)。
- 第3组键的记录集
第3组键的记录集为0204,B187,1600,0000
,其中:
- 第1个值为_键 ID_,读取的值为
0402
,十进制为1026,具体描述参照3.1.1.1小节; - 第2个值为_标记位置_,读取的值为
87B1
,十进制为34737,参照3.1.2小节,该值的类型为字符串,也就是对应的GeoAsciiParamsTag; - 第3个值为_计数_,读取的值为
0016
,十进制为22; - 第4个值为_偏移_,读取的值为
0000
,十进制为0,也就是说,该值的内容为GeoAsciiParamsTag
标记值的第0-22位。
- 第4组键的记录集
第4组键的记录集为0108,B187,0700,1600
,其中:
- 第1个值为_键 ID_,读取的值为
0801
,十进制为2049,具体描述参照3.1.1.2小节,文档,适用于所有的地理坐标系参数的一般的引文和参考; - 第2个值为_标记位置_,读取的值为
87B1
,十进制为34737,参照3.1.2小节,该值的类型为字符串,也就是对应的GeoAsciiParamsTag; - 第3个值为_计数_,读取的值为
0007
,十进制为7; - 第4个值为_偏移_,读取的值为
0016
,十进制为22,也就是说,该值的内容为GeoAsciiParamsTag
标记值的第22-29位。
- 第5组键的记录集
第5组键的记录集为0608,0000,0100,8E23
,其中:
- 第1个值为_键 ID_,读取的值为
0806
,十进制为2054,具体描述参照3.1.1.2小节; - 第2个值为_标记位置_,读取的值为
0000
,十进制为0,即指为_偏移_; - 第3个值为_计数_,读取的值为
0001
,十进制为1; - 第4个值为_偏移_,读取的值为
238E
,十进制为9102。
- 第6组键的记录集
第6组键的记录集为000C,0000,0100,777F
,其中:
- 第1个值为_键 ID_,读取的值为
0C00
,十进制为3072,具体描述参照3.1.1.3小节; - 第2个值为_标记位置_,读取的值为
0000
,十进制为0,即指为_偏移_; - 第3个值为_计数_,读取的值为
0001
,十进制为1; - 第4个值为_偏移_,读取的值为
7F77
,十进制为32631,表示WGS 1984 UTM Zone 31N
投影坐标系。
- 第7组键的记录集
第7组键的记录集为040C,0000,0100,2923
,其中:
- 第1个值为_键 ID_,读取的值为
0C04
,十进制为3076,具体描述参照3.1.1.3小节; - 第2个值为_标记位置_,读取的值为
0000
,十进制为0,即指为_偏移_; - 第3个值为_计数_,读取的值为
0001
,十进制为1; - 第4个值为_偏移_,读取的值为
2329
,十进制为9001,表示线性单位编码Linear_Meter
。
7.5 GeoAsciiParamsTag 信息分析
该信息在第15个 DE 中,其中,偏移量6360刚好等于6296 + 64
首先来看该信息的打印结果。因为有30条数据,每条数据都是 ASCII 类型(8字节),因此共占用了30 * 8=240个字节,所以该信息的偏移量为6360~(6360 + 240),具体打印结果为:
574753203834202F2055544D207A6F6E652033314E7C5747532038347C000000000000001F032B024A011403220242010B031C0244011F031D0242011F031A0243011E031C023701150314023D01130319023D0113031A02380113031E0249010E032002440114031E02420114031D0246011D0315024D011903180241011503220248010C031B023C011A0322023D011B0316024701140318023F012303210230011B031D0237011903190239012603210240012303270243010803240242011F0325024C01190324023A01140321024201140319023D011F031E0234010E0325023101120327023C012B031E023F01
- GeoKeyDirectory 第3组键的值
在4.4节中,第3组键的值为GeoAsciiParamsTag
标记值的第0-21位,打印的值如下,对应的字符串为WGS 84 / UTM zone 31N|
。
GeoKeyDirectoryTag第3组键的值:574753203834202F2055544D207A6F6E652033314E7C
2. GeoKeyDirectory 第4组键的记录集
在4.4节中,第4组键的值为GeoAsciiParamsTag
标记值的第22-29位,打印的值如下,对应的字符串为WGS 84|
。
GeoKeyDirectoryTag第4组键的值:5747532038347C