Esempio n. 1
0
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 );
}
Esempio n. 2
0
/******************************************************************************

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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}