GMT 脚本进阶(四):GMT 的 C 语言 API

本系列共 4 篇:(一)Shell 技巧 · (二)怎样 getopts · (三)分享与扩展 · (四)C 语言 API 说明:本篇为归档笔记,内容仍在整理中,后续会继续补充。 简单的说明 作者在本系列的前几期教程中给大家分享了一些编写 GMT 脚本的小技巧,相信大家如果应用得当的话一定能有效提升你的脚本质量。本期教程所涉及的内容并不是 shell 脚本的相关内容,而是关于 GMT 动态库的使用方法。这也是我这几天研究的结果,想给大家粗略地介绍一下,也算给自己留个档。 本篇教程中所使用编程语言为 C/C++,因为也算是预编译脚本吧,姑且就放在这个系列里了。其实 GMT 的接口语言类型很丰富,包括 Matlab、Julia、python 等等,以后有机会再给大家分享这些语言的接口用法。目前,GMT 官方对于其动态库 API 的说明文档还不是很完善,因此很多地方我也是摸着石头过河,不是很清楚,请大家见谅。 本篇教程不涉及动态库的构建讲解,仅从一般使用方法入手。首先我们大致讲解一下 GMT 的 C 语言接口的总体使用策略。 总体策略 一般我们在命令行或者脚本中使用 GMT 命令时,典型的用法如下: $ gmt grd2cpt example.nc -Rd -Z -D > user.cpt 我们大致可以将这个命令分成这样几个部分: gmt grd2cpt 指定我们要使用的模块; example.nc 输入文件; -Rd -Z -D 模块使用的参数; user.cpt 输出文件。 其中,2 到 4 可以合并成一项,即某个模块运行需要的一系列参数,其实就是一个字符串。因此,我们首先祭出最核心的一个接口(函数): int GMT_Call_Module (void *API, const char *module, int mode, void *args); 这个函数一共有 4 个参数,分别为: void *API GMT 模块调用总接口指针,同一个指针表示同一组调用。一般不用管,除非你在一个程序里要调用多组画图流程; const char *module 需要调用的模块名称,如 grd2cpt; int mode 调用的模式,一般为 GMT_MODULE_CMD(文后我们会列出可选的类型); void *args 模块调用使用的参数,如 example.nc -Rd -Z -D > user.cpt。 看明白了么?GMT 的 C 语言接口其实非常的强大(傻瓜),我们要做的就是根据我们的数据编写相应模版的参数字符串。例如上面的 grd2cpt 命令从 API 调用就可以写成: ...

September 4, 2020 · 1 分钟 · 142 字 · 张壹

GMT 脚本进阶(三):脚本的分享与扩展

