Exemple #1
0
GDALDataset *ELASDataset::Create( const char * pszFilename,
                                  int nXSize, int nYSize, int nBands,
                                  GDALDataType eType,
                                  char ** /* notdef: papszParmList */ )

{
    int		nBandOffset;
    
/* -------------------------------------------------------------------- */
/*      Verify input options.                                           */
/* -------------------------------------------------------------------- */
    if (nBands <= 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "ELAS driver does not support %d bands.\n", nBands);
        return NULL;
    }

    if( eType != GDT_Byte && eType != GDT_Float32 && eType != GDT_Float64 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Attempt to create an ELAS dataset with an illegal\n"
                  "data type (%d).\n",
                  eType );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Try to create the file.                                         */
/* -------------------------------------------------------------------- */
    FILE	*fp;

    fp = VSIFOpen( pszFilename, "w" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to create file `%s' failed.\n",
                  pszFilename );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*	How long will each band of a scanline be?			*/
/* -------------------------------------------------------------------- */
    nBandOffset = nXSize * GDALGetDataTypeSize(eType)/8;

    if( nBandOffset % 256 != 0 )
    {
        nBandOffset = nBandOffset - (nBandOffset % 256) + 256;
    }

/* -------------------------------------------------------------------- */
/*      Setup header data block.                                        */
/*                                                                      */
/*      Note that CPL_MSBWORD32() will swap little endian words to      */
/*      big endian on little endian platforms.                          */
/* -------------------------------------------------------------------- */
    ELASHeader	sHeader;

    memset( &sHeader, 0, 1024 );

    sHeader.NBIH = CPL_MSBWORD32(1024);

    sHeader.NBPR = CPL_MSBWORD32(nBands * nBandOffset);
    
    sHeader.IL = CPL_MSBWORD32(1);
    sHeader.LL = CPL_MSBWORD32(nYSize);

    sHeader.IE = CPL_MSBWORD32(1);
    sHeader.LE = CPL_MSBWORD32(nXSize);

    sHeader.NC = CPL_MSBWORD32(nBands);

    sHeader.H4321 = CPL_MSBWORD32(4321);

    sHeader.IH19[0] = 0x04;
    sHeader.IH19[1] = 0xd2;
    sHeader.IH19[3] = (GByte) (GDALGetDataTypeSize(eType) / 8);

    if( eType == GDT_Byte )
        sHeader.IH19[2] = 1 << 2;
    else if( eType == GDT_Float32 )
        sHeader.IH19[2] = 16 << 2;
    else if( eType == GDT_Float64 )
        sHeader.IH19[2] = 17 << 2;

/* -------------------------------------------------------------------- */
/*      Write the header data.                                          */
/* -------------------------------------------------------------------- */
    VSIFWrite( &sHeader, 1024, 1, fp );

/* -------------------------------------------------------------------- */
/*      Now write out zero data for all the imagery.  This is           */
/*      inefficient, but simplies the IReadBlock() / IWriteBlock() logic.*/
/* -------------------------------------------------------------------- */
    GByte	*pabyLine;

    pabyLine = (GByte *) CPLCalloc(nBandOffset,nBands);
    for( int iLine = 0; iLine < nYSize; iLine++ )
    {
        if( VSIFWrite( pabyLine, 1, nBandOffset, fp ) != (size_t) nBandOffset )
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Error writing ELAS image data ... likely insufficient"
                      " disk space.\n" );
            VSIFClose( fp );
            CPLFree( pabyLine );
            return NULL;
        }
    }

    CPLFree( pabyLine );
    
    VSIFClose( fp );

/* -------------------------------------------------------------------- */
/*      Try to return a regular handle on the file.                     */
/* -------------------------------------------------------------------- */
    return (GDALDataset *) GDALOpen( pszFilename, GA_Update );
}
Exemple #2
0
int DDFModule::Open( const char * pszFilename, int bFailQuietly )

{
    static const size_t nLeaderSize = 24;

/* -------------------------------------------------------------------- */
/*      Close the existing file if there is one.                        */
/* -------------------------------------------------------------------- */
    if( fpDDF != NULL )
        Close();
    
/* -------------------------------------------------------------------- */
/*      Open the file.                                                  */
/* -------------------------------------------------------------------- */
    fpDDF = VSIFOpen( pszFilename, "rb" );

    if( fpDDF == NULL )
    {
        if( !bFailQuietly )
            CPLError( CE_Failure, CPLE_OpenFailed,
                      "Unable to open DDF file `%s'.",
                      pszFilename );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Read the 24 byte leader.                                        */
/* -------------------------------------------------------------------- */
    char        achLeader[nLeaderSize];
    
    if( VSIFRead( achLeader, 1, nLeaderSize, fpDDF ) != nLeaderSize )
    {
        VSIFClose( fpDDF );
        fpDDF = NULL;

        if( !bFailQuietly )
            CPLError( CE_Failure, CPLE_FileIO,
                      "Leader is short on DDF file `%s'.",
                      pszFilename );
        
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Verify that this appears to be a valid DDF file.                */
/* -------------------------------------------------------------------- */
    int         i, bValid = TRUE;

    for( i = 0; i < (int)nLeaderSize; i++ )
    {
        if( achLeader[i] < 32 || achLeader[i] > 126 )
            bValid = FALSE;
    }

    if( achLeader[5] != '1' && achLeader[5] != '2' && achLeader[5] != '3' )
        bValid = FALSE;

    if( achLeader[6] != 'L' )
        bValid = FALSE;
    if( achLeader[8] != '1' && achLeader[8] != ' ' )
        bValid = FALSE;

/* -------------------------------------------------------------------- */
/*      Extract information from leader.                                */
/* -------------------------------------------------------------------- */

    if( bValid )
    {
        _recLength                        = DDFScanInt( achLeader+0, 5 );
        _interchangeLevel                 = achLeader[5];
        _leaderIden                   = achLeader[6];
        _inlineCodeExtensionIndicator = achLeader[7];
        _versionNumber                = achLeader[8];
        _appIndicator                 = achLeader[9];
        _fieldControlLength           = DDFScanInt(achLeader+10,2);
        _fieldAreaStart               = DDFScanInt(achLeader+12,5);
        _extendedCharSet[0]           = achLeader[17];
        _extendedCharSet[1]           = achLeader[18];
        _extendedCharSet[2]           = achLeader[19];
        _extendedCharSet[3]           = '\0';
        _sizeFieldLength              = DDFScanInt(achLeader+20,1);
        _sizeFieldPos                 = DDFScanInt(achLeader+21,1);
        _sizeFieldTag                 = DDFScanInt(achLeader+23,1);

        if( _recLength < 12 || _fieldControlLength == 0
            || _fieldAreaStart < 24 || _sizeFieldLength == 0
            || _sizeFieldPos == 0 || _sizeFieldTag == 0 )
        {
            bValid = FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      If the header is invalid, then clean up, report the error       */
/*      and return.                                                     */
/* -------------------------------------------------------------------- */
    if( !bValid )
    {
        VSIFClose( fpDDF );
        fpDDF = NULL;

        if( !bFailQuietly )
            CPLError( CE_Failure, CPLE_AppDefined,
                      "File `%s' does not appear to have\n"
                      "a valid ISO 8211 header.\n",
                      pszFilename );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Read the whole record info memory.                              */
/* -------------------------------------------------------------------- */
    char        *pachRecord;

    pachRecord = (char *) CPLMalloc(_recLength);
    memcpy( pachRecord, achLeader, nLeaderSize );

    if( VSIFRead( pachRecord+nLeaderSize, 1, _recLength-nLeaderSize, fpDDF )
        != _recLength - nLeaderSize )
    {
        if( !bFailQuietly )
            CPLError( CE_Failure, CPLE_FileIO,
                      "Header record is short on DDF file `%s'.",
                      pszFilename );
        
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      First make a pass counting the directory entries.               */
/* -------------------------------------------------------------------- */
    int         nFieldEntryWidth, nFDCount = 0;

    nFieldEntryWidth = _sizeFieldLength + _sizeFieldPos + _sizeFieldTag;

    for( i = nLeaderSize; i < _recLength; i += nFieldEntryWidth )
    {
        if( pachRecord[i] == DDF_FIELD_TERMINATOR )
            break;

        nFDCount++;
    }

/* -------------------------------------------------------------------- */
/*      Allocate, and read field definitions.                           */
/* -------------------------------------------------------------------- */
    for( i = 0; i < nFDCount; i++ )
    {
        char    szTag[128];
        int     nEntryOffset = nLeaderSize + i*nFieldEntryWidth;
        int     nFieldLength, nFieldPos;
        DDFFieldDefn *poFDefn;
        
        strncpy( szTag, pachRecord+nEntryOffset, _sizeFieldTag );
        szTag[_sizeFieldTag] = '\0';

        nEntryOffset += _sizeFieldTag;
        nFieldLength = DDFScanInt( pachRecord+nEntryOffset, _sizeFieldLength );
        
        nEntryOffset += _sizeFieldLength;
        nFieldPos = DDFScanInt( pachRecord+nEntryOffset, _sizeFieldPos );
        
        poFDefn = new DDFFieldDefn();
        if( poFDefn->Initialize( this, szTag, nFieldLength,
                                 pachRecord+_fieldAreaStart+nFieldPos ) )
            AddField( poFDefn );
        else
            delete poFDefn;
    }

    CPLFree( pachRecord );
    
/* -------------------------------------------------------------------- */
/*      Record the current file offset, the beginning of the first      */
/*      data record.                                                    */
/* -------------------------------------------------------------------- */
    nFirstRecordOffset = VSIFTell( fpDDF );
    
    return TRUE;
}
Exemple #3
0
int OGRNASDataSource::Open( const char * pszNewName )

{
    poReader = CreateNASReader();
    if( poReader == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "File %s appears to be NAS but the NAS reader cannot\n"
                  "be instantiated, likely because Xerces support was not\n"
                  "configured in.",
                  pszNewName );
        return FALSE;
    }

    poReader->SetSourceFile( pszNewName );

    pszName = CPLStrdup( pszNewName );

/* -------------------------------------------------------------------- */
/*      Can we find a NAS Feature Schema (.gfs) for the input file?     */
/* -------------------------------------------------------------------- */
    bool bHaveSchema = false;

    const char *pszGFSFilename = CPLResetExtension( pszNewName, "gfs" );
    VSIStatBuf sGFSStatBuf;
    if( CPLStat( pszGFSFilename, &sGFSStatBuf ) == 0 )
    {
        VSIStatBuf sNASStatBuf;
        if( CPLStat( pszNewName, &sNASStatBuf ) == 0 &&
            sNASStatBuf.st_mtime > sGFSStatBuf.st_mtime )
        {
            CPLDebug( "NAS",
                      "Found %s but ignoring because it appears\n"
                      "be older than the associated NAS file.",
                      pszGFSFilename );
        }
        else
        {
            bHaveSchema = poReader->LoadClasses( pszGFSFilename );
        }
    }

/* -------------------------------------------------------------------- */
/*      Force a first pass to establish the schema.  Eventually we      */
/*      will have mechanisms for remembering the schema and related     */
/*      information.                                                    */
/* -------------------------------------------------------------------- */
    CPLErrorReset();
    if( !bHaveSchema
        && !poReader->PrescanForSchema( TRUE )
        && CPLGetLastErrorType() == CE_Failure )
    {
        // Assume an error has been reported.
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Save the schema file if possible.  Do not make a fuss if we     */
/*      cannot.  It could be read-only directory or something.          */
/* -------------------------------------------------------------------- */
    if( !bHaveSchema && poReader->GetClassCount() > 0 )
    {
        FILE *fp = NULL;

        pszGFSFilename = CPLResetExtension( pszNewName, "gfs" );
        if( CPLStat( pszGFSFilename, &sGFSStatBuf ) != 0
            && (fp = VSIFOpen( pszGFSFilename, "wt" )) != NULL )
        {
            VSIFClose( fp );
            poReader->SaveClasses( pszGFSFilename );
        }
        else
        {
            CPLDebug( "NAS",
                      "Not saving %s files already exists or can't be created.",
                      pszGFSFilename );
        }
    }

/* -------------------------------------------------------------------- */
/*      Translate the NASFeatureClasses into layers.                    */
/* -------------------------------------------------------------------- */
    papoLayers = (OGRLayer **)
        CPLCalloc( sizeof(OGRNASLayer *), poReader->GetClassCount()+1 );
    nLayers = 0;

    while( nLayers < poReader->GetClassCount() )
    {
        papoLayers[nLayers] = TranslateNASSchema(poReader->GetClass(nLayers));
        nLayers++;
    }

    poRelationLayer = new OGRNASRelationLayer( this );

    // keep delete the last layer
    if( nLayers>0 && EQUAL( papoLayers[nLayers-1]->GetName(), "Delete" ) )
    {
      papoLayers[nLayers]   = papoLayers[nLayers-1];
      papoLayers[nLayers-1] = poRelationLayer;
    }
    else
    {
      papoLayers[nLayers] = poRelationLayer;
    }

    nLayers++;

    return TRUE;
}
Exemple #4
0
/**********************************************************************
 *                          AVCE00WriteOpen()
 *
 * Open (create) an Arc/Info coverage, ready to be receive a stream
 * of ASCII E00 lines and convert that to the binary coverage format.
 *
 * For now, writing to or overwriting existing coverages is not supported
 * (and may quite well never be!)... you can only create new coverages.
 *
 * Important Note: The E00 source lines are assumed to be valid... the
 * library performs no validation on the consistency of what it is 
 * given as input (i.e. topology, polygons consistency, etc.).
 * So the coverage that will be created will be only as good as the 
 * E00 input that is used to generate it.
 *
 * pszCoverPath MUST be the name of the coverage directory, including 
 * the path to it.
 * (contrary to AVCE00ReadOpen(), you cannot pass the name of one of
 *  the files in the coverage directory).
 * The name of the coverage MUST be included in pszCoverPath... this 
 * means that passing "." is invalid.
 *
 * nPrecision should always be AVC_DEFAULT_PREC to automagically detect the
 *            source coverage's precision and use that same precision
 *            for the new coverage.  
 *
 *            This parameter has been included to allow adding the 
 *            possibility to eventually create coverages with a precision 
 *            different from the source E00.
 *            Given the way the lib is built, it could be possible to
 *            also pass  AVC_SINGLE_PREC or AVC_DOUBLE_PREC to explicitly
 *            request the creation of a coverage with that precision, 
 *            but the library does not (not yet!) properly convert the 
 *            TABLE attributes' precision, and the resulting coverage may
 *            be invalid in some cases.  
 *            This improvement is on the ToDo list!
 *
 * Returns a new AVCE00WritePtr handle or NULL if the coverage could 
 * not be created or if a coverage with that name already exists.
 *
 * The handle will eventually have to be released with AVCE00ReadClose().
 **********************************************************************/
AVCE00WritePtr  AVCE00WriteOpen(const char *pszCoverPath, int nPrecision)
{
    AVCE00WritePtr  psInfo;
    int             i, nLen;
    VSIStatBuf      sStatBuf;
    
    CPLErrorReset();

    /*-----------------------------------------------------------------
     * Create pszCoverPath directory.  
     * This should fail if the directory already exists.
     *----------------------------------------------------------------*/
    if (pszCoverPath == NULL || strlen(pszCoverPath) == 0 ||
#ifdef WIN32
        mkdir(pszCoverPath) != 0
#else
        mkdir (pszCoverPath, 0777) != 0
#endif
        )
    {
        CPLError(CE_Failure, CPLE_OpenFailed, 
                 "Unable to create coverage directory: %s.", 
                 pszCoverPath?pszCoverPath:"(NULL)");
        return NULL;
    }

    /*-----------------------------------------------------------------
     * Alloc the AVCE00WritePtr handle
     *----------------------------------------------------------------*/
    psInfo = (AVCE00WritePtr)CPLCalloc(1, sizeof(struct AVCE00WriteInfo_t));

    /*-----------------------------------------------------------------
     * Requested precision for the new coverage... for now only
     * AVC_DEFAULT_PREC is supported.  When the first section is
     * read, then this section's precision will be used for the whole
     * coverage.  (This is done inside AVCE00WriteNextLine())
     *----------------------------------------------------------------*/
    if (nPrecision == AVC_DEFAULT_PREC)
        psInfo->nPrecision = nPrecision;
    else
    {
        CPLError(CE_Failure, CPLE_IllegalArg, 
                 "Coverages can only be created using AVC_DEFAULT_PREC. "
                 "Please see the documentation for AVCE00WriteOpen().");
        CPLFree(psInfo);
        return NULL;
    }

    /*-----------------------------------------------------------------
     * Make sure coverage directory name is terminated with a '/' (or '\\')
     *----------------------------------------------------------------*/
    nLen = strlen(pszCoverPath);

    if (pszCoverPath[nLen-1] == '/' || pszCoverPath[nLen-1] == '\\')
        psInfo->pszCoverPath = CPLStrdup(pszCoverPath);
    else
    {
#ifdef WIN32
        psInfo->pszCoverPath = CPLStrdup(CPLSPrintf("%s\\",pszCoverPath));
#else
        psInfo->pszCoverPath = CPLStrdup(CPLSPrintf("%s/",pszCoverPath));
#endif
    }

    /*-----------------------------------------------------------------
     * Extract the coverage name from the coverage path.  Note that
     * for this the coverage path must be in the form:
     * "dir1/dir2/dir3/covername/" ... if it is not the case, then
     * we would have to use getcwd() to find the current directory name...
     * but for now we'll just produce an error if this happens.
     *----------------------------------------------------------------*/
    nLen = 0;
    for( i = strlen(psInfo->pszCoverPath)-1; 
	 i > 0 && psInfo->pszCoverPath[i-1] != '/' &&
	          psInfo->pszCoverPath[i-1] != '\\'&&
	          psInfo->pszCoverPath[i-1] != ':';
	 i-- ) 
    {
        nLen++;
    }

    if (nLen > 0)
    {
        psInfo->pszCoverName = CPLStrdup(psInfo->pszCoverPath+i);
        psInfo->pszCoverName[nLen] = '\0';
    }
    else
    {
        CPLError(CE_Failure, CPLE_OpenFailed, 
                 "Invalid coverage path (%s): "
                 "coverage name must be included in path.", pszCoverPath);

        CPLFree(psInfo->pszCoverPath);
        CPLFree(psInfo);
        return NULL;
    }

    if (strlen(psInfo->pszCoverName) > 13 ||
        !_IsStringAlnum(psInfo->pszCoverName) )
    {
        CPLError(CE_Failure, CPLE_OpenFailed, 
                 "Invalid coverage name (%s): "
                 "coverage name must be 13 chars or less and contain only "
                 "alphanumerical characters or '_'.", 
                 psInfo->pszCoverName);

        CPLFree(psInfo->pszCoverPath);
        CPLFree(psInfo->pszCoverName);
        CPLFree(psInfo);
        return NULL;
    }

    /*-----------------------------------------------------------------
     * Lazy way to build the INFO path: simply add "../info/"...
     * this could probably be improved!
     *----------------------------------------------------------------*/
    psInfo->pszInfoPath = (char*)CPLMalloc((strlen(psInfo->pszCoverPath)+9)*
                                           sizeof(char));
#ifdef WIN32
#  define AVC_INFOPATH "..\\info\\"
#else
#  define AVC_INFOPATH "../info/"
#endif
    sprintf(psInfo->pszInfoPath, "%s%s", psInfo->pszCoverPath, AVC_INFOPATH);

    /*-----------------------------------------------------------------
     * Check if the info directory exists and contains the "arc.dir"
     * if the info dir does not exist, then make sure we can create
     * the arc.dir file (i.e. try to create an empty one)
     *
     * Note: On Windows, this VSIStat() call seems to sometimes fail even 
     *       when the directory exists (buffering issue?), and the 
     *       following if() block is sometimes executed even if it 
     *       should not, but this should not cause problems since the 
     *       arc.dir is opened with "a+b" access.
     *----------------------------------------------------------------*/
    if ( VSIStat(psInfo->pszInfoPath, &sStatBuf) == -1)
    {
        FILE *fp;
        char *pszArcDir;
#ifdef WIN32
        mkdir(psInfo->pszInfoPath);
#else
        mkdir (psInfo->pszInfoPath, 0777);
#endif
        pszArcDir = CPLStrdup(CPLSPrintf("%s%s", 
                                         psInfo->pszInfoPath, "arc.dir"));
        fp = VSIFOpen(pszArcDir, "a+b");
        CPLFree(pszArcDir);
        if (fp)
        {
            VSIFClose(fp);
        }
        else
        {
            CPLError(CE_Failure, CPLE_OpenFailed, 
                     "Unable to create (or write to) 'info' directory %s", 
                     psInfo->pszInfoPath);
            CPLFree(psInfo->pszCoverPath);
            CPLFree(psInfo->pszInfoPath);
            CPLFree(psInfo);
            return NULL;
        }
    }

    /*-----------------------------------------------------------------
     * Init the E00 parser.
     *----------------------------------------------------------------*/
    psInfo->hParseInfo = AVCE00ParseInfoAlloc();
    psInfo->eCurFileType = AVCFileUnknown;

    /*-----------------------------------------------------------------
     * If an error happened during the open call, cleanup and return NULL.
     *----------------------------------------------------------------*/
    if (CPLGetLastErrorNo() != 0)
    {
        AVCE00WriteClose(psInfo);
        psInfo = NULL;
    }

    return psInfo;
}
int VSIFCloseL( FILE * fp )

{
    return VSIFClose( fp );
}
Exemple #6
0
const char *CPLFormCIFilename( const char * pszPath,
                               const char * pszBasename,
                               const char * pszExtension )

{
#ifdef WIN32
    return CPLFormFilename( pszPath, pszBasename, pszExtension );
#else
    const char  *pszAddedExtSep = "";
    char        *pszFilename;
    const char  *pszFullPath;
    int         nLen = strlen(pszBasename)+2, i;
    FILE        *fp;

    if( pszExtension != NULL )
        nLen += strlen(pszExtension);

    pszFilename = (char *) CPLMalloc(nLen);

    if( pszExtension == NULL )
        pszExtension = "";
    else if( pszExtension[0] != '.' && strlen(pszExtension) > 0 )
        pszAddedExtSep = ".";

    sprintf( pszFilename, "%s%s%s",
             pszBasename, pszAddedExtSep, pszExtension );

    pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL );
    fp = VSIFOpen( pszFullPath, "r" );
    if( fp == NULL )
    {
        for( i = 0; pszFilename[i] != '\0'; i++ )
        {
            if( pszFilename[i] >= 'a' && pszFilename[i] <= 'z' )
                pszFilename[i] = pszFilename[i] + 'A' - 'a';
        }

        pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL );
        fp = VSIFOpen( pszFullPath, "r" );
    }

    if( fp == NULL )
    {
        for( i = 0; pszFilename[i] != '\0'; i++ )
        {
            if( pszFilename[i] >= 'A' && pszFilename[i] <= 'Z' )
                pszFilename[i] = pszFilename[i] + 'a' - 'A';
        }

        pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL );
        fp = VSIFOpen( pszFullPath, "r" );
    }

    if( fp != NULL )
        VSIFClose( fp );
    else
        pszFullPath = CPLFormFilename( pszPath, pszBasename, pszExtension );

    CPLFree( pszFilename );

    return pszFullPath;
#endif
}
TigerPolygon::~TigerPolygon()

{
    if( fpRTS != NULL )
        VSIFClose( fpRTS );
}
int S57ClassRegistrar::LoadInfo( const char * pszDirectory, 
                                 const char * pszProfile,
                                 int bReportErr )

{
    FILE        *fp;
    char        szTargetFile[1024];

    if( pszDirectory == NULL )
        pszDirectory = CPLGetConfigOption("S57_CSV",NULL);

/* ==================================================================== */
/*      Read the s57objectclasses file.                                 */
/* ==================================================================== */
    if( pszProfile == NULL )
        pszProfile = CPLGetConfigOption( "S57_PROFILE", "" );
    
    if( EQUAL(pszProfile, "Additional_Military_Layers") )
    {
       sprintf( szTargetFile, "s57objectclasses_%s.csv", "aml" );
    }
    else if ( EQUAL(pszProfile, "Inland_Waterways") )
    {
       sprintf( szTargetFile, "s57objectclasses_%s.csv", "iw" );
    }
    else if( strlen(pszProfile) > 0 )
    {
       sprintf( szTargetFile, "s57objectclasses_%s.csv", pszProfile );
    }
    else
    {
       strcpy( szTargetFile, "s57objectclasses.csv" );
    }

    if( !FindFile( szTargetFile, pszDirectory, bReportErr, &fp ) )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Skip the line defining the column titles.                       */
/* -------------------------------------------------------------------- */
    const char * pszLine = ReadLine( fp );

    if( !EQUAL(pszLine,
               "\"Code\",\"ObjectClass\",\"Acronym\",\"Attribute_A\","
               "\"Attribute_B\",\"Attribute_C\",\"Class\",\"Primitives\"" ) )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "s57objectclasses columns don't match expected format!\n" );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Read and form string list.                                      */
/* -------------------------------------------------------------------- */
    
    CSLDestroy( papszClassesInfo );
    papszClassesInfo = (char **) CPLCalloc(sizeof(char *),MAX_CLASSES);

    nClasses = 0;

    while( nClasses < MAX_CLASSES
           && (pszLine = ReadLine(fp)) != NULL )
    {
        papszClassesInfo[nClasses] = CPLStrdup(pszLine);
        if( papszClassesInfo[nClasses] == NULL )
            break;

        nClasses++;
    }

    if( nClasses == MAX_CLASSES )
        CPLError( CE_Warning, CPLE_AppDefined,
                  "MAX_CLASSES exceeded in S57ClassRegistrar::LoadInfo().\n" );

/* -------------------------------------------------------------------- */
/*      Cleanup, and establish state.                                   */
/* -------------------------------------------------------------------- */
    if( fp != NULL )
        VSIFClose( fp );
    iCurrentClass = -1;

    if( nClasses == 0 )
        return FALSE;

/* ==================================================================== */
/*      Read the attributes list.                                       */
/* ==================================================================== */

    if( EQUAL(pszProfile, "Additional_Military_Layers") )
    {
        sprintf( szTargetFile, "s57attributes_%s.csv", "aml" );
    }
    else if ( EQUAL(pszProfile, "Inland_Waterways") )
    {
       sprintf( szTargetFile, "s57attributes_%s.csv", "iw" );
    }
    else if( strlen(pszProfile) > 0 )
    {
       sprintf( szTargetFile, "s57attributes_%s.csv", pszProfile );
    }
    else
    {
       strcpy( szTargetFile, "s57attributes.csv" );
    }
       
    if( !FindFile( szTargetFile, pszDirectory, bReportErr, &fp ) )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Skip the line defining the column titles.                       */
/* -------------------------------------------------------------------- */
    pszLine = ReadLine( fp );

    if( !EQUAL(pszLine,
          "\"Code\",\"Attribute\",\"Acronym\",\"Attributetype\",\"Class\"") )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "s57attributes columns don't match expected format!\n" );
        return FALSE;
    }
    
