如题。——这是一篇工作日志。
今天基本上没写代码,我感觉整个身体的细胞都活跃了一些。干了件啥事儿呢?去年在服务器和地面站上都搞了个全中国的DEM数据服务,方便用户在线和离线查询高程,也方便一些航线规划算法的实现,比如“仿地飞行”啦之类的。这两年销售和技服陆陆续续打出国门,开始服务国外客户了,中国区域的DEM数据不够用了,最近韩国和马拉西亚卖出去的无人机配套服务都需要这玩意儿。所以,今天应同事要求先把这两个区域的DEM数据制备了。DEM数据当然用的SRTM_GL1,目前30m分辨率下我觉得质量最好的一款免费产品。N多种数据下载福利链接看这里:圣地亚哥超级计算中心的教育资源。
工作内容很简单,但为什么决定说一说呢?——因为我翻出以前用IDL写的批处理小程序时,那洋洋得意之情需要宣泄啊!(*^▽^*)
说起IDL(Interactive Data Language)这门语言(有两种IDL,我说的是交互式数据语言),啧啧啧,真是不堪回首的东西。曾几何时的研究生阶段,自学了一学期的IDL。我倾心于它那优异的运算性能和庞大的数学和图像计算库,冀望于用它搞出基于我自研的SAR图像边缘检测算法IROEWA&NMS的应用软件,但从入门到放弃。那时国内就仅有一本中文教程,买来一看那简陋得就只剩语法了。然鹅,语法还很不C系,写起来超级别扭;处理事件的消息泵只能放在每篇代码末尾,特别不自由,学习了一下和CSharp的混合编程最后也放弃了。
其实IDL是一门很强大的语言,怎么说呢?它和Matlab一样,是科学计算语言,根子里的世界观都是“矩阵”,强大的数学和图像计算库,非常适合搞算法实现和仿真(听说现在很火的是Python?);但我当初用它搞图形界面的应用软件,毫无意外会很痛苦。如果你和我一样是遥感或GIS专业,应该对它有所了解或者耳闻。遥感学界强大的ENVI软件,就是用IDL写的,并且IDL是其官方的二次开发语言,IDL和ENVI的库经常搅在一起傻傻分不清,编程模式也分为纯IDL和IDL+ENVI等等。用IDL最多的人应该主要集中在——NASA和美国国家地质局。总之,Matlab有的优点它基本都有,它还比Matlab小而且快。我曾经还对比过OpenCV和IDL实现的Canny算子,论起检测效果和速度来说OpenCV被爆了菊花,——鹅,我的意思是测试用图是一朵菊花。
研究生毕业以后,我算是离开这个恶魔很久了。但是自去年搞DEM数据服务,IDL又瞬间变成了天使,对于空间栅格数据的各种批处理,真的是又快又能干,需要转个格式或者加个高程异常修正啥的,短短几行代码搞定。说到这儿,我就把DEM数据HGT转GeoTIFF文件格式的批处理小程序放出来分享分享吧!
博客编辑器没有提供这门语言的代码着色,只好纯白凑合一下:
PRO ENVI_BATCH_HGT2TIFF
compile_opt IDL2
;
; First restore all the base save files.
;
envi, /restore_base_save_files
;
; Init ENVI batch, and set the log file
;
envi_batch_init, log_file = 'batch_hgt2tif.log'
;
; Turn off the status window and do the same
;
envi_batch_status_window, /off
;
; Open the input files
;
files = envi_pickfile(FILTER = '*.hgt', /MULTIPLE_FILES, /NO_CHANGE)
print, files
print, n_elements(files)
;
; Set the saving folder
;
out_dir = envi_pickfile(/DIRECTORY, /NO_CHANGE)
print, out_dir
;
; Convert hgt to tiff
;
for i = 0, n_elements(files) - 1 do begin
envi_open_file, files[i], r_fid = fid
envi_file_query, fid, dims = dims, nb = nb
if (fid eq -1) then begin
print, 'miss:' + files[i] + '!'
continue
endif
out_name = out_dir + '\' + file_basename(files[i], '.hgt') + '.tif'
print, out_name
envi_output_to_external_format, out_name = out_name, fid = fid, dims = dims, pos = indgen(nb), /TIFF
endfor
print, 'done!'
;
; Exit ENVI Batch
;
envi_batch_exit
END
如你所见:①是的,IDL大小写不敏感,并且分号是注释符号;②函数(FUNCTION)和程式(PRO)有两类参数——占位参数Arguments和关键字参数Keywords,占位参数通过在参数表中的确定位置来赋值,而形如FILTER = '*.hgt'的是关键字参数,这里是给FILTER关键字参数赋值,而不是C系的参数默认值语法;③形如/KEYWORD的是一类特殊的关键字参数,可以理解成KEYWORD=1,主要用于某些可选功能的“开”和“闭”;④关键字参数都是顺序无关、位置无关的,甚至是可以缩写的(这要求同一函数或程式中任何关键字不等于或部分包含其他关键字),因此IDL的参数表是可变的,不像C系语法是强签名;⑤关键字参数还有一个特性,那就是如果你给一个关键字参数赋以外部变量,那么程式内部改变关键字参数的值,外部变量的值跟着改变,这相当于C系的引用传参;⑥调用程式的语法是“程式名称, 参数表“,而调用函数的语法是“返回值=函数名称(参数表)”;⑦另外函数和程式的代码文件后缀都是.pro,和Qt工程文件一样,呵呵~
工作流程很简单:
先在ArcGIS里添加了一个世界街道地图作为底图,用1°×1°的网格划分一下,把完全覆盖目标区域的网格左下角经纬度读出来,组成形如“N03E110”的文件名,去前面介绍的网站的对应目录下载对应文件(当然要下的数据量大的话可以自己写个爬虫,我这里就没有必要了,都是些小国家)。
下载完数据之后是HGT格式的数据,这个格式只有专业遥感和GIS软件才能打开,运行一下我的IDL批处理小程序,转成大家都能接受的TIFF格式(实际上是GeoTIFF,并带有附属文件WorldFile(.tfw)存着仿射变换参数)——控制台回车,多选HGT文件,选择一个文件夹存放转出的*.tif文件,然后小酌一口咖啡吧!
最后在ArcGIS里看一下,没有转换损坏的文件,就OK啦!