IDL处理卫星数据
- HDF文件
- 数据集属性
- 通用属性
- 常用HDF4操作函数
- 常用的HDF5操作函数
- 读取HDF文件的一般步骤
- HDF4文件读取-----数据信息查询
- HDF4文件读取示例-----目标数据TIFF输出
HDF文件
数据集属性
数据集名称,是“:”前的一部分,不是long_name中的文字
通用属性
查看hdf的软件为HDF Explorer。也可以尝试使用Panoply进行简单的数据可视化(该软件也可以读nc文件)。
常用HDF4操作函数
HDF_SD_START函数是打开一个hdf文件。
HDF_SD_FILEINFO函数是查询hdf文件信息的。
HDF_SD_SELECT是选择数据集。
HDF_SD_NAMETOINDEX,已知数据集名称的情况下,获取数据集id号。
HDF_SD_GETDATA,获取指定数据集的id号所包含的数据。
HDF_SD_ATTRINFO,获取hdf属性信息。
使用完之后必须要关闭这个文件,不然的话相当于这个文件一直被占用,需要关闭、释放后掉。
常用的HDF5操作函数
读取HDF文件的一般步骤
1.指定文件名
2.打开文件
3.获取数据集/属性名称
4.获取数据集/属性ID
5.获取数据集/属性内容
6.下一步处理
HDF4文件读取-----数据信息查询
流程:
指定文件名–打开文件–获取文件数据集、属性的个数—循环获取数据集信息—(循环)—选中当前循环的数据集----获取当前数据集名称、属性个数、循环获取数据集属性信息----(是否完成循环)----否----获取属性名。-----是----判断数据集循环是否结束,若是则释放文件,若否循环继续。最后,释放文件
把光标放在函数上,按f1会直接跳转帮助
hdf_sd_fileinfo,sd_id,sds_num,att_num
文件名,文件id,(再任意定义两个文件名装返回结果),DataSets(数据集个数), Attributes(属性个数)--------获取文件数据集/属性个数
循环获取数据集信息:
pro hdf4_file_info_extractmodis_data = 'E:\Data\modis\2019\05\MOD09GA.A2019130.h27v05.061.2020293213719.hdf'sd_id = hdf_sd_start(modis_data,/read)hdf_sd_fileinfo,sd_id,sds_num,att_num;print,sds_num;print,att_numfor sds_i = 0, sds_num - 1 do beginsds_id = hdf_sd_select(sd_id, sds_i)hdf_sd_getinfo,sds_id,name = sds_name,natts = sds_att_num ;此时这一行的左边赋值给右边,name是关键字,特例print, 'The sds name of '+strcompress(string(sds_i))+':'print,sds_att_numprint,'The include attributes name:'if sds_att_num gt 0 then begin ;循环获取属性信息for att_i=0,sds_att_num-1 do beginhdf_sd_attrinfo, sds_id, att_i, name=sds_att_name;通过name关键字传递属性名称给右边的sds_att_nameprint,sds_att_nameendforprint,string('****************************************')endifhdf_sd_endaccess, sds_id;关闭释放数据集endforend
- sds_id = hdf_sd_select(sd_id, sds_i)选中数据集.在sd_id文件下,sds_i的地址id是多少传递给sds_id
- hdf_sd_getinfo,sds_id,name = sds_name,natts = sds_att_num获取在sds_id位置上,文件的名字是什么,在这个文件下,又有多少数据集的属性att_num,赋值给natts
- hdf_sd_getinfo,sds_id,name = sds_name,natts = sds_att_num ;此时这一行的左边赋值给右边,name是关键字,特例
- hdf_sd_attrinfo, sds_id, att_i, name=sds_att_name;通过name关键字传递属性名称给右边的sds_att_name
- hdf_sd_endaccess, sds_id;关闭释放数据集
- hdf_sd_attrinfo, sds_id, att_i, name=sds_att_name只是显示了数据集名字,如果想显示内容,可以加一个关键词,data = sds_data_info,获取到的信息很多时候是一个数组
pro hdf4_file_info_extractmodis_data = 'E:\Data\modis\2019\05\MOD09GA.A2019130.h27v05.061.2020293213719.hdf'sd_id = hdf_sd_start(modis_data,/read)hdf_sd_fileinfo,sd_id,sds_num,att_num;print,sds_num;print,att_numfor sds_i = 0, sds_num - 1 do beginsds_id = hdf_sd_select(sd_id, sds_i)hdf_sd_getinfo,sds_id,name = sds_name,natts = sds_att_num ;此时这一行的左边赋值给右边,name是关键字,特例print, 'The sds name of '+strcompress(string(sds_i))+':'print,sds_att_numprint,'The include attributes name:'if sds_att_num gt 0 then begin ;循环获取属性信息for att_i=0,sds_att_num-1 do beginhdf_sd_attrinfo, sds_id, att_i, name=sds_att_name,data = sds_data_info;通过name关键字传递属性名称给右边的sds_att_nameprint,sds_att_namehelp,sds_attnamehelp,sds_data_infoendforprint,string('****************************************')endifhdf_sd_endaccess, sds_id;关闭释放数据集endforend
如果想把sds_att_name、sds_attname同时输出的时候呢?
if sds_att_num gt 0 then begin ;循环获取属性信息for att_i=0,sds_att_num-1 do beginhdf_sd_attrinfo, sds_id, att_i, name=sds_att_name,data = sds_data_info;通过name关键字传递属性名称给右边的sds_att_nameprint,sds_att_name + sds_data_infoendforprint,string('****************************************')endif
此时有内部转换错误,因为字符串和数据集内变量相加,不能直接相加,需要强制类型转换为string
if sds_att_num gt 0 then begin ;循环获取属性信息for att_i=0,sds_att_num-1 do beginhdf_sd_attrinfo, sds_id, att_i, name=sds_att_name,data = sds_data_info;通过name关键字传递属性名称给右边的sds_att_nameprint,sds_att_name + string(sds_data_info)endforprint,string('****************************************')endif
此时可以相加,但是结果如图所示
valid_range 0
valid_range 2147483647
_FillValue -1
中间有很长的空格,此时是因为强制类型转换后,把转换前前面有多少个位也显示出来了,因此需要添加函数strcompress,使得空格不再那么长
if sds_att_num gt 0 then begin ;循环获取属性信息for att_i=0,sds_att_num-1 do beginhdf_sd_attrinfo, sds_id, att_i, name=sds_att_name,data = sds_data_info;通过name关键字传递属性名称给右边的sds_att_nameprint,sds_att_name + strcompress(string(sds_data_info))endforprint,string('****************************************')endif
此时结果:
The include attributes name:
long_nameNumber of additional observations per row
unitsnone
valid_range 0 valid_range 2147483647
_FillValue -1
如果一个空格都不想要,就可以添加关键字“/remove_all”
if sds_att_num gt 0 then begin ;循环获取属性信息for att_i=0,sds_att_num-1 do beginhdf_sd_attrinfo, sds_id, att_i, name=sds_att_name,data = sds_data_info;通过name关键字传递属性名称给右边的sds_att_nameprint,sds_att_name + strcompress(string(sds_data_info),/remove_al)endforprint,string('****************************************')endif
结果为:
The include attributes name:
long_nameNumberofadditionalobservationsperrow
unitsnone
valid_range0 valid_range2147483647
_FillValue-1
此时结果不好区分,可以认为在中间加一个冒号
print,sds_att_name + ':'+strcompress(string(sds_data_info),/remove_al)
获取全局信息,以及释放文件:
pro hdf4_file_info_extractmodis_data = 'E:\Data\modis\2019\05\MOD09GA.A2019130.h27v05.061.2020293213719.hdf'sd_id = hdf_sd_start(modis_data,/read)hdf_sd_fileinfo,sd_id,sds_num,att_num;print,sds_num;print,att_numfor sds_i = 0, sds_num - 1 do beginsds_id = hdf_sd_select(sd_id, sds_i)hdf_sd_getinfo,sds_id,name = sds_name,natts = sds_att_num ;此时这一行的左边赋值给右边,name是关键字,特例print, 'The sds name of '+strcompress(string(sds_i))+':'print,sds_att_numprint,'The include attributes name:'if sds_att_num gt 0 then begin ;循环获取属性信息for att_i=0,sds_att_num-1 do beginhdf_sd_attrinfo, sds_id, att_i, name=sds_att_name,data = sds_data_info;通过name关键字传递属性名称给右边的sds_att_nameprint,sds_att_name + ':'+strcompress(string(sds_data_info),/remove_al)endforprint,string('****************************************')endifhdf_sd_endaccess, sds_id;关闭释放数据集endforfor att_i = 0, att_num-1 do beginhdf_sd_attrinfo,sd_id,att_i, name = att_nameprint,'global att name:'print,att_nameendforhdf_Sd_end,sd_idend
HDF4文件读取示例-----目标数据TIFF输出
数组和数字 sf[0] 相乘 VS 数组和数组 sf 相乘 注意区分!
pro hdf4_dataset_readfilename = 'E:\Data\modis\2019\05\MOD09GA.A2019130.h27v05.061.2020293213719.hdf'result_name = 'E:\Data\modis\2019\result\MOD09GA.A2019130.h27v05.061.2020293213719.tiff'modis_sd_id = hdf_sd_start(filename,/read)modis_sds = 'sur_refl_b02_1'modis_sds_index = hdf_sd_nametoindex(modis_sd_id,modis_sds);找到文件地址modis_sds_id = hdf_sd_select(modis_sd_id,modis_sds_index);转换为文件id号hdf_sd_getdata,modis_sds_id,modis_band2 ;由id找到文数据集,赋值给modis_band2modis_sds = 'sur_refl_b03_1'modis_sds_index = hdf_sd_nametoindex(modis_sd_id,modis_sds)modis_sds_id = hdf_sd_select(modis_sd_id,modis_sds_index)hdf_sd_getdata,modis_sds_id,modis_band3modis_att_index = hdf_sd_attrfind(modis_sds_id,'scale_factor')hdf_sd_attrinfo, modis_sds_id,modis_att_index,data=sfmodis_att_index = hdf_sd_attrfind(modis_sds_id,'_FillValue')hdf_sd_attrinfo,modis_sds_id,modis_att_index,data=fvhdf_sd_endaccess,modis_sds_idhdf_SD_end,modis_sd_idmodis_target_data = modis_band2modis_target_data = (modis_target_data ne fv[0])*modis_target_data*sf[0] ;注意这里乘以的是一个数,而不是一个恶搞数组write_tiff,result_name, modis_target_data,/float ;必须要加一个 /float 否则可能输出的是一个黑白图end
保存出去的图为:
保存成功!