使用GDAL获取HDF等数据集中的图像

来源:互联网 发布:淘宝投诉不成立 申诉 编辑:程序博客网 时间:2024/05/02 01:03

使用GDAL读取HDF,NetCDF等数据集中的数据时,一般需要两个步骤,第一,获取数据集中的子数据集;第二,通过第一步获取的子数据集读取图像数据。一般的HDF图像中会有很多个子数据集,比如常用的MODIS数据,使用Envi打开会弹出下面的对话框来让用户选择需要打开的子数据集(如图1)。


图1 Envi打开Modis数据

从图1中可以看出,Envi是把所有的子数据集的波段都进行了列举,不过这点和GDAL读取有点不一样。(这里有个比较疑惑的地方就是,使用GDALInfo获取的子数据一共有46个,而且很多图像大小都不一样,而这里Envi所有的波段图像大小都是1354×2030,希望知道的同学告知一下,难道那些小一点的406×271的都不要了?)。

看完Envi的,我们使用GDALInfo工具查看这个数据的信息,输出的内容如下:

Driver: HDF4/Hierarchical Data Format Release 4Files: F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdfSize is 512, 512Coordinate System is `'Metadata:  % Dead Detector EV Data=0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   此处省略NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN多字........................................  SOUTHBOUNDINGCOORDINATE=27.4153536499348  VERSIONID=5  WESTBOUNDINGCOORDINATE=106.240739628195Subdatasets:  SUBDATASET_1_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_1KM_RefSB  SUBDATASET_1_DESC=[15x2030x1354] EV_1KM_RefSB MODIS_SWATH_Type_L1B (16-bit unsigned integer)  SUBDATASET_2_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_1KM_RefSB_Uncert_Indexes  SUBDATASET_2_DESC=[15x2030x1354] EV_1KM_RefSB_Uncert_Indexes MODIS_SWATH_Type_L1B (8-bit unsigned integer)  SUBDATASET_3_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_1KM_Emissive  SUBDATASET_3_DESC=[16x2030x1354] EV_1KM_Emissive MODIS_SWATH_Type_L1B (16-bit unsigned integer)  SUBDATASET_4_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_1KM_Emissive_Uncert_Indexes  SUBDATASET_4_DESC=[16x2030x1354] EV_1KM_Emissive_Uncert_Indexes MODIS_SWATH_Type_L1B (8-bit unsigned integer)  SUBDATASET_5_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_250_Aggr1km_RefSB  SUBDATASET_5_DESC=[2x2030x1354] EV_250_Aggr1km_RefSB MODIS_SWATH_Type_L1B (16-bit unsigned integer)  SUBDATASET_6_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_250_Aggr1km_RefSB_Uncert_Indexes  SUBDATASET_6_DESC=[2x2030x1354] EV_250_Aggr1km_RefSB_Uncert_Indexes MODIS_SWATH_Type_L1B (8-bit unsigned integer)  SUBDATASET_7_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_250_Aggr1km_RefSB_Samples_Used  SUBDATASET_7_DESC=[2x2030x1354] EV_250_Aggr1km_RefSB_Samples_Used MODIS_SWATH_Type_L1B (8-bit integer)  SUBDATASET_8_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_500_Aggr1km_RefSB  SUBDATASET_8_DESC=[5x2030x1354] EV_500_Aggr1km_RefSB MODIS_SWATH_Type_L1B (16-bit unsigned integer)  SUBDATASET_9_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_500_Aggr1km_RefSB_Uncert_Indexes  SUBDATASET_9_DESC=[5x2030x1354] EV_500_Aggr1km_RefSB_Uncert_Indexes MODIS_SWATH_Type_L1B (8-bit unsigned integer)  SUBDATASET_10_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_500_Aggr1km_RefSB_Samples_Used  SUBDATASET_10_DESC=[5x2030x1354] EV_500_Aggr1km_RefSB_Samples_Used MODIS_SWATH_Type_L1B (8-bit integer)  SUBDATASET_11_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:Height  SUBDATASET_11_DESC=[406x271] Height MODIS_SWATH_Type_L1B (16-bit integer)  SUBDATASET_12_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:SensorZenith  SUBDATASET_12_DESC=[406x271] SensorZenith MODIS_SWATH_Type_L1B (16-bit integer)  SUBDATASET_13_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:SensorAzimuth  SUBDATASET_13_DESC=[406x271] SensorAzimuth MODIS_SWATH_Type_L1B (16-bit integer)  SUBDATASET_14_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:Range  SUBDATASET_14_DESC=[406x271] Range MODIS_SWATH_Type_L1B (16-bit unsigned integer)  SUBDATASET_15_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:SolarZenith  SUBDATASET_15_DESC=[406x271] SolarZenith MODIS_SWATH_Type_L1B (16-bit integer)  SUBDATASET_16_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:SolarAzimuth  SUBDATASET_16_DESC=[406x271] SolarAzimuth MODIS_SWATH_Type_L1B (16-bit integer)  SUBDATASET_17_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:gflags  SUBDATASET_17_DESC=[406x271] gflags MODIS_SWATH_Type_L1B (8-bit unsigned integer)  SUBDATASET_18_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_Band26  SUBDATASET_18_DESC=[2030x1354] EV_Band26 MODIS_SWATH_Type_L1B (16-bit unsigned integer)  SUBDATASET_19_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_Band26_Uncert_Indexes  SUBDATASET_19_DESC=[2030x1354] EV_Band26_Uncert_Indexes MODIS_SWATH_Type_L1B (8-bit unsigned integer)  SUBDATASET_20_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":0  SUBDATASET_20_DESC=[406x271] Latitude (32-bit floating-point)  SUBDATASET_21_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":1  SUBDATASET_21_DESC=[406x271] Longitude (32-bit floating-point)  SUBDATASET_22_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":2  SUBDATASET_22_DESC=[15x2030x1354] EV_1KM_RefSB (16-bit unsigned integer)  SUBDATASET_23_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":3  SUBDATASET_23_DESC=[15x2030x1354] EV_1KM_RefSB_Uncert_Indexes (8-bit unsigned integer)  SUBDATASET_24_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":4  SUBDATASET_24_DESC=[16x2030x1354] EV_1KM_Emissive (16-bit unsigned integer)  SUBDATASET_25_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":5  SUBDATASET_25_DESC=[16x2030x1354] EV_1KM_Emissive_Uncert_Indexes (8-bit unsigned integer)  SUBDATASET_26_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":6  SUBDATASET_26_DESC=[2x2030x1354] EV_250_Aggr1km_RefSB (16-bit unsigned integer)  SUBDATASET_27_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":7  SUBDATASET_27_DESC=[2x2030x1354] EV_250_Aggr1km_RefSB_Uncert_Indexes (8-bit unsigned integer)  SUBDATASET_28_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":8  SUBDATASET_28_DESC=[2x2030x1354] EV_250_Aggr1km_RefSB_Samples_Used (8-bit integer)  SUBDATASET_29_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":9  SUBDATASET_29_DESC=[5x2030x1354] EV_500_Aggr1km_RefSB (16-bit unsigned integer)  SUBDATASET_30_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":10  SUBDATASET_30_DESC=[5x2030x1354] EV_500_Aggr1km_RefSB_Uncert_Indexes (8-bit unsigned integer)  SUBDATASET_31_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":11  SUBDATASET_31_DESC=[5x2030x1354] EV_500_Aggr1km_RefSB_Samples_Used (8-bit integer)  SUBDATASET_32_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":12  SUBDATASET_32_DESC=[406x271] Height (16-bit integer)  SUBDATASET_33_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":13  SUBDATASET_33_DESC=[406x271] SensorZenith (16-bit integer)  SUBDATASET_34_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":14  SUBDATASET_34_DESC=[406x271] SensorAzimuth (16-bit integer)  SUBDATASET_35_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":15  SUBDATASET_35_DESC=[406x271] Range (16-bit unsigned integer)  SUBDATASET_36_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":16  SUBDATASET_36_DESC=[406x271] SolarZenith (16-bit integer)  SUBDATASET_37_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":17  SUBDATASET_37_DESC=[406x271] SolarAzimuth (16-bit integer)  SUBDATASET_38_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":18  SUBDATASET_38_DESC=[406x271] gflags (8-bit unsigned integer)  SUBDATASET_39_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":19  SUBDATASET_39_DESC=[2030x1354] EV_Band26 (16-bit unsigned integer)  SUBDATASET_40_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":20  SUBDATASET_40_DESC=[2030x1354] EV_Band26_Uncert_Indexes (8-bit unsigned integer)  SUBDATASET_41_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":21  SUBDATASET_41_DESC=[16x10] Noise in Thermal Detectors (8-bit unsigned integer)  SUBDATASET_42_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":22  SUBDATASET_42_DESC=[16x10] Change in relative responses of thermal detectors (8-bit unsigned integer)  SUBDATASET_43_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":23  SUBDATASET_43_DESC=[203x16x10] DC Restore Change for Thermal Bands (8-bit integer)  SUBDATASET_44_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":24  SUBDATASET_44_DESC=[203x2x40] DC Restore Change for Reflective 250m Bands (8-bit integer)  SUBDATASET_45_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":25  SUBDATASET_45_DESC=[203x5x20] DC Restore Change for Reflective 500m Bands (8-bit integer)  SUBDATASET_46_NAME=HDF4_SDS:UNKNOWN:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":26  SUBDATASET_46_DESC=[203x15x10] DC Restore Change for Reflective 1km Bands (8-bit integer)Corner Coordinates:Upper Left  (    0.0,    0.0)Lower Left  (    0.0,  512.0)Upper Right (  512.0,    0.0)Lower Right (  512.0,  512.0)Center      (  256.0,  256.0)
从上面的输出信息中可以看出,这个HDF数据其实有46个子数据,从上面的Subdatasets开始,一共有46个子数据集,同时GDAL列举了这些数据的描述信息,包括数据大小波段数以及数据类型。下面以第一个子数据集为例说明一下GDAL输出的这个信息的大致意思,第一个子数据集的描述如下:

  SUBDATASET_1_NAME=HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_1KM_RefSB  SUBDATASET_1_DESC=[15x2030x1354] EV_1KM_RefSB MODIS_SWATH_Type_L1B (16-bit unsigned integer)
可以看出,一个子数据集由两行组成,第一行表示这个子数据集的“路径”,这里的路径可以认为是这个子数据集存储在HDF文件中的路径。后面使用GDAL读取数据就要使用这个路径。第二行表示的是对这个子数据的描述信息,比如这里的,15×2030×1354就表示这个子数据有15个波段,长和宽分别是2030和1354。周末的EV_1KM_RefSB MODIS_SWATH_Type_L1B表示的是这个数据的处理级别和类型等,接下来的括弧里面的16-bit unsigned integer表示这个子数据集是个16位的无符号整数。

那么接下来如何使用gdal来获取子数据集里面的图像信息呢,我们还是以gdalinfo这个工具来说明。要获取hdf中每个子数据集的信息,首先要获取hdf中子数据集的路径才行,这个路径就需要上面的SUBDATASET_1_NAM来确定了。还是以第一个子数据集为例,使用的命令行如下,截图如图2所示:

gdalinfo.exe HDF4_EOS:EOS_SWATH:"F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf":MODIS_SWATH_Type_L1B:EV_1KM_RefSB
图2 使用gdalinfo查看子数据集的输出信息
由于输出的信息太多,截图不能全部显示,就意思一下,这里就不在贴出来了。有了上面的试验,接下来我们就可以写程序来读取HDF数据了,首先是用gdal打开hdf数据,获取Subdatasets中的子数据集路径,然后再使用gdalopen来打开。至于这个Subdatasets其实就在gdal的元数据里面,可以使用函数,GDALDataset::GetMetadata()函数来获取。示例代码如下:

GDALAllRegister();const char* pszSrcFile = "F:\\Data\\HDF\\MOD021KM.A2010287.0250.005.2010287121743.hdf";GDALDataset *pDataSet = (GDALDataset *) GDALOpen( pszSrcFile, GA_ReadOnly );if (pDataSet == NULL){printf("不能打开该文件,请检查文件是否存在!");return RE_FILENOTEXIST;}char ** papszSUBDATASETS = GDALGetMetadata( (GDALDatasetH)pDataSet, "SUBDATASETS");
这段代码最后一行的papszSUBDATASETS中就是存储的子数据的路径和描述信息。papszSUBDATASETS其实就是个字符串数组,接下来就是解析这个字符串数组,然后从里面获取HDF子数据集的路径和描述信息,这里需要注意的是,如果一个HDF文件获取的子数据集是NULL,也就是papszSUBDATASETS这个变量如果为NULL,说明这个hdf数据本身就是一个单一的数据,里面没有子数据集。接下来的代码就是解析这个子数据集的字符串数组:

vector<string> vSubDataSets, vector<string> vSubDataDesc;if ( papszSUBDATASETS == NULL ){string papszMetadata = GDALGetDriverShortName((GDALDriverH)pDataSet);vSubDataSets.push_back(papszMetadata);vSubDataDesc.push_back(papszMetadata);}
上面的代码中是如果当前的HDF数据没有子数据集,那么其本身就是一个数据集。这里定义了两个vector<string>,分别用来存储子数据集的路径和描述信息。下面的代码就是解析含有子数据集的HDF数据了。这里需要一点点的std::string的函数,主要是用来截取字符串用的substr函数。

else{int iCount = CSLCount(papszSUBDATASETS);if(  iCount <= 0 ){if(pProcess != NULL)pProcess->SetMessage("该HDF文件中没有子数据!");GDALClose((GDALDriverH)pDataSet);return RE_SUCCESS;}for(int i=0; papszSUBDATASETS[i] != NULL; i++ ){if(i%2 != 0)continue;string tmpstr = string(papszSUBDATASETS[i]);tmpstr = tmpstr.substr(tmpstr.find_first_of("=") + 1);const char *tmpc_str = tmpstr.c_str();string tmpdsc = string(papszSUBDATASETS[i+1]);tmpdsc = tmpdsc.substr(tmpdsc.find_first_of("=") + 1);GDALDatasetH hTmpDt = GDALOpen(tmpc_str, GA_ReadOnly);if(hTmpDt != NULL){vSubDataSets.push_back(tmpstr);vSubDataDesc.push_back(tmpdsc);GDALClose(hTmpDt);}}//end for}GDALClose((GDALDriverH)pDataSet);
对上面的代码稍微解释一下:首先使用CSLCount函数获取这个字符串数组的个数,如果不大于0就说明没有,直接关闭HDF数据返回。如果大于0,遍历这个字符串数组,一般这个字符串数组个数肯定是个偶数,你也可以提前判断一下。如果数组的下标是奇数,直接跳过,也就是说,我们直接取下标是0、2、4的字符串。接下来取出的字符串中是有一个“=”连接起来的(具体可以看上面的例子)。这个等号的左边是描述数据集的顺序,右边是值也就是子数据集的路径。使用substr函数把路径取出来存储到前面定义的vector<string>中,同时获取描述信息也存进去(这个描述信息可以不用,如果需要用户交互的话还是留着的好),接下来使用GDALOpen打开测试一下这个子数据集的路径是否正确,如果可以打开就说明正常。

通过上面的说明,对于HDF的数据(包括HDF4、HDF5、NetCDF等类型的数据)怎么使用GDAL打开就有个了解了吧。下面是我写的一个简单的Demo截图,核心功能就是用的上面这段代码。
首先是打开HDF数据,如图3所示:

图3 打开HDF数据

点击打开之后会弹出一个对话框,如图4所示,会在列表中显示打开的HDF数据中所有的子数据集的描述信息,通过用户选择来指定所要打开的子数据集,这个对话框中的列表显示的内容就是上面代码中解析的描述信息。然后点击确定的时候通过选择的第几个来定位子数据集的路径,然后使用GDAL打开进行显示或者进行其他的处理即可。


图4 打开HDF数据后列举的子数据集描述

原创粉丝点击