Ejemplo n.º 1
0
int VSIFPrintfL( VSILFILE *fp, const char *pszFormat, ... )

{
    va_list args;
    CPLString osResult;

    va_start( args, pszFormat );
    osResult.vPrintf( pszFormat, args );
    va_end( args );

    return VSIFWriteL( osResult.c_str(), 1, osResult.length(), fp );
}
Ejemplo n.º 2
0
int ERSHdrNode::ReadLine( VSILFILE * fp, CPLString &osLine )

{
    int  nBracketLevel = 0;
    bool bInQuote = false;
    size_t i = 0;
    bool bLastCharWasSlashInQuote = false;

    osLine = "";
    do
    {
        const char *pszNewLine = CPLReadLineL( fp );

        if( pszNewLine == nullptr )
            return FALSE;

        osLine += pszNewLine;

        for( ; i < osLine.length(); i++ )
        {
            const char ch = osLine[i];
            if( bLastCharWasSlashInQuote )
            {
                bLastCharWasSlashInQuote = false;
            }
            else if( ch == '"' )
                bInQuote = !bInQuote;
            else if( ch == '{' && !bInQuote )
                nBracketLevel++;
            else if( ch == '}' && !bInQuote )
                nBracketLevel--;
            // We have to ignore escaped quotes and backslashes in strings.
            else if( ch == '\\' && bInQuote )
            {
                bLastCharWasSlashInQuote = true;
            }
        }
    } while( nBracketLevel > 0 );

    return TRUE;
}
Ejemplo n.º 3
0
int ERSHdrNode::ReadLine( VSILFILE * fp, CPLString &osLine )

{
    int  nBracketLevel;

    osLine = "";

    do
    {
        const char *pszNewLine = CPLReadLineL( fp );
        
        if( pszNewLine == NULL )
            return FALSE;

        osLine += pszNewLine;

        int  bInQuote = FALSE;
        size_t  i;

        nBracketLevel = 0;

        for( i = 0; i < osLine.length(); i++ )
        {
            if( osLine[i] == '"' )
                bInQuote = !bInQuote;
            else if( osLine[i] == '{' && !bInQuote )
                nBracketLevel++;
            else if( osLine[i] == '}' && !bInQuote )
                nBracketLevel--;

            // We have to ignore escaped quotes and backslashes in strings.
            else if( osLine[i] == '\\' && osLine[i+1] == '"' && bInQuote )
                i++;
            else if( osLine[i] == '\\' && osLine[i+1] == '\\' && bInQuote )
                i++;
        }
    } while( nBracketLevel > 0 );

    return TRUE;
}
Ejemplo n.º 4
0
/*!
  \brief VFKReaderSQLite constructor
*/
VFKReaderSQLite::VFKReaderSQLite(const char *pszFilename) : VFKReader(pszFilename)
{
    const char *pszDbNameConf;
    CPLString   osDbName;
    CPLString   osCommand;
    VSIStatBufL sStatBufDb, sStatBufVfk;

    /* open tmp SQLite DB (re-use DB file if already exists) */
    pszDbNameConf = CPLGetConfigOption("OGR_VFK_DB_NAME", NULL);
    if (pszDbNameConf) {
	osDbName = pszDbNameConf;
    }
    else {
	osDbName = CPLResetExtension(m_pszFilename, "db");
    }
    size_t nLen = osDbName.length();
    if( nLen > 2048 )
    {
        nLen = 2048;
        osDbName.resize(nLen);
    }
    m_pszDBname = new char [nLen+1];
    std::strncpy(m_pszDBname, osDbName.c_str(), nLen);
    m_pszDBname[nLen] = 0;
    CPLDebug("OGR-VFK", "Using internal DB: %s",
             m_pszDBname);

    if (CPLTestBool(CPLGetConfigOption("OGR_VFK_DB_SPATIAL", "YES")))
	m_bSpatial = TRUE;    /* build geometry from DB */
    else
	m_bSpatial = FALSE;   /* store also geometry in DB */

    m_bNewDb = TRUE;
    if (VSIStatL(osDbName, &sStatBufDb) == 0) {
	if (CPLTestBool(CPLGetConfigOption("OGR_VFK_DB_OVERWRITE", "NO"))) {
	    m_bNewDb = TRUE;     /* overwrite existing DB */
            CPLDebug("OGR-VFK", "Internal DB (%s) already exists and will be overwritten",
                     m_pszDBname);
	    VSIUnlink(osDbName);
        }
        else {
            if (VSIStatL(pszFilename, &sStatBufVfk) == 0 &&
                sStatBufVfk.st_mtime > sStatBufDb.st_mtime) {
                CPLDebug("OGR-VFK",
                         "Found %s but ignoring because it appears\n"
                         "be older than the associated VFK file.",
                         osDbName.c_str());
                m_bNewDb = TRUE;
                VSIUnlink(osDbName);
            }
            else {
                m_bNewDb = FALSE;    /* re-use existing DB */
            }
        }
    }

    /*
    if (m_bNewDb) {
      CPLError(CE_Warning, CPLE_AppDefined,
               "INFO: No internal SQLite DB found. Reading VFK data may take some time...");
    }
    */

    CPLDebug("OGR-VFK", "New DB: %s Spatial: %s",
	     m_bNewDb ? "yes" : "no", m_bSpatial ? "yes" : "no");

    if (SQLITE_OK != sqlite3_open(osDbName, &m_poDB)) {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Creating SQLite DB failed");
    }
    else {
        char* pszErrMsg = NULL;
        CPL_IGNORE_RET_VAL(sqlite3_exec(m_poDB, "PRAGMA synchronous = OFF", NULL, NULL, &pszErrMsg));
        sqlite3_free(pszErrMsg);
    }

    if (m_bNewDb) {
        /* new DB, create support metadata tables */
        osCommand.Printf("CREATE TABLE %s (file_name text, table_name text, num_records integer, "
                         "num_features integer, num_geometries integer, table_defn text)",
                         VFK_DB_TABLE);
        ExecuteSQL(osCommand.c_str());

        /* header table */
        osCommand.Printf("CREATE TABLE %s (key text, value text)", VFK_DB_HEADER);
        ExecuteSQL(osCommand.c_str());
    }
}
Ejemplo n.º 5
0
void BSBDataset::ScanForGCPs( bool isNos, const char *pszFilename )