本系列共 4 篇:(一)Shell 技巧 · (二)怎样 getopts · (三)分享与扩展 · (四)C 语言 API 上一篇文章中我们介绍了如何使用 getopts 来获取 GMT 脚本执行时需要的命令行参数。通过使用 getopts 我们已经基本实现了 GMT 绘图过程的对象化,即给一个网格文件画一张图这样的基本操作。这样的工作流程的确很方便,但是它也有它不方便的地方。 其一是你不太可能在编写脚本之初就考虑到以后在使用过程中的所有需求,所以你可能还是需要经常为你的脚本添加和修改命令选项。这当然很好,你的脚本会越来越强大。但是过多的命令选项会让脚本的使用变得越来越困难,其他人可能需要花很多时间来学习它。而且,有的需求其实是一次性的,这时候去修改脚本显然并不划算。另一个不足之处是分享你的脚本将变得困难。设想这样一个情景,你想分享你的数据和对应的绘图脚本给你的同事,你发现你面对的并不是简单地将文件夹打包一下的情况。你需要将你的模版脚本拷贝到文件夹打包发送,然后告诉你的同事怎么使用这个脚本绘图,或者另写一个说明。这无疑增加了整个分享过程的复杂度。要是你的同事想将压缩包分享给第三人,那情况就更复杂了。 看到这里你可能会想“赶紧来点干的啊!”。 干的来了。 本篇教程我们就是要来解决分享与扩展性的问题,即如何将脚本特例化。什么意思?为了应对分享与扩展性这两个问题,我们的解决思路是在需要的时候为特定的数据(集)自动生成对应的绘图脚本。这个脚本内只包含 GMT 绘图命令,所以可以在任何装有 GMT 的电脑上运行。你的同事面对的只是单纯的 GMT 脚本,因此不需要额外学习任何其他知识。同时,你自己可以使用生成的脚本进行二次编辑,从而满足额外的绘图需求。这样就大大提高了模版脚本的扩展性。 说了这么多,到底怎么弄? 答:写一个 Shell 函数,接收一个规则字符串和一个命令字符串,视规则执行或者打印命令字符串。就是说每当我们要执行一条 GMT 绘图命令时都要经过这个函数。如果我们想要绘图,这个时候就执行这个绘图命令;如果我们想要得到的是命令本身,就打印这条命令。 有了这个思路,我们来直接看这个函数: # 执行输入的语句或者将其显示在屏幕上 参数1(0显示 1执行)参数2(命令语句)参数3(命令语句) RunOrEcho() { # 预处理 去除命令语句中的制表符 first_str=`echo ${2// /''}` # 判断第三个参数是否存在 if [[ x${3} != x ]]; then sec_str=`echo ${3// /''}` fi # 如果第一个参数为1则执行命令语句 否则在屏幕上显示命令语句 if [[ ${1} == 1 ]]; then ${first_str} if [[ x${3} != x ]]; then ${sec_str} fi else if [[ x${3} != x ]]; then printf "%s\n%s\n" "${first_str}" "${sec_str}" else printf "%s\n" "${first_str}" fi fi } 简单地测试一下这个函数: ...

July 22, 2020 · 2 分钟 · 419 字 · 张壹

GMT 脚本进阶(二):怎样用 getopts 拾取命令行参数

本系列共 4 篇:(一)Shell 技巧 · (二)怎样 getopts · (三)分享与扩展 · (四)C 语言 API 上一篇文章中我们介绍了一些在 GMT 脚本编写中可能会用到的 Shell 编程基础知识,今天我们将介绍 Linux 中一个很棒的内置命令 getopts。使用它我们可以方便地自定义标签并获取命令行参数。本篇教程将首先通过一个例子介绍 getopts 的使用方法,然后结合之前我们学习的 gmt_shell_functions.sh 脚本编写一个自动化绘制平面图的 Shell 脚本。如果你准备好了,我们就开始吧。 getopts 简短说明 话不多说,先上例子(personal_info.sh,不用着急看脚本,我们会在后面逐步讲解): #!/bin/bash # 这个简单脚本会拾取姓名、年龄与性别三个参数并显示对应的信息。 # 初始化三个变量name age gender为Unknown name="Unknown" age="Unknown" gender="Unknown" # 显示个人信息 参数依次为 name age gender show_info() { if [[ ${2} -ge 18 && ${3} == 'm' ]]; then echo ${1} is a ${2} years ago man. elif [[ ${2} -ge 18 && ${3} == 'f' ]]; then echo ${1} is a ${2} years ago woman. elif [[ ${2} -lt 18 && ${3} == 'm' ]]; then echo ${1} is a ${2} years ago boy. elif [[ ${2} -lt 18 && ${3} == 'f' ]]; then echo ${1} is a ${2} years ago girl. else echo "Alien." fi } # 使用getopts从命令行获取参数 while getopts "hn:a:g:" arg do case $arg in # 拾取到-h选项,显示帮助信息后退出 h) printf "usage: ${0##*/} -n<name> -a<age> -g<gender> [-h]\n" printf "%s\t%s\n" "-n" "Your name" printf "%s\t%s\n" "-a" "Your age." printf "%s\t%s\n" "-g" "Your gender. Enter 'm' for male and 'f' for female." printf "%s\t%s\n" "-h" "Show help information." exit 0;; n) name=$OPTARG;; # 对变量进行赋值,注意后跟双分号结束。 a) age=$OPTARG;; g) gender=$OPTARG;; ?) # 拾取到未知参数,显示帮助信息后退出。 printf "error: unknow argument\nuse -h option to see help information.\n" exit 1;; esac done # 检查参数值并调用函数显示个人信息 if [[ ${name} != "Unknown" && ${age} != "Unknown" && ${gender} != "Unknown" ]]; then show_info ${name} ${age} ${gender} fi 在终端运行此脚本: ...

