1. 课堂内容
读取OMI数据(HDF5)并输出为Geotiff文件,最重要的是数据的处理以及输出
这里我个人觉得难度不大,
第一,获取OMI文件的NO2数据集的数据以及对数据中的异常值做处理(譬如全部变成0),以及数据中每一个值都比较大,那么我们为了方便会进行数据的单位换算
第二,本来现在就可以输出为tiff文件了, 但是我们由于需要输出为有地理信息的tiff文件而不是说普通的tiff文件,那么地理信息怎么输出,会有一个结构体,专门用来存储地理信息,而且里里面的大部分信息都不需要我们去填写,按常规就好,主要需要填写两个内容,一个输出的空间分辨率是多少,另一个是需要填写 某一点(一般是左上角点)或者说某一个像元在整幅图像的行列数以及该点或者说该像元的经纬度——》即像元的行列数和经纬度
2. 知识储备
3. 编程
; 构建函数:得到数据集的数据 function get_hdf5_ds, file_path, ds_path ; 传入数据集所在文件的路径、传入数据集在文件里的路径 ; 获取数据集所在文件的路径 file_id = h5f_open(file_path) ; 传入数据集所在文件的id ; 获取数据集的id ds_id = h5d_open(file_id, ds_path) ; 传入数据集所在文件的id, 传入数据集在文件中的路径 ; 另外,这里和HDF4文件的数据集id的获取有一些差别,4里面是需要先由name获取index,在由index获取id。5里面可以直接由name获取id ; 获取数据集的数据 ds_data = h5d_read(ds_id) ; 传入数据集的id ; 关闭数据集以及文件的id h5d_close, ds_id h5f_close, file_id ; 返回数据集的数据 return, ds_data end pro week_three_study2 ; 本程序主要解决如何读取OMI数据(HDF5格式)并将其输出为Geotiff格式(和之前的输出为普通的Tiff格式不同) ; 获取数据集所在文件的路径 file_path = 'D:\IDL_program\experiment_data\chapter_2\NO2\2017\OMI-Aura_L3-OMNO2d_2017m0101_v003-2018m0627t042221.he5' ; 数据集所在文件的路径 ds_path = '/HDFEOS/GRIDS/ColumnAmountNO2/Data Fields/ColumnAmountNO2TropCloudScreened' ; 大家应该看得出来这个数据集是关于什么的吧——》NO2 的 柱含量 ; 获取数据集的数据 data = get_hdf5_ds(file_path, ds_path) ; 通过hdf explorer软件查看GRidSpan属性知从左至右图像范围是(-180W, 180E), 从上至下是(-90S, 90N) ; 显然,我们需要将南北纬颠倒一下(东西经则不需要), 也就是x = x, y = -y data = rotate(data, 7) ; 使用rotate()函数可以实现矩阵的颠倒 ; 通过F1键(光标要在rotate处)可以查看几种矩阵颠倒的方式,我们的颠倒方式的代号是7 ; 进行数据的处理 ; 1. 由于气候等原因有一些地方的NO2无法观测,所以会有一个 ; 1. (通过hdf explorer软件查看该数据集的Missing Value属性可知该数据集的填充值是-1.26765*10^30)填充值 ; 现在进行异常值(为负数的异常值)的处理 data = (data gt 0) * data ; 将负数(异常的填充值)全部变成0,其它值不变 ; 2. 由于NO2的在每个像元的柱含量实在太大了(可以通过HDF Explorer软件进行查看是30次方) ; 2.一是为了阅读方便,二就是之后转成tiff格式方便做拉伸处理(太大的值可能软件就不会考虑进行拉伸导致失败) ; 2. 这里做一些单位换算,现在的单位是NO2分子数每立方cm(HDF Explorer软件查的),那么我们将其转化为mol/km2差不多是百位数字了 data = (data * 10.0 ^ 10.0) / (!const.NA) ; 另外这里最好10.0 ^ 10.0 而不是10 ^ 10,不然的话子出来的tiff你可能普通照片查看器看的就是一张黑色的 ; 你需要在Arcgis或者在Envi里面进行拉伸2%才可看的到 ; 至于这种换算应该是化学知识,我就不解释了,相信大家都会 ; 3. 现在转化为geotiff格式还差个地理信息没有 ; 这里构造geo结构体 geo_info = {$ ; 这里的$表示换行的意思,因为一行写不完这么多信息 MODELPIXELSCALETAG:[0.25,0.25,0.0],$;x、y、z方向的像元分辨率 MODELTIEPOINTTAG:[0.0,0.0,0.0,-180.0,90.0,0.0],$ ; 坐标转换信息,前三个0.0代表栅格图像上的第0,0,0个像元位置(z方向一般不存在), ; 后面-180.0代表x方向第0个位置对应的经度是-180.0度,90.0代表y方向第0个位置对应的纬度是90.0度 ; 另外为什么是-180,90呢?因为这是一张全球影像。 ; 另外需要说一下,原点是在左上角处,横轴是x轴(正方向是向右),纵轴是y(正方向是向下),这就是为什么(x = 0, y = 0)表示(E = -180W, N = 90N) ; 其实下面的信息了解就好(我也不太会,照抄就行),上面的信息是至关重要的的。 GTMODELTYPEGEOKEY:2,$ ; 这个我也知道,是二维网格(其实没看懂) GTRASTERTYPEGEOKEY:1,$ GEOGRAPHICTYPEGEOKEY:4326,$ GEOGCITATIONGEOKEY:'GCS_WGS_1984',$ ; 这个我知道,说明是WGS84椭球体 GEOGANGULARUNITSGEOKEY:9102,$ GEOGSEMIMAJORAXISGEOKEY:6378137.0,$ ; 这个应该是长半轴长度之类的,忘了 GEOGINVFLATTENINGGEOKEY:298.25722} ; 输出文件夹的路径 out_dir_path = 'D:\IDL_program\experiment_data\chapter_2\output' ; 假定你不知道最后你添加的文件夹output到底是不是之前创建过,而且你又不想查看资源管理器 if file_test(out_dir_path, /directory) eq 0 then begin ; 这里file_test()函数默认是用来检查文件是否存在,当然如果需要检查文件夹需要加上参数/directory ; 如果文件夹存在返回1,不存在返回0 ; 既然都已经进来if语句了,那就是不存在了,所以创建文件 file_mkdir, out_dir_path ; 传入路径 endif ; 输出文件的名称 out_name = file_basename(file_path, '.he5') + '.tiff' ; 传入文件的路径,那么会返回路径里面文件的名称,另外继续传入的字符串会与返回的文件名称做匹配,有一样的字符串就会被删除 ; 其实就是'.he5'相当于告诉函数将返回的文件名称不着急返回,看看它是不是也有'.he5',有的话就删除它 ; 后面那个'.tiff'就是前面的字符串连接起'.tiff'来嘛 ; 输出文件的路径 out_path = out_dir_path + '\' + out_name ; 输出geo_tiff文件 write_tiff, out_path, data, /float, geotiff = geo_info ; 传入即将导出的tiff文件的存储路径, 传入需要处理成tiff文件的数据,传入前面数据的存储格式(这里通过hdf explorer软件知道是float) ; 由于我们传入的不是普通的tiff文件,而是有地理信息的tiff文件,所以需要关键字参数geotiff=指定一下相关的地理信息 end
这里没有难度,报错不可怕,just see and fuck code