/* -------------------------------------------------------------------- */
/*      Prepare arrays for the per-attribute information.               */
/* -------------------------------------------------------------------- */
    nAttrMax = MAX_ATTRIBUTES-1;
    papszAttrNames = (char **) CPLCalloc(sizeof(char *),MAX_ATTRIBUTES);
    papszAttrAcronym = (char **) CPLCalloc(sizeof(char *),MAX_ATTRIBUTES);
    //papapszAttrValues = (char ***) CPLCalloc(sizeof(char **),MAX_ATTRIBUTES);
    pachAttrType = (char *) CPLCalloc(sizeof(char),MAX_ATTRIBUTES);
    pachAttrClass = (char *) CPLCalloc(sizeof(char),MAX_ATTRIBUTES);
    panAttrIndex = (int *) CPLCalloc(sizeof(int),MAX_ATTRIBUTES);
    
/* -------------------------------------------------------------------- */
/*      Read and form string list.                                      */
/* -------------------------------------------------------------------- */
    int         iAttr;
    
    while( (pszLine = ReadLine(fp)) != NULL )
    {
        char    **papszTokens = CSLTokenizeStringComplex( pszLine, ",",
                                                          TRUE, TRUE );

        if( CSLCount(papszTokens) < 5 )
        {
            CPLAssert( FALSE );
            continue;
        }
        
        iAttr = atoi(papszTokens[0]);
        if( iAttr < 0 || iAttr >= nAttrMax
            || papszAttrNames[iAttr] != NULL )
        {
            CPLDebug( "S57", "Duplicate definition for attribute %d:%s", 
                      iAttr, papszTokens[2] );
            continue;
        }
        
        papszAttrNames[iAttr] = CPLStrdup(papszTokens[1]);
        papszAttrAcronym[iAttr] = CPLStrdup(papszTokens[2]);
        pachAttrType[iAttr] = papszTokens[3][0];
        pachAttrClass[iAttr] = papszTokens[4][0];

        CSLDestroy( papszTokens );
    }

    if( fp != NULL )
        VSIFClose( fp );
    
/* -------------------------------------------------------------------- */
/*      Build unsorted index of attributes.                             */
/* -------------------------------------------------------------------- */
    nAttrCount = 0;
    for( iAttr = 0; iAttr < nAttrMax; iAttr++ )
    {
        if( papszAttrAcronym[iAttr] != NULL )
            panAttrIndex[nAttrCount++] = iAttr;
    }

/* -------------------------------------------------------------------- */
/*      Sort index by acronym.                                          */
/* -------------------------------------------------------------------- */
    int         bModified;

    do
    {
        bModified = FALSE;
        for( iAttr = 0; iAttr < nAttrCount-1; iAttr++ )
        {
            if( strcmp(papszAttrAcronym[panAttrIndex[iAttr]],
                       papszAttrAcronym[panAttrIndex[iAttr+1]]) > 0 )
            {
                int     nTemp;

                nTemp = panAttrIndex[iAttr];
                panAttrIndex[iAttr] = panAttrIndex[iAttr+1];
                panAttrIndex[iAttr+1] = nTemp;

                bModified = TRUE;
            }
        }
    } while( bModified );
    
    return TRUE;
}
int OGRTigerDataSource::Open( const char * pszFilename, int bTestOpen,
                              char ** papszLimitedFileList )

{
    VSIStatBuf      stat;
    char            **papszFileList = NULL;
    int             i;

    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Is the given path a directory or a regular file?                */
/* -------------------------------------------------------------------- */
    if( CPLStat( pszFilename, &stat ) != 0 
        || (!VSI_ISDIR(stat.st_mode) && !VSI_ISREG(stat.st_mode)) )
    {
        if( !bTestOpen )
            CPLError( CE_Failure, CPLE_AppDefined,
                   "%s is neither a file or directory, Tiger access failed.\n",
                      pszFilename );

        return FALSE;
    }
    
/* -------------------------------------------------------------------- */
/*      Build a list of filenames we figure are Tiger files.            */
/* -------------------------------------------------------------------- */
    if( VSI_ISREG(stat.st_mode) )
    {
        char       szModule[128];

        pszPath = CPLStrdup( CPLGetPath(pszFilename) );

        strncpy( szModule, CPLGetFilename(pszFilename), sizeof(szModule)-1 );
        szModule[strlen(szModule)-1] = '\0';

        papszFileList = CSLAddString( papszFileList, szModule );
    }
    else
    {
        char      **candidateFileList = CPLReadDir( pszFilename );
        int         i;

        pszPath = CPLStrdup( pszFilename );

        for( i = 0; 
             candidateFileList != NULL && candidateFileList[i] != NULL; 
             i++ ) 
        {
            int nCandidateLen = strlen(candidateFileList[i]);

            if( papszLimitedFileList != NULL 
                && CSLFindString(papszLimitedFileList,
                                 CPLGetBasename(candidateFileList[i])) == -1 )
            {
                continue;
            }

            if( nCandidateLen > 4 
                && candidateFileList[i][nCandidateLen-4] == '.'
                && candidateFileList[i][nCandidateLen-1] == '1')
            {
                char       szModule[128];

                strncpy( szModule, candidateFileList[i],
                         strlen(candidateFileList[i])-1 );

                szModule[strlen(candidateFileList[i])-1] = '\0';

                papszFileList = CSLAddString(papszFileList, szModule);
            }
        }

        CSLDestroy( candidateFileList );

        if( CSLCount(papszFileList) == 0 )
        {
            if( !bTestOpen )
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "No candidate Tiger files (TGR*.RT1) found in\n"
                          "directory: %s",
                          pszFilename );

            return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Loop over all these files trying to open them.  In testopen     */
/*      mode we first read the first 80 characters, to verify that      */
/*      it looks like an Tiger file.  Note that we don't keep the file  */
/*      open ... we don't want to occupy alot of file handles when      */
/*      handling a whole directory.                                     */
/* -------------------------------------------------------------------- */
    papszModules = NULL;
    
    for( i = 0; papszFileList[i] != NULL; i++ )
    {
        if( bTestOpen || i == 0 )
        {
            char        szHeader[500];
            FILE        *fp;
            char        *pszRecStart = NULL;
            int         bIsGDT = FALSE;
            char       *pszFilename;

            pszFilename = BuildFilename( papszFileList[i], "1" );

            fp = VSIFOpen( pszFilename, "rb" );
            CPLFree( pszFilename );

            if( fp == NULL )
                continue;
            
            if( VSIFRead( szHeader, sizeof(szHeader)-1, 1, fp ) < 1 )
            {
                VSIFClose( fp );
                continue;
            }

            VSIFClose( fp );

            pszRecStart = szHeader;
            szHeader[sizeof(szHeader)-1] = '\0';

            if( EQUALN(pszRecStart,"Copyright (C)",13) 
                && strstr(pszRecStart,"Geographic Data Tech") != NULL )
            {
                bIsGDT = TRUE;

                while( *pszRecStart != '\0' 
                       && *pszRecStart != 10 
                       && *pszRecStart != 13 )
                    pszRecStart++;

                while( *pszRecStart == 10 || *pszRecStart == 13 )
                    pszRecStart++;
            }
            
            if( pszRecStart[0] != '1' )
                continue;

            if( !isdigit(pszRecStart[1]) || !isdigit(pszRecStart[2])
                || !isdigit(pszRecStart[3]) || !isdigit(pszRecStart[4]) )
                continue;

            nVersionCode = atoi(TigerFileBase::GetField( pszRecStart, 2, 5 ));
            nVersion = TigerClassifyVersion( nVersionCode );
            nVersion = TigerCheckVersion( nVersion, papszFileList[i] );

            CPLDebug( "OGR", "Tiger Version Code=%d, Classified as %s ", 
                      nVersionCode, TigerVersionString(nVersion) );

            if(    nVersionCode !=  0
                && nVersionCode !=  2
                && nVersionCode !=  3
                && nVersionCode !=  5
                && nVersionCode != 21 
                && nVersionCode != 24
                && pszRecStart[3]  != '9'
                && pszRecStart[3]  != '0'
                && !bIsGDT )
                continue;

            // we could (and should) add a bunch more validation here.
        }

        papszModules = CSLAddString( papszModules, papszFileList[i] );
    }

    CSLDestroy( papszFileList );

    nModules = CSLCount( papszModules );

    if( nModules == 0 )
    {
        if( !bTestOpen )
        {
            if( VSI_ISREG(stat.st_mode) )
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "No TIGER/Line files (TGR*.RT1) found in\n"
                          "directory: %s",
                          pszFilename );
            else
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "File %s does not appear to be a TIGER/Line .RT1 file.",
                          pszFilename );
        }

        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Do we have a user provided version override?                    */
/* -------------------------------------------------------------------- */
    if( CPLGetConfigOption( "TIGER_VERSION", NULL ) != NULL )
    {
        const char *pszRequestedVersion = 
            CPLGetConfigOption( "TIGER_VERSION", NULL );

        if( EQUALN(pszRequestedVersion,"TIGER_",6) )
        {
            int iCode;

            for( iCode = 1; iCode < TIGER_Unknown; iCode++ )
            {
                if( EQUAL(TigerVersionString((TigerVersion)iCode),
                          pszRequestedVersion) )
                {
                    nVersion = (TigerVersion) iCode;
                    break;
                }
            }

            if( iCode == TIGER_Unknown )
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "Failed to recognise TIGER_VERSION setting: %s", 
                          pszRequestedVersion );
                return FALSE;
            }                          

            CPLDebug( "OGR", "OVERRIDE Tiger Version %s ", 
                      TigerVersionString(nVersion) );
        }
        else
        {
            nVersionCode = atoi(pszRequestedVersion);
            nVersion = TigerClassifyVersion( nVersionCode );

            CPLDebug( "OGR", 
                      "OVERRIDE Tiger Version Code=%d, Classified as %s ", 
                      nVersionCode, TigerVersionString(nVersion) );
        }
    }