July 6, 2020 · 4 分钟 · 685 字 · 张壹

GMT 脚本进阶(一):Shell 编程技巧

本系列共 4 篇:(一)Shell 技巧 · (二)怎样 getopts · (三)分享与扩展 · (四)C 语言 API 一般来说,我们在使用 GMT 绘制图件时可能会保留一些老的脚本。在需要时拷贝到工作文件夹中,再做适当修改并使用。这种方式的好处是对于特定数据有定制化的绘图脚本,可以方便的分享给他人。但是这种方式的不足即是脚本编写的工作量大、复用性差。而且随着脚本数量的增多,我们可能很难快速找到适用的老脚本。所以,利用 Shell 可编程属性,将常用的绘图流程标准化、模块化是提高 GMT 使用效率的重要一步,也是我们 GMT 脚本进阶的第一步。 本系列将分步骤介绍如何编写模块化的 GMT 脚本,帮助我们在日常使用中达到在任意文件夹内无需编写专门脚本也可以快速出图、批量化出图的要求。本篇内容为 Shell 编程中的一些基础知识,在我们后续的教程中会用到,大家可以先熟悉一下。 本教程中的脚本均在 Bash Shell 中测试通过。Windows 用户可使用 PowerShell。 使用变量 Shell 中可声明并使用变量,语法如下: # 注意变量名称与值之间用等号连接,不能有空格 name="Joe" age="19" # 使用变量时需添加$符号或使用${}包含,下面的语句将在终端显示Joe is 19 echo ${name} is ${age} # 对变量赋值时不需要添加$符号 age=20 # 下面的语句将在终端显示Joe is 20 echo ${name} is ${age} 为保证变量的正确调用,建议在任何时候都使用 ${ } 的方式。需要说明的是 Shell 中的所有变量都是作为字符串处理的,所以 age="19" 与 age=19 的含义是一样的。我们可以使用双引号或单引号来表示一个字符串,不同的是双引号中可包含变量,而单引号内的所有字符都将按照其原意进行处理。 使用函数 在 Shell 中我们可以将常用方法定义为函数,方便重复使用与管理。语法如下: # function标识可省略 function <func_name>() { <action> # return语句可省略 <return int> } 看一个具体的例子: ...

July 4, 2020 · 1 分钟 · 200 字 · 张壹

gmtsph-JA:方位等距投影下全球网格数据绘图

gmtsph-JA 是一个 shell 脚本,基于 GMT5 使用方位等距投影(azimuthal equidistant projection)绘制全球网格数据,用于快速浏览 .nc 或 .grid 文件的整体面貌。对于更精细、定制化的需求,仍然需要自行编写脚本。 安装 将脚本 dispOptions.sh 和 gmtsph-JA.sh 复制(或软链接)到任意一个位于 $PATH 中的目录,然后重新打开终端即可使用。 下载 gmtsph-JA.zip Setup 配置 请打开 gmtsph-JA.sh 文件末尾,你会看到类似下面的行: imgcat $jpgfile #open the output file in terminal, this requires the iTerm.app and imgcat.sh open $jpgfile #'open' is a command in-build within MacOS 可按你的环境选用其中一种。若使用 Ubuntu,可以用命令 see;其他 Linux 发行版对应的命令需自行确认。 用法 gmtsph-JA -i<grid-data> [-r<xmin>/<xmax>/<ymin>/<ymax>] [-l<clon>/<clat>/<horizon>] [-u<unit>] [-c<cpt-file>] [-a<x-label>,<y-label>] [-v<c-tick>] [-g] [-s] [-G<grad-data>] [-p<polygon-file>] 选项说明 -i:输入网格文件名。最好使用 .nc 文件,不过 GMT5 也支持 Surfer 的网格格式。注意数据范围应覆盖整个地球。 -r:输入网格数据的范围,默认使用全部数据范围;使用此选项可强制自定义绘图范围。 -l:设置投影中心经纬度与图上显示的角度范围。 -u:输入数据的单位。特殊情况下,若数据单位为米而想用 km 标注色标,可将参数设为 km+Uk 以开启该功能。 -c:用于生成数据专属 cpt 文件的输入 cpt 文件。默认使用 GMT 的 grd2cpt 命令;若想直接使用输入 cpt 文件,需用 -n 选项禁用 grd2cpt。 -a:用逗号分隔的坐标轴标签。 -v:手动设置色标标注的间隔。 -g:额外叠加一层地形阴影,使输出图像具有 3D 质感,默认使用输入网格数据。 -G:用另一个网格文件绘制地形阴影,注意该文件范围应等于或大于数据网格。 -s:绘制昼夜分界线。 -p:读取并绘制多边形边界。 示例 用以下命令绘制 example.nc。输出文件名取自输入网格文件名,脚本会同时输出一张 png(无背景)和一张 eps 文件: ...

