6.5 写网格文件

6.5.1 网格文件格式

上面已经说过,GMT可以读写三类格式的网格数据:netCDF格式、二进制格式和Sun光栅文件。进一步细分,GMT可以读取几十种不同格式的网格数据。

GMT所支持的网格文件格式在下表列出,每种网格文件格式都有一个对应的两字符ID。

表 6.2 网格文件格式ID
ID 说明
  GMT 4 netCDF standard formats
nb GMT netCDF format (8-bit integer, COARDS, CF-1.5)
ns GMT netCDF format (16-bit integer, COARDS, CF-1.5)
ni GMT netCDF format (32-bit integer, COARDS, CF-1.5)
nf GMT netCDF format (32-bit float, COARDS, CF-1.5)
nd GMT netCDF format (64-bit float, COARDS, CF-1.5)
  GMT 3 netCDF legacy formats
cb GMT netCDF format (8-bit integer, depreciated)
cs GMT netCDF format (16-bit integer, depreciated)
ci GMT netCDF format (32-bit integer, depreciated)
cf GMT netCDF format (32-bit float, depreciated)
cd GMT netCDF format (64-bit float, depreciated)
  GMT native binary formats
bm GMT native, C-binary format (bit-mask)
bb GMT native, C-binary format (8-bit integer)
bs GMT native, C-binary format (16-bit integer)
bi GMT native, C-binary format (32-bit integer)
bf GMT native, C-binary format (32-bit float)
bd GMT native, C-binary format (64-bit float)
  Miscellaneous grid formats
rb SUN raster file format (8-bit standard)
rf GEODAS grid format GRD98 (NGDC)
sf Golden Software Surfer format 6 (32-bit float)
sd Golden Software Surfer format 7 (64-bit float)
af Atlantic Geoscience Center AGC (32-bit float)
ei ESRI Arc/Info ASCII Grid Interchange format (ASCII integer)
ef ESRI Arc/Info ASCII Grid Interchange format (ASCII float)
gd Import/export via GDAL

除了上面列出的网格文件格式之外,有C编程经验的高级用户还可以自己自定义网格文件格式,并将读写该格式的子程序链接到GMT函数库中,使得GMT可以支持自定义网格文件格式的读取。详情见源码中的 gmt_customio.c

GMT在读网格数据时,可以自动检测网格文件的格式,所以不用担心。而在写网格数据时,GMT会默认使用 nf 格式(可以修改 IO_GRIDFILE_FORMAT 以设置其他网格文件格式为默认值)。如果想要以其他格式写网格数据,则可以在网格文件名后加上 =<ID> 参数以指定要使用的网格文件格式。

无论是读还是写网格文件,都可以按照如下格式指定网格文件的文件名:

<name>[=<ID>][+s<scale>][+o<offset>][+n<nan>]

其中

  • <name> 是网格文件名
  • <ID> 是写网格文件时要使用的网格文件格式
  • <scale> 将所有数据乘以比例因子 <scale>,默认值为1
  • <offset> 将所有数据加上一个常数 <offset>,默认值为0
  • <nan> 表明将文件中值为 <nan> 认为是NaN

<scale><offset> 都可以取为 a,表明由程序自动决定比例因子和偏移量的值。在读网格文件时,会先乘以比例因子再加上偏移量;在写网格文件时,会先加上偏移量,再乘以比例因子。

举几个例子:

  1. 读入Golden软件公司的surfer软件生成的网格文件,GMT可以自动识别,故而直接用 file.grd
  2. 读一个二进制短整型网格文件,先将所有值为32767的值设置为NaN,再将数据乘以10 并加上32000,可以用 myfile.i2=bs+s10+o32000+n32767
  3. 将一个二进制短整数网格文件减去32000再除以10,然后写到标准输出,可以用 =bs+s0.1+o-3200
  4. 读一个8字节标准Sun光栅文件(其原始范围为0到255),并将其归一化到正负1范围内,可以用 rasterfile+s7.84313725e-3+o-1,即先乘以因子使得数据范围从0到255 变成0到2,再减去1,则数据范围变成-1到1
  5. 写一个8字节整型netCDF网格文件,偏移距由GMT自动决定,可以用 =nb+oa

GMT还支持通过网格文件后缀自动识别网格文件格式,详情见 网格文件后缀 一节。

6.5.2 分块与压缩

出于性能的考虑,GMT在输出超过16384个网格单元的网格文件时,会打开分块功能。所谓分块,即数据不是按照一行一行序列存储的,而是将整个网格分成若干个区块,然后依次存储每个区块的数据。

在读取数据时,若只需要读取数据的一部分,netCDF只需要读取相应的区块即可,不用先读取整个数据。

由于数据的压缩和解压比磁盘IO要快,因而可以对netCDF数据进行压缩,使得磁盘占用更少,IO负载更少。netCDF的压缩可以分为若干等级,压缩级别越高,文件越小,读写数据越快,但压缩/解压越耗时。通常,压缩级别取1到3效果比较好。

GMT参数 IO_NC4_CHUNK_SIZE 可以控制分块的大小, IO_NC4_DEFLATION_LEVEL 可以控制压缩等级。