/* -------------------------------------------------------------------- */
/*      Create the layers which appear to exist.                        */
/* -------------------------------------------------------------------- */
    // RT1, RT2, RT3
    AddLayer( new OGRTigerLayer( this,
                                 new TigerCompleteChain( this,
                                                         papszModules[0]) ));

    /* should we have kept track of whether we encountered an RT4 file? */
    // RT4
    AddLayer( new OGRTigerLayer( this,
                                 new TigerAltName( this,
                                                   papszModules[0]) ));

    // RT5
    AddLayer( new OGRTigerLayer( this,
                                 new TigerFeatureIds( this,
                                                      papszModules[0]) ));

    // RT6
    AddLayer( new OGRTigerLayer( this,
                                 new TigerZipCodes( this,
                                                    papszModules[0]) ));
    // RT7
    AddLayer( new OGRTigerLayer( this,
                                 new TigerLandmarks( this,
                                                     papszModules[0]) ));
    
    // RT8
    AddLayer( new OGRTigerLayer( this,
                                 new TigerAreaLandmarks( this,
                                                     papszModules[0]) ));

    // RT9
    if (nVersion < TIGER_2002) {
      AddLayer( new OGRTigerLayer( this,
                                   new TigerKeyFeatures( this,
                                                         papszModules[0]) ));
    }
    
    // RTA, RTS
    AddLayer( new OGRTigerLayer( this,
                                 new TigerPolygon( this,
                                                   papszModules[0]) ));

    // RTB
    if (nVersion >= TIGER_2002) {
      AddLayer( new OGRTigerLayer( this,
                                   new TigerPolygonCorrections( this,
                                                                papszModules[0]) ));
    }
    
    // RTC
    AddLayer( new OGRTigerLayer( this,
                                 new TigerEntityNames( this,
                                                       papszModules[0]) ));

    // RTE
    if (nVersion >= TIGER_2002) {
      AddLayer( new OGRTigerLayer( this,
                                   new TigerPolygonEconomic( this,
                                                             papszModules[0]) ));
    }

    // RTH
    AddLayer( new OGRTigerLayer( this,
                                 new TigerIDHistory( this,
                                                     papszModules[0]) ));
    
    // RTI
    AddLayer( new OGRTigerLayer( this,
                                 new TigerPolyChainLink( this,
                                                       papszModules[0]) ));
    
    // RTM
    AddLayer( new OGRTigerLayer( this,
                                 new TigerSpatialMetadata( this,
                                                           papszModules[0] ) ) );
    
    // RTP
    AddLayer( new OGRTigerLayer( this,
                                 new TigerPIP( this,
                                               papszModules[0]) ));
    
    // RTR
    AddLayer( new OGRTigerLayer( this,
                                 new TigerTLIDRange( this,
                                                     papszModules[0]) ));
    
    // RTT
    if (nVersion >= TIGER_2002) {
      AddLayer( new OGRTigerLayer( this,
                                   new TigerZeroCellID( this,
                                                        papszModules[0]) ));
    }

    // RTU
    if (nVersion >= TIGER_2002) {
      AddLayer( new OGRTigerLayer( this,
                                   new TigerOverUnder( this,
                                                       papszModules[0]) ));
    }

    // RTZ
    AddLayer( new OGRTigerLayer( this,
                                 new TigerZipPlus4( this,
                                                     papszModules[0]) ));
    
    return TRUE;
}
void OGRGMLDataSource::InsertHeader()