November 26, 2018 · 1 分钟 · 115 字 · 张壹

gmtsph-profile:极坐标剖面数据绘图

gmtsph-profile 是一个 shell 脚本,基于 GMT5 在极坐标系下绘制 2D 网格数据的垂直剖面图,用于快速浏览 .nc 或 .grid 文件。对于更精细、定制化的需求,仍然需要自行编写脚本。 安装 将脚本 dispOptions.sh 和 gmtsph-profile.sh 复制(或软链接)到任意一个位于 $PATH 中的目录,然后重新打开终端即可使用。 下载 gmtsph-profile.zip Setup 配置 请打开 gmtsph-profile.sh 文件末尾,你会看到类似下面的行: imgcat $jpgfile #open the output file in terminal, this requires the iTerm.app and imgcat.sh open $jpgfile #'open' is a command in-build within MacOS 可按你的环境选用其中一种。若使用 Ubuntu,可以用命令 see;其他 Linux 发行版对应的命令需自行确认。 用法 gmtsph-profile -i<grid-data> [-r<start-deg>/<end-deg>/<r>/<R>] [-u<unit>] [-c<cpt-file>] [-a<x-label>;<y-label>] [-f<offset>] [-h] 选项说明 -i:输入网格文件名。最好使用 .nc 文件,不过 GMT5 也支持 Surfer 的网格格式。 -r:输入网格数据的范围,默认使用全部数据范围;使用此选项可强制自定义绘图范围。 -u:输入数据的单位。 -c:用于生成数据专属 cpt 文件的输入 cpt 文件,默认使用 GMT 的 grd2cpt 命令。 -a:用分号分隔的坐标轴标签。 -f:剖面的偏移角度,默认使用 x 范围的平均值,这样会把 x 的平均值置于绘图中心。 -h:显示帮助信息。 示例 用以下命令绘制 example.nc。输出文件名取自输入网格文件名,脚本会同时输出一张 png(无背景)和一张 eps 文件: ...

November 16, 2018 · 1 分钟 · 100 字 · 张壹

gmtxy-image:直角坐标下网格数据图像化绘图

gmtxy-image 是一个 shell 脚本,基于 GMT5 在直角坐标系下将 2D 网格数据绘制为图像,用于快速浏览 .nc 或 .grid 文件。对于更精细、定制化的需求,仍然需要自行编写脚本。 安装 将脚本 dispOptions.sh 和 gmtxy-image.sh 复制(或软链接)到任意一个位于 $PATH 中的目录,然后重新打开终端即可使用。 下载 gmtxy-image.zip Setup 配置 请打开 gmtxy-image.sh 文件末尾,你会看到类似下面的行: imgcat $jpgfile #open the output file in terminal, this requires the iTerm.app and imgcat.sh open $jpgfile #'open' is a command in-build within MacOS 可按你的环境选用其中一种。若使用 Ubuntu,可以用命令 see;其他 Linux 发行版对应的命令需自行确认。 用法 gmtxy-image.sh -i<grid-data> [-r<xmin>/<xmax>/<ymin>/<ymax>] [-u<unit>] [-c<cpt-file>] [-a<x-label>,<y-label>] [-g] [-h] 选项说明 -i:输入网格文件名。最好使用 .nc 文件,不过 GMT5 也支持 Surfer 的网格格式。 -r:输入网格数据的范围,默认使用全部数据范围;使用此选项可强制自定义绘图范围。 -u:输入数据的单位。特殊情况下,若数据单位为米而想用 km 标注色标,可将参数设为 km+Uk 以开启该功能。 -c:用于生成数据专属 cpt 文件的输入 cpt 文件,默认使用 GMT 的 grd2cpt 命令。 -a:用逗号分隔的坐标轴标签。 -g:额外叠加一层地形阴影,使输出图像具有 3D 质感,默认使用输入网格数据。 -h:显示帮助信息。 示例 用以下命令绘制 example.nc。输出文件名取自输入网格文件名,脚本会同时输出一张 png(无背景)和一张 eps 文件: ...