{
/* -------------------------------------------------------------------- */
/*      Collect GCPs as appropriate to source.                          */
/* -------------------------------------------------------------------- */
    nGCPCount = 0;

    if ( isNos )
    {
        ScanForGCPsNos(pszFilename);
    } else {
        ScanForGCPsBSB();
    }

/* -------------------------------------------------------------------- */
/*      Apply heuristics to re-wrap GCPs to maintain continguity        */
/*      over the international dateline.                                */
/* -------------------------------------------------------------------- */
    if( nGCPCount > 1 )
        GDALHeuristicDatelineWrapGCPs( nGCPCount, pasGCPList );

/* -------------------------------------------------------------------- */
/*      Collect coordinate system related parameters from header.       */
/* -------------------------------------------------------------------- */
    int i;
    const char *pszKNP=NULL, *pszKNQ=NULL;

    for( i = 0; psInfo->papszHeader[i] != NULL; i++ )
    {
        if( EQUALN(psInfo->papszHeader[i],"KNP/",4) )
        {
            pszKNP = psInfo->papszHeader[i];
            SetMetadataItem( "BSB_KNP", pszKNP + 4 );
        }
        if( EQUALN(psInfo->papszHeader[i],"KNQ/",4) )
        {
            pszKNQ = psInfo->papszHeader[i]; 
            SetMetadataItem( "BSB_KNQ", pszKNQ + 4 );
        }
    }

    
/* -------------------------------------------------------------------- */
/*      Can we derive a reasonable coordinate system definition for     */
/*      this file?  For now we keep it simple, just handling            */
/*      mercator. In the future we should consider others.              */
/* -------------------------------------------------------------------- */
    CPLString osUnderlyingSRS;
    if( pszKNP != NULL )
    {
        const char *pszPR = strstr(pszKNP,"PR=");
        const char *pszGD = strstr(pszKNP,"GD=");
        const char *pszValue, *pszEnd = NULL;
        const char *pszGEOGCS = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]],AUTHORITY[\"EPSG\",\"4326\"]]";
        CPLString osPP;
        
        // Capture the PP string.
        pszValue = strstr(pszKNP,"PP=");
        if( pszValue )
            pszEnd = strstr(pszValue,",");
        if( pszValue && pszEnd )
            osPP.assign(pszValue+3,pszEnd-pszValue-3);
        
        // Look at the datum
        if( pszGD == NULL )
        {
            /* no match. We'll default to EPSG:4326 */
        }
        else if( EQUALN(pszGD,"GD=European 1950", 16) )
        {
            pszGEOGCS = "GEOGCS[\"ED50\",DATUM[\"European_Datum_1950\",SPHEROID[\"International 1924\",6378388,297,AUTHORITY[\"EPSG\",\"7022\"]],TOWGS84[-87,-98,-121,0,0,0,0],AUTHORITY[\"EPSG\",\"6230\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4230\"]]";
        }

        // Look at the projection
        if( pszPR == NULL )
        {
            /* no match */
        }
        else if( EQUALN(pszPR,"PR=MERCATOR", 11) )
        {
            // We somewhat arbitrarily select our first GCPX as our 
            // central meridian.  This is mostly helpful to ensure 
            // that regions crossing the dateline will be contiguous 
            // in mercator.
            osUnderlyingSRS.Printf( "PROJCS[\"Global Mercator\",%s,PROJECTION[\"Mercator_2SP\"],PARAMETER[\"standard_parallel_1\",0],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",%d],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1]]",
                pszGEOGCS, (int) pasGCPList[0].dfGCPX );
        }

        else if( EQUALN(pszPR,"PR=TRANSVERSE MERCATOR", 22)
                 && osPP.size() > 0 )
        {
            
            osUnderlyingSRS.Printf( 
                "PROJCS[\"unnamed\",%s,PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",%s],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0]]",
                pszGEOGCS, osPP.c_str() );
        }

        else if( EQUALN(pszPR,"PR=UNIVERSAL TRANSVERSE MERCATOR", 32)
                 && osPP.size() > 0 )
        {
            // This is not *really* UTM unless the central meridian 
            // matches a zone which it does not in some (most?) maps. 
            osUnderlyingSRS.Printf( 
                "PROJCS[\"unnamed\",%s,PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",%s],PARAMETER[\"scale_factor\",0.9996],PARAMETER[\"false_easting\",500000],PARAMETER[\"false_northing\",0]]", 
                pszGEOGCS, osPP.c_str() );
        }

        else if( EQUALN(pszPR,"PR=POLYCONIC", 12) && osPP.size() > 0 )
        {
            osUnderlyingSRS.Printf( 
                "PROJCS[\"unnamed\",%s,PROJECTION[\"Polyconic\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",%s],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0]]", 
                pszGEOGCS, osPP.c_str() );
        }
        
        else if( EQUALN(pszPR,"PR=LAMBERT CONFORMAL CONIC", 26) 
                 && osPP.size() > 0 && pszKNQ != NULL )
        {
            CPLString osP2, osP3;
        
            // Capture the KNQ/P2 string.
            pszValue = strstr(pszKNQ,"P2=");
            if( pszValue )
                pszEnd = strstr(pszValue,",");
            if( pszValue && pszEnd )
                osP2.assign(pszValue+3,pszEnd-pszValue-3);
            
            // Capture the KNQ/P3 string.
            pszValue = strstr(pszKNQ,"P3=");
            if( pszValue )
                pszEnd = strstr(pszValue,",");
            if( pszValue )
            {
                if( pszEnd )
                    osP3.assign(pszValue+3,pszEnd-pszValue-3);
                else
                    osP3.assign(pszValue+3);
            }

            if( osP2.size() > 0 && osP3.size() > 0 )
                osUnderlyingSRS.Printf( 
                    "PROJCS[\"unnamed\",%s,PROJECTION[\"Lambert_Conformal_Conic_2SP\"],PARAMETER[\"standard_parallel_1\",%s],PARAMETER[\"standard_parallel_2\",%s],PARAMETER[\"latitude_of_origin\",0.0],PARAMETER[\"central_meridian\",%s],PARAMETER[\"false_easting\",0.0],PARAMETER[\"false_northing\",0.0]]",
                    pszGEOGCS, osP2.c_str(), osP3.c_str(), osPP.c_str() );

        }
    }

/* -------------------------------------------------------------------- */
/*      If we got an alternate underlying coordinate system, try        */
/*      converting the GCPs to that coordinate system.                  */
/* -------------------------------------------------------------------- */
    if( osUnderlyingSRS.length() > 0 )
    {
        OGRSpatialReference oGeog_SRS, oProjected_SRS;
        OGRCoordinateTransformation *poCT;
        
        oProjected_SRS.SetFromUserInput( osUnderlyingSRS );
        oGeog_SRS.CopyGeogCSFrom( &oProjected_SRS );
        
        poCT = OGRCreateCoordinateTransformation( &oGeog_SRS, 
                                                  &oProjected_SRS );
        if( poCT != NULL )
        {
            for( i = 0; i < nGCPCount; i++ )
            {
                poCT->Transform( 1, 
                                 &(pasGCPList[i].dfGCPX), 
                                 &(pasGCPList[i].dfGCPY), 
                                 &(pasGCPList[i].dfGCPZ) );
            }

            osGCPProjection = osUnderlyingSRS;

            delete poCT;
        }
        else
            CPLErrorReset();
    }

/* -------------------------------------------------------------------- */
/*      Attempt to prepare a geotransform from the GCPs.                */
/* -------------------------------------------------------------------- */
    if( GDALGCPsToGeoTransform( nGCPCount, pasGCPList, adfGeoTransform, 
                                FALSE ) )
    {
        bGeoTransformSet = TRUE;
    }
}
Ejemplo n.º 6
0
GDALDataset *ERSDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      We assume the user selects the .ers file.                       */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes > 15
        && EQUALN((const char *) poOpenInfo->pabyHeader,"Algorithm Begin",15) )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "%s appears to be an algorithm ERS file, which is not currently supported.", 
                  poOpenInfo->pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      We assume the user selects the .ers file.                       */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 15 
        || !EQUALN((const char *) poOpenInfo->pabyHeader,"DatasetHeader ",14) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Open the .ers file, and read the first line.                    */
/* -------------------------------------------------------------------- */
    VSILFILE *fpERS = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    
    if( fpERS == NULL )
        return NULL;

    CPLReadLineL( fpERS );

/* -------------------------------------------------------------------- */
/*      Now ingest the rest of the file as a tree of header nodes.      */
/* -------------------------------------------------------------------- */
    ERSHdrNode *poHeader = new ERSHdrNode();

    if( !poHeader->ParseChildren( fpERS ) )
    {
        delete poHeader;
        VSIFCloseL( fpERS );
        return NULL;
    }

    VSIFCloseL( fpERS );