{
    FILE        *fpSchema;
    int         nSchemaStart = 0;

    if( fpOutput == NULL || fpOutput == stdout )
        return;

/* -------------------------------------------------------------------- */
/*      Do we want to write the schema within the GML instance doc      */
/*      or to a separate file?  For now we only support external.       */
/* -------------------------------------------------------------------- */
    const char *pszSchemaURI = CSLFetchNameValue(papszCreateOptions,
                                                 "XSISCHEMAURI");
    const char *pszSchemaOpt = CSLFetchNameValue( papszCreateOptions, 
                                                  "XSISCHEMA" );

    if( pszSchemaURI != NULL )
        return;

    if( pszSchemaOpt == NULL || EQUAL(pszSchemaOpt,"EXTERNAL") )
    {
        const char *pszXSDFilename = CPLResetExtension( pszName, "xsd" );

        fpSchema = VSIFOpen( pszXSDFilename, "wt" );
        if( fpSchema == NULL )
        {
            CPLError( CE_Failure, CPLE_OpenFailed, 
                      "Failed to open file %.500s for schema output.", 
                      pszXSDFilename );
            return;
        }
        fprintf( fpSchema, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
    }
    else if( EQUAL(pszSchemaOpt,"INTERNAL") )
    {
        nSchemaStart = VSIFTell( fpOutput );
        fpSchema = fpOutput;
    }
    else                                                               
        return;

/* ==================================================================== */
/*      Write the schema section at the end of the file.  Once          */
/*      complete, we will read it back in, and then move the whole      */
/*      file "down" enough to insert the schema at the beginning.       */
/* ==================================================================== */

/* -------------------------------------------------------------------- */
/*      Emit the start of the schema section.                           */
/* -------------------------------------------------------------------- */
    const char *pszTargetNameSpace = "http://ogr.maptools.org/";
    const char *pszPrefix = "ogr";

    VSIFPrintf( fpSchema, 
                "<xs:schema targetNamespace=\"%s\" xmlns:%s=\"%s\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:gml=\"http://www.opengis.net/gml\" elementFormDefault=\"qualified\" version=\"1.0\">\n", 
                pszTargetNameSpace, pszPrefix, pszTargetNameSpace );
    
    VSIFPrintf( fpSchema, 
                "<xs:import namespace=\"http://www.opengis.net/gml\" schemaLocation=\"http://schemas.opengeospatial.net/gml/2.1.2/feature.xsd\"/>" );

/* -------------------------------------------------------------------- */
/*      Define the FeatureCollection                                    */
/* -------------------------------------------------------------------- */
    VSIFPrintf( fpSchema, 
                "<xs:element name=\"FeatureCollection\" type=\"%s:FeatureCollectionType\" substitutionGroup=\"gml:_FeatureCollection\"/>\n", 
                pszPrefix );

    VSIFPrintf( 
        fpSchema, 
        "<xs:complexType name=\"FeatureCollectionType\">\n"
        "  <xs:complexContent>\n"
        "    <xs:extension base=\"gml:AbstractFeatureCollectionType\">\n"
        "      <xs:attribute name=\"lockId\" type=\"xs:string\" use=\"optional\"/>\n"
        "      <xs:attribute name=\"scope\" type=\"xs:string\" use=\"optional\"/>\n"
        "    </xs:extension>\n"
        "  </xs:complexContent>\n"
        "</xs:complexType>\n" );

/* ==================================================================== */
/*      Define the schema for each layer.                               */
/* ==================================================================== */
    int iLayer;

    for( iLayer = 0; iLayer < GetLayerCount(); iLayer++ )
    {
        OGRFeatureDefn *poFDefn = GetLayer(iLayer)->GetLayerDefn();
        
/* -------------------------------------------------------------------- */
/*      Emit initial stuff for a feature type.                          */
/* -------------------------------------------------------------------- */
        VSIFPrintf( 
            fpSchema,
            "<xs:element name=\"%s\" type=\"%s:%s_Type\" substitutionGroup=\"gml:_Feature\"/>\n",
            poFDefn->GetName(), pszPrefix, poFDefn->GetName() );

        VSIFPrintf( 
            fpSchema, 
            "<xs:complexType name=\"%s_Type\">\n"
            "  <xs:complexContent>\n"
            "    <xs:extension base=\"gml:AbstractFeatureType\">\n"
            "      <xs:sequence>\n",
            poFDefn->GetName() );

/* -------------------------------------------------------------------- */
/*      Define the geometry attribute.  For now I always use the        */
/*      generic geometry type, but eventually we should express         */
/*      particulars if available.                                       */
/* -------------------------------------------------------------------- */
        VSIFPrintf( 
            fpSchema,
            "<xs:element name=\"geometryProperty\" type=\"gml:GeometryPropertyType\" nillable=\"true\" minOccurs=\"1\" maxOccurs=\"1\"/>\n" );
            
/* -------------------------------------------------------------------- */
/*      Emit each of the attributes.                                    */
/* -------------------------------------------------------------------- */
        for( int iField = 0; iField < poFDefn->GetFieldCount(); iField++ )
        {
            OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn(iField);

            if( poFieldDefn->GetType() == OFTInteger )
            {
                int nWidth;

                if( poFieldDefn->GetWidth() > 0 )
                    nWidth = poFieldDefn->GetWidth();
                else
                    nWidth = 16;

                VSIFPrintf( fpSchema, 
                            "    <xs:element name=\"%s\" nillable=\"true\" minOccurs=\"0\" maxOccurs=\"1\">\n"
                            "      <xs:simpleType>\n"
                            "        <xs:restriction base=\"xs:integer\">\n"
                            "          <xs:totalDigits value=\"%d\"/>\n"
                            "        </xs:restriction>\n"
                            "      </xs:simpleType>\n"
                            "    </xs:element>\n",
                            poFieldDefn->GetNameRef(), nWidth );
            }
            else if( poFieldDefn->GetType() == OFTReal )
            {
                int nWidth, nDecimals;

                if( poFieldDefn->GetPrecision() == 0 )
                    nDecimals = 0;
                else
                    nDecimals = poFieldDefn->GetPrecision();

                if( poFieldDefn->GetWidth() > 0 )
                    nWidth = poFieldDefn->GetWidth();
                else
                    nWidth = 33;

                VSIFPrintf( fpSchema, 
                            "    <xs:element name=\"%s\" nillable=\"true\" minOccurs=\"0\" maxOccurs=\"1\">\n"
                            "      <xs:simpleType>\n"
                            "        <xs:restriction base=\"xs:decimal\">\n"
                            "          <xs:totalDigits value=\"%d\"/>\n"
                            "          <xs:fractionDigits value=\"%d\"/>\n"
                            "        </xs:restriction>\n"
                            "      </xs:simpleType>\n"
                            "    </xs:element>\n",
                            poFieldDefn->GetNameRef(), nWidth, nDecimals );
            }
            else if( poFieldDefn->GetType() == OFTString )
            {
                char szMaxLength[48];

                if( poFieldDefn->GetWidth() == 0 )
                    sprintf( szMaxLength, "unbounded" );
                else
                    sprintf( szMaxLength, "%d", poFieldDefn->GetWidth() );

                VSIFPrintf( fpSchema, 
                            "    <xs:element name=\"%s\" nillable=\"true\" minOccurs=\"0\" maxOccurs=\"1\">\n"
                            "      <xs:simpleType>\n"
                            "        <xs:restriction base=\"xs:string\">\n"
                            "          <xs:maxLength value=\"%s\"/>\n"
                            "        </xs:restriction>\n"
                            "      </xs:simpleType>\n"
                            "    </xs:element>\n",
                            poFieldDefn->GetNameRef(), szMaxLength );
            }
            else if( poFieldDefn->GetType() == OFTDate || poFieldDefn->GetType() == OFTDateTime )
            {
                VSIFPrintf( fpSchema, 
                            "    <xs:element name=\"%s\" nillable=\"true\" minOccurs=\"0\" maxOccurs=\"1\">\n"
                            "      <xs:simpleType>\n"
                            "        <xs:restriction base=\"xs:string\">\n"
                            "          <xs:maxLength value=\"unbounded\"/>\n"
                            "        </xs:restriction>\n"
                            "      </xs:simpleType>\n"
                            "    </xs:element>\n",
                            poFieldDefn->GetNameRef() );
            }
            else
            {
                /* TODO */
            }
        } /* next field */

/* -------------------------------------------------------------------- */
/*      Finish off feature type.                                        */
/* -------------------------------------------------------------------- */
        VSIFPrintf( fpSchema, 
                    "      </xs:sequence>\n"
                    "    </xs:extension>\n"
                    "  </xs:complexContent>\n"
                    "</xs:complexType>\n" );
    } /* next layer */

    VSIFPrintf( fpSchema, "</xs:schema>\n" );

/* ==================================================================== */
/*      Move schema to the start of the file.                           */
/* ==================================================================== */
    if( fpSchema == fpOutput )
    {
/* -------------------------------------------------------------------- */
/*      Read the schema into memory.                                    */
/* -------------------------------------------------------------------- */
        int nSchemaSize = VSIFTell( fpOutput ) - nSchemaStart;
        char *pszSchema = (char *) CPLMalloc(nSchemaSize+1);
    
        VSIFSeek( fpOutput, nSchemaStart, SEEK_SET );

        VSIFRead( pszSchema, 1, nSchemaSize, fpOutput );
        pszSchema[nSchemaSize] = '\0';
    
/* -------------------------------------------------------------------- */
/*      Move file data down by "schema size" bytes from after <?xml>    */
/*      header so we have room insert the schema.  Move in pretty       */
/*      big chunks.                                                     */
/* -------------------------------------------------------------------- */
        int nChunkSize = MIN(nSchemaStart-nSchemaInsertLocation,250000);
        char *pszChunk = (char *) CPLMalloc(nChunkSize);
        int nEndOfUnmovedData = nSchemaStart;

        for( nEndOfUnmovedData = nSchemaStart;
             nEndOfUnmovedData > nSchemaInsertLocation; )
        {
            int nBytesToMove = 
                MIN(nChunkSize, nEndOfUnmovedData - nSchemaInsertLocation );

            VSIFSeek( fpOutput, nEndOfUnmovedData - nBytesToMove, SEEK_SET );
            VSIFRead( pszChunk, 1, nBytesToMove, fpOutput );
            VSIFSeek( fpOutput, nEndOfUnmovedData - nBytesToMove + nSchemaSize, 
                      SEEK_SET );
            VSIFWrite( pszChunk, 1, nBytesToMove, fpOutput );
        
            nEndOfUnmovedData -= nBytesToMove;
        }

        CPLFree( pszChunk );

/* -------------------------------------------------------------------- */
/*      Write the schema in the opened slot.                            */
/* -------------------------------------------------------------------- */
        VSIFSeek( fpOutput, nSchemaInsertLocation, SEEK_SET );
        VSIFWrite( pszSchema, 1, nSchemaSize, fpOutput );

        VSIFSeek( fpOutput, 0, SEEK_END );

        nBoundedByLocation += nSchemaSize;
    }
/* -------------------------------------------------------------------- */
/*      Close external schema files.                                    */
/* -------------------------------------------------------------------- */
    else
        VSIFClose( fpSchema );
}
int OGRILI1DataSource::Open( const char * pszNewName, int bTestOpen )

{
    FILE        *fp;
    char        szHeader[1000];
    std::string osBasename, osModelFilename;

    if (strlen(pszNewName) == 0)
    {
        return FALSE;
    }

    char **filenames = CSLTokenizeString2( pszNewName, ",", 0 );

    osBasename = filenames[0];

    if( CSLCount(filenames) > 1 )
        osModelFilename = filenames[1];

    CSLDestroy( filenames );

/* -------------------------------------------------------------------- */
/*      Open the source file.                                           */
/* -------------------------------------------------------------------- */
    fp = VSIFOpen( osBasename.c_str(), "r" );
    if( fp == NULL )
    {
        if( !bTestOpen )
            CPLError( CE_Failure, CPLE_OpenFailed,
                      "Failed to open ILI1 file `%s'.",
                      pszNewName );

        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      If we aren't sure it is ILI1, load a header chunk and check      */
/*      for signs it is ILI1                                             */
/* -------------------------------------------------------------------- */
    if( bTestOpen )
    {
        int nLen = (int)VSIFRead( szHeader, 1, sizeof(szHeader), fp );
        if (nLen == sizeof(szHeader))
            szHeader[sizeof(szHeader)-1] = '\0';
        else
            szHeader[nLen] = '\0';

        if( strstr(szHeader,"SCNT") == NULL )
        {
            VSIFClose( fp );
            return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      We assume now that it is ILI1.  Close and instantiate a          */
/*      ILI1Reader on it.                                                */
/* -------------------------------------------------------------------- */
    VSIFClose( fp );

    poReader = CreateILI1Reader();
    if( poReader == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "File %s appears to be ILI1 but the ILI1 reader can't\n"
                  "be instantiated, likely because Xerces support wasn't\n"
                  "configured in.",
                  pszNewName );
        return FALSE;
     }

    poReader->OpenFile( osBasename.c_str() );

    pszName = CPLStrdup( osBasename.c_str() );

    if (osModelFilename.length() > 0 )
        poReader->ReadModel( poImdReader, osModelFilename.c_str(), this );

    if( getenv( "ARC_DEGREES" ) != NULL ) {
      //No better way to pass arguments to the reader (it could even be an -lco arg)
      poReader->SetArcDegrees( atof( getenv("ARC_DEGREES") ) );
    }

    //Parse model and read data - without surface joing and polygonizing
    poReader->ReadFeatures();

    return TRUE;
}
int OGRGMLDataSource::Open( const char * pszNewName, int bTestOpen )

{
    FILE        *fp;
    char        szHeader[1000];

/* -------------------------------------------------------------------- */
/*      Open the source file.                                           */
/* -------------------------------------------------------------------- */
    fp = VSIFOpen( pszNewName, "r" );
    if( fp == NULL )
    {
        if( !bTestOpen )
            CPLError( CE_Failure, CPLE_OpenFailed, 
                      "Failed to open GML file `%s'.", 
                      pszNewName );

        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      If we aren't sure it is GML, load a header chunk and check      */
/*      for signs it is GML                                             */
/* -------------------------------------------------------------------- */
    if( bTestOpen )
    {
        size_t nRead = VSIFRead( szHeader, 1, sizeof(szHeader), fp );
        if (nRead <= 0)
        {
            VSIFClose( fp );
            return FALSE;
        }
        szHeader[MIN(nRead, sizeof(szHeader))-1] = '\0';

/* -------------------------------------------------------------------- */
/*      Check for a UTF-8 BOM and skip if found                         */
/*                                                                      */
/*      TODO: BOM is variable-lenght parameter and depends on encoding. */
/*            Add BOM detection for other encodings.                    */
/* -------------------------------------------------------------------- */

        // Used to skip to actual beginning of XML data
        char* szPtr = szHeader;

        if( ( (unsigned char)szHeader[0] == 0xEF )
            && ( (unsigned char)szHeader[1] == 0xBB )
            && ( (unsigned char)szHeader[2] == 0xBF) )
        {
            szPtr += 3;
        }

/* -------------------------------------------------------------------- */
/*      Here, we expect the opening chevrons of GML tree root element   */
/* -------------------------------------------------------------------- */
        if( szPtr[0] != '<' 
            || strstr(szPtr,"opengis.net/gml") == NULL )
        {
            VSIFClose( fp );
            return FALSE;
        }
    }
    
/* -------------------------------------------------------------------- */
/*      We assume now that it is GML.  Close and instantiate a          */
/*      GMLReader on it.                                                */
/* -------------------------------------------------------------------- */
    VSIFClose( fp );
    
    poReader = CreateGMLReader();
    if( poReader == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "File %s appears to be GML but the GML reader can't\n"
                  "be instantiated, likely because Xerces or Expat support wasn't\n"
                  "configured in.", 
                  pszNewName );
        return FALSE;
    }

    poReader->SetSourceFile( pszNewName );
    
    pszName = CPLStrdup( pszNewName );

/* -------------------------------------------------------------------- */
/*      Can we find a GML Feature Schema (.gfs) for the input file?     */
/* -------------------------------------------------------------------- */
    const char *pszGFSFilename;
    VSIStatBuf sGFSStatBuf, sGMLStatBuf;
    int        bHaveSchema = FALSE;

    pszGFSFilename = CPLResetExtension( pszNewName, "gfs" );
    if( CPLStat( pszGFSFilename, &sGFSStatBuf ) == 0 )
    {
        CPLStat( pszNewName, &sGMLStatBuf );

        if( sGMLStatBuf.st_mtime > sGFSStatBuf.st_mtime )
        {
            CPLDebug( "GML", 
                      "Found %s but ignoring because it appears\n"
                      "be older than the associated GML file.", 
                      pszGFSFilename );
        }
        else
        {
            bHaveSchema = poReader->LoadClasses( pszGFSFilename );
        }
    }

/* -------------------------------------------------------------------- */
/*      Can we find an xsd which might conform to tbe GML3 Level 0      */
/*      profile?  We really ought to look for it based on the rules     */
/*      schemaLocation in the GML feature collection but for now we     */
/*      just hopes it is in the same director with the same name.       */
/* -------------------------------------------------------------------- */
    const char *pszXSDFilename;

    if( !bHaveSchema )
    {
        pszXSDFilename = CPLResetExtension( pszNewName, "xsd" );
        if( CPLStat( pszXSDFilename, &sGMLStatBuf ) == 0 )
        {
            bHaveSchema = poReader->ParseXSD( pszXSDFilename );
        }
    }
    
/* -------------------------------------------------------------------- */
/*      Force a first pass to establish the schema.  Eventually we      */
/*      will have mechanisms for remembering the schema and related     */
/*      information.                                                    */
/* -------------------------------------------------------------------- */
    if( !bHaveSchema && !poReader->PrescanForSchema( TRUE ) )
    {
        // we assume an errors have been reported.
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Save the schema file if possible.  Don't make a fuss if we      */
/*      can't ... could be read-only directory or something.            */
/* -------------------------------------------------------------------- */
    if( !bHaveSchema && !poReader->HasStoppedParsing())
    {
        FILE    *fp = NULL;

        pszGFSFilename = CPLResetExtension( pszNewName, "gfs" );
        if( CPLStat( pszGFSFilename, &sGFSStatBuf ) != 0 
            && (fp = VSIFOpen( pszGFSFilename, "wt" )) != NULL )
        {
            VSIFClose( fp );
            poReader->SaveClasses( pszGFSFilename );
        }
        else
        {
            CPLDebug("GML", 
                     "Not saving %s files already exists or can't be created.",
                     pszGFSFilename );
        }
    }

/* -------------------------------------------------------------------- */
/*      Translate the GMLFeatureClasses into layers.                    */
/* -------------------------------------------------------------------- */
    papoLayers = (OGRGMLLayer **)
        CPLCalloc( sizeof(OGRGMLLayer *), poReader->GetClassCount());
    nLayers = 0;

    while( nLayers < poReader->GetClassCount() )
    {
        papoLayers[nLayers] = TranslateGMLSchema(poReader->GetClass(nLayers));
        nLayers++;
    }
    

    
    return TRUE;
}
OGRLayer *
OGRShapeDataSource::CreateLayer( const char * pszLayerName,
                                 OGRSpatialReference *poSRS,
                                 OGRwkbGeometryType eType,
                                 char ** papszOptions )

{
    SHPHandle   hSHP;
    DBFHandle   hDBF;
    int         nShapeType;

/* -------------------------------------------------------------------- */
/*      Verify we are in update mode.                                   */
/* -------------------------------------------------------------------- */
    if( !bDSUpdate )
    {
        CPLError( CE_Failure, CPLE_NoWriteAccess,
                  "Data source %s opened read-only.\n"
                  "New layer %s cannot be created.\n",
                  pszName, pszLayerName );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Figure out what type of layer we need.                          */
/* -------------------------------------------------------------------- */
    if( eType == wkbUnknown || eType == wkbLineString )
        nShapeType = SHPT_ARC;
    else if( eType == wkbPoint )
        nShapeType = SHPT_POINT;
    else if( eType == wkbPolygon )
        nShapeType = SHPT_POLYGON;
    else if( eType == wkbMultiPoint )
        nShapeType = SHPT_MULTIPOINT;
    else if( eType == wkbPoint25D )
        nShapeType = SHPT_POINTZ;
    else if( eType == wkbLineString25D )
        nShapeType = SHPT_ARCZ;
    else if( eType == wkbMultiLineString )
        nShapeType = SHPT_ARC;
    else if( eType == wkbMultiLineString25D )
        nShapeType = SHPT_ARCZ;
    else if( eType == wkbPolygon25D )
        nShapeType = SHPT_POLYGONZ;
    else if( eType == wkbMultiPolygon )
        nShapeType = SHPT_POLYGON;
    else if( eType == wkbMultiPolygon25D )
        nShapeType = SHPT_POLYGONZ;
    else if( eType == wkbMultiPoint25D )
        nShapeType = SHPT_MULTIPOINTZ;
    else if( eType == wkbNone )
        nShapeType = SHPT_NULL;
    else
        nShapeType = -1;

/* -------------------------------------------------------------------- */
/*      Has the application overridden this with a special creation     */
/*      option?                                                         */
/* -------------------------------------------------------------------- */
    const char *pszOverride = CSLFetchNameValue( papszOptions, "SHPT" );

    if( pszOverride == NULL )
        /* ignore */;
    else if( EQUAL(pszOverride,"POINT") )
    {
        nShapeType = SHPT_POINT;
        eType = wkbPoint;
    }
    else if( EQUAL(pszOverride,"ARC") )
    {
        nShapeType = SHPT_ARC;
        eType = wkbLineString;
    }
    else if( EQUAL(pszOverride,"POLYGON") )
    {
        nShapeType = SHPT_POLYGON;
        eType = wkbPolygon;
    }
    else if( EQUAL(pszOverride,"MULTIPOINT") )
    {
        nShapeType = SHPT_MULTIPOINT;
        eType = wkbMultiPoint;
    }
    else if( EQUAL(pszOverride,"POINTZ") )
    {
        nShapeType = SHPT_POINTZ;
        eType = wkbPoint25D;
    }
    else if( EQUAL(pszOverride,"ARCZ") )
    {
        nShapeType = SHPT_ARCZ;
        eType = wkbLineString25D;
    }
    else if( EQUAL(pszOverride,"POLYGONZ") )
    {
        nShapeType = SHPT_POLYGONZ;
        eType = wkbPolygon25D;
    }
    else if( EQUAL(pszOverride,"MULTIPOINTZ") )
    {
        nShapeType = SHPT_MULTIPOINTZ;
        eType = wkbMultiPoint25D;
    }
    else if( EQUAL(pszOverride,"NONE") )
    {
        nShapeType = SHPT_NULL;
    }
    else
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Unknown SHPT value of `%s' passed to Shapefile layer\n"
                  "creation.  Creation aborted.\n",
                  pszOverride );

        return NULL;
    }

    if( nShapeType == -1 )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Geometry type of `%s' not supported in shapefiles.\n"
                  "Type can be overridden with a layer creation option\n"
                  "of SHPT=POINT/ARC/POLYGON/MULTIPOINT/POINTZ/ARCZ/POLYGONZ/MULTIPOINTZ.\n",
                  OGRGeometryTypeToName(eType) );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      What filename do we use, excluding the extension?               */
/* -------------------------------------------------------------------- */
    char *pszBasename;

    if( bSingleNewFile && nLayers == 0 )
    {
        char *pszPath = CPLStrdup(CPLGetPath(pszName));
        char *pszFBasename = CPLStrdup(CPLGetBasename(pszName));

        pszBasename = CPLStrdup(CPLFormFilename(pszPath, pszFBasename, NULL));

        CPLFree( pszFBasename );
        CPLFree( pszPath );
    }
    else if( bSingleNewFile )
    {
        char *pszPath = CPLStrdup(CPLGetPath(pszName));
        pszBasename = CPLStrdup(CPLFormFilename(pszPath,pszLayerName,NULL));
        CPLFree( pszPath );
    }
    else
        pszBasename = CPLStrdup(CPLFormFilename(pszName,pszLayerName,NULL));

/* -------------------------------------------------------------------- */
/*      Create the shapefile.                                           */
/* -------------------------------------------------------------------- */
    char        *pszFilename;

    if( nShapeType != SHPT_NULL )
    {
        pszFilename = CPLStrdup(CPLFormFilename( NULL, pszBasename, "shp" ));

        hSHP = SHPCreate( pszFilename, nShapeType );
        
        if( hSHP == NULL )
        {
            CPLError( CE_Failure, CPLE_OpenFailed,
                      "Failed to open Shapefile `%s'.\n",
                      pszFilename );
            CPLFree( pszFilename );
            CPLFree( pszBasename );
            return NULL;
        }
        CPLFree( pszFilename );
    }
    else
        hSHP = NULL;

/* -------------------------------------------------------------------- */
/*      Create a DBF file.                                              */
/* -------------------------------------------------------------------- */
    pszFilename = CPLStrdup(CPLFormFilename( NULL, pszBasename, "dbf" ));
    
    hDBF = DBFCreate( pszFilename );

    if( hDBF == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to open Shape DBF file `%s'.\n",
                  pszFilename );
        CPLFree( pszFilename );
        CPLFree( pszBasename );
        return NULL;
    }

    CPLFree( pszFilename );

/* -------------------------------------------------------------------- */
/*      Create the .prj file, if required.                              */
/* -------------------------------------------------------------------- */
    if( poSRS != NULL )
    {
        char    *pszWKT = NULL;
        CPLString osPrjFile = CPLFormFilename( NULL, pszBasename, "prj");
        FILE    *fp;

        /* the shape layer needs it's own copy */
        poSRS = poSRS->Clone();
        poSRS->morphToESRI();

        if( poSRS->exportToWkt( &pszWKT ) == OGRERR_NONE 
            && (fp = VSIFOpen( osPrjFile, "wt" )) != NULL )
        {
            VSIFWrite( pszWKT, strlen(pszWKT), 1, fp );
            VSIFClose( fp );
        }

        CPLFree( pszWKT );

        poSRS->morphFromESRI();
    }

/* -------------------------------------------------------------------- */
/*      Create the layer object.                                        */
/* -------------------------------------------------------------------- */
    OGRShapeLayer       *poLayer;

    poLayer = new OGRShapeLayer( pszBasename, hSHP, hDBF, poSRS, TRUE,
                                 eType );
    
    poLayer->InitializeIndexSupport( pszBasename );

    CPLFree( pszBasename );

/* -------------------------------------------------------------------- */
/*      Add layer to data source layer list.                            */
/* -------------------------------------------------------------------- */
    papoLayers = (OGRShapeLayer **)
        CPLRealloc( papoLayers,  sizeof(OGRShapeLayer *) * (nLayers+1) );
    
    papoLayers[nLayers++] = poLayer;

    return poLayer;
}
int OGRShapeDataSource::OpenFile( const char *pszNewName, int bUpdate,
                                  int bTestOpen )

{
    SHPHandle   hSHP;
    DBFHandle   hDBF;
    const char *pszExtension = CPLGetExtension( pszNewName );

    (void) bTestOpen;

    if( !EQUAL(pszExtension,"shp") && !EQUAL(pszExtension,"shx")
        && !EQUAL(pszExtension,"dbf") )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      SHPOpen() should include better (CPL based) error reporting,    */
/*      and we should be trying to distinquish at this point whether    */
/*      failure is a result of trying to open a non-shapefile, or       */
/*      whether it was a shapefile and we want to report the error      */
/*      up.                                                             */
/*                                                                      */
/*      Care is taken to suppress the error and only reissue it if      */
/*      we think it is appropriate.                                     */
/* -------------------------------------------------------------------- */
    CPLPushErrorHandler( CPLQuietErrorHandler );
    if( bUpdate )
        hSHP = SHPOpen( pszNewName, "r+" );
    else
        hSHP = SHPOpen( pszNewName, "r" );
    CPLPopErrorHandler();

    if( hSHP == NULL 
        && (!EQUAL(CPLGetExtension(pszNewName),"dbf") 
            || strstr(CPLGetLastErrorMsg(),".shp") == NULL) )
    {
        CPLString osMsg = CPLGetLastErrorMsg();

        CPLError( CE_Failure, CPLE_OpenFailed, "%s", osMsg.c_str() );

        return FALSE;
    }
    CPLErrorReset();
    
/* -------------------------------------------------------------------- */
/*      Open the .dbf file, if it exists.  To open a dbf file, the      */
/*      filename has to either refer to a successfully opened shp       */
/*      file or has to refer to the actual .dbf file.                   */
/* -------------------------------------------------------------------- */
    if( hSHP != NULL || EQUAL(CPLGetExtension(pszNewName),"dbf") )
    {
        if( bUpdate )
            hDBF = DBFOpen( pszNewName, "r+" );
        else
            hDBF = DBFOpen( pszNewName, "r" );
    }
    else
        hDBF = NULL;
        
    if( hDBF == NULL && hSHP == NULL )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Is there an associated .prj file we can read?                   */
/* -------------------------------------------------------------------- */
    OGRSpatialReference *poSRS = NULL;
    const char  *pszPrjFile = CPLResetExtension( pszNewName, "prj" );
    FILE        *fp = NULL;

    fp = VSIFOpen( pszPrjFile, "r" );

#ifndef WIN32
    if( NULL == fp )
    {
        pszPrjFile = CPLResetExtension( pszNewName, "PRJ" );
        fp = VSIFOpen( pszPrjFile, "r" );
    }
#endif

    if( fp != NULL )
    {
        char    **papszLines;

        VSIFClose( fp );
        
        papszLines = CSLLoad( pszPrjFile );

        poSRS = new OGRSpatialReference();
        if( poSRS->importFromESRI( papszLines ) != OGRERR_NONE )
        {
            delete poSRS;
            poSRS = NULL;
        }
        CSLDestroy( papszLines );
    }

/* -------------------------------------------------------------------- */
/*      Create the layer object.                                        */
/* -------------------------------------------------------------------- */
    OGRShapeLayer       *poLayer;

    poLayer = new OGRShapeLayer( pszNewName, hSHP, hDBF, poSRS, bUpdate,
                                 wkbNone );


    poLayer->InitializeIndexSupport( pszNewName );

/* -------------------------------------------------------------------- */
/*      Add layer to data source layer list.                            */
/* -------------------------------------------------------------------- */
    papoLayers = (OGRShapeLayer **)
        CPLRealloc( papoLayers,  sizeof(OGRShapeLayer *) * (nLayers+1) );
    papoLayers[nLayers++] = poLayer;
    
    return TRUE;
}
Exemple #15
0
static void CSVIngest( const char *pszFilename )

{
    CSVTable *psTable = CSVAccess( pszFilename );
    int       nFileLen, i, nMaxLineCount, iLine = 0;
    char *pszThisLine;

    if( psTable->pszRawData != NULL )
        return;

/* -------------------------------------------------------------------- */
/*      Ingest whole file.                                              */
/* -------------------------------------------------------------------- */
    VSIFSeek( psTable->fp, 0, SEEK_END );
    nFileLen = VSIFTell( psTable->fp );
    VSIRewind( psTable->fp );

    psTable->pszRawData = (char *) CPLMalloc(nFileLen+1);
    if( (int) VSIFRead( psTable->pszRawData, 1, nFileLen, psTable->fp ) 
        != nFileLen )
    {
        CPLFree( psTable->pszRawData );
        psTable->pszRawData = NULL;

        CPLError( CE_Failure, CPLE_FileIO, "Read of file %s failed.", 
                  psTable->pszFilename );
        return;
    }

    psTable->pszRawData[nFileLen] = '\0';

/* -------------------------------------------------------------------- */
/*      Get count of newlines so we can allocate line array.            */
/* -------------------------------------------------------------------- */
    nMaxLineCount = 0;
    for( i = 0; i < nFileLen; i++ )
    {
        if( psTable->pszRawData[i] == 10 )
            nMaxLineCount++;
    }

    psTable->papszLines = (char **) CPLCalloc(sizeof(char*),nMaxLineCount);
    
/* -------------------------------------------------------------------- */
/*      Build a list of record pointers into the raw data buffer        */
/*      based on line terminators.  Zero terminate the line             */
/*      strings.                                                        */
/* -------------------------------------------------------------------- */
    /* skip header line */
    pszThisLine = CSVFindNextLine( psTable->pszRawData );

    while( pszThisLine != NULL && iLine < nMaxLineCount )
    {
        psTable->papszLines[iLine++] = pszThisLine;
        pszThisLine = CSVFindNextLine( pszThisLine );
    }

    psTable->nLineCount = iLine;

/* -------------------------------------------------------------------- */
/*      Allocate and populate index array.  Ensure they are in          */
/*      ascending order so that binary searches can be done on the      */
/*      array.                                                          */
/* -------------------------------------------------------------------- */
    psTable->panLineIndex = (int *) CPLMalloc(sizeof(int)*psTable->nLineCount);
    for( i = 0; i < psTable->nLineCount; i++ )
    {
        psTable->panLineIndex[i] = atoi(psTable->papszLines[i]);

        if( i > 0 && psTable->panLineIndex[i] < psTable->panLineIndex[i-1] )
        {
            CPLFree( psTable->panLineIndex );
            psTable->panLineIndex = NULL;
            break;
        }
    }

    psTable->iLastLine = -1;

/* -------------------------------------------------------------------- */
/*      We should never need the file handle against, so close it.      */
/* -------------------------------------------------------------------- */
    VSIFClose( psTable->fp );
    psTable->fp = NULL;
}
/**********************************************************************
 *                   IMapInfoFile::SmartOpen()
 *
 * Use this static method to automatically open any flavour of MapInfo
 * dataset.  This method will detect the file type, create an object
 * of the right type, and open the file.
 *
 * Call GetFileClass() on the returned object if you need to find out
 * its exact type.  (To access format-specific methods for instance)
 *
 * Returns the new object ptr. , or NULL if the open failed.
 **********************************************************************/
IMapInfoFile *IMapInfoFile::SmartOpen(const char *pszFname,
                                      GBool bTestOpenNoError /*=FALSE*/)
{
    IMapInfoFile *poFile = NULL;
    int nLen = 0;

    if (pszFname)
        nLen = strlen(pszFname);

    if (nLen > 4 && (EQUAL(pszFname + nLen-4, ".MIF") ||
                     EQUAL(pszFname + nLen-4, ".MID") ) )
    {
        /*-------------------------------------------------------------
         * MIF/MID file
         *------------------------------------------------------------*/
        poFile = new MIFFile;
    }
    else if (nLen > 4 && EQUAL(pszFname + nLen-4, ".TAB"))
    {
        /*-------------------------------------------------------------
         * .TAB file ... is it a TABFileView or a TABFile?
         * We have to read the .tab header to find out.
         *------------------------------------------------------------*/
        FILE *fp;
        const char *pszLine;
        char *pszAdjFname = CPLStrdup(pszFname);
        GBool bFoundFields = FALSE, bFoundView=FALSE, bFoundSeamless=FALSE;

        TABAdjustFilenameExtension(pszAdjFname);
        fp = VSIFOpen(pszAdjFname, "r");
        while(fp && (pszLine = CPLReadLine(fp)) != NULL)
        {
            while (isspace((unsigned char)*pszLine))  pszLine++;
            if (EQUALN(pszLine, "Fields", 6))
                bFoundFields = TRUE;
            else if (EQUALN(pszLine, "create view", 11))
                bFoundView = TRUE;
            else if (EQUALN(pszLine, "\"\\IsSeamless\" = \"TRUE\"", 21))
                bFoundSeamless = TRUE;
        }

        if (bFoundView)
            poFile = new TABView;
        else if (bFoundFields && bFoundSeamless)
            poFile = new TABSeamless;
        else if (bFoundFields)
            poFile = new TABFile;

        if (fp)
            VSIFClose(fp);

        CPLFree(pszAdjFname);
    }

    /*-----------------------------------------------------------------
     * Perform the open() call
     *----------------------------------------------------------------*/
    if (poFile && poFile->Open(pszFname, "r", bTestOpenNoError) != 0)
    {
        delete poFile;
        poFile = NULL;
    }

    if (!bTestOpenNoError && poFile == NULL)
    {
        CPLError(CE_Failure, CPLE_FileIO,
                 "%s could not be opened as a MapInfo dataset.", pszFname);
    }

    return poFile;
}
GDALDataset *PNMDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      Verify that this is a _raw_ ppm or pgm file.  Note, we don't    */
/*      support ascii files, or pbm (1bit) files.                       */
/* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Parse out the tokens from the header.                           */
/* -------------------------------------------------------------------- */
    const char  *pszSrc = (const char *) poOpenInfo->pabyHeader;
    char        szToken[512];
    int         iIn, iToken = 0, nWidth =-1, nHeight=-1, nMaxValue=-1;
    unsigned int iOut;

    iIn = 2;
    while( iIn < poOpenInfo->nHeaderBytes && iToken < 3 )
    {
        iOut = 0;
        szToken[0] = '\0';
        while( iOut < sizeof(szToken) && iIn < poOpenInfo->nHeaderBytes )
        {
            if( pszSrc[iIn] == '#' )
            {
                while( pszSrc[iIn] != 10 && pszSrc[iIn] != 13
                       && iIn < poOpenInfo->nHeaderBytes - 1 )
                    iIn++;
            }

            if( iOut != 0 && isspace((unsigned char)pszSrc[iIn]) )
            {
                szToken[iOut] = '\0';

                if( iToken == 0 )
                    nWidth = atoi(szToken);
                else if( iToken == 1 )
                    nHeight = atoi(szToken);
                else if( iToken == 2 )
                    nMaxValue = atoi(szToken);

                iToken++;
                iIn++;
                break;
            }

            else if( !isspace((unsigned char)pszSrc[iIn]) )
            {
                szToken[iOut++] = pszSrc[iIn];
            }

            iIn++;
        }
    }

    CPLDebug( "PNM", "PNM header contains: width=%d, height=%d, maxval=%d",
              nWidth, nHeight, nMaxValue );

    if( iToken != 3 || nWidth < 1 || nHeight < 1 || nMaxValue < 1 )
        return NULL;

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

    poDS = new PNMDataset();

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nWidth;
    poDS->nRasterYSize = nHeight;

/* -------------------------------------------------------------------- */
/*      Assume ownership of the file handled from the GDALOpenInfo.     */
/* -------------------------------------------------------------------- */
    VSIFClose( poOpenInfo->fp );
    poOpenInfo->fp = NULL;

    if( poOpenInfo->eAccess == GA_Update )
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" );
    else
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );

    if( poDS->fpImage == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to re-open %s within PNM driver.\n",
                  poOpenInfo->pszFilename );
        return NULL;
    }

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    int         bMSBFirst = TRUE, iPixelSize;
    GDALDataType eDataType;

#ifdef CPL_LSB
    bMSBFirst = FALSE;
#endif

    if ( nMaxValue < 256 )
        eDataType = GDT_Byte;
    else
        eDataType = GDT_UInt16;

    iPixelSize = GDALGetDataTypeSize( eDataType ) / 8;

    if( poOpenInfo->pabyHeader[1] == '5' )
    {
        if (nWidth > INT_MAX / iPixelSize)
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                  "Int overflow occured.");
            delete poDS;
            return NULL;
        }
        poDS->SetBand(
            1, new RawRasterBand( poDS, 1, poDS->fpImage, iIn, iPixelSize,
                                  nWidth*iPixelSize, eDataType, bMSBFirst, TRUE ));
        poDS->GetRasterBand(1)->SetColorInterpretation( GCI_GrayIndex );
    }
    else
    {
        if (nWidth > INT_MAX / (3 * iPixelSize))
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                  "Int overflow occured.");
            delete poDS;
            return NULL;
        }
        poDS->SetBand(
            1, new RawRasterBand( poDS, 1, poDS->fpImage, iIn, 3*iPixelSize,
                                  nWidth*3*iPixelSize, eDataType, bMSBFirst, TRUE ));
        poDS->SetBand(
            2, new RawRasterBand( poDS, 2, poDS->fpImage, iIn+iPixelSize,
                                  3*iPixelSize, nWidth*3*iPixelSize,
                                  eDataType, bMSBFirst, TRUE ));
        poDS->SetBand(
            3, new RawRasterBand( poDS, 3, poDS->fpImage, iIn+2*iPixelSize,
                                  3*iPixelSize, nWidth*3*iPixelSize,
                                  eDataType, bMSBFirst, TRUE ));

        poDS->GetRasterBand(1)->SetColorInterpretation( GCI_RedBand );
        poDS->GetRasterBand(2)->SetColorInterpretation( GCI_GreenBand );
        poDS->GetRasterBand(3)->SetColorInterpretation( GCI_BlueBand );
    }

/* -------------------------------------------------------------------- */
/*      Check for world file.                                           */
/* -------------------------------------------------------------------- */
    poDS->bGeoTransformValid = 
        GDALReadWorldFile( poOpenInfo->pszFilename, ".wld", 
                           poDS->adfGeoTransform );

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

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

    return( poDS );
}
Exemple #18
0
GDALDataset *ISIS2Dataset::Open( GDALOpenInfo * poOpenInfo )
{
/* -------------------------------------------------------------------- */
/*      Does this look like a CUBE dataset?                             */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->pabyHeader == NULL
        || strstr((const char *)poOpenInfo->pabyHeader,"^QUBE") == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Open the file using the large file API.                         */
/* -------------------------------------------------------------------- */
    FILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" );

    if( fpQube == NULL )
        return NULL;

    ISIS2Dataset 	*poDS;

    poDS = new ISIS2Dataset();

    if( ! poDS->oKeywords.Ingest( fpQube, 0 ) )
    {
        VSIFCloseL( fpQube );
        delete poDS;
        return NULL;
    }
    
    VSIFCloseL( fpQube );

/* -------------------------------------------------------------------- */
/*	We assume the user is pointing to the label (ie. .lab) file.  	*/
/* -------------------------------------------------------------------- */
    // QUBE can be inline or detached and point to an image name
    // ^QUBE = 76
    // ^QUBE = ("ui31s015.img",6441<BYTES>) - has another label on the image
    // ^QUBE = "ui31s015.img" - which implies no label or skip value

    const char *pszQube = poDS->GetKeyword( "^QUBE" );
    int nQube = atoi(pszQube);

    if( pszQube[0] == '"' || pszQube[0] == '(' )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "ISIS2 driver does not support detached images." );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Check if file an ISIS2 header file?  Read a few lines of text   */
/*      searching for something starting with nrows or ncols.           */
/* -------------------------------------------------------------------- */
    GDALDataType eDataType = GDT_Byte;
    OGRSpatialReference oSRS;

    //image parameters
    int	nRows, nCols, nBands = 1;
    int nSkipBytes = 0;
    int itype;
    int  s_ix, s_iy, s_iz; // check SUFFIX_ITEMS params.
    int record_bytes;
    int	bNoDataSet = FALSE;
    char chByteOrder = 'M';  //default to MSB
 
    //Georef parameters
    double dfULXMap=0.5;
    double dfULYMap = 0.5;
    double dfXDim = 1.0;
    double dfYDim = 1.0;
    double dfNoData = 0.0;
    double xulcenter = 0.0;
    double yulcenter = 0.0;

    //projection parameters
    int	bProjectionSet = TRUE;
    double semi_major = 0.0;
    double semi_minor = 0.0;
    double iflattening = 0.0;
    float center_lat = 0.0;
    float center_lon = 0.0;
    float first_std_parallel = 0.0;
    float second_std_parallel = 0.0;
    FILE	*fp;

    /* -------------------------------------------------------------------- */
    /*      Checks to see if this is valid ISIS2 cube                       */
    /*      SUFFIX_ITEM tag in .cub file should be (0,0,0); no side-planes  */
    /* -------------------------------------------------------------------- */
    s_ix = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 1 ));
    s_iy = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 2 ));
    s_iz = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 3 ));
     
    if( s_ix != 0 || s_iy != 0 || s_iz != 0 ) 
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "*** ISIS 2 cube file has invalid SUFFIX_ITEMS parameters:\n"
                  "*** gdal isis2 driver requires (0, 0, 0), thus no sideplanes or backplanes\n"
                  "found: (%i, %i, %i)\n\n", s_ix, s_iy, s_iz );
        return NULL;
    } 

    /**************** end SUFFIX_ITEM check ***********************/
    
    
    /***********   Grab layout type (BSQ, BIP, BIL) ************/
    //  AXIS_NAME = (SAMPLE,LINE,BAND)
    /***********************************************************/
    const char *value;

    char szLayout[10] = "BSQ"; //default to band seq.
    value = poDS->GetKeyword( "QUBE.AXIS_NAME", "" );
    if (EQUAL(value,"(SAMPLE,LINE,BAND)") )
        strcpy(szLayout,"BSQ");
    else if (EQUAL(value,"(BAND,LINE,SAMPLE)") )
        strcpy(szLayout,"BIP");
    else if (EQUAL(value,"(SAMPLE,BAND,LINE)") || EQUAL(value,"") )
        strcpy(szLayout,"BSQ");
    else {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "%s layout not supported. Abort\n\n", value);
        return NULL;
    }

    /***********   Grab samples lines band ************/
    nCols = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",1));
    nRows = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",2));
    nBands = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",3));
    
    /***********   Grab Qube record bytes  **********/
    record_bytes = atoi(poDS->GetKeyword("RECORD_BYTES"));

    if (nQube > 0)
        nSkipBytes = (nQube - 1) * record_bytes;     
    else
        nSkipBytes = 0;     
     
    /********   Grab format type - isis2 only supports 8,16,32 *******/
    itype = atoi(poDS->GetKeyword("QUBE.CORE_ITEM_BYTES",""));
    switch(itype) {
      case 1 :
        eDataType = GDT_Byte;
        dfNoData = NULL1;
        bNoDataSet = TRUE;
        break;
      case 2 :
        eDataType = GDT_Int16;
        dfNoData = NULL2;
        bNoDataSet = TRUE;
        break;
      case 4 :
        eDataType = GDT_Float32;
        dfNoData = NULL3;
        bNoDataSet = TRUE;
        break;
      default :
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Itype of %d is not supported in ISIS 2.",
                  itype); 
        delete poDS;
        return NULL;
    }

    /***********   Grab samples lines band ************/
    value = poDS->GetKeyword( "QUBE.CORE_ITEM_TYPE" );
    if( (EQUAL(value,"PC_INTEGER")) || 
        (EQUAL(value,"PC_UNSIGNED_INTEGER")) || 
        (EQUAL(value,"PC_REAL")) ) {
        chByteOrder = 'I';
    }
    
    /***********   Grab Cellsize ************/
    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.MAP_SCALE");
    if (strlen(value) > 0 ) {
        dfXDim = (float) atof(value) * 1000.0; /* convert from km to m */
        dfYDim = (float) atof(value) * 1000.0 * -1;
    }
    
    /***********   Grab LINE_PROJECTION_OFFSET ************/
    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET");
    if (strlen(value) > 0) {
        yulcenter = (float) atof(value);
        yulcenter = ((yulcenter) * dfYDim);
        dfULYMap = yulcenter - (dfYDim/2);
    }
     
    /***********   Grab SAMPLE_PROJECTION_OFFSET ************/
    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET");
    if( strlen(value) > 0 ) {
        xulcenter = (float) atof(value);
        xulcenter = ((xulcenter) * dfXDim);
        dfULXMap = xulcenter - (dfXDim/2);
    }
     
    /***********  Grab TARGET_NAME  ************/
    /**** This is the planets name i.e. MARS ***/
    CPLString target_name = poDS->GetKeyword("QUBE.TARGET_NAME");
     
    /***********   Grab MAP_PROJECTION_TYPE ************/
    CPLString map_proj_name = 
        poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE");
    poDS->CleanString( map_proj_name );

    /***********   Grab SEMI-MAJOR ************/
    semi_major = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0;

    /***********   Grab semi-minor ************/
    semi_minor = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0;

    /***********   Grab CENTER_LAT ************/
    center_lat = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LATITUDE"));

    /***********   Grab CENTER_LON ************/
    center_lon = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LONGITUDE"));

    /***********   Grab 1st std parallel ************/
    first_std_parallel = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL"));

    /***********   Grab 2nd std parallel ************/
    second_std_parallel = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.SECOND_STANDARD_PARALLEL"));
     
    /*** grab  PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/
    // Need to further study how ocentric/ographic will effect the gdal library.
    // So far we will use this fact to define a sphere or ellipse for some projections
    // Frank - may need to talk this over
    char bIsGeographic = TRUE;
    value = poDS->GetKeyword("CUBE.IMAGE_MAP_PROJECTION.PROJECTION_LATITUDE_TYPE");
    if (EQUAL( value, "\"PLANETOCENTRIC\"" ))
        bIsGeographic = FALSE; 
     
    CPLDebug("ISIS2","using projection %s", map_proj_name.c_str() );

    //Set oSRS projection and parameters
    if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) ||
        (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ||
        (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ) {
        oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 );
    } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) { 
        oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 );
    } else if ((EQUAL( map_proj_name, "SINUSOIDAL" )) ||
               (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" ))) {
        oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "MERCATOR" )) {
        oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )) {
        oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) {
        oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) {
        oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 );
    } else {
        CPLDebug( "ISIS2",
                  "Dataset projection %s is not supported. Continuing...",
                  map_proj_name.c_str() );
        bProjectionSet = FALSE;
    }

    if (bProjectionSet) {
        //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword
        CPLString proj_target_name = map_proj_name + " " + target_name;
        oSRS.SetProjCS(proj_target_name); //set ProjCS keyword
     
        //The geographic/geocentric name will be the same basic name as the body name
        //'GCS' = Geographic/Geocentric Coordinate System
        CPLString geog_name = "GCS_" + target_name;
        
        //The datum and sphere names will be the same basic name aas the planet
        CPLString datum_name = "D_" + target_name;
        CPLString sphere_name = target_name; // + "_IAU_IAG");  //Might not be IAU defined so don't add
          
        //calculate inverse flattening from major and minor axis: 1/f = a/(a-b)
        if ((semi_major - semi_minor) < 0.0000001) 
            iflattening = 0;
        else
            iflattening = semi_major / (semi_major - semi_minor);
     
        //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility
        //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally
        if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) || 
             (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )))  
        {
            if (bIsGeographic) { 
                //Geograpraphic, so set an ellipse
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening, 
                                "Reference_Meridian", 0.0 );
            } else {
                //Geocentric, so force a sphere using the semi-minor axis. I hope... 
                sphere_name += "_polarRadius";
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_minor, 0.0, 
                                "Reference_Meridian", 0.0 );
            }
        }
        else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || 
                  (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) ||
                  (EQUAL( map_proj_name, "STEREOGRAPHIC" )) ||
                  (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" )) ||
                  (EQUAL( map_proj_name, "SINUSOIDAL" ))  ) {
            //isis uses the sphereical equation for these projections so force a sphere
            oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                            semi_major, 0.0, 
                            "Reference_Meridian", 0.0 );
        } 
        else if  ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || 
                  (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ) {
            //Calculate localRadius using ISIS3 simple elliptical method 
            //  not the more standard Radius of Curvature method
            //PI = 4 * atan(1);
            double radLat, localRadius;
            if (center_lon == 0) { //No need to calculate local radius
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0, 
                                "Reference_Meridian", 0.0 );
            } else {  
                radLat = center_lat * PI / 180;  // in radians
                localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2)
                                                             + pow(semi_major*sin(radLat),2) );
                sphere_name += "_localRadius";
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                localRadius, 0.0, 
                                "Reference_Meridian", 0.0 );
                CPLDebug( "ISIS2", "local radius: %f", localRadius);
            }
        } 
        else { 
            //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc.
            //Geographic, so set an ellipse
            if (bIsGeographic) {
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening, 
                                "Reference_Meridian", 0.0 );
            } else { 
                //Geocentric, so force a sphere. I hope... 
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0, 
                                "Reference_Meridian", 0.0 );
            }
        }
        

        // translate back into a projection string.
        char *pszResult = NULL;
        oSRS.exportToWkt( &pszResult );
        poDS->osProjection = pszResult;
        CPLFree( pszResult );
    }

/* END ISIS2 Label Read */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    
/* -------------------------------------------------------------------- */
/*      Did we get the required keywords?  If not we return with        */
/*      this never having been considered to be a match. This isn't     */
/*      an error!                                                       */
/* -------------------------------------------------------------------- */
    if( nRows < 1 || nCols < 1 || nBands < 1 )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;

/* -------------------------------------------------------------------- */
/*      Open target binary file.                                        */
/* -------------------------------------------------------------------- */
    
    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    else
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "r+b" );

    if( poDS->fpImage == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to open %s with write permission.\n%s", 
                  poOpenInfo->pszFilename, VSIStrerror( errno ) );
        delete poDS;
        return NULL;
    }

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Compute the line offset.                                        */
/* -------------------------------------------------------------------- */
    int     nItemSize = GDALGetDataTypeSize(eDataType)/8;
    int		nLineOffset, nPixelOffset, nBandOffset;
    
    if( EQUAL(szLayout,"BIP") )
    {
        nPixelOffset = nItemSize * nBands;
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = nItemSize;
    }
    else if( EQUAL(szLayout,"BSQ") )
    {
        nPixelOffset = nItemSize;
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = nLineOffset * nRows;
    }
    else /* assume BIL */
    {
        nPixelOffset = nItemSize;
        nLineOffset = nItemSize * nBands * nCols;
        nBandOffset = nItemSize * nCols;
    }
    
/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    int i;

    poDS->nBands = nBands;;
    for( i = 0; i < poDS->nBands; i++ )
    {
        RawRasterBand	*poBand;

        poBand = 
            new RawRasterBand( poDS, i+1, poDS->fpImage,
                               nSkipBytes + nBandOffset * i, 
                               nPixelOffset, nLineOffset, eDataType,
#ifdef CPL_LSB                               
                               chByteOrder == 'I' || chByteOrder == 'L',
#else
                               chByteOrder == 'M',
#endif        
                               TRUE );

        if( bNoDataSet )
            poBand->SetNoDataValue( dfNoData );

        poDS->SetBand( i+1, poBand );

        // Set offset/scale values at the PAM level.
        poBand->SetOffset( 
            CPLAtofM(poDS->GetKeyword("QUBE.CORE_BASE","0.0")));
        poBand->SetScale( 
            CPLAtofM(poDS->GetKeyword("QUBE.CORE_MULTIPLIER","1.0")));
    }

/* -------------------------------------------------------------------- */
/*      Check for a .prj file. For isis2 I would like to keep this in   */
/* -------------------------------------------------------------------- */
    CPLString osPath, osName;

    osPath = CPLGetPath( poOpenInfo->pszFilename );
    osName = CPLGetBasename(poOpenInfo->pszFilename);
    const char  *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" );

    fp = VSIFOpen( pszPrjFile, "r" );
    if( fp != NULL )
    {
        char	**papszLines;
        OGRSpatialReference oSRS;

        VSIFClose( fp );
        
        papszLines = CSLLoad( pszPrjFile );

        if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE )
        {
            char *pszResult = NULL;
            oSRS.exportToWkt( &pszResult );
            poDS->osProjection = pszResult;
            CPLFree( pszResult );
        }

        CSLDestroy( papszLines );
    }

    
    if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 )
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = dfULXMap;
        poDS->adfGeoTransform[1] = dfXDim;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = dfULYMap;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = dfYDim;
    }
    
    if( !poDS->bGotTransform )
        poDS->bGotTransform = 
            GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", 
                               poDS->adfGeoTransform );

    if( !poDS->bGotTransform )
        poDS->bGotTransform = 
            GDALReadWorldFile( poOpenInfo->pszFilename, "wld", 
                               poDS->adfGeoTransform );

/* -------------------------------------------------------------------- */ 
/*      Initialize any PAM information.                                 */ 
/* -------------------------------------------------------------------- */ 
    poDS->SetDescription( poOpenInfo->pszFilename ); 
    poDS->TryLoadXML(); 

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

    return( poDS );
}
Exemple #19
0
GDALDataset *GXFDataset::Open( GDALOpenInfo * poOpenInfo )

{
    GXFHandle	l_hGXF;
    int		i, bFoundKeyword, bFoundIllegal;

/* -------------------------------------------------------------------- */
/*      Before trying GXFOpen() we first verify that there is at        */
/*      least one "\n#keyword" type signature in the first chunk of     */
/*      the file.                                                       */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 50 )
        return NULL;

    bFoundKeyword = FALSE;
    bFoundIllegal = FALSE;
    for( i = 0; i < poOpenInfo->nHeaderBytes-1; i++ )
    {
        if( (poOpenInfo->pabyHeader[i] == 10
             || poOpenInfo->pabyHeader[i] == 13)
            && poOpenInfo->pabyHeader[i+1] == '#' )
        {
            if( STARTS_WITH((const char*)poOpenInfo->pabyHeader + i + 2, "include") )
                return NULL;
            if( STARTS_WITH((const char*)poOpenInfo->pabyHeader + i + 2, "define") )
                return NULL;
            if( STARTS_WITH((const char*)poOpenInfo->pabyHeader + i + 2, "ifdef") )
                return NULL;
            bFoundKeyword = TRUE;
        }
        if( poOpenInfo->pabyHeader[i] == 0 )
        {
            bFoundIllegal = TRUE;
            break;
        }
    }

    if( !bFoundKeyword || bFoundIllegal )
        return NULL;

/* -------------------------------------------------------------------- */
/*      At this point it is plausible that this is a GXF file, but      */
/*      we also now verify that there is a #GRID keyword before         */
/*      passing it off to GXFOpen().  We check in the first 50K.        */
/* -------------------------------------------------------------------- */
#define BIGBUFSIZE 50000
    int nBytesRead, bGotGrid = FALSE;
    FILE *fp;

    fp = VSIFOpen( poOpenInfo->pszFilename, "rb" );
    if( fp == NULL )
        return NULL;

    char *pszBigBuf = (char *) CPLMalloc(BIGBUFSIZE);
    nBytesRead = static_cast<int>(VSIFRead( pszBigBuf, 1, BIGBUFSIZE, fp ));
    VSIFClose( fp );

    for( i = 0; i < nBytesRead - 5 && !bGotGrid; i++ )
    {
        if( pszBigBuf[i] == '#' && STARTS_WITH_CI(pszBigBuf+i+1, "GRID") )
            bGotGrid = TRUE;
    }

    CPLFree( pszBigBuf );

    if( !bGotGrid )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Try opening the dataset.                                        */
/* -------------------------------------------------------------------- */

    l_hGXF = GXFOpen( poOpenInfo->pszFilename );

    if( l_hGXF == NULL )
        return( NULL );

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        GXFClose(l_hGXF);
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The GXF driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }

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

    poDS = new GXFDataset();

    const char* pszGXFDataType = CPLGetConfigOption("GXF_DATATYPE", "Float32");
    GDALDataType eDT = GDALGetDataTypeByName(pszGXFDataType);
    if (!(eDT == GDT_Float32 || eDT == GDT_Float64))
    {
        CPLError(CE_Warning, CPLE_NotSupported,
                 "Unsupported value for GXF_DATATYPE : %s", pszGXFDataType);
        eDT = GDT_Float32;
    }

    poDS->hGXF = l_hGXF;
    poDS->eDataType = eDT;

/* -------------------------------------------------------------------- */
/*	Establish the projection.					*/
/* -------------------------------------------------------------------- */
    poDS->pszProjection = GXFGetMapProjectionAsOGCWKT( l_hGXF );

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    GXFGetRawInfo( l_hGXF, &(poDS->nRasterXSize), &(poDS->nRasterYSize), NULL,
                   NULL, NULL, &(poDS->dfNoDataValue) );

    if  (poDS->nRasterXSize <= 0 || poDS->nRasterYSize <= 0)
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Invalid dimensions : %d x %d",
                  poDS->nRasterXSize, poDS->nRasterYSize);
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = 1;
    poDS->SetBand( 1, new GXFRasterBand( poDS, 1 ));

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for external overviews.                                   */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles() );

    return( poDS );
}
Exemple #20
0
GDALDataset *IDADataset::Create( const char * pszFilename,
                                 int nXSize, int nYSize, int nBands,
                                 GDALDataType eType,
                                 char ** /* papszParmList */ )

{
/* -------------------------------------------------------------------- */
/*      Verify input options.                                           */
/* -------------------------------------------------------------------- */
    if( eType != GDT_Byte || nBands != 1 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Only 1 band, Byte datasets supported for IDA format." );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Try to create the file.                                         */
/* -------------------------------------------------------------------- */
    FILE	*fp;

    fp = VSIFOpen( pszFilename, "wb" );

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

/* -------------------------------------------------------------------- */
/*      Prepare formatted header.                                       */
/* -------------------------------------------------------------------- */
    GByte abyHeader[512];
    
    memset( abyHeader, 0, sizeof(abyHeader) );
    
    abyHeader[22] = 200; /* image type - CALCULATED */
    abyHeader[23] = 0; /* projection - NONE */
    abyHeader[30] = nYSize % 256;
    abyHeader[31] = (GByte) (nYSize / 256);
    abyHeader[32] = nXSize % 256;
    abyHeader[33] = (GByte) (nXSize / 256);

    abyHeader[170] = 255; /* missing = 255 */
    c2tp( 1.0, abyHeader + 171 ); /* slope = 1.0 */
    c2tp( 0.0, abyHeader + 177 ); /* offset = 0 */
    abyHeader[168] = 0; // lower limit
    abyHeader[169] = 254; // upper limit

    // pixel size = 1.0
    c2tp( 1.0, abyHeader + 144 );
    c2tp( 1.0, abyHeader + 150 );

    if( VSIFWrite( abyHeader, 1, 512, fp ) != 512 )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "IO error writing %s.\n%s", 
                  pszFilename, VSIStrerror( errno ) );
        VSIFClose( fp );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Now we need to extend the file to just the right number of      */
/*      bytes for the data we have to ensure it will open again         */
/*      properly.                                                       */
/* -------------------------------------------------------------------- */
    if( VSIFSeek( fp, nXSize * nYSize - 1, SEEK_CUR ) != 0
        || VSIFWrite( abyHeader, 1, 1, fp ) != 1 )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "IO error writing %s.\n%s", 
                  pszFilename, VSIStrerror( errno ) );
        VSIFClose( fp );
        return NULL;
    }

    VSIFClose( fp );

    return (GDALDataset *) GDALOpen( pszFilename, GA_Update );
}
Exemple #21
0
int OGRGeneralCmdLineProcessor( int nArgc, char ***ppapszArgv, int nOptions )

{
    char **papszReturn = NULL;
    int  iArg;
    char **papszArgv = *ppapszArgv;

    (void) nOptions;
    
/* -------------------------------------------------------------------- */
/*      Preserve the program name.                                      */
/* -------------------------------------------------------------------- */
    papszReturn = CSLAddString( papszReturn, papszArgv[0] );

/* ==================================================================== */
/*      Loop over all arguments.                                        */
/* ==================================================================== */
    for( iArg = 1; iArg < nArgc; iArg++ )
    {

/* -------------------------------------------------------------------- */
/*      --config                                                        */
/* -------------------------------------------------------------------- */
        if( EQUAL(papszArgv[iArg],"--config") )
        {
            if( iArg + 2 >= nArgc )
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "--config option given without a key and value argument." );
                CSLDestroy( papszReturn );
                return -1;
            }

            CPLSetConfigOption( papszArgv[iArg+1], papszArgv[iArg+2] );

            iArg += 2;
        }

/* -------------------------------------------------------------------- */
/*      --mempreload                                                    */
/* -------------------------------------------------------------------- */
        else if( EQUAL(papszArgv[iArg],"--mempreload") )
        {
            int i;

            if( iArg + 1 >= nArgc )
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "--mempreload option given without directory path.");
                CSLDestroy( papszReturn );
                return -1;
            }
            
            char **papszFiles = CPLReadDir( papszArgv[iArg+1] );
            if( CSLCount(papszFiles) == 0 )
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "--mempreload given invalid or empty directory.");
                CSLDestroy( papszReturn );
                return -1;
            }
                
            for( i = 0; papszFiles[i] != NULL; i++ )
            {
                CPLString osOldPath, osNewPath;
                
                if( EQUAL(papszFiles[i],".") || EQUAL(papszFiles[i],"..") )
                    continue;

                osOldPath = CPLFormFilename( papszArgv[iArg+1], 
                                             papszFiles[i], NULL );
                osNewPath.Printf( "/vsimem/%s", papszFiles[i] );

                CPLDebug( "VSI", "Preloading %s to %s.", 
                          osOldPath.c_str(), osNewPath.c_str() );

                if( CPLCopyFile( osNewPath, osOldPath ) != 0 )
                    return -1;
            }
            
            CSLDestroy( papszFiles );
            iArg += 1;
        }

/* -------------------------------------------------------------------- */
/*      --debug                                                         */
/* -------------------------------------------------------------------- */
        else if( EQUAL(papszArgv[iArg],"--debug") )
        {
            if( iArg + 1 >= nArgc )
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "--debug option given without debug level." );
                CSLDestroy( papszReturn );
                return -1;
            }

            CPLSetConfigOption( "CPL_DEBUG", papszArgv[iArg+1] );
            iArg += 1;
        }

/* -------------------------------------------------------------------- */
/*      --optfile                                                       */
/*                                                                      */
/*      Annoyingly the options inserted by --optfile will *not* be      */
/*      processed properly if they are general options.                 */
/* -------------------------------------------------------------------- */
        else if( EQUAL(papszArgv[iArg],"--optfile") )
        {
            const char *pszLine;
            FILE *fpOptFile;

            if( iArg + 1 >= nArgc )
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "--optfile option given without filename." );
                CSLDestroy( papszReturn );
                return -1;
            }

            fpOptFile = VSIFOpen( papszArgv[iArg+1], "rb" );

            if( fpOptFile == NULL )
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "Unable to open optfile '%s'.\n%s",
                          papszArgv[iArg+1], VSIStrerror( errno ) );
                CSLDestroy( papszReturn );
                return -1;
            }
            
            while( (pszLine = CPLReadLine( fpOptFile )) != NULL )
            {
                char **papszTokens;
                int i;

                if( pszLine[0] == '#' || strlen(pszLine) == 0 )
                    continue;

                papszTokens = CSLTokenizeString( pszLine );
                for( i = 0; papszTokens != NULL && papszTokens[i] != NULL; i++)
                    papszReturn = CSLAddString( papszReturn, papszTokens[i] );
                CSLDestroy( papszTokens );
            }

            VSIFClose( fpOptFile );
                
            iArg += 1;
        }

/* -------------------------------------------------------------------- */
/*      --formats                                                       */
/* -------------------------------------------------------------------- */
#ifdef OGR_ENABLED
        else if( EQUAL(papszArgv[iArg], "--formats") )
        {
            int iDr;

            printf( "Supported Formats:\n" );

            OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
        
            for( iDr = 0; iDr < poR->GetDriverCount(); iDr++ )
            {
                OGRSFDriver *poDriver = poR->GetDriver(iDr);

                if( poDriver->TestCapability( ODrCCreateDataSource ) )
                    printf( "  -> \"%s\" (read/write)\n", 
                            poDriver->GetName() );
                else
                    printf( "  -> \"%s\" (readonly)\n", 
                            poDriver->GetName() );
            }

            CSLDestroy( papszReturn );
            return 0;
        }
#endif /* OGR_ENABLED */

/* -------------------------------------------------------------------- */
/*      --locale                                                        */
/* -------------------------------------------------------------------- */
        else if( EQUAL(papszArgv[iArg],"--locale") && iArg < nArgc-1 )
        {
            setlocale( LC_ALL, papszArgv[++iArg] );
        }

/* -------------------------------------------------------------------- */
/*      --help-general                                                  */
/* -------------------------------------------------------------------- */
        else if( EQUAL(papszArgv[iArg],"--help-general") )
        {
            printf( "Generic GDAL/OGR utility command options:\n" );
#ifdef OGR_ENABLED
            printf( "  --formats: report all configured format drivers.\n" );
#endif /* OGR_ENABLED */
            printf( "  --optfile filename: expand an option file into the argument list.\n" );
            printf( "  --config key value: set system configuration option.\n" );
            printf( "  --debug [on/off/value]: set debug level.\n" );
            printf( "  --help-general: report detailed help on general options.\n" );
            CSLDestroy( papszReturn );
            return 0;
        }

/* -------------------------------------------------------------------- */
/*      carry through unrecognised options.                             */
/* -------------------------------------------------------------------- */
        else
        {
            papszReturn = CSLAddString( papszReturn, papszArgv[iArg] );
        }
    }

    *ppapszArgv = papszReturn;

    return CSLCount( *ppapszArgv );
}
Exemple #22
0
void IDADataset::ReadColorTable()

{
/* -------------------------------------------------------------------- */
/*      Decide what .clr file to look for and try to open.              */
/* -------------------------------------------------------------------- */
    CPLString osCLRFilename;

    osCLRFilename = CPLGetConfigOption( "IDA_COLOR_FILE", "" );
    if( strlen(osCLRFilename) == 0 )
        osCLRFilename = CPLResetExtension(GetDescription(), "clr" );


    FILE *fp = VSIFOpen( osCLRFilename, "r" );
    if( fp == NULL )
    {
        osCLRFilename = CPLResetExtension(osCLRFilename, "CLR" );
        fp = VSIFOpen( osCLRFilename, "r" );
    }

    if( fp == NULL )
        return;

/* -------------------------------------------------------------------- */
/*      Skip first line, with the column titles.                        */
/* -------------------------------------------------------------------- */
    CPLReadLine( fp );

/* -------------------------------------------------------------------- */
/*      Create a RAT to populate.                                       */
/* -------------------------------------------------------------------- */
    GDALRasterAttributeTable *poRAT = new GDALDefaultRasterAttributeTable();

    poRAT->CreateColumn( "FROM", GFT_Integer, GFU_Min );
    poRAT->CreateColumn( "TO", GFT_Integer, GFU_Max );
    poRAT->CreateColumn( "RED", GFT_Integer, GFU_Red );
    poRAT->CreateColumn( "GREEN", GFT_Integer, GFU_Green );
    poRAT->CreateColumn( "BLUE", GFT_Integer, GFU_Blue );
    poRAT->CreateColumn( "LEGEND", GFT_String, GFU_Name );

/* -------------------------------------------------------------------- */
/*      Apply lines.                                                    */
/* -------------------------------------------------------------------- */
    const char *pszLine = CPLReadLine( fp );
    int iRow = 0;

    while( pszLine != NULL )
    {
        char **papszTokens = 
            CSLTokenizeStringComplex( pszLine, " \t", FALSE, FALSE );
        
        if( CSLCount( papszTokens ) >= 5 )
        {
            poRAT->SetValue( iRow, 0, atoi(papszTokens[0]) );
            poRAT->SetValue( iRow, 1, atoi(papszTokens[1]) );
            poRAT->SetValue( iRow, 2, atoi(papszTokens[2]) );
            poRAT->SetValue( iRow, 3, atoi(papszTokens[3]) );
            poRAT->SetValue( iRow, 4, atoi(papszTokens[4]) );

            // find name, first nonspace after 5th token. 
            const char *pszName = pszLine;

            // skip from
            while( *pszName == ' ' || *pszName == '\t' )
                pszName++;
            while( *pszName != ' ' && *pszName != '\t' && *pszName != '\0' )
                pszName++;
            
            // skip to
            while( *pszName == ' ' || *pszName == '\t' )
                pszName++;
            while( *pszName != ' ' && *pszName != '\t' && *pszName != '\0' )
                pszName++;
            
            // skip red
            while( *pszName == ' ' || *pszName == '\t' )
                pszName++;
            while( *pszName != ' ' && *pszName != '\t' && *pszName != '\0' )
                pszName++;
            
            // skip green
            while( *pszName == ' ' || *pszName == '\t' )
                pszName++;
            while( *pszName != ' ' && *pszName != '\t' && *pszName != '\0' )
                pszName++;
            
            // skip blue
            while( *pszName == ' ' || *pszName == '\t' )
                pszName++;
            while( *pszName != ' ' && *pszName != '\t' && *pszName != '\0' )
                pszName++;

            // skip pre-name white space
            while( *pszName == ' ' || *pszName == '\t' )
                pszName++;

            poRAT->SetValue( iRow, 5, pszName );
            
            iRow++;
        }

        CSLDestroy( papszTokens );
        pszLine = CPLReadLine( fp );
    }

    VSIFClose( fp );

/* -------------------------------------------------------------------- */
/*      Attach RAT to band.                                             */
/* -------------------------------------------------------------------- */
    ((IDARasterBand *) GetRasterBand( 1 ))->poRAT = poRAT;

/* -------------------------------------------------------------------- */
/*      Build a conventional color table from this.                     */
/* -------------------------------------------------------------------- */
    ((IDARasterBand *) GetRasterBand( 1 ))->poColorTable = 
        poRAT->TranslateToColorTable();
}
int OGRSDTSDataSource::Open( const char * pszFilename, int bTestOpen )

{
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Verify that the extension is DDF if we are testopening.         */
/* -------------------------------------------------------------------- */
    if( bTestOpen && !(strlen(pszFilename) > 4 &&
        EQUAL(pszFilename+strlen(pszFilename)-4,".ddf")) )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Check a few bits of the header to see if it looks like an       */
/*      SDTS file (really, if it looks like an ISO8211 file).           */
/* -------------------------------------------------------------------- */
    if( bTestOpen )
    {
        FILE    *fp;
        char    pachLeader[10];

        fp = VSIFOpen( pszFilename, "rb" );
        if( fp == NULL )
            return FALSE;

        if( VSIFRead( pachLeader, 1, 10, fp ) != 10
            || (pachLeader[5] != '1' && pachLeader[5] != '2'
                && pachLeader[5] != '3' )
            || pachLeader[6] != 'L'
            || (pachLeader[8] != '1' && pachLeader[8] != ' ') )
        {
            VSIFClose( fp );
            return FALSE;
        }

        VSIFClose( fp );
    }

/* -------------------------------------------------------------------- */
/*      Create a transfer, and open it.                                 */
/* -------------------------------------------------------------------- */
    poTransfer = new SDTSTransfer();

    if( !poTransfer->Open( pszFilename ) )
    {
        delete poTransfer;
        poTransfer = NULL;

        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Initialize the projection.                                      */
/* -------------------------------------------------------------------- */
    SDTS_XREF   *poXREF = poTransfer->GetXREF();

    poSRS = new OGRSpatialReference();

    if( EQUAL(poXREF->pszSystemName,"UTM") )
    {
        poSRS->SetUTM( poXREF->nZone, TRUE );
    }

    if( EQUAL(poXREF->pszDatum,"NAS") )
        poSRS->SetGeogCS("NAD27", "North_American_Datum_1927",
                         "Clarke 1866", 6378206.4, 294.978698213901 );

    else if( EQUAL(poXREF->pszDatum,"NAX") )
        poSRS->SetGeogCS("NAD83", "North_American_Datum_1983",
                         "GRS 1980", 6378137, 298.257222101 );

    else if( EQUAL(poXREF->pszDatum,"WGC") )
        poSRS->SetGeogCS("WGS 72", "WGS_1972", "NWL 10D", 6378135, 298.26 );

    else if( EQUAL(poXREF->pszDatum,"WGE") )
        poSRS->SetGeogCS("WGS 84", "WGS_1984",
                         "WGS 84", 6378137, 298.257223563 );

    else
        poSRS->SetGeogCS("WGS 84", "WGS_1984",
                         "WGS 84", 6378137, 298.257223563 );

    poSRS->Fixup();

/* -------------------------------------------------------------------- */
/*      Initialize a layer for each source dataset layer.               */
/* -------------------------------------------------------------------- */
    for( int iLayer = 0; iLayer < poTransfer->GetLayerCount(); iLayer++ )
    {
        SDTSIndexedReader       *poReader;

        if( poTransfer->GetLayerType( iLayer ) == SLTRaster )
            continue;

        poReader = poTransfer->GetLayerIndexedReader( iLayer );
        if( poReader == NULL )
            continue;

        papoLayers = (OGRSDTSLayer **)
            CPLRealloc( papoLayers, sizeof(void*) * ++nLayers );
        papoLayers[nLayers-1] = new OGRSDTSLayer( poTransfer, iLayer, this );
    }

    return TRUE;
}
int NASReader::LoadClasses( const char *pszFile )

{
    // Add logic later to determine reasonable default schema file. 
    if( pszFile == NULL )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Load the raw XML file.                                          */
/* -------------------------------------------------------------------- */
    FILE       *fp;
    int         nLength;
    char        *pszWholeText;

    fp = VSIFOpen( pszFile, "rb" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to open file %s.", pszFile );
        return FALSE;
    }

    VSIFSeek( fp, 0, SEEK_END );
    nLength = VSIFTell( fp );
    VSIFSeek( fp, 0, SEEK_SET );

    pszWholeText = (char *) VSIMalloc(nLength+1);
    if( pszWholeText == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Failed to allocate %d byte buffer for %s,\n"
                  "is this really a GMLFeatureClassList file?",
                  nLength, pszFile );
        VSIFClose( fp );
        return FALSE;
    }
    
    if( VSIFRead( pszWholeText, nLength, 1, fp ) != 1 )
    {
        VSIFree( pszWholeText );
        VSIFClose( fp );
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Read failed on %s.", pszFile );
        return FALSE;
    }
    pszWholeText[nLength] = '\0';

    VSIFClose( fp );

    if( strstr( pszWholeText, "<GMLFeatureClassList>" ) == NULL )
    {
        VSIFree( pszWholeText );
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "File %s does not contain a GMLFeatureClassList tree.",
                  pszFile );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Convert to XML parse tree.                                      */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRoot;

    psRoot = CPLParseXMLString( pszWholeText );
    VSIFree( pszWholeText );

    // We assume parser will report errors via CPL.
    if( psRoot == NULL )
        return FALSE;

    if( psRoot->eType != CXT_Element 
        || !EQUAL(psRoot->pszValue,"GMLFeatureClassList") )
    {
        CPLDestroyXMLNode(psRoot);
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "File %s is not a GMLFeatureClassList document.",
                  pszFile );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Extract feature classes for all definitions found.              */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psThis;

    for( psThis = psRoot->psChild; psThis != NULL; psThis = psThis->psNext )
    {
        if( psThis->eType == CXT_Element 
            && EQUAL(psThis->pszValue,"GMLFeatureClass") )
        {
            GMLFeatureClass   *poClass;

            poClass = new GMLFeatureClass();

            if( !poClass->InitializeFromXML( psThis ) )
            {
                delete poClass;
                CPLDestroyXMLNode( psRoot );
                return FALSE;
            }

            poClass->SetSchemaLocked( TRUE );

            AddClass( poClass );
        }
    }

    CPLDestroyXMLNode( psRoot );
    
    SetClassListLocked( TRUE );

    return TRUE;
}
static GDALDataset *
XPMCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
               int bStrict, char ** papszOptions, 
               GDALProgressFunc pfnProgress, void * pProgressData )

{
    int  nBands = poSrcDS->GetRasterCount();
    int  nXSize = poSrcDS->GetRasterXSize();
    int  nYSize = poSrcDS->GetRasterYSize();
    GDALColorTable *poCT;

/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    if( nBands != 1 )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "XPM driver only supports one band images.\n" );

        return NULL;
    }

    if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte 
        && bStrict )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "XPM driver doesn't support data type %s. "
                  "Only eight bit bands supported.\n", 
                  GDALGetDataTypeName( 
                      poSrcDS->GetRasterBand(1)->GetRasterDataType()) );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      If there is no colortable on the source image, create a         */
/*      greyscale one with 64 levels of grey.                           */
/* -------------------------------------------------------------------- */
    GDALRasterBand	*poBand = poSrcDS->GetRasterBand(1);
    int                 i;
    GDALColorTable      oGreyTable;

    poCT = poBand->GetColorTable();
    if( poCT == NULL )
    {
        poCT = &oGreyTable;

        for( i = 0; i < 256; i++ )
        {
            GDALColorEntry sColor;

            sColor.c1 = (short) i;
            sColor.c2 = (short) i;
            sColor.c3 = (short) i;
            sColor.c4 = 255;

            poCT->SetColorEntry( i, &sColor );
        }
    }

/* -------------------------------------------------------------------- */
/*      Build list of active colors, and the mapping from pixels to     */
/*      our active colormap.                                            */
/* -------------------------------------------------------------------- */
    const char *pszColorCodes = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-+=[]|:;,.<>?/";

    int  anPixelMapping[256];
    GDALColorEntry asPixelColor[256];
    int  nActiveColors = MIN(poCT->GetColorEntryCount(),256);

    // Setup initial colortable and pixel value mapping. 
    memset( anPixelMapping+0, 0, sizeof(int) * 256 );
    for( i = 0; i < nActiveColors; i++ )
    {
        poCT->GetColorEntryAsRGB( i, asPixelColor + i );
        anPixelMapping[i] = i;
    }

/* ==================================================================== */
/*      Iterate merging colors until we are under our limit (about 85). */
/* ==================================================================== */
    while( nActiveColors > (int) strlen(pszColorCodes) )
    {
        int nClosestDistance = 768;
        int iClose1 = -1, iClose2 = -1;
        int iColor1, iColor2;

        // Find the closest pair of colors. 
        for( iColor1 = 0; iColor1 < nActiveColors; iColor1++ )
        {
            for( iColor2 = iColor1+1; iColor2 < nActiveColors; iColor2++ )
            {
                int	nDistance;

                if( asPixelColor[iColor1].c4 < 128 
                    && asPixelColor[iColor2].c4 < 128 )
                    nDistance = 0;
                else
                    nDistance = 
                        ABS(asPixelColor[iColor1].c1-asPixelColor[iColor2].c1)
                      + ABS(asPixelColor[iColor1].c2-asPixelColor[iColor2].c2)
                      + ABS(asPixelColor[iColor1].c3-asPixelColor[iColor2].c3);

                if( nDistance < nClosestDistance )
                {
                    nClosestDistance = nDistance;
                    iClose1 = iColor1;
                    iClose2 = iColor2;
                }
            }

            if( nClosestDistance < 8 )
                break;
        }

        // This should never happen!
        if( iClose1 == -1 )
            break;

        // Merge two selected colors - shift icolor2 into icolor1 and
        // move the last active color into icolor2's slot. 
        for( i = 0; i < 256; i++ )
        {
            if( anPixelMapping[i] == iClose2 )
                anPixelMapping[i] = iClose1;
            else if( anPixelMapping[i] == nActiveColors-1 )
                anPixelMapping[i] = iClose2;
        }

        asPixelColor[iClose2] = asPixelColor[nActiveColors-1];
        nActiveColors--;
    }
        
/* ==================================================================== */
/*      Write the output image.                                         */
/* ==================================================================== */
    FILE	*fpPBM;

    fpPBM = VSIFOpen( pszFilename, "wt+" );
    if( fpPBM == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Unable to create file `%s'.", 
                  pszFilename );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Write the header lines.                                         */
/* -------------------------------------------------------------------- */
    fprintf( fpPBM, "/* XPM */\n" );
    fprintf( fpPBM, "static char *%s[] = {\n", 
             CPLGetBasename( pszFilename ) );
    fprintf( fpPBM, "/* width height num_colors chars_per_pixel */\n" );
    fprintf( fpPBM, "\"  %3d   %3d     %3d             1\",\n",
             nXSize, nYSize, nActiveColors );
    fprintf( fpPBM, "/* colors */\n" );

/* -------------------------------------------------------------------- */
/*      Write the color table.                                          */
/* -------------------------------------------------------------------- */
    for( i = 0; i < nActiveColors; i++ )
    {
        if( asPixelColor[i].c4 < 128 )
            fprintf( fpPBM, "\"%c c None\",\n", pszColorCodes[i] );
        else
            fprintf( fpPBM, 
                     "\"%c c #%02x%02x%02x\",\n",
                     pszColorCodes[i],
                     asPixelColor[i].c1, 
                     asPixelColor[i].c2, 
                     asPixelColor[i].c3 );
    }

/* -------------------------------------------------------------------- */
/*	Dump image.							*/
/* -------------------------------------------------------------------- */
    int iLine;
    GByte 	*pabyScanline;

    pabyScanline = (GByte *) CPLMalloc( nXSize );
    for( iLine = 0; iLine < nYSize; iLine++ )
    {
        poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, 
                          (void *) pabyScanline, nXSize, 1, GDT_Byte, 0, 0 );
        
        fputc( '"', fpPBM );
        for( int iPixel = 0; iPixel < nXSize; iPixel++ )
            fputc( pszColorCodes[anPixelMapping[pabyScanline[iPixel]]], 
                   fpPBM);
        fprintf( fpPBM, "\",\n" );
    }
    
    CPLFree( pabyScanline );

/* -------------------------------------------------------------------- */
/*      cleanup                                                         */
/* -------------------------------------------------------------------- */
    fprintf( fpPBM, "};\n" );
    VSIFClose( fpPBM );

/* -------------------------------------------------------------------- */
/*      Re-open dataset, and copy any auxilary pam information.         */
/* -------------------------------------------------------------------- */
    GDALPamDataset *poDS = (GDALPamDataset *) 
        GDALOpen( pszFilename, GA_ReadOnly );

    if( poDS )
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );

    return poDS;
}
Exemple #26
0
int TigerFileBase::SetWriteModule( const char *pszExtension, int nRecLen,
                                   OGRFeature *poFeature )

{
/* -------------------------------------------------------------------- */
/*      Work out what module we should be writing to.                   */
/* -------------------------------------------------------------------- */
    const char *pszTargetModule = poFeature->GetFieldAsString( "MODULE" );
    char        szFullModule[30];

    /* TODO/notdef: eventually more logic based on FILE and STATE/COUNTY can 
       be inserted here. */

    if( pszTargetModule == NULL )
        return FALSE;

    sprintf( szFullModule, "%s.RT", pszTargetModule );

/* -------------------------------------------------------------------- */
/*      Is this our current module?                                     */
/* -------------------------------------------------------------------- */
    if( pszModule != NULL && EQUAL(szFullModule,pszModule) )
        return TRUE;

/* -------------------------------------------------------------------- */
/*      Cleanup the previous file, if any.                              */
/* -------------------------------------------------------------------- */
    if( fpPrimary != NULL )
    {
        VSIFClose( fpPrimary );
        fpPrimary = NULL;
    }

    if( pszModule != NULL )
    {
        CPLFree( pszModule );
        pszModule = NULL;
    }

/* -------------------------------------------------------------------- */
/*      Is this a module we have never written to before?  If so, we    */
/*      will try to blow away any existing files in this file set.      */
/* -------------------------------------------------------------------- */
    if( !poDS->CheckModule( szFullModule ) )
    {
        poDS->DeleteModuleFiles( szFullModule );
        poDS->AddModule( szFullModule );
    }
    
/* -------------------------------------------------------------------- */
/*      Does this file already exist?                                   */
/* -------------------------------------------------------------------- */
    char *pszFilename;

    pszFilename = poDS->BuildFilename( szFullModule, pszExtension );

    fpPrimary = VSIFOpen( pszFilename, "ab" );
    CPLFree(pszFilename);
    if( fpPrimary == NULL )
        return FALSE;

    pszModule = CPLStrdup( szFullModule );

    return TRUE;
}
Exemple #27
0
OGRErr OGRMILayerAttrIndex::LoadConfigFromXML()

{
    FILE *fp;
    int  nXMLSize;
    char *pszRawXML;

    CPLAssert( poINDFile == NULL );

/* -------------------------------------------------------------------- */
/*      Read the XML file.                                              */
/* -------------------------------------------------------------------- */
    fp = VSIFOpen( pszMetadataFilename, "rb" );
    if( fp == NULL )
        return OGRERR_NONE;

    VSIFSeek( fp, 0, SEEK_END );
    nXMLSize = VSIFTell( fp );
    VSIFSeek( fp, 0, SEEK_SET );

    pszRawXML = (char *) CPLMalloc(nXMLSize+1);
    pszRawXML[nXMLSize] = '\0';
    VSIFRead( pszRawXML, nXMLSize, 1, fp );

    VSIFClose( fp );

/* -------------------------------------------------------------------- */
/*      Parse the XML.                                                  */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRoot = CPLParseXMLString( pszRawXML );
    CPLFree( pszRawXML );

    if( psRoot == NULL )
        return OGRERR_FAILURE;

/* -------------------------------------------------------------------- */
/*      Open the index file.                                            */
/* -------------------------------------------------------------------- */
    poINDFile = new TABINDFile();
    if( poINDFile->Open( pszMetadataFilename, "r+" ) != 0 )
    {
        CPLDestroyXMLNode( psRoot );
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to open index file %s.", 
                  pszMIINDFilename );
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Process each attrindex.                                         */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psAttrIndex;

    for( psAttrIndex = psRoot->psChild; 
         psAttrIndex != NULL; 
         psAttrIndex = psAttrIndex->psNext )
    {
        int iField, iIndexIndex;

        if( psAttrIndex->eType != CXT_Element 
            || !EQUAL(psAttrIndex->pszValue,"OGRMIAttrIndex") )
            continue;

        iField = atoi(CPLGetXMLValue(psAttrIndex,"FieldIndex","-1"));
        iIndexIndex = atoi(CPLGetXMLValue(psAttrIndex,"IndexIndex","-1"));

        if( iField == -1 || iIndexIndex == -1 )
        {
            CPLError( CE_Warning, CPLE_AppDefined, 
                      "Skipping corrupt OGRMIAttrIndex entry." );
            continue;
        }

        AddAttrInd( iField, iIndexIndex );
    }

    CPLDestroyXMLNode( psRoot );

    CPLDebug( "OGR", "Restored %d field indexes for layer %s from %s on %s.",
              nIndexCount, poLayer->GetLayerDefn()->GetName(), 
              pszMetadataFilename, pszMIINDFilename );

    return OGRERR_NONE;
}
Exemple #28
0
static void CSVDeaccessInternal( CSVTable **ppsCSVTableList, int bCanUseTLS, const char * pszFilename )

{
    CSVTable    *psLast, *psTable;
    
    if( ppsCSVTableList == NULL )
        return;
    
/* -------------------------------------------------------------------- */
/*      A NULL means deaccess all tables.                               */
/* -------------------------------------------------------------------- */
    if( pszFilename == NULL )
    {
        while( *ppsCSVTableList != NULL )
            CSVDeaccessInternal( ppsCSVTableList, bCanUseTLS, (*ppsCSVTableList)->pszFilename );
        
        return;
    }

/* -------------------------------------------------------------------- */
/*      Find this table.                                                */
/* -------------------------------------------------------------------- */
    psLast = NULL;
    for( psTable = *ppsCSVTableList;
         psTable != NULL && !EQUAL(psTable->pszFilename,pszFilename);
         psTable = psTable->psNext )
    {
        psLast = psTable;
    }

    if( psTable == NULL )
    {
        if (bCanUseTLS)
            CPLDebug( "CPL_CSV", "CPLDeaccess( %s ) - no match.", pszFilename );
        return;
    }

/* -------------------------------------------------------------------- */
/*      Remove the link from the list.                                  */
/* -------------------------------------------------------------------- */
    if( psLast != NULL )
        psLast->psNext = psTable->psNext;
    else
        *ppsCSVTableList = psTable->psNext;

/* -------------------------------------------------------------------- */
/*      Free the table.                                                 */
/* -------------------------------------------------------------------- */
    if( psTable->fp != NULL )
        VSIFClose( psTable->fp );

    CSLDestroy( psTable->papszFieldNames );
    CSLDestroy( psTable->papszRecFields );
    CPLFree( psTable->pszFilename );
    CPLFree( psTable->panLineIndex );
    CPLFree( psTable->pszRawData );
    CPLFree( psTable->papszLines );

    CPLFree( psTable );

    if (bCanUseTLS)
        CPLReadLine( NULL );
}
Exemple #29
0
DGNHandle DGNOpen( const char * pszFilename, int bUpdate )

{
    DGNInfo     *psDGN;
    FILE        *fp;

/* -------------------------------------------------------------------- */
/*      Open the file.                                                  */
/* -------------------------------------------------------------------- */
    if( bUpdate )
        fp = VSIFOpen( pszFilename, "rb+" );
    else
        fp = VSIFOpen( pszFilename, "rb" );
    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Unable to open `%s' for read access.\n", 
                  pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Verify the format ... add later.                                */
/* -------------------------------------------------------------------- */
    GByte       abyHeader[512];

    VSIFRead( abyHeader, 1, sizeof(abyHeader), fp );
    if( !DGNTestOpen( abyHeader, sizeof(abyHeader) ) )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "File `%s' does not have expected DGN header.\n", 
                  pszFilename );
        VSIFClose( fp );
        return NULL;
    }

    VSIRewind( fp );

/* -------------------------------------------------------------------- */
/*      Create the info structure.                                      */
/* -------------------------------------------------------------------- */
    psDGN = (DGNInfo *) CPLCalloc(sizeof(DGNInfo),1);
    psDGN->fp = fp;
    psDGN->next_element_id = 0;

    psDGN->got_tcb = FALSE;
    psDGN->scale = 1.0;
    psDGN->origin_x = 0.0;
    psDGN->origin_y = 0.0;
    psDGN->origin_z = 0.0;                                             

    psDGN->index_built = FALSE;
    psDGN->element_count = 0;
    psDGN->element_index = NULL;

    psDGN->got_bounds = FALSE;

    if( abyHeader[0] == 0xC8 )
        psDGN->dimension = 3;
    else
        psDGN->dimension = 2;

    psDGN->has_spatial_filter = FALSE;
    psDGN->sf_converted_to_uor = FALSE;
    psDGN->select_complex_group = FALSE;
    psDGN->in_complex_group = FALSE;

    return (DGNHandle) psDGN;
}
/*!
  \brief Open VFK datasource

  \param pszNewName datasource name
  \param bTextOpen True to test if datasource is possible to open

  \return TRUE on success
  \return FALSE on failure
*/
int OGRVFKDataSource::Open(const char *pszNewName, int bTestOpen)
{
    FILE * fp;
    char   szHeader[1000];
    
    /* open the source file */
    fp = VSIFOpen(pszNewName, "r");
    if (fp == NULL) {
        if (!bTestOpen)
            CPLError(CE_Failure, CPLE_OpenFailed, 
		     "Failed to open VFK file `%s'.",
		     pszNewName);
	
        return FALSE;
    }

   /* If we aren't sure it is VFK, load a header chunk and check    
      for signs it is VFK */
    if (bTestOpen) {
	size_t nRead = VSIFRead(szHeader, 1, sizeof(szHeader), fp);
	if (nRead <= 0) {
            VSIFClose(fp);
            return FALSE;
        }
        szHeader[MIN(nRead, sizeof(szHeader))-1] = '\0';
	
	// TODO: improve check
	if (strncmp(szHeader, "&HVERZE;", 8) != 0) {
	    VSIFClose(fp);
            return FALSE;
	} 
    }

    /* We assume now that it is VFK. Close and instantiate a
       VFKReader on it. */
    VSIFClose(fp);

    pszName = CPLStrdup(pszNewName);
    
    poReader = CreateVFKReader();
    if (poReader == NULL) {
        CPLError(CE_Failure, CPLE_AppDefined, 
		 "File %s appears to be VFK but the VFK reader can't"
		 "be instantiated.",
		 pszNewName );
        return FALSE;
    }
    /* load data (whole file) */
    poReader->SetSourceFile(pszNewName);
    poReader->LoadData();

    /* get data blocks, i.e. &B */
    poReader->LoadDataBlocks();
    /* collect geometry properties
       load on first request
    */
    /* poReader->LoadGeometry(); */
    
    /* get list of layers */
    papoLayers = (OGRVFKLayer **) CPLCalloc(sizeof(OGRVFKLayer *), poReader->GetDataBlockCount());
    
    for (int iLayer = 0; iLayer < poReader->GetDataBlockCount(); iLayer++) {
        papoLayers[iLayer] = CreateLayer(poReader->GetDataBlock(iLayer));
	nLayers++;
    }
    
    return TRUE;
}