GDALDataset *HDF4Dataset::Open( GDALOpenInfo * poOpenInfo ) { int32 i; if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ int32 hHDF4; hHDF4 = Hopen(poOpenInfo->pszFilename, DFACC_READ, 0); if( hHDF4 <= 0 ) return( NULL ); Hclose( hHDF4 ); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ HDF4Dataset *poDS; poDS = new HDF4Dataset(); poDS->fp = poOpenInfo->fp; poOpenInfo->fp = NULL; /* -------------------------------------------------------------------- */ /* Open HDF SDS Interface. */ /* -------------------------------------------------------------------- */ poDS->hSD = SDstart( poOpenInfo->pszFilename, DFACC_READ ); if ( poDS->hSD == -1 ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Now read Global Attributes. */ /* -------------------------------------------------------------------- */ if ( poDS->ReadGlobalAttributes( poDS->hSD ) != CE_None ) { delete poDS; return NULL; } poDS->SetMetadata( poDS->papszGlobalMetadata, "" ); /* -------------------------------------------------------------------- */ /* Determine type of file we read. */ /* -------------------------------------------------------------------- */ const char *pszValue; if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Signature")) && EQUAL( pszValue, pszGDALSignature ) ) { poDS->iSubdatasetType = H4ST_GDAL; poDS->pszSubdatasetType = "GDAL_HDF4"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) && EQUAL( pszValue, "SeaWiFS Level-1A Data" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L1A; poDS->pszSubdatasetType = "SEAWIFS_L1A"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) && EQUAL( pszValue, "SeaWiFS Level-2 Data" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L2; poDS->pszSubdatasetType = "SEAWIFS_L2"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) && EQUAL( pszValue, "SeaWiFS Level-3 Standard Mapped Image" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L3; poDS->pszSubdatasetType = "SEAWIFS_L3"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "L1 File Generated By")) && EQUALN( pszValue, "HYP version ", 12 ) ) { poDS->iSubdatasetType = H4ST_HYPERION_L1; poDS->pszSubdatasetType = "HYPERION_L1"; } else { poDS->iSubdatasetType = H4ST_UNKNOWN; poDS->pszSubdatasetType = "UNKNOWN"; } /* -------------------------------------------------------------------- */ /* If we have HDF-EOS dataset, process it here. */ /* -------------------------------------------------------------------- */ char szName[VSNAMELENMAX + 1], szTemp[8192]; char *pszString; const char *pszName; int nCount; int32 aiDimSizes[H4_MAX_VAR_DIMS]; int32 iRank, iNumType, nAttrs; bool bIsHDF = true; // Sometimes "HDFEOSVersion" attribute is not defined and we will // determine HDF-EOS datasets using other records // (see ReadGlobalAttributes() method). if ( poDS->bIsHDFEOS || CSLFetchNameValue(poDS->papszGlobalMetadata, "HDFEOSVersion") ) { bIsHDF = false; int32 nSubDatasets, nStrBufSize; /* -------------------------------------------------------------------- */ /* Process swath layers. */ /* -------------------------------------------------------------------- */ hHDF4 = SWopen( poOpenInfo->pszFilename, DFACC_READ ); if( hHDF4 < 0) { delete poDS; CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open HDF4 `%s'.\n", poOpenInfo->pszFilename ); return NULL; } nSubDatasets = SWinqswath(poOpenInfo->pszFilename, NULL, &nStrBufSize); #if DEBUG CPLDebug( "HDF4", "Number of HDF-EOS swaths: %d", (int)nSubDatasets ); #endif if ( nSubDatasets > 0 && nStrBufSize > 0 ) { char *pszSwathList; char **papszSwaths; pszSwathList = (char *)CPLMalloc( nStrBufSize + 1 ); SWinqswath( poOpenInfo->pszFilename, pszSwathList, &nStrBufSize ); pszSwathList[nStrBufSize] = '\0'; #if DEBUG CPLDebug( "HDF4", "List of HDF-EOS swaths: %s", pszSwathList ); #endif papszSwaths = CSLTokenizeString2( pszSwathList, ",", CSLT_HONOURSTRINGS ); CPLFree( pszSwathList ); if ( nSubDatasets != CSLCount(papszSwaths) ) { CSLDestroy( papszSwaths ); delete poDS; CPLDebug( "HDF4", "Can not parse list of HDF-EOS grids." ); return NULL; } for ( i = 0; i < nSubDatasets; i++) { char *pszFieldList; char **papszFields; int32 *paiRank, *paiNumType; int32 hSW, nFields, j; hSW = SWattach( hHDF4, papszSwaths[i] ); nFields = SWnentries( hSW, HDFE_NENTDFLD, &nStrBufSize ); pszFieldList = (char *)CPLMalloc( nStrBufSize + 1 ); paiRank = (int32 *)CPLMalloc( nFields * sizeof(int32) ); paiNumType = (int32 *)CPLMalloc( nFields * sizeof(int32) ); SWinqdatafields( hSW, pszFieldList, paiRank, paiNumType ); #if DEBUG { char *pszTmp = SPrintArray( GDT_UInt32, paiRank, nFields, "," ); CPLDebug( "HDF4", "Number of data fields in swath %d: %d", (int) i, (int) nFields ); CPLDebug( "HDF4", "List of data fields in swath %d: %s", (int) i, pszFieldList ); CPLDebug( "HDF4", "Data fields ranks: %s", pszTmp ); CPLFree( pszTmp ); } #endif papszFields = CSLTokenizeString2( pszFieldList, ",", CSLT_HONOURSTRINGS ); for ( j = 0; j < nFields; j++ ) { SWfieldinfo( hSW, papszFields[j], &iRank, aiDimSizes, &iNumType, NULL ); if ( iRank < 2 ) continue; // Add field to the list of GDAL subdatasets nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); // We will use the field index as an identificator. poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf("HDF4_EOS:EOS_SWATH:\"%s\":%s:%s", poOpenInfo->pszFilename, papszSwaths[i], papszFields[j]) ); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%s] %s %s (%s)", pszString, papszFields[j], papszSwaths[i], poDS->GetDataTypeName(iNumType) ) ); CPLFree( pszString ); } CSLDestroy( papszFields ); CPLFree( paiNumType ); CPLFree( paiRank ); CPLFree( pszFieldList ); SWdetach( hSW ); } CSLDestroy( papszSwaths ); } SWclose( hHDF4 ); /* -------------------------------------------------------------------- */ /* Process grid layers. */ /* -------------------------------------------------------------------- */ hHDF4 = GDopen( poOpenInfo->pszFilename, DFACC_READ ); nSubDatasets = GDinqgrid( poOpenInfo->pszFilename, NULL, &nStrBufSize ); #if DEBUG CPLDebug( "HDF4", "Number of HDF-EOS grids: %d", (int)nSubDatasets ); #endif if ( nSubDatasets > 0 && nStrBufSize > 0 ) { char *pszGridList; char **papszGrids; pszGridList = (char *)CPLMalloc( nStrBufSize + 1 ); GDinqgrid( poOpenInfo->pszFilename, pszGridList, &nStrBufSize ); #if DEBUG CPLDebug( "HDF4", "List of HDF-EOS grids: %s", pszGridList ); #endif papszGrids = CSLTokenizeString2( pszGridList, ",", CSLT_HONOURSTRINGS ); CPLFree( pszGridList ); if ( nSubDatasets != CSLCount(papszGrids) ) { CSLDestroy( papszGrids ); delete poDS; CPLDebug( "HDF4", "Can not parse list of HDF-EOS grids." ); return NULL; } for ( i = 0; i < nSubDatasets; i++) { char *pszFieldList; char **papszFields; int32 *paiRank, *paiNumType; int32 hGD, nFields, j; hGD = GDattach( hHDF4, papszGrids[i] ); nFields = GDnentries( hGD, HDFE_NENTDFLD, &nStrBufSize ); pszFieldList = (char *)CPLMalloc( nStrBufSize + 1 ); paiRank = (int32 *)CPLMalloc( nFields * sizeof(int32) ); paiNumType = (int32 *)CPLMalloc( nFields * sizeof(int32) ); GDinqfields( hGD, pszFieldList, paiRank, paiNumType ); #if DEBUG { char* pszTmp = SPrintArray( GDT_UInt32, paiRank, nFields, "," ); CPLDebug( "HDF4", "Number of fields in grid %d: %d", (int) i, (int) nFields ); CPLDebug( "HDF4", "List of fields in grid %d: %s", (int) i, pszFieldList ); CPLDebug( "HDF4", "Fields ranks: %s", pszTmp ); CPLFree( pszTmp ); } #endif papszFields = CSLTokenizeString2( pszFieldList, ",", CSLT_HONOURSTRINGS ); for ( j = 0; j < nFields; j++ ) { GDfieldinfo( hGD, papszFields[j], &iRank, aiDimSizes, &iNumType, NULL ); if ( iRank < 2 ) continue; // Add field to the list of GDAL subdatasets nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); // We will use the field index as an identificator. poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "HDF4_EOS:EOS_GRID:\"%s\":%s:%s", poOpenInfo->pszFilename, papszGrids[i], papszFields[j])); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf("[%s] %s %s (%s)", pszString, papszFields[j], papszGrids[i], poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); } CSLDestroy( papszFields ); CPLFree( paiNumType ); CPLFree( paiRank ); CPLFree( pszFieldList ); GDdetach( hGD ); } CSLDestroy( papszGrids ); GDclose( hHDF4 ); } GDclose( hHDF4 ); bIsHDF = ( nSubDatasets == 0 ); // Try to read as HDF } if( bIsHDF ) { /* -------------------------------------------------------------------- */ /* Make a list of subdatasets from SDSs contained in input HDF file. */ /* -------------------------------------------------------------------- */ int32 nDatasets; if ( SDfileinfo( poDS->hSD, &nDatasets, &nAttrs ) != 0 ) return NULL; for ( i = 0; i < nDatasets; i++ ) { int32 iSDS; iSDS = SDselect( poDS->hSD, i ); if ( SDgetinfo( iSDS, szName, &iRank, aiDimSizes, &iNumType, &nAttrs) != 0 ) return NULL; if ( iRank == 1 ) // Skip 1D datsets continue; // Do sort of known datasets. We will display only image bands if ( (poDS->iSubdatasetType == H4ST_SEAWIFS_L1A ) && !EQUALN( szName, "l1a_data", 8 ) ) continue; else pszName = szName; // Add datasets with multiple dimensions to the list of GDAL subdatasets nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); // We will use SDS index as an identificator, because SDS names // are not unique. Filename also needed for further file opening poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "HDF4_SDS:%s:\"%s\":%ld", poDS->pszSubdatasetType, poOpenInfo->pszFilename, (long)i) ); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%s] %s (%s)", pszString, pszName, poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); SDendaccess( iSDS ); } SDend( poDS->hSD ); poDS->hSD = 0; } /* -------------------------------------------------------------------- */ /* Build a list of raster images. Note, that HDF-EOS dataset may */ /* contain a raster image as well. */ /* -------------------------------------------------------------------- */ hHDF4 = Hopen(poOpenInfo->pszFilename, DFACC_READ, 0); poDS->hGR = GRstart( hHDF4 ); if ( poDS->hGR != -1 ) { if ( GRfileinfo( poDS->hGR, &poDS->nImages, &nAttrs ) == -1 ) return NULL; for ( i = 0; i < poDS->nImages; i++ ) { int32 iInterlaceMode; int32 iGR = GRselect( poDS->hGR, i ); // iRank in GR interface has another meaning. It represents number // of samples per pixel. aiDimSizes has only two dimensions. if ( GRgetiminfo( iGR, szName, &iRank, &iNumType, &iInterlaceMode, aiDimSizes, &nAttrs ) != 0 ) return NULL; nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp,CPLSPrintf( "HDF4_GR:UNKNOWN:\"%s\":%ld", poOpenInfo->pszFilename, (long)i)); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, 2, "x" ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%sx%ld] %s (%s)", pszString, (long)iRank, szName, poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); GRendaccess( iGR ); } GRend( poDS->hGR ); poDS->hGR = 0; } Hclose( hHDF4 ); poDS->nRasterXSize = poDS->nRasterYSize = 512; // XXX: bogus values // Make sure we don't try to do any pam stuff with this dataset. poDS->nPamFlags |= GPF_NOSAVE; /* -------------------------------------------------------------------- */ /* If we have single subdataset only, open it immediately */ /* -------------------------------------------------------------------- */ if ( CSLCount( poDS->papszSubDatasets ) / 2 == 1 ) { char *pszSDSName; pszSDSName = CPLStrdup( CSLFetchNameValue( poDS->papszSubDatasets, "SUBDATASET_1_NAME" )); delete poDS; poDS = NULL; GDALDataset* poRetDS = (GDALDataset*) GDALOpen( pszSDSName, poOpenInfo->eAccess ); CPLFree( pszSDSName ); if (poRetDS) { poRetDS->SetDescription(poOpenInfo->pszFilename); } return poRetDS; } else { /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { delete poDS; CPLError( CE_Failure, CPLE_NotSupported, "The HDF4 driver does not support update access to existing" " datasets.\n" ); return NULL; } } return( poDS ); }
/****************************************************************************** MODULE: OpenHdfEosFile PURPOSE: Open an HDF-EOS file for reading or writing RETURN VALUE: Type = HdfEosFD Value Description ----- ----------- HdfEosFD* An opened HDF file NULL Failure HISTORY: Version Date Programmer Code Reason ------- ----- --------------- ---- ------------------------------------- 06/00 John Weiss Original Development 01/01 John Rishea Standardized formatting NOTES: ******************************************************************************/ HdfEosFD *OpenHdfEosFile ( char *input_filename, /* I: input filename for reading */ char *output_filename, /* I: output filename for writing */ FileOpenType mode, /* I: reading or writing */ int *status /* I/O: error code status */ ) { char str[LARGE_STRING], /* LARGE_STRING defined in shared_resample.h */ gridlist[HUGE_STRING]; /* HUGE_STRING defined in shared_resample.h */ int fid, ngrids; int32 bufsiz; HdfEosFD *hdfptr = NULL; /* open input HDF-EOS file */ if ( mode == FILE_READ_MODE ) { /* open file for reading */ fid = GDopen( input_filename, DFACC_READ ); /* check if file was successfully opened */ if ( fid == -1 ) { sprintf( str, "Unable to open %s for reading\n", input_filename ); ErrorHandler( TRUE, "OpenHdfEosFile", ERROR_OPEN_INPUTIMAGE, str ); *status = ERROR_OPEN_INPUTIMAGE; return NULL; } /* create HDF-EOS file pointer */ hdfptr = ( HdfEosFD * ) calloc( 1, sizeof( HdfEosFD ) ); if ( !hdfptr ) { sprintf( str, "Unable to create HdfEosFD for %s\n", input_filename ); ErrorHandler( TRUE, "OpenHdfEosFile", ERROR_OPEN_INPUTIMAGE, str ); *status = ERROR_OPEN_INPUTIMAGE; return NULL; } /* multi-grid bug fix by JMW 06/06/01 */ /* see if there are any grids in the file */ ngrids = GDinqgrid( input_filename, gridlist, &bufsiz ); if ( ngrids < 1 || strlen( gridlist ) < 1 ) { sprintf( str, "Unable to find any gridnames in %s\n", input_filename ); ErrorHandler( TRUE, "OpenHdfEosFile", ERROR_OPEN_INPUTIMAGE, str ); *status = ERROR_OPEN_INPUTIMAGE; return NULL; } /* fill in fields in hdfptr */ hdfptr->fid = fid; hdfptr->gid = -1; hdfptr->ngrids = ngrids; hdfptr->gridlist = strdup( gridlist ); if ( hdfptr->gridlist == NULL ) { sprintf( str, "Unable to allocate memory for gridlist for %s\n", input_filename ); ErrorHandler( TRUE, "OpenHdfEosFile", ERROR_MEMORY, str ); *status = ERROR_MEMORY; return NULL; } hdfptr->currgrid = NULL; hdfptr->fieldlist = NULL; hdfptr->currfield = NULL; } /* open output HDF-EOS file */ else /* if ( mode == FILE_WRITE_MODE ) */ { /* open HDF-EOS file for output */ fid = GDopen( output_filename, DFACC_CREATE ); /* check if file was successfully opened */ if ( fid == -1 ) { sprintf( str, "Unable to open %s for writing", output_filename ); ErrorHandler( TRUE, "OpenHdfEosFile", ERROR_OPEN_OUTPUTIMAGE, str ); *status = ERROR_OPEN_OUTPUTIMAGE; return NULL; } /* create HDF-EOS file pointer */ hdfptr = ( HdfEosFD * ) calloc( 1, sizeof( HdfEosFD ) ); if ( !hdfptr ) { sprintf( str, "Unable to create HdfEosFD for %s", output_filename ); ErrorHandler( TRUE, "OpenHdfEosFile", ERROR_OPEN_OUTPUTIMAGE, str ); *status = ERROR_OPEN_OUTPUTIMAGE; return NULL; } /* fill in fields in hdfptr */ hdfptr->fid = fid; hdfptr->gid = -1; hdfptr->ngrids = 0; hdfptr->gridlist = NULL; hdfptr->currgrid = NULL; hdfptr->fieldlist = NULL; hdfptr->currfield = NULL; } /* finish up */ return hdfptr; }
GDALDataset *HDF4Dataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return NULL; CPLMutexHolderD(&hHDF4Mutex); /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ // Attempt to increase maximum number of opened HDF files. #ifdef HDF4_HAS_MAXOPENFILES intn nCurrMax = 0; intn nSysLimit = 0; if ( SDget_maxopenfiles(&nCurrMax, &nSysLimit) >= 0 && nCurrMax < nSysLimit ) { /*intn res = */SDreset_maxopenfiles( nSysLimit ); } #endif /* HDF4_HAS_MAXOPENFILES */ int32 hHDF4 = Hopen(poOpenInfo->pszFilename, DFACC_READ, 0); if( hHDF4 <= 0 ) return NULL; Hclose( hHDF4 ); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ // Release mutex otherwise we will deadlock with GDALDataset own mutex. CPLReleaseMutex(hHDF4Mutex); HDF4Dataset *poDS = new HDF4Dataset(); CPLAcquireMutex(hHDF4Mutex, 1000.0); if( poOpenInfo->fpL != NULL ) { VSIFCloseL(poOpenInfo->fpL); poOpenInfo->fpL = NULL; } /* -------------------------------------------------------------------- */ /* Open HDF SDS Interface. */ /* -------------------------------------------------------------------- */ poDS->hSD = SDstart( poOpenInfo->pszFilename, DFACC_READ ); if ( poDS->hSD == -1 ) { // Release mutex otherwise we will deadlock with GDALDataset own mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open HDF4 file \"%s\" for SDS reading.", poOpenInfo->pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Now read Global Attributes. */ /* -------------------------------------------------------------------- */ if ( poDS->ReadGlobalAttributes( poDS->hSD ) != CE_None ) { // Release mutex otherwise we will deadlock with GDALDataset own mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to read global attributes from HDF4 file \"%s\".", poOpenInfo->pszFilename ); return NULL; } poDS->SetMetadata( poDS->papszGlobalMetadata, "" ); /* -------------------------------------------------------------------- */ /* Determine type of file we read. */ /* -------------------------------------------------------------------- */ const char *pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Signature"); if ( pszValue != NULL && EQUAL( pszValue, pszGDALSignature ) ) { poDS->iSubdatasetType = H4ST_GDAL; poDS->pszSubdatasetType = "GDAL_HDF4"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) != NULL && EQUAL( pszValue, "SeaWiFS Level-1A Data" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L1A; poDS->pszSubdatasetType = "SEAWIFS_L1A"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) != NULL && EQUAL( pszValue, "SeaWiFS Level-2 Data" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L2; poDS->pszSubdatasetType = "SEAWIFS_L2"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) != NULL && EQUAL( pszValue, "SeaWiFS Level-3 Standard Mapped Image" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L3; poDS->pszSubdatasetType = "SEAWIFS_L3"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "L1 File Generated By")) != NULL && STARTS_WITH_CI(pszValue, "HYP version ") ) { poDS->iSubdatasetType = H4ST_HYPERION_L1; poDS->pszSubdatasetType = "HYPERION_L1"; } else { poDS->iSubdatasetType = H4ST_UNKNOWN; poDS->pszSubdatasetType = "UNKNOWN"; } /* -------------------------------------------------------------------- */ /* If we have HDF-EOS dataset, process it here. */ /* -------------------------------------------------------------------- */ int32 aiDimSizes[H4_MAX_VAR_DIMS] = {}; // TODO: Get this off of the stack. int32 iRank = 0; int32 iNumType = 0; int32 nAttrs = 0; bool bIsHDF = true; // Sometimes "HDFEOSVersion" attribute is not defined and we will // determine HDF-EOS datasets using other records // (see ReadGlobalAttributes() method). if ( poDS->bIsHDFEOS || CSLFetchNameValue(poDS->papszGlobalMetadata, "HDFEOSVersion") ) { /* -------------------------------------------------------------------- */ /* Process swath layers. */ /* -------------------------------------------------------------------- */ hHDF4 = SWopen( poOpenInfo->pszFilename, DFACC_READ ); if( hHDF4 < 0) { // Release mutex otherwise we will deadlock with GDALDataset own // mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open HDF-EOS file \"%s\" for swath reading.", poOpenInfo->pszFilename ); return NULL; } int32 nStrBufSize = 0; int32 nSubDatasets = SWinqswath(poOpenInfo->pszFilename, NULL, &nStrBufSize); #ifdef DEBUG CPLDebug( "HDF4", "Number of HDF-EOS swaths: %d", static_cast<int>( nSubDatasets ) ); #endif if ( nSubDatasets > 0 && nStrBufSize > 0 ) { char *pszSwathList = static_cast<char *>( CPLMalloc( nStrBufSize + 1 ) ); SWinqswath( poOpenInfo->pszFilename, pszSwathList, &nStrBufSize ); pszSwathList[nStrBufSize] = '\0'; #ifdef DEBUG CPLDebug( "HDF4", "List of HDF-EOS swaths: %s", pszSwathList ); #endif char **papszSwaths = CSLTokenizeString2( pszSwathList, ",", CSLT_HONOURSTRINGS ); CPLFree( pszSwathList ); if ( nSubDatasets != CSLCount(papszSwaths) ) { CSLDestroy( papszSwaths ); // Release mutex otherwise we will deadlock with GDALDataset own // mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLDebug( "HDF4", "Cannot parse list of HDF-EOS grids." ); return NULL; } for( int32 i = 0; i < nSubDatasets; i++) { const int32 hSW = SWattach( hHDF4, papszSwaths[i] ); const int32 nFields = SWnentries( hSW, HDFE_NENTDFLD, &nStrBufSize ); char *pszFieldList = static_cast<char *>( CPLMalloc( nStrBufSize + 1 ) ); int32 *paiRank = static_cast<int32 *>( CPLMalloc( nFields * sizeof(int32) ) ); int32 *paiNumType = static_cast<int32 *>( CPLMalloc( nFields * sizeof(int32) ) ); SWinqdatafields( hSW, pszFieldList, paiRank, paiNumType ); #ifdef DEBUG { char * const pszTmp = SPrintArray( GDT_UInt32, paiRank, nFields, "," ); CPLDebug( "HDF4", "Number of data fields in swath %d: %d", static_cast<int>( i ), static_cast<int>( nFields ) ); CPLDebug( "HDF4", "List of data fields in swath %d: %s", static_cast<int>( i ), pszFieldList ); CPLDebug( "HDF4", "Data fields ranks: %s", pszTmp ); CPLFree( pszTmp ); } #endif char **papszFields = CSLTokenizeString2( pszFieldList, ",", CSLT_HONOURSTRINGS ); char szTemp[256] = {'\0'}; // TODO: Get this off the stack. for( int32 j = 0; j < nFields; j++ ) { SWfieldinfo( hSW, papszFields[j], &iRank, aiDimSizes, &iNumType, NULL ); if ( iRank < 2 ) continue; // Add field to the list of GDAL subdatasets. const int nCount = CSLCount( poDS->papszSubDatasets ) / 2; snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_NAME", nCount + 1 ); // We will use the field index as an identificator. poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf("HDF4_EOS:EOS_SWATH:\"%s\":%s:%s", poOpenInfo->pszFilename, papszSwaths[i], papszFields[j]) ); snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_DESC", nCount + 1 ); char *pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%s] %s %s (%s)", pszString, papszFields[j], papszSwaths[i], poDS->GetDataTypeName(iNumType) ) ); CPLFree( pszString ); szTemp[0] = '\0'; } CSLDestroy( papszFields ); CPLFree( paiNumType ); CPLFree( paiRank ); CPLFree( pszFieldList ); SWdetach( hSW ); } CSLDestroy( papszSwaths ); } SWclose( hHDF4 ); /* -------------------------------------------------------------------- */ /* Process grid layers. */ /* -------------------------------------------------------------------- */ hHDF4 = GDopen( poOpenInfo->pszFilename, DFACC_READ ); nSubDatasets = GDinqgrid( poOpenInfo->pszFilename, NULL, &nStrBufSize ); #ifdef DEBUG CPLDebug( "HDF4", "Number of HDF-EOS grids: %d", static_cast<int>( nSubDatasets ) ); #endif if ( nSubDatasets > 0 && nStrBufSize > 0 ) { char *pszGridList = static_cast<char *>( CPLMalloc( nStrBufSize + 1 ) ); GDinqgrid( poOpenInfo->pszFilename, pszGridList, &nStrBufSize ); #ifdef DEBUG CPLDebug( "HDF4", "List of HDF-EOS grids: %s", pszGridList ); #endif char **papszGrids = CSLTokenizeString2( pszGridList, ",", CSLT_HONOURSTRINGS ); CPLFree( pszGridList ); if ( nSubDatasets != CSLCount(papszGrids) ) { CSLDestroy( papszGrids ); GDclose( hHDF4 ); // Release mutex otherwise we will deadlock with GDALDataset own // mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLDebug( "HDF4", "Cannot parse list of HDF-EOS grids." ); return NULL; } for( int32 i = 0; i < nSubDatasets; i++) { const int32 hGD = GDattach( hHDF4, papszGrids[i] ); const int32 nFields = GDnentries( hGD, HDFE_NENTDFLD, &nStrBufSize ); char *pszFieldList = static_cast<char *>( CPLMalloc( nStrBufSize + 1 ) ); int32 *paiRank = static_cast<int32 *>( CPLMalloc( nFields * sizeof(int32) ) ); int32 *paiNumType = static_cast<int32 *>( CPLMalloc( nFields * sizeof(int32) ) ); GDinqfields( hGD, pszFieldList, paiRank, paiNumType ); #ifdef DEBUG { char* pszTmp = SPrintArray( GDT_UInt32, paiRank, nFields, "," ); CPLDebug( "HDF4", "Number of fields in grid %d: %d", static_cast<int>( i ), static_cast<int>( nFields ) ); CPLDebug( "HDF4", "List of fields in grid %d: %s", static_cast<int>( i ), pszFieldList ); CPLDebug( "HDF4", "Fields ranks: %s", pszTmp ); CPLFree( pszTmp ); } #endif char **papszFields = CSLTokenizeString2( pszFieldList, ",", CSLT_HONOURSTRINGS ); char szTemp[256]; for( int32 j = 0; j < nFields; j++ ) { GDfieldinfo( hGD, papszFields[j], &iRank, aiDimSizes, &iNumType, NULL ); if ( iRank < 2 ) continue; // Add field to the list of GDAL subdatasets const int nCount = CSLCount( poDS->papszSubDatasets ) / 2; snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_NAME", nCount + 1 ); // We will use the field index as an identificator. poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "HDF4_EOS:EOS_GRID:\"%s\":%s:%s", poOpenInfo->pszFilename, papszGrids[i], papszFields[j])); snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_DESC", nCount + 1 ); char *pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf("[%s] %s %s (%s)", pszString, papszFields[j], papszGrids[i], poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); } CSLDestroy( papszFields ); CPLFree( paiNumType ); CPLFree( paiRank ); CPLFree( pszFieldList ); GDdetach( hGD ); } CSLDestroy( papszGrids ); } GDclose( hHDF4 ); bIsHDF = ( nSubDatasets == 0 ); // Try to read as HDF } char szName[VSNAMELENMAX + 1]; if( bIsHDF ) { /* -------------------------------------------------------------------- */ /* Make a list of subdatasets from SDSs contained in input HDF file. */ /* -------------------------------------------------------------------- */ int32 nDatasets = 0; if ( SDfileinfo( poDS->hSD, &nDatasets, &nAttrs ) != 0 ) return NULL; char szTemp[256] = {'\0'}; // TODO: Get this off the stack. const char *pszName = NULL; for( int32 i = 0; i < nDatasets; i++ ) { const int32 iSDS = SDselect( poDS->hSD, i ); if ( SDgetinfo( iSDS, szName, &iRank, aiDimSizes, &iNumType, &nAttrs) != 0 ) return NULL; if ( iRank == 1 ) // Skip 1D datsets continue; // Do sort of known datasets. We will display only image bands if ( (poDS->iSubdatasetType == H4ST_SEAWIFS_L1A ) && !STARTS_WITH_CI(szName, "l1a_data") ) continue; else pszName = szName; // Add datasets with multiple dimensions to the list of GDAL // subdatasets. const int nCount = CSLCount( poDS->papszSubDatasets ) / 2; snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_NAME", nCount + 1 ); // We will use SDS index as an identificator, because SDS names // are not unique. Filename also needed for further file opening poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf( "HDF4_SDS:%s:\"%s\":%ld", poDS->pszSubdatasetType, poOpenInfo->pszFilename, static_cast<long>( i ) ) ); snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_DESC", nCount + 1 ); char *pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%s] %s (%s)", pszString, pszName, poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); SDendaccess( iSDS ); szTemp[0] = '\0'; } SDend( poDS->hSD ); poDS->hSD = 0; } /* -------------------------------------------------------------------- */ /* Build a list of raster images. Note, that HDF-EOS dataset may */ /* contain a raster image as well. */ /* -------------------------------------------------------------------- */ hHDF4 = Hopen(poOpenInfo->pszFilename, DFACC_READ, 0); poDS->hGR = GRstart( hHDF4 ); if ( poDS->hGR != -1 ) { if ( GRfileinfo( poDS->hGR, &poDS->nImages, &nAttrs ) == -1 ) { // Release mutex otherwise we will deadlock with GDALDataset own // mutex. CPLReleaseMutex(hHDF4Mutex); GRend( poDS->hGR ); poDS->hGR = 0; Hclose( hHDF4 ); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); return NULL; } char szTemp[256] = {'\0'}; // TODO: Get this off the stack. for( int32 i = 0; i < poDS->nImages; i++ ) { const int32 iGR = GRselect( poDS->hGR, i ); // iRank in GR interface has another meaning. It represents number // of samples per pixel. aiDimSizes has only two dimensions. int32 iInterlaceMode = 0; if ( GRgetiminfo( iGR, szName, &iRank, &iNumType, &iInterlaceMode, aiDimSizes, &nAttrs ) != 0 ) { // Release mutex otherwise we will deadlock with GDALDataset // own mutex. CPLReleaseMutex(hHDF4Mutex); GRend( poDS->hGR ); poDS->hGR = 0; Hclose( hHDF4 ); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); return NULL; } const int nCount = CSLCount( poDS->papszSubDatasets ) / 2; snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_NAME", nCount + 1 ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp,CPLSPrintf( "HDF4_GR:UNKNOWN:\"%s\":%ld", poOpenInfo->pszFilename, static_cast<long>( i ) ) ); snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_DESC", nCount + 1 ); char *pszString = SPrintArray( GDT_UInt32, aiDimSizes, 2, "x" ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%sx%ld] %s (%s)", pszString, static_cast<long>( iRank ), szName, poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); GRendaccess( iGR ); szTemp[0] = '\0'; } GRend( poDS->hGR ); poDS->hGR = 0; } Hclose( hHDF4 ); poDS->nRasterXSize = poDS->nRasterYSize = 512; // XXX: bogus values // Make sure we don't try to do any pam stuff with this dataset. poDS->nPamFlags |= GPF_NOSAVE; /* -------------------------------------------------------------------- */ /* If we have single subdataset only, open it immediately */ /* -------------------------------------------------------------------- */ if ( CSLCount( poDS->papszSubDatasets ) / 2 == 1 ) { char *pszSDSName = CPLStrdup( CSLFetchNameValue( poDS->papszSubDatasets, "SUBDATASET_1_NAME" )); // Release mutex otherwise we will deadlock with GDALDataset own mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; poDS = NULL; GDALDataset* poRetDS = reinterpret_cast<GDALDataset*>( GDALOpen( pszSDSName, poOpenInfo->eAccess ) ); CPLFree( pszSDSName ); CPLAcquireMutex(hHDF4Mutex, 1000.0); if (poRetDS) { poRetDS->SetDescription(poOpenInfo->pszFilename); } return poRetDS; } else { /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { // Release mutex otherwise we will deadlock with GDALDataset own // mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_NotSupported, "The HDF4 driver does not support update access to " "existing datasets." ); return NULL; } } return poDS; }
int main ( int argc, char *argv[] ) { int i, j; int32 fid, gid; int32 ngrids, nentries, nattrs, ndims, nfields; int32 rank, numbertype, sizedim, status, bufsiz; int32 projcode, zonecode, spherecode; int32 xdimsize, ydimsize, origininfo; int16 fillvalue; int32 dims[10], ranks[100], numbertypes[100]; float64 upleft[2], lowright[2], projparm[16]; char strbuf[4096]; char *attrname = NULL, *dimname = NULL; char *fieldlist = NULL, *fieldname = NULL; char *gridlist = NULL, *gridname = NULL, *gridend = NULL; /* check usage */ if ( argc != 2 ) { fprintf( stdout, "Usage: %s file.hdf\n", argv[0] ); fflush( stdout ); return -1; } /* test GDinqgrid() */ ngrids = GDinqgrid( argv[1], strbuf, &bufsiz ); gridlist = strdup( strbuf ); printf( "%s: %i grids (%s)\n", argv[1], (int) ngrids, gridlist ); /* open file */ fid = GDopen( argv[1], DFACC_READ ); /* loop through the grids in gridlist using strtok() */ for ( i = 0; i < ngrids; i++ ) { /* open next grid */ /* unfortunately, can't use strtok for parsing both grids and fields */ gridname = gridlist; gridend = strchr( gridlist, ',' ); if ( gridend != NULL ) { gridlist = gridend + 1; *gridend = '\0'; } /* attach to grid gridname */ gid = GDattach( fid, gridname ); /* get number of entries (fields?) */ nentries = GDnentries( gid, HDFE_NENTDFLD, &bufsiz ); printf( "\nGrid %i: %s (%i entries)\n", i + 1, gridname, (int) nentries ); /* get attribute info */ /* NOTE: not HDF-EOS readable, must use HDF SDreadattr() */ strbuf[0] = '\0'; nattrs = GDinqattrs( gid, strbuf, &bufsiz ); printf( "%i attributes:", (int) nattrs ); for ( attrname = strtok( strbuf, "," ); attrname != NULL; attrname = strtok( NULL, "," ) ) printf( " %s", attrname ); printf( "\n" ); /* try specifically to read background fill value */ /* NOTE: not HDF-EOS readable, must use HDF SDgetfillvalue() */ status = GDreadattr( gid, "_FillValue", &fillvalue ); if ( status != -1 ) printf( "_FillValue = %i\n", fillvalue ); /* else printf( "could not read _FillValue attribute\n" ); */ /* get dimension info */ strbuf[0] = '\0'; ndims = GDinqdims( gid, strbuf, dims ); printf( "GDinqdims: %i dimensions (%s):", (int) ndims, strbuf ); for ( j = 0, dimname = strtok( strbuf, "," ); dimname != NULL; j++, dimname = strtok( NULL, "," ) ) { sizedim = GDdiminfo( gid, dimname ); printf( " %s (%i) %i", dimname, (int) sizedim, (int) dims[j] ); } printf( "\n" ); /* get grid info */ status = GDgridinfo( gid, &xdimsize, &ydimsize, upleft, lowright ); printf( "gridinfo: xdimsize = %i, ydimsize = %i\n", (int) xdimsize, (int) ydimsize ); printf( " UL = (%f, %f)\n", upleft[0], upleft[1] ); printf( " LR = (%f, %f)\n", lowright[0], lowright[1] ); /* get grid origin info (this seems to work) */ status = GDorigininfo( gid, &origininfo ); if ( status == -1 ) printf( "no origin info\n" ); else printf( "origin code = %i\n", (int) origininfo ); /* get list of fields (entries?) */ strbuf[0] = '\0'; nfields = GDinqfields( gid, strbuf, ranks, numbertypes ); fieldlist = strdup( strbuf ); printf( "%i fields (%s):\n", (int) nfields, fieldlist ); printf( "ranks:" ); for ( j = 0; j < nfields; j++ ) printf( " %i", (int) ranks[j] ); printf( "\n" ); printf( "numbertypes:" ); for ( j = 0; j < nfields; j++ ) printf( " %i", (int) numbertypes[j] ); printf( "\n" ); /* loop through field names using strtok() */ for ( fieldname = strtok( fieldlist, "," ); fieldname != NULL; fieldname = strtok( NULL, "," ) ) { /* get field info */ status = GDfieldinfo( gid, fieldname, &rank, dims, &numbertype, strbuf ); printf( "%s: rank %i, numbertype %i, dimlist %s:", fieldname, (int) rank, (int) numbertype, strbuf ); for ( j = 0; j < rank; j++ ) printf( " %i", (int) dims[j] ); printf( "\n" ); } /* get projection parameters */ GDprojinfo( gid, &projcode, &zonecode, &spherecode, projparm ); printf( "projcode %i, zonecode %i, spherecode %i\n", (int) projcode, (int) zonecode, (int) spherecode ); printf( "projparm:" ); for ( j = 0; j < 13; j++ ) printf( " %f", projparm[j] ); printf( " %f %f\n", 0.0, 0.0 ); /* last two proj params are zero */ /* detach from grid */ GDdetach( gid ); } /* close file and quit */ GDclose( fid ); return 0; }
main() { intn i, j, status; int32 gdfid, GDid,start[3],stride[3],edge[3]; float32 f32=1.0; float32 veg[200][120], temp[100][100]; /* Fill veg array */ for (i=0; i<200;i++) for (j=0; j<120; j++) veg[i][j] = 10+i; /* Fill temp array */ for (i=0; i<100;i++) for (j=0; j<100; j++) temp[i][j] = 100*i+j; /* * Open the HDF grid file, "GridFile.hdf". */ gdfid = GDopen("GridFile_created_with_hadeos_sample_file_writer_of_HDFEOS2_version_219_or_higher_release.hdf", DFACC_RDWR); if (gdfid != -1) { /* * Attach the "UTMGrid". */ GDid = GDattach(gdfid, "UTMGrid"); if (GDid != -1) { status = GDwritefield(GDid, "Vegetation", NULL, NULL, NULL, veg); if (status == -1) { printf("\t\tError: Cannot write field \"Vegetation\"\n"); return -1; } /* * It will always fail status = GDwritefield(GDid, "Vegetat", NULL, NULL, NULL, veg); if (status == -1) { printf("\t\tError: Cannot write field \"Vegetat\"\n"); printf("\t\tField \"Vegetat\" has not been defined.\n"); } */ status = GDwriteattr(GDid, "float32", DFNT_FLOAT32, 1, &f32); if (status == -1) { printf("\t\tError: Cannot write attribute \"float32\"\n"); return -1; } } GDdetach(GDid); GDid = GDattach(gdfid, "PolarGrid"); if (GDid != -1) { status = GDwritefield(GDid, "Temperature", NULL, NULL, NULL, temp); if (status == -1) { printf("\t\tError: Cannot write field \"Temperature\"\n"); return -1; } } GDdetach(GDid); } GDclose(gdfid); return 0; }
main() { intn status, i; int32 gdfid, GDid1, ndim, nmap, nfld, rk, nt, nflds; int32 dims[32], rank[32], ntype[32]; int32 n, strbufsize, sizes[16], GDid2; int32 xdimsize, ydimsize, dimsize, projcode, zonecode; int32 spherecode; float64 upleftpt[2], lowrightpt[2], projparm[16]; char dimname[1024], fieldlist[1024]; /* * Open the Grid File for read only access */ gdfid = GDopen("GridFile_created_with_hadeos_sample_file_writer_of_HDFEOS2_version_219_or_higher_release.hdf", DFACC_READ); if (gdfid != -1) { /* Attach the grid */ GDid1 = GDattach(gdfid, "UTMGrid"); if (GDid1 == -1) { printf("\t\tError: Cannot attach grid \"UTMGrid\"\n"); return -1; } GDid2 = GDattach(gdfid, "PolarGrid"); if (GDid1 == -1) { printf("\t\tError: Cannot attach grid \"PolarGrid\"\n"); return -1; } ndim = GDinqdims(GDid1, dimname, dims); if (ndim == -1) { printf("\t\tError: Cannot get number of dims for grid \"UTMGrid\"\n"); return -1; } printf("Dimension list (UTMGrid): %s\n", dimname); for (i=0;i<ndim;i++) printf("dim size: %d\n", dims[i]); ndim = GDinqdims(GDid2, dimname, dims); if (ndim == -1) { printf("\t\tError: Cannot get number of dims for grid \"PolarGrid\"\n"); return -1; } printf("Dimension list (PolarGrid): %s\n", dimname); for (i=0;i<ndim;i++) printf("dim size: %d\n", dims[i]); dimsize = GDdiminfo(GDid1, "Time"); if (dimsize == -1) { printf("\t\tError: Cannot get dim info for \"Time\"\n"); return -1; } printf("Size of \"Time\" Array: %d\n", dimsize); dimsize = GDdiminfo(GDid2, "Bands"); if (dimsize == -1) { printf("\t\tError: Cannot get dim info for \"Bands\"\n"); return -1; } printf("Size of \"Bands\" Array: %d\n", dimsize); status = GDgridinfo(GDid1, &xdimsize, &ydimsize, upleftpt, lowrightpt); if (status == -1) { printf("\t\tError: Cannot get grid info for \"UTMGrid\"\n"); return -1; } printf("X dim size, Y dim size (UTMGrid): %d %d\n", xdimsize, ydimsize); printf("Up left pt (UTMGrid): %lf %lf\n", upleftpt[0], upleftpt[1]); printf("Low right pt (UTMGrid): %lf %lf\n", lowrightpt[0], lowrightpt[1]); status = GDgridinfo(GDid2, &xdimsize, &ydimsize, upleftpt, lowrightpt); if (status == -1) { printf("\t\tError: Cannot get grid info for \"PolarGrid\"\n"); return -1; } printf("X dim size, Y dim size (PolarGrid): %d %d\n", xdimsize, ydimsize); printf("Up left pt (PolarGrid): %lf %lf\n", upleftpt[0], upleftpt[1]); printf("Low right pt (PolarGrid): %lf %lf\n", lowrightpt[0], lowrightpt[1]); status = GDprojinfo(GDid1, &projcode, &zonecode, &spherecode, NULL); if (status == -1) { printf("\t\tError: Cannot get projection info for \"UTMGrid\"\n"); return -1; } printf("projcode , zonecode (UTMGrid): %d %d\n", projcode, zonecode); printf("spherecode (UTMGrid): %d\n", spherecode); status = GDprojinfo(GDid2, &projcode, NULL, &spherecode, projparm); if (status == -1) { printf("\t\tError: Cannot get projection info for \"PolarGrid\"\n"); return -1; } printf("projcode (PolarGrid): %d\n", projcode); printf("spherecode (PolarGrid): %d\n", spherecode); for (i=0; i<13; i++) printf("Projection Parameter: %d %lf\n",i,projparm[i]); nflds = GDinqfields(GDid1, fieldlist, rank, ntype); if (nflds == -1) { printf("\t\tError: Cannot inquire field info for \"UTMGrid\"\n"); return -1; } if (nflds != 0) { printf("Data fields (UTMGrid): %s\n", fieldlist); for (i=0;i<nflds;i++) printf("rank type: %d %d\n",rank[i],ntype[i]); } nflds = GDinqfields(GDid2, fieldlist, rank, ntype); if (nflds == -1) { printf("\t\tError: Cannot inquire field info for \"PolarGrid\"\n"); return -1; } if (nflds != 0) { printf("Data fields (PolarGrid): %s\n", fieldlist); for (i=0;i<nflds;i++) printf("rank type: %d %d\n",rank[i],ntype[i]); } status = GDfieldinfo(GDid2, "Spectra", rank, dims, ntype, dimname); if (nflds == -1) { printf("\t\tError: Cannot get field info for field \"Spectra\"\n"); return -1; } printf("Spectra rank dims: %d\n",rank[0]); for (i=0; i<rank[0]; i++) printf("Spectra dims: %d %d\n",i,dims[i]); printf("Spectra dims: %s\n", dimname); n = GDnentries(GDid1, HDFE_NENTDIM, &strbufsize); if (n == -1) { printf("\t\tError: Cannot get dim entries info for field \"UTMGrid\"\n"); return -1; } printf("Number of dimension entries (UTMGrid): %d\n", n); printf("Length of Dimension List (UTMGrid): %d\n", strbufsize); n = GDnentries(GDid1, HDFE_NENTDFLD, &strbufsize); if (n == -1) { printf("\t\tError: Cannot get dim entries info for field \"PolarGrid\"\n"); return -1; } printf("Number of data fields (UTMGrid): %d\n", n); printf("Length of Field List (UTMGrid): %d\n", strbufsize); } GDdetach(GDid1); GDdetach(GDid2); GDclose(gdfid); return 0; }