/* -------------------------------------------------------------------- */
/*      Do we have the minimum required information from this header?   */
/* -------------------------------------------------------------------- */
    if( poHeader->Find( "RasterInfo.NrOfLines" ) == NULL 
        || poHeader->Find( "RasterInfo.NrOfCellsPerLine" ) == NULL 
        || poHeader->Find( "RasterInfo.NrOfBands" ) == NULL )
    {
        if( poHeader->FindNode( "Algorithm" ) != NULL )
        {
            CPLError( CE_Failure, CPLE_OpenFailed, 
                      "%s appears to be an algorithm ERS file, which is not currently supported.", 
                      poOpenInfo->pszFilename );
        }
        delete poHeader;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    ERSDataset     *poDS;

    poDS = new ERSDataset();
    poDS->poHeader = poHeader;
    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    int nBands = atoi(poHeader->Find( "RasterInfo.NrOfBands" ));
    poDS->nRasterXSize = atoi(poHeader->Find( "RasterInfo.NrOfCellsPerLine" ));
    poDS->nRasterYSize = atoi(poHeader->Find( "RasterInfo.NrOfLines" ));
    
    if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
        !GDALCheckBandCount(nBands, FALSE))
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*     Get the HeaderOffset if it exists in the header                  */
/* -------------------------------------------------------------------- */
    GIntBig nHeaderOffset = 0;
    if( poHeader->Find( "HeaderOffset" ) != NULL )
    {
        nHeaderOffset = atoi(poHeader->Find( "HeaderOffset" ));
    }

/* -------------------------------------------------------------------- */
/*      Establish the data type.                                        */
/* -------------------------------------------------------------------- */
    GDALDataType eType;
    CPLString osCellType = poHeader->Find( "RasterInfo.CellType", 
                                           "Unsigned8BitInteger" );
    if( EQUAL(osCellType,"Unsigned8BitInteger") )
        eType = GDT_Byte;
    else if( EQUAL(osCellType,"Signed8BitInteger") )
        eType = GDT_Byte;
    else if( EQUAL(osCellType,"Unsigned16BitInteger") )
        eType = GDT_UInt16;
    else if( EQUAL(osCellType,"Signed16BitInteger") )
        eType = GDT_Int16;
    else if( EQUAL(osCellType,"Unsigned32BitInteger") )
        eType = GDT_UInt32;
    else if( EQUAL(osCellType,"Signed32BitInteger") )
        eType = GDT_Int32;
    else if( EQUAL(osCellType,"IEEE4ByteReal") )
        eType = GDT_Float32;
    else if( EQUAL(osCellType,"IEEE8ByteReal") )
        eType = GDT_Float64;
    else
    {
        CPLDebug( "ERS", "Unknown CellType '%s'", osCellType.c_str() );
        eType = GDT_Byte;
    }

/* -------------------------------------------------------------------- */
/*      Pick up the word order.                                         */
/* -------------------------------------------------------------------- */
    int bNative;

#ifdef CPL_LSB
    bNative = EQUAL(poHeader->Find( "ByteOrder", "LSBFirst" ),
                    "LSBFirst");
#else
    bNative = EQUAL(poHeader->Find( "ByteOrder", "MSBFirst" ),
                    "MSBFirst");
#endif

/* -------------------------------------------------------------------- */
/*      Figure out the name of the target file.                         */
/* -------------------------------------------------------------------- */
    CPLString osPath = CPLGetPath( poOpenInfo->pszFilename );
    CPLString osDataFile = poHeader->Find( "DataFile", "" );
    CPLString osDataFilePath;

    if( osDataFile.length() == 0 ) // just strip off extension.
    {
        osDataFile = CPLGetFilename( poOpenInfo->pszFilename );
        osDataFile = osDataFile.substr( 0, osDataFile.find_last_of('.') );
    }
        
    osDataFilePath = CPLFormFilename( osPath, osDataFile, NULL );

/* -------------------------------------------------------------------- */
/*      DataSetType = Translated files are links to things like ecw     */
/*      files.                                                          */
/* -------------------------------------------------------------------- */
    if( EQUAL(poHeader->Find("DataSetType",""),"Translated") )
    {
        poDS->poDepFile = (GDALDataset *) 
            GDALOpenShared( osDataFilePath, poOpenInfo->eAccess );

        if( poDS->poDepFile != NULL 
            && poDS->poDepFile->GetRasterCount() >= nBands )
        {
            int iBand;

            for( iBand = 0; iBand < nBands; iBand++ )
            {
                // Assume pixel interleaved.
                poDS->SetBand( iBand+1, 
                               poDS->poDepFile->GetRasterBand( iBand+1 ) );
            }
        }
    }

