使用GDAL获取HDF等数据集中的图像
使用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 4 Files: F:\Data\HDF\MOD021KM.A2010287.0250.005.2010287121743.hdf Size is 512, 512 Coordinate 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.240739628195 Subdatasets: 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
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所示:
点击打开之后会弹出一个对话框,如图4所示,会在列表中显示打开的HDF数据中所有的子数据集的描述信息,通过用户选择来指定所要打开的子数据集,这个对话框中的列表显示的内容就是上面代码中解析的描述信息。然后点击确定的时候通过选择的第几个来定位子数据集的路径,然后使用GDAL打开进行显示或者进行其他的处理即可。
图4 打开HDF数据后列举的子数据集描述