November 15, 2018 · 1 分钟 · 102 字 · 张壹

gmtsph-regional:球坐标下局部网格数据快速绘图

gmtsph-regional 是一个 shell 脚本,基于 GMT5 在球坐标系下绘制区域网格数据。它的设计目的是让你能够快速浏览一个 .nc 或 .grid 文件的整体面貌,省去每次都要敲一长串 GMT 命令的麻烦。对于更精细、定制化的需求,仍然需要自行编写脚本。 安装 将脚本 dispOptions.sh 和 gmtsph-regional.sh 复制(或软链接)到任意一个位于 $PATH 中的目录,然后重新打开终端即可使用。 下载 gmtsph-regional.zip Setup 配置 请打开 gmtsph-regional.sh 文件末尾,你会看到类似下面的行: imgcat $jpgfile #open the output file in terminal, this requires the iTerm.app and imgcat.sh open $jpgfile #'open' is a command in-build within MacOS 可按你的环境选用其中一种。若使用 Ubuntu,可以用命令 see;其他 Linux 发行版对应的命令需自行确认。思路都是一样的。 用法 gmtsph-regional -i<grid-data> [-r<xmin>/<xmax>/<ymin>/<ymax>] [-u<unit>] [-c<cpt-file>] [-a<x-label>,<y-label>] [-t<x-tick>,<y-tick>] [-v<c-tick>] [-l<size>] [-g] [-G<grad-data>] [-b] [-n] [-p] 选项说明 唯一必须输入的参数是网格文件名,即可快速查看文件面貌。若想细致调整,可使用以下选项: -i:输入网格文件名。最好使用 .nc 文件,不过 GMT5 也支持 Surfer 的网格格式。注意数据范围不应跨越赤道,否则 GMT5 的 -JL 投影会触发内部错误。基于这一点,你也可以很方便地修改脚本中 grdimage 命令的 -J 选项来改用其他投影。 -r:输入网格数据的范围,默认使用全部数据范围;使用此选项可强制自定义绘图范围。 -u:输入数据的单位。特殊情况下,若数据单位为米而想用 km 标注色标,可将参数设为 km+Uk 以开启该功能。 -c:用于生成数据专属 cpt 文件的输入 cpt 文件。默认使用 GMT 的 grd2cpt 命令;若想直接使用输入 cpt 文件,需用 -n 选项禁用 grd2cpt。 -a:用逗号分隔的坐标轴标签。 -t:手动设置坐标轴标注的间隔。 -v:手动设置色标标注的间隔。 -l:从预定义类型 exsmall、small、middle、large 中选择页面布局,各类型的具体数值见脚本内部。 -b:绘制海岸线。 -g:额外叠加一层地形阴影,使输出图像具有 3D 质感,默认使用输入网格数据。 -G:用另一个网格文件绘制地形阴影,注意该文件范围应等于或大于数据网格。 -n:禁用 grd2cpt。 -p:反转 -c 选项指定的颜色模式;若使用了 -n 选项则此选项无效。 示例 用以下命令绘制 example.nc。输出文件名取自输入网格文件名,脚本会同时输出一张 png(无背景)和一张 eps 文件: ...

November 12, 2018 · 1 分钟 · 135 字 · 张壹