/* ==================================================================== */
/*      While ERStorage indicates a raw file.                           */
/* ==================================================================== */
    else if( EQUAL(poHeader->Find("DataSetType",""),"ERStorage") )
    {
        // Open data file.
        if( poOpenInfo->eAccess == GA_Update )
            poDS->fpImage = VSIFOpenL( osDataFilePath, "r+" );
        else
            poDS->fpImage = VSIFOpenL( osDataFilePath, "r" );

        poDS->osRawFilename = osDataFilePath;

        if( poDS->fpImage != NULL )
        {
            int iWordSize = GDALGetDataTypeSize(eType) / 8;
            int iBand;

            for( iBand = 0; iBand < nBands; iBand++ )
            {
                // Assume pixel interleaved.
                poDS->SetBand( 
                    iBand+1, 
                    new RawRasterBand( poDS, iBand+1, poDS->fpImage,
                                       nHeaderOffset 
                                       + iWordSize * iBand * poDS->nRasterXSize,
                                       iWordSize,
                                       iWordSize * nBands * poDS->nRasterXSize,
                                       eType, bNative, TRUE ));
                if( EQUAL(osCellType,"Signed8BitInteger") )
                    poDS->GetRasterBand(iBand+1)->
                        SetMetadataItem( "PIXELTYPE", "SIGNEDBYTE", 
                                         "IMAGE_STRUCTURE" );
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Otherwise we have an error!                                     */
/* -------------------------------------------------------------------- */
    if( poDS->nBands == 0 )
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Look for band descriptions.                                     */
/* -------------------------------------------------------------------- */
    int iChild, iBand = 0;
    ERSHdrNode *poRI = poHeader->FindNode( "RasterInfo" );

    for( iChild = 0; 
         poRI != NULL && iChild < poRI->nItemCount && iBand < poDS->nBands; 
         iChild++ )
    {
        if( poRI->papoItemChild[iChild] != NULL
            && EQUAL(poRI->papszItemName[iChild],"BandId") )
        {
            const char *pszValue = 
                poRI->papoItemChild[iChild]->Find( "Value", NULL );

            iBand++;
            if( pszValue )
            {
                CPLPushErrorHandler( CPLQuietErrorHandler );
                poDS->GetRasterBand( iBand )->SetDescription( pszValue );
                CPLPopErrorHandler();
            }

            pszValue = poRI->papoItemChild[iChild]->Find( "Units", NULL );
            if ( pszValue )
            {
                CPLPushErrorHandler( CPLQuietErrorHandler );
                poDS->GetRasterBand( iBand )->SetUnitType( pszValue );
                CPLPopErrorHandler();
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Look for projection.                                            */
/* -------------------------------------------------------------------- */
    OGRSpatialReference oSRS;

    CPLString osProjection = poHeader->Find( "CoordinateSpace.Projection", 
                                             "RAW" );
    CPLString osDatum = poHeader->Find( "CoordinateSpace.Datum", "WGS84" );
    CPLString osUnits = poHeader->Find( "CoordinateSpace.Units", "METERS" );

    oSRS.importFromERM( osProjection, osDatum, osUnits );

    CPLFree( poDS->pszProjection );
    oSRS.exportToWkt( &(poDS->pszProjection) );

/* -------------------------------------------------------------------- */
/*      Look for the geotransform.                                      */
/* -------------------------------------------------------------------- */
    if( poHeader->Find( "RasterInfo.RegistrationCoord.Eastings", NULL )
        && poHeader->Find( "RasterInfo.CellInfo.Xdimension", NULL ) )
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = CPLAtof( 
            poHeader->Find( "RasterInfo.RegistrationCoord.Eastings", "" ));
        poDS->adfGeoTransform[1] = CPLAtof( 
            poHeader->Find( "RasterInfo.CellInfo.Xdimension", "" ));
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = CPLAtof( 
            poHeader->Find( "RasterInfo.RegistrationCoord.Northings", "" ));
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = -CPLAtof( 
            poHeader->Find( "RasterInfo.CellInfo.Ydimension", "" ));
    }
    else if( poHeader->Find( "RasterInfo.RegistrationCoord.Latitude", NULL )
             && poHeader->Find( "RasterInfo.CellInfo.Xdimension", NULL ) )
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = ERSDMS2Dec( 
            poHeader->Find( "RasterInfo.RegistrationCoord.Longitude", "" ));
        poDS->adfGeoTransform[1] = CPLAtof( 
            poHeader->Find( "RasterInfo.CellInfo.Xdimension", "" ));
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = ERSDMS2Dec( 
            poHeader->Find( "RasterInfo.RegistrationCoord.Latitude", "" ));
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = -CPLAtof( 
            poHeader->Find( "RasterInfo.CellInfo.Ydimension", "" ));
    }

/* -------------------------------------------------------------------- */
/*      Adjust if we have a registration cell.                          */
/* -------------------------------------------------------------------- */
    int iCellX = atoi(poHeader->Find("RasterInfo.RegistrationCellX", "1"));
    int iCellY = atoi(poHeader->Find("RasterInfo.RegistrationCellY", "1"));

    if( poDS->bGotTransform )
    {
        poDS->adfGeoTransform[0] -=
            (iCellX-1) * poDS->adfGeoTransform[1]
            + (iCellY-1) * poDS->adfGeoTransform[2];
        poDS->adfGeoTransform[3] -= 
            (iCellX-1) * poDS->adfGeoTransform[4]
            + (iCellY-1) * poDS->adfGeoTransform[5];
    }

/* -------------------------------------------------------------------- */
/*      Check for null values.                                          */
/* -------------------------------------------------------------------- */
    if( poHeader->Find( "RasterInfo.NullCellValue", NULL ) )
    {
        CPLPushErrorHandler( CPLQuietErrorHandler );

        for( iBand = 1; iBand <= poDS->nBands; iBand++ )
            poDS->GetRasterBand(iBand)->SetNoDataValue(
                CPLAtofM(poHeader->Find( "RasterInfo.NullCellValue" )) );
        
        CPLPopErrorHandler();
    }

/* -------------------------------------------------------------------- */
/*      Do we have an "All" region?                                     */
/* -------------------------------------------------------------------- */
    ERSHdrNode *poAll = NULL;

    for( iChild = 0; 
         poRI != NULL && iChild < poRI->nItemCount; 
         iChild++ )
    {
        if( poRI->papoItemChild[iChild] != NULL
            && EQUAL(poRI->papszItemName[iChild],"RegionInfo") )
        {
            if( EQUAL(poRI->papoItemChild[iChild]->Find("RegionName",""), 
                      "All") )
                poAll = poRI->papoItemChild[iChild];
        }
    }

/* -------------------------------------------------------------------- */
/*      Do we have statistics?                                          */
/* -------------------------------------------------------------------- */
    if( poAll && poAll->FindNode( "Stats" ) )
    {
        CPLPushErrorHandler( CPLQuietErrorHandler );

        for( iBand = 1; iBand <= poDS->nBands; iBand++ )
        {
            const char *pszValue = 
                poAll->FindElem( "Stats.MinimumValue", iBand-1 );

            if( pszValue )
                poDS->GetRasterBand(iBand)->SetMetadataItem(
                    "STATISTICS_MINIMUM", pszValue );

            pszValue = poAll->FindElem( "Stats.MaximumValue", iBand-1 );

            if( pszValue )
                poDS->GetRasterBand(iBand)->SetMetadataItem(
                    "STATISTICS_MAXIMUM", pszValue );

            pszValue = poAll->FindElem( "Stats.MeanValue", iBand-1 );

            if( pszValue )
                poDS->GetRasterBand(iBand)->SetMetadataItem(
                    "STATISTICS_MEAN", pszValue );

            pszValue = poAll->FindElem( "Stats.MedianValue", iBand-1 );

            if( pszValue )
                poDS->GetRasterBand(iBand)->SetMetadataItem(
                    "STATISTICS_MEDIAN", pszValue );
        }
        
        CPLPopErrorHandler();
        
    }

/* -------------------------------------------------------------------- */
/*      Do we have GCPs.                                                */
/* -------------------------------------------------------------------- */
    if( poHeader->FindNode( "RasterInfo.WarpControl" ) )
        poDS->ReadGCPs();

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();
    
    // if no SR in xml, try aux
    const char* pszPrj = poDS->GDALPamDataset::GetProjectionRef();
    if( !pszPrj || strlen(pszPrj) == 0 )
    {
        // try aux
        GDALDataset* poAuxDS = GDALFindAssociatedAuxFile( poOpenInfo->pszFilename, GA_ReadOnly, poDS );
        if( poAuxDS )
        {
            pszPrj = poAuxDS->GetProjectionRef();
            if( pszPrj && strlen(pszPrj) > 0 )
            {
                CPLFree( poDS->pszProjection );
                poDS->pszProjection = CPLStrdup(pszPrj);
            }

            GDALClose( poAuxDS );
        }
    }
/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
Ejemplo n.º 7
0
CPLErr GSAGRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
				    void * pImage )

{
    if( eAccess == GA_ReadOnly )
    {
	CPLError( CE_Failure, CPLE_NoWriteAccess,
		  "Unable to write block, dataset opened read only.\n" );
	return CE_Failure;
    }

    if( nBlockYOff < 0 || nBlockYOff > nRasterYSize - 1 || nBlockXOff != 0 )
	return CE_Failure;

    GSAGDataset *poGDS = (GSAGDataset *)poDS;
    assert( poGDS != NULL );

    if( padfRowMinZ == NULL || padfRowMaxZ == NULL
	|| nMinZRow < 0 || nMaxZRow < 0 )
    {
	padfRowMinZ = (double *)VSIMalloc2( nRasterYSize,sizeof(double) );
	if( padfRowMinZ == NULL )
	{
	    CPLError( CE_Failure, CPLE_OutOfMemory,
		      "Unable to allocate space for row minimums array.\n" );
	    return CE_Failure;
	}

	padfRowMaxZ = (double *)VSIMalloc2( nRasterYSize,sizeof(double) );
	if( padfRowMaxZ == NULL )
	{
	    VSIFree( padfRowMinZ );
	    padfRowMinZ = NULL;
	    CPLError( CE_Failure, CPLE_OutOfMemory,
		      "Unable to allocate space for row maximums array.\n" );
	    return CE_Failure;
	}

	CPLErr eErr = ScanForMinMaxZ();
	if( eErr != CE_None )
	    return eErr;
    }

    if( panLineOffset[nBlockYOff+1] == 0 )
	IReadBlock( nBlockXOff, nBlockYOff, NULL );

    if( panLineOffset[nBlockYOff+1] == 0 || panLineOffset[nBlockYOff] == 0 )
	return CE_Failure;

    std::ostringstream ssOutBuf;
    ssOutBuf.precision( GSAGDataset::nFIELD_PRECISION );
    ssOutBuf.setf( std::ios::uppercase );

    double *pdfImage = (double *)pImage;
    padfRowMinZ[nBlockYOff] = DBL_MAX;
    padfRowMaxZ[nBlockYOff] = -DBL_MAX;
    for( int iCell=0; iCell<nBlockXSize; )
    {
	for( int iCol=0; iCol<10 && iCell<nBlockXSize; iCol++, iCell++ )
	{
	    if( AlmostEqual( pdfImage[iCell], GSAGDataset::dfNODATA_VALUE ) )
	    {
		if( pdfImage[iCell] < padfRowMinZ[nBlockYOff] )
		    padfRowMinZ[nBlockYOff] = pdfImage[iCell];

		if( pdfImage[iCell] > padfRowMaxZ[nBlockYOff] )
		    padfRowMaxZ[nBlockYOff] = pdfImage[iCell];
	    }

	    ssOutBuf << pdfImage[iCell] << " ";
	}
	ssOutBuf << poGDS->szEOL;
    }
    ssOutBuf << poGDS->szEOL;

    CPLString sOut = ssOutBuf.str();
    if( sOut.length() != panLineOffset[nBlockYOff+1]-panLineOffset[nBlockYOff] )
    {
	int nShiftSize = (int) (sOut.length() - (panLineOffset[nBlockYOff+1]
                                                 - panLineOffset[nBlockYOff]));
	if( nBlockYOff != poGDS->nRasterYSize
	    && GSAGDataset::ShiftFileContents( poGDS->fp,
					       panLineOffset[nBlockYOff+1],
					       nShiftSize,
					       poGDS->szEOL ) != CE_None )
	{
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Failure writing block, "
		      "unable to shift file contents.\n" );
	    return CE_Failure;
	}

	for( size_t iLine=nBlockYOff+1;
	     iLine < static_cast<unsigned>(poGDS->nRasterYSize+1)
		&& panLineOffset[iLine] != 0; iLine++ )
	    panLineOffset[iLine] += nShiftSize;
    }

    if( VSIFSeekL( poGDS->fp, panLineOffset[nBlockYOff], SEEK_SET ) != 0 )
    {
	CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to grid line.\n" );
	return CE_Failure;
    }

    if( VSIFWriteL( sOut.c_str(), 1, sOut.length(),
		    poGDS->fp ) != sOut.length() )
    {
	CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid block.\n" );
	return CE_Failure;
    }

    /* Update header as needed */
    bool bHeaderNeedsUpdate = false;
    if( nMinZRow == nBlockYOff && padfRowMinZ[nBlockYOff] > dfMinZ )
    {
	double dfNewMinZ = -DBL_MAX;
	for( int iRow=0; iRow<nRasterYSize; iRow++ )
	{
	    if( padfRowMinZ[iRow] < dfNewMinZ )
	    {
		dfNewMinZ = padfRowMinZ[iRow];
		nMinZRow = iRow;
	    }
	}

	if( dfNewMinZ != dfMinZ )
	{
	    dfMinZ = dfNewMinZ;
	    bHeaderNeedsUpdate = true;
	}
    }

    if( nMaxZRow == nBlockYOff && padfRowMaxZ[nBlockYOff] < dfMaxZ )
    {
	double dfNewMaxZ = -DBL_MAX;
	for( int iRow=0; iRow<nRasterYSize; iRow++ )
	{
	    if( padfRowMaxZ[iRow] > dfNewMaxZ )
	    {
		dfNewMaxZ = padfRowMaxZ[iRow];
		nMaxZRow = iRow;
	    }
	}

	if( dfNewMaxZ != dfMaxZ )
	{
	    dfMaxZ = dfNewMaxZ;
	    bHeaderNeedsUpdate = true;
	}
    }

    if( padfRowMinZ[nBlockYOff] < dfMinZ || padfRowMaxZ[nBlockYOff] > dfMaxZ )
    {
	if( padfRowMinZ[nBlockYOff] < dfMinZ )
	{
	    dfMinZ = padfRowMinZ[nBlockYOff];
	    nMinZRow = nBlockYOff;
	}

	if( padfRowMaxZ[nBlockYOff] > dfMaxZ )
	{
	    dfMaxZ = padfRowMaxZ[nBlockYOff];
	    nMaxZRow = nBlockYOff;
	}

	bHeaderNeedsUpdate = true;
    }

    if( bHeaderNeedsUpdate && dfMaxZ > dfMinZ )
    {
	CPLErr eErr = poGDS->UpdateHeader();
	return eErr;
    }

    return CE_None;
}
Ejemplo n.º 8
0
GDALDataset *GSAGDataset::CreateCopy( const char *pszFilename,
				      GDALDataset *poSrcDS,
				      int bStrict, char **papszOptions,
				      GDALProgressFunc pfnProgress,
				      void *pProgressData )
{
    if( pfnProgress == NULL )
	pfnProgress = GDALDummyProgress;

    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GSAG driver does not support source dataset with zero band.\n");
        return NULL;
    }
    else if (nBands > 1)
    {
	if( bStrict )
	{
	    CPLError( CE_Failure, CPLE_NotSupported,
		      "Unable to create copy, Golden Software ASCII Grid "
		      "format only supports one raster band.\n" );
	    return NULL;
	}
	else
	    CPLError( CE_Warning, CPLE_NotSupported,
		      "Golden Software ASCII Grid format only supports one "
		      "raster band, first band will be copied.\n" );
    }

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" );
        return NULL;
    }

    VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to create file '%s' failed.\n",
                  pszFilename );
        return NULL;
    }

    int          nXSize = poSrcDS->GetRasterXSize();
    int          nYSize = poSrcDS->GetRasterYSize();
    double	 adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    std::ostringstream ssHeader;
    ssHeader.precision( nFIELD_PRECISION );
    ssHeader.setf( std::ios::uppercase );

    ssHeader << "DSAA\x0D\x0A";

    ssHeader << nXSize << " " << nYSize << "\x0D\x0A";

    ssHeader << adfGeoTransform[0] + adfGeoTransform[1] / 2 << " "
	     << adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0]
	     << "\x0D\x0A";

    ssHeader << adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3] << " "
	     << adfGeoTransform[3] + adfGeoTransform[5] / 2
	     << "\x0D\x0A";

    if( VSIFWriteL( (void *)ssHeader.str().c_str(), 1, ssHeader.str().length(),
		    fp ) != ssHeader.str().length() )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to create copy, writing header failed.\n" );
        return NULL;
    }

    /* Save the location and write placeholders for the min/max Z value */
    vsi_l_offset nRangeStart = VSIFTellL( fp );
    const char *szDummyRange = "0.0000000000001 0.0000000000001\x0D\x0A";
    size_t nDummyRangeLen = strlen( szDummyRange );
    if( VSIFWriteL( (void *)szDummyRange, 1, nDummyRangeLen,
		    fp ) != nDummyRangeLen )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to create copy, writing header failed.\n" );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Copy band data.							*/
/* -------------------------------------------------------------------- */
    double *pdfData = (double *)VSIMalloc2( nXSize, sizeof( double ) );
    if( pdfData == NULL )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to create copy, unable to allocate line buffer.\n" );
	return NULL;
    }

    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand(1);
    int bSrcHasNDValue;
    double dfSrcNoDataValue = poSrcBand->GetNoDataValue( &bSrcHasNDValue );
    double dfMin = DBL_MAX;
    double dfMax = -DBL_MAX;
    for( int iRow=0; iRow<nYSize; iRow++ )
    {
	CPLErr eErr = poSrcBand->RasterIO( GF_Read, 0, nYSize-iRow-1,
					   nXSize, 1, pdfData,
					   nXSize, 1, GDT_Float64, 0, 0 );

	if( eErr != CE_None )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    return NULL;
	}

	for( int iCol=0; iCol<nXSize; )
	{
	    for( int iCount=0;
		 iCount<10 && iCol<nXSize;
		 iCount++, iCol++ )
	    {
		double dfValue = pdfData[iCol];

		if( bSrcHasNDValue && AlmostEqual( dfValue, dfSrcNoDataValue ) )
		{
		    dfValue = dfNODATA_VALUE;
		}
		else
		{
		    if( dfValue > dfMax )
			dfMax = dfValue;

		    if( dfValue < dfMin )
			dfMin = dfValue;
		}

		std::ostringstream ssOut;
		ssOut.precision(nFIELD_PRECISION);
		ssOut.setf( std::ios::uppercase );
		ssOut << dfValue << " ";
		CPLString sOut = ssOut.str();

		if( VSIFWriteL( sOut.c_str(), 1, sOut.length(), fp )
		    != sOut.length() )
		{
		    VSIFCloseL( fp );
		    VSIFree( pdfData );
		    CPLError( CE_Failure, CPLE_FileIO,
			      "Unable to write grid cell.  Disk full?\n" );
		    return NULL;
		}
	    }

	    if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 )
	    {
		VSIFCloseL( fp );
		VSIFree( pdfData );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to finish write of grid line. Disk full?\n" );
		return NULL;
	    }
	}

	if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to finish write of grid row. Disk full?\n" );
	    return NULL;
	}

	if( !pfnProgress( static_cast<double>(iRow + 1)/nYSize,
			  NULL, pProgressData ) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
	    return NULL;
	}
    }

    VSIFree( pdfData );

    /* write out the min and max values */
    std::ostringstream ssRange;
    ssRange.precision( nFIELD_PRECISION );
    ssRange.setf( std::ios::uppercase );
    ssRange << dfMin << " " << dfMax << "\x0D\x0A";
    if( ssRange.str().length() != nDummyRangeLen )
    {
	int nShiftSize = ssRange.str().length() - nDummyRangeLen;
	if( ShiftFileContents( fp, nRangeStart + nDummyRangeLen,
			       nShiftSize, "\x0D\x0A" ) != CE_None )
	{
	    VSIFCloseL( fp );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to shift file contents.\n" );
	    return NULL;
	}
    }

    if( VSIFSeekL( fp, nRangeStart, SEEK_SET ) != 0 )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to seek to start of grid file copy.\n" );
	return NULL;
    }

    if( VSIFWriteL( (void *)ssRange.str().c_str(), 1, ssRange.str().length(),
		    fp ) != ssRange.str().length() )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to write range information.\n" );
        return NULL;
    }

    VSIFCloseL( fp );

    GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename,
                                                GA_Update );
    if (poDS)
    {
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
    }
    return poDS;
}
Ejemplo n.º 9
0
CPLErr GSAGDataset::UpdateHeader()

{
    GSAGRasterBand *poBand = (GSAGRasterBand *)GetRasterBand( 1 );
    if( poBand == NULL )
    {
	CPLError( CE_Failure, CPLE_FileIO, "Unable to open raster band.\n" );
	return CE_Failure;
    }

    std::ostringstream ssOutBuf;
    ssOutBuf.precision( nFIELD_PRECISION );
    ssOutBuf.setf( std::ios::uppercase );

    /* signature */
    ssOutBuf << "DSAA" << szEOL;

    /* columns rows */
    ssOutBuf << nRasterXSize << " " << nRasterYSize << szEOL;

    /* x range */
    ssOutBuf << poBand->dfMinX << " " << poBand->dfMaxX << szEOL;

    /* y range */
    ssOutBuf << poBand->dfMinY << " " << poBand->dfMaxY << szEOL;

    /* z range */
    ssOutBuf << poBand->dfMinZ << " " << poBand->dfMaxZ << szEOL;

    CPLString sOut = ssOutBuf.str();
    if( sOut.length() != poBand->panLineOffset[0] )
    {
	int nShiftSize = (int) (sOut.length() - poBand->panLineOffset[0]);
	if( ShiftFileContents( fp, poBand->panLineOffset[0], nShiftSize,
			       szEOL ) != CE_None )
	{
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to update grid header, "
		      "failure shifting file contents.\n" );
	    return CE_Failure;
	}

	for( size_t iLine=0;
	     iLine < static_cast<unsigned>(nRasterYSize+1)
		&& poBand->panLineOffset[iLine] != 0;
	     iLine++ )
	    poBand->panLineOffset[iLine] += nShiftSize;
    }

    if( VSIFSeekL( fp, 0, SEEK_SET ) != 0 )
    {
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to seek to start of grid file.\n" );
	return CE_Failure;
    }

    if( VSIFWriteL( sOut.c_str(), 1, sOut.length(), fp ) != sOut.length() )
    {
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to update file header.  Disk full?\n" );
	return CE_Failure;
    }

    return CE_None;
}
Ejemplo n.º 10
0
static herr_t HDF5AttrIterate( hid_t hH5ObjID,
                               const char *pszAttrName,
                               // TODO(schwehr): void * -> HDF5Dataset *
                               void *pDS )
{
    char **papszTokens = nullptr;
    CPLString osKey;
    HDF5Dataset *const poDS = static_cast<HDF5Dataset *>(pDS);

    // Convert "/" into "_" for the path component
    const char *pszPath = poDS->poH5CurrentObject->pszUnderscorePath;
    if(pszPath != nullptr && strlen(pszPath) > 0)
    {
        papszTokens = CSLTokenizeString2(pszPath, "/", CSLT_HONOURSTRINGS);

        for( hsize_t i = 0; papszTokens != nullptr && papszTokens[i] != nullptr; ++i )
        {
            if( i != 0)
                osKey += '_';
            osKey += papszTokens[i];
        }
        CSLDestroy(papszTokens);
    }

    // Convert whitespaces into "_" for the attribute name component
    papszTokens = CSLTokenizeString2(
        pszAttrName, " ", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES);
    for( hsize_t i = 0; papszTokens != nullptr && papszTokens[i] != nullptr; ++i )
    {
        if(!osKey.empty())
            osKey += '_';
        osKey += papszTokens[i];
    }
    CSLDestroy(papszTokens);

    const hid_t hAttrID = H5Aopen_name(hH5ObjID, pszAttrName);
    const hid_t hAttrTypeID = H5Aget_type(hAttrID);
    const hid_t hAttrNativeType =
        H5Tget_native_type(hAttrTypeID, H5T_DIR_DEFAULT);
    const hid_t hAttrSpace = H5Aget_space(hAttrID);

    if( H5Tget_class(hAttrNativeType) == H5T_VLEN )
        return 0;

    hsize_t nSize[64] = {};
    const unsigned int nAttrDims =
        H5Sget_simple_extent_dims(hAttrSpace, nSize, nullptr);

    unsigned int nAttrElmts = 1;
    for( hsize_t i = 0; i < nAttrDims; i++ )
    {
        nAttrElmts *= static_cast<int>(nSize[i]);
    }

    char *szData = nullptr;
    hsize_t nAttrSize = 0;
    char *szValue = nullptr;

    if( H5Tget_class(hAttrNativeType) == H5T_STRING )
    {
        if ( H5Tis_variable_str(hAttrNativeType) )
        {
            char **papszStrings =
                static_cast<char **>(CPLMalloc(nAttrElmts * sizeof(char *)));

            // Read the values.
            H5Aread(hAttrID, hAttrNativeType, papszStrings);

            // Concatenate all values as one string separated by a space.
            CPLString osVal = papszStrings[0];
            for( hsize_t i = 1; i < nAttrElmts; i++ )
            {
                osVal += " ";
                osVal += papszStrings[i];
            }

            szValue = static_cast<char *>(CPLMalloc(osVal.length() + 1));
            strcpy(szValue, osVal.c_str());

            H5Dvlen_reclaim(hAttrNativeType, hAttrSpace, H5P_DEFAULT,
                            papszStrings);
            CPLFree(papszStrings);
        }
        else
        {
            nAttrSize = H5Aget_storage_size(hAttrID);
            szValue = static_cast<char *>(CPLMalloc((size_t)(nAttrSize + 1)));
            H5Aread(hAttrID, hAttrNativeType, szValue);
            szValue[nAttrSize] = '\0';
        }
    }
    else
    {
        const size_t nDataLen = 8192;
        void *buf = nullptr;

        if( nAttrElmts > 0 )
        {
            buf = CPLMalloc(nAttrElmts * H5Tget_size(hAttrNativeType));
            szData = static_cast<char *>(CPLMalloc(nDataLen));
            szValue = static_cast<char *>(CPLMalloc(MAX_METADATA_LEN));
            szData[0] = '\0';
            szValue[0] = '\0';
            H5Aread(hAttrID, hAttrNativeType, buf);
        }
        if( H5Tequal(H5T_NATIVE_CHAR, hAttrNativeType ) ||
            H5Tequal(H5T_NATIVE_SCHAR, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%c ", static_cast<char *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_UCHAR, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%c", static_cast<char *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_SHORT, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%d ", static_cast<short *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_USHORT, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
              snprintf(szData, nDataLen, "%ud ",
                       static_cast<unsigned short *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_INT, hAttrNativeType) )
        {
            for( hsize_t i=0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%d ", static_cast<int *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_UINT, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%ud ",
                         static_cast<unsigned int *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_LONG, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%ld ", static_cast<long *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_ULONG, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ ) {
                snprintf(szData, nDataLen, "%lu ",
                         static_cast<unsigned long *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_FLOAT, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                CPLsnprintf(szData, nDataLen, "%.8g ",
                            static_cast<float *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_DOUBLE, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                CPLsnprintf(szData, nDataLen, "%.15g ",
                            static_cast<double *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        CPLFree(buf);
    }
    H5Sclose(hAttrSpace);
    H5Tclose(hAttrNativeType);
    H5Tclose(hAttrTypeID);
    H5Aclose(hAttrID);
    poDS->papszMetadata = CSLSetNameValue(poDS->papszMetadata, osKey, szValue);

    CPLFree(szData);
    CPLFree(szValue);

    return 0;
}
Ejemplo n.º 11
0
herr_t HDF5AttrIterate( hid_t hH5ObjID,
                        const char *pszAttrName,
                        void *pDS )
{
    hid_t           hAttrID;
    hid_t           hAttrTypeID;
    hid_t           hAttrNativeType;
    hid_t           hAttrSpace;

    char           *szData = NULL;
    hsize_t        nSize[64];
    unsigned int   nAttrElmts;
    hsize_t        nAttrSize;
    hsize_t        i;
    void           *buf = NULL;
    unsigned int   nAttrDims;

    char          **papszTokens;

    HDF5Dataset    *poDS;
    CPLString       osKey;
    char           *szValue = NULL;

    poDS = (HDF5Dataset *) pDS;

    // Convert "/" into "_" for the path component
    const char* pszPath = poDS->poH5CurrentObject->pszUnderscorePath;
    if(pszPath != NULL && strlen(pszPath) > 0)
    {
        papszTokens = CSLTokenizeString2( pszPath, "/", CSLT_HONOURSTRINGS );

        for( i = 0; papszTokens != NULL && papszTokens[i] != NULL; ++i )
        {
            if( i != 0)
                osKey += '_';
            osKey += papszTokens[i];
        }
        CSLDestroy( papszTokens );
    }

    // Convert whitespaces into "_" for the attribute name component
    papszTokens = CSLTokenizeString2( pszAttrName, " ",
                            CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES );
    for( i = 0; papszTokens != NULL && papszTokens[i] != NULL; ++i )
    {
        if(!osKey.empty())
            osKey += '_';
        osKey += papszTokens[i];
    }
    CSLDestroy( papszTokens );

    hAttrID          = H5Aopen_name( hH5ObjID, pszAttrName );
    hAttrTypeID      = H5Aget_type( hAttrID );
    hAttrNativeType  = H5Tget_native_type( hAttrTypeID, H5T_DIR_DEFAULT );
    hAttrSpace       = H5Aget_space( hAttrID );
    nAttrDims        = H5Sget_simple_extent_dims( hAttrSpace, nSize, NULL );

    nAttrElmts = 1;
    for( i=0; i < nAttrDims; i++ ) {
        nAttrElmts *= (int) nSize[i];
    }

    if( H5Tget_class( hAttrNativeType ) == H5T_STRING )
    {
        if ( H5Tis_variable_str(hAttrNativeType) )
        {
            char** papszStrings;
            papszStrings = (char**) CPLMalloc( nAttrElmts * sizeof(char*) );

            // Read the values
            H5Aread( hAttrID, hAttrNativeType, papszStrings );

            // Concatenate all values as one string (separated by a space)
            CPLString osVal = papszStrings[0];
            for( i=1; i < nAttrElmts; i++ ) {
                osVal += " ";
                osVal += papszStrings[i];
            }

            szValue = (char*) CPLMalloc(osVal.length() + 1);
            strcpy( szValue, osVal.c_str() );

            H5Dvlen_reclaim( hAttrNativeType, hAttrSpace, H5P_DEFAULT,
                             papszStrings );
            CPLFree( papszStrings );
        }
        else
        {
            nAttrSize = H5Aget_storage_size( hAttrID );
            szValue = (char*) CPLMalloc((size_t) (nAttrSize+1));
            H5Aread( hAttrID, hAttrNativeType, szValue );
            szValue[nAttrSize] = '\0';
        }
    }
    else {
        if( nAttrElmts > 0 ) {
            buf = (void *) CPLMalloc( nAttrElmts*
                          H5Tget_size( hAttrNativeType ));
            szData = (char*) CPLMalloc( 8192 );
            szValue = (char*) CPLMalloc( MAX_METADATA_LEN );
            szData[0] = '\0';
            szValue[0] ='\0';
            H5Aread( hAttrID, hAttrNativeType, buf );
        }
        if( H5Tequal( H5T_NATIVE_CHAR, hAttrNativeType ) 
            || H5Tequal( H5T_NATIVE_SCHAR,  hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%c ", ((char *) buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_UCHAR,  hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%c", ((char *) buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_SHORT,  hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%d ", ((short *) buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_USHORT, hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%ud ", ((unsigned short *) buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_INT,    hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%d ", ((int *) buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_UINT,   hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%ud ", ((unsigned int *) buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_LONG,   hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%ld ", ((long *)buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_ULONG,  hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%ld ", ((unsigned long *)buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_FLOAT,  hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                CPLsprintf( szData, "%.8g ",  ((float *)buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_DOUBLE, hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                CPLsprintf( szData, "%.15g ",  ((double *)buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        CPLFree( buf );

    }
    H5Sclose(hAttrSpace);
    H5Tclose(hAttrNativeType);
    H5Tclose(hAttrTypeID);
    H5Aclose( hAttrID );
    poDS->papszMetadata = CSLSetNameValue( poDS->papszMetadata, osKey, szValue);

    CPLFree( szData );
    CPLFree( szValue );

    return 0;
}
Ejemplo n.º 12
0
OGRGmtLayer::OGRGmtLayer( const char * pszFilename, int bUpdateIn ) :
    poSRS(NULL),
    poFeatureDefn(NULL),
    iNextFID(0),
    bUpdate(CPL_TO_BOOL(bUpdateIn)),
    // Assume header complete in readonly mode.
    bHeaderComplete(CPL_TO_BOOL(!bUpdate)),
    bRegionComplete(false),
    nRegionOffset(0),
    papszKeyedValues(NULL),
    bValidFile(FALSE)
{

/* -------------------------------------------------------------------- */
/*      Open file.                                                      */
/* -------------------------------------------------------------------- */
    if( bUpdate )
        fp = VSIFOpenL( pszFilename, "r+" );
    else
        fp = VSIFOpenL( pszFilename, "r" );

    if( fp == NULL )
        return;

/* -------------------------------------------------------------------- */
/*      Read the header.                                                */
/* -------------------------------------------------------------------- */
    CPLString osFieldNames;
    CPLString osFieldTypes;
    CPLString osGeometryType;
    CPLString osRegion;
    CPLString osWKT;
    CPLString osProj4;
    CPLString osEPSG;
    vsi_l_offset nStartOfLine = VSIFTellL(fp);

    while( ReadLine() && osLine[0] == '#' )
    {
        if( strstr( osLine, "FEATURE_DATA" ) )
        {
            bHeaderComplete = TRUE;
            ReadLine();
            break;
        }

        if( STARTS_WITH_CI(osLine, "# REGION_STUB ") )
            nRegionOffset = nStartOfLine;

        for( int iKey = 0;
             papszKeyedValues != NULL && papszKeyedValues[iKey] != NULL;
             iKey++ )
        {
            if( papszKeyedValues[iKey][0] == 'N' )
                osFieldNames = papszKeyedValues[iKey] + 1;
            if( papszKeyedValues[iKey][0] == 'T' )
                osFieldTypes = papszKeyedValues[iKey] + 1;
            if( papszKeyedValues[iKey][0] == 'G' )
                osGeometryType = papszKeyedValues[iKey] + 1;
            if( papszKeyedValues[iKey][0] == 'R' )
                osRegion = papszKeyedValues[iKey] + 1;
            if( papszKeyedValues[iKey][0] == 'J' )
            {
                CPLString osArg = papszKeyedValues[iKey] + 2;
                if( osArg[0] == '"' && osArg[osArg.length()-1] == '"' )
                {
                    osArg = osArg.substr(1,osArg.length()-2);
                    char *pszArg = CPLUnescapeString(osArg, NULL,
                                                     CPLES_BackslashQuotable);
                    osArg = pszArg;
                    CPLFree( pszArg );
                }

                if( papszKeyedValues[iKey][1] == 'e' )
                    osEPSG = osArg;
                if( papszKeyedValues[iKey][1] == 'p' )
                    osProj4 = osArg;
                if( papszKeyedValues[iKey][1] == 'w' )
                    osWKT = osArg;
            }
        }

        nStartOfLine = VSIFTellL(fp);
    }

/* -------------------------------------------------------------------- */
/*      Handle coordinate system.                                       */
/* -------------------------------------------------------------------- */
    if( osWKT.length() )
    {
        char *pszWKT = (char *) osWKT.c_str();

        poSRS = new OGRSpatialReference();
        if( poSRS->importFromWkt(&pszWKT) != OGRERR_NONE )
        {
            delete poSRS;
            poSRS = NULL;
        }
    }
    else if( osEPSG.length() )
    {
        poSRS = new OGRSpatialReference();
        if( poSRS->importFromEPSG( atoi(osEPSG) ) != OGRERR_NONE )
        {
            delete poSRS;
            poSRS = NULL;
        }
    }
    else if( osProj4.length() )
    {
        poSRS = new OGRSpatialReference();
        if( poSRS->importFromProj4( osProj4 ) != OGRERR_NONE )
        {
            delete poSRS;
            poSRS = NULL;
        }
    }

/* -------------------------------------------------------------------- */
/*      Create the feature definition, and set the geometry type, if    */
/*      known.                                                          */
/* -------------------------------------------------------------------- */
    poFeatureDefn = new OGRFeatureDefn( CPLGetBasename(pszFilename) );
    SetDescription( poFeatureDefn->GetName() );
    poFeatureDefn->Reference();
    poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);

    if( osGeometryType == "POINT" )
        poFeatureDefn->SetGeomType( wkbPoint );
    else if( osGeometryType == "MULTIPOINT" )
        poFeatureDefn->SetGeomType( wkbMultiPoint );
    else if( osGeometryType == "LINESTRING" )
        poFeatureDefn->SetGeomType( wkbLineString );
    else if( osGeometryType == "MULTILINESTRING" )
        poFeatureDefn->SetGeomType( wkbMultiLineString );
    else if( osGeometryType == "POLYGON" )
        poFeatureDefn->SetGeomType( wkbPolygon );
    else if( osGeometryType == "MULTIPOLYGON" )
        poFeatureDefn->SetGeomType( wkbMultiPolygon );

/* -------------------------------------------------------------------- */
/*      Process a region line.                                          */
/* -------------------------------------------------------------------- */
    if( osRegion.length() > 0 )
    {
        char **papszTokens = CSLTokenizeStringComplex( osRegion.c_str(),
                                                       "/", FALSE, FALSE );

        if( CSLCount(papszTokens) == 4 )
        {
            sRegion.MinX = CPLAtofM(papszTokens[0]);
            sRegion.MaxX = CPLAtofM(papszTokens[1]);
            sRegion.MinY = CPLAtofM(papszTokens[2]);
            sRegion.MaxY = CPLAtofM(papszTokens[3]);
        }

        bRegionComplete = TRUE;

        CSLDestroy( papszTokens );
    }

/* -------------------------------------------------------------------- */
/*      Process fields.                                                 */
/* -------------------------------------------------------------------- */
    if( osFieldNames.length() || osFieldTypes.length() )
    {
        char **papszFN = CSLTokenizeStringComplex( osFieldNames, "|",
                                                   TRUE, TRUE );
        char **papszFT = CSLTokenizeStringComplex( osFieldTypes, "|",
                                                   TRUE, TRUE );
        const int nFieldCount = MAX(CSLCount(papszFN),CSLCount(papszFT));

        for( int iField = 0; iField < nFieldCount; iField++ )
        {
            OGRFieldDefn oField("", OFTString );

            if( iField < CSLCount(papszFN) )
                oField.SetName( papszFN[iField] );
            else
                oField.SetName( CPLString().Printf( "Field_%d", iField+1 ));

            if( iField < CSLCount(papszFT) )
            {
                if( EQUAL(papszFT[iField],"integer") )
                    oField.SetType( OFTInteger );
                else if( EQUAL(papszFT[iField],"double") )
                    oField.SetType( OFTReal );
                else if( EQUAL(papszFT[iField],"datetime") )
                    oField.SetType( OFTDateTime );
            }

            poFeatureDefn->AddFieldDefn( &oField );
        }

        CSLDestroy( papszFN );
        CSLDestroy( papszFT );
    }

    bValidFile = TRUE;
}