需求決定了動力,此時近凌晨一點,忙里偷閑,終於忙完了今天的“這點兒”事兒。參考幫助文檔,從hdf的讀寫,捉摸hdf5的讀寫,總算弄明白了。稍作總結,以備候查。
hdf5作為hdf數據的補充與升級,目前被新型的傳感器所采用(VIIRS,風雲三號等),但是如果沒有hdf5的sav擴展,低於5.1版本的envi是無法打開的(擴展可以到網上搜)方便起見,花一點兒時間捉摸了下hdf5的數據讀取,提取部分內容,寫為hdf文件,以方便查看。
Hdf5數據重要的是幾個概念:文件(File),組(Group),數據集(Dataset)。常用讀的數據過程是:文件讀取,組的讀取和數據集的讀取。
對應使用的函數是h5f_,h5g_,h5d_這三種。
常用的函數是:
h5_list可以列出一個文件中的所有的數據集,然后可以通過這些數據集,直接利用相應的read來獲取數據。
H5F_IS_HDF5判斷是不是h5格式的數據;H5F_OPEN打開一個文件,返回文件的id;H5G_GET_NMEMBERS可以根據組別的名字獲取組的成員個數;H5G_OPEN是根據組別的名字打開一個組,得到組的id;H5G_GET_MEMBER_NAME根據元素在文件中的索引位置(從0開始)獲取數據集,返回的是數據集的name;H5D_OPEN根據數據集的name打開數據集,返回數據集的id;H5D_READ是根據數據集的id獲取該數據集的數據內容。然后是對應的close函數。記得,打開的數據要注意關閉。
例子:讀取hdf5的數據(seadas產生的rrc數據),提取出bands組別內的所有數據集,寫入到一個hdf文件中,便於其他程序訪問。
PRO HDF5
;
COMPILE_OPT idl2
ENVI,/RESTORE_BASE_SAVE_FILES
ENVI_BATCH_INIT
;
hdf = 'F:\temp\A2014119053500.L2_LAC_OC_reprojected.h5'
is_h5 = H5F_IS_HDF5(hdf)
IF is_h5 EQ 0 THEN RETURN
;h5_list,hdf
hdf_id = H5F_OPEN(hdf)
group= '/bands'
elements_num = H5G_GET_NMEMBERS(hdf_id,group)
band_g_id = H5G_OPEN(hdf_id,group)
;
outpath = 'F:\temp\hdf_test.hdf'
if file_test(outpath) then file_delete,outpath
sd_id=HDF_SD_START(outpath,/CREATE)
;進度條
str=['Outpath='+outpath,'Reading and writing']
ENVI_REPORT_INIT, str, title="Processing...",base=base ,/INTERRUPT
ENVI_REPORT_INC, base, elements_num
FOR index = 0L, elements_num-1 DO BEGIN
;更新進度條
ENVI_REPORT_STAT,base, index, elements_num
;
item_Name = H5G_GET_MEMBER_NAME(hdf_id,group,index)
item_id = H5D_OPEN(band_g_id,item_Name)
;item_type_code = H5D_GET_TYPE(item_id)
;item_type = H5T_IDLTYPE(item_type_code)
item_data = H5D_READ(item_id)
;print,item_Name,typename(item_data)
;help,item_data
WRITE_HDF,sd_id,item_Name,item_data,typename(item_data)
h5d_close,item_id
ENDFOR
;close
h5g_close,band_g_id
h5f_close,hdf_id
HDF_SD_END,sd_id
envi_report_init,base=base,/finish
void = dialog_message('Processing completed!',/info)
; print, members
;envi_batch_exit
END
writehdf的pro:
PRO WRITE_HDF,sd_id,data_set_name,data,datatype
;add dataset into hdf file
;sd_id: hdf identifer;data_set_name: the name you will add
;datatype:the data type
sds_id = 1
dims = SIZE(data,/dimensions)
; datatype = '/'+datatype
CASE (datatype) OF
'LONG': BEGIN
sds_id=HDF_SD_CREATE(sd_id,data_set_name,dims[*,*],/long)
END
'FLOAT':BEGIN
sds_id=HDF_SD_CREATE(sd_id,data_set_name,dims[*,*],/float)
END
ELSE: BEGIN
sds_id=HDF_SD_CREATE(sd_id,data_set_name,dims[*,*],/DFNT_UINT32)
END
ENDCASE
HDF_SD_ADDDATA, sds_id, REFORM(data[*,*])
HDF_SD_SETINFO,sds_id,Label = data_set_name
HDF_SD_ENDACCESS,sds_id
;
END;
效果顯示: