int OGRS57DataSource::Create( const char *pszFilename, char **papszOptions )

{
/* -------------------------------------------------------------------- */
/*      Instantiate the class registrar if possible.                    */
/* -------------------------------------------------------------------- */
    if( OGRS57Driver::GetS57Registrar() == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Unable to load s57objectclasses.csv, unable to continue." );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Create the S-57 file with definition record.                    */
/* -------------------------------------------------------------------- */
    poWriter = new S57Writer();

    if( !poWriter->CreateS57File( pszFilename ) )
        return FALSE;

    poWriter->SetClassBased( OGRS57Driver::GetS57Registrar() );
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Add the primitive layers if they are called for.                */
/* -------------------------------------------------------------------- */
    OGRFeatureDefn  *poDefn;
    int nOptionFlags = S57M_RETURN_LINKAGES | S57M_LNAM_REFS;

    poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VI, nOptionFlags );
    AddLayer( new OGRS57Layer( this, poDefn ) );
    
    poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VC, nOptionFlags );
    AddLayer( new OGRS57Layer( this, poDefn ) );
    
    poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VE, nOptionFlags );
    AddLayer( new OGRS57Layer( this, poDefn ) );
    
    poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VF, nOptionFlags );
    AddLayer( new OGRS57Layer( this, poDefn ) );

/* -------------------------------------------------------------------- */
/*      Initialize a feature definition for each object class.          */
/* -------------------------------------------------------------------- */
    for( int iClass = 0; iClass < MAX_CLASSES; iClass++ )
    {
        poDefn = 
            S57GenerateObjectClassDefn( OGRS57Driver::GetS57Registrar(), 
                                        iClass, nOptionFlags );
        
        if( poDefn == NULL )
            continue;

        AddLayer( new OGRS57Layer( this, poDefn, 0, iClass ) );
    }

/* -------------------------------------------------------------------- */
/*      Write out "header" records.                                     */
/* -------------------------------------------------------------------- */
    poWriter->WriteDSID( pszFilename, "20010409", "03.1", 540, "" );

    poWriter->WriteDSPM();


    return TRUE;
}
int OGRS57DataSource::Open( const char * pszFilename, int bTestOpen )

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

        fp = VSIFOpenL( pszFilename, "rb" );
        if( fp == NULL )
            return FALSE;
        
        if( VSIFReadL( pachLeader, 1, 10, fp ) != 10
            || (pachLeader[5] != '1' && pachLeader[5] != '2'
                && pachLeader[5] != '3' )
            || pachLeader[6] != 'L'
            || (pachLeader[8] != '1' && pachLeader[8] != ' ') )
        {
            VSIFCloseL( fp );
            return FALSE;
        }

        VSIFCloseL( fp );
    }

/* -------------------------------------------------------------------- */
/*      Setup reader options.                                           */
/* -------------------------------------------------------------------- */
    char **papszReaderOptions = NULL;
    S57Reader   *poModule;

    poModule = new S57Reader( pszFilename );

    papszReaderOptions = CSLSetNameValue(papszReaderOptions, 
                                         S57O_LNAM_REFS, "ON" );
    if( GetOption(S57O_UPDATES) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_UPDATES, 
                             GetOption(S57O_UPDATES));
                                              
    if( GetOption(S57O_SPLIT_MULTIPOINT) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_SPLIT_MULTIPOINT,
                             GetOption(S57O_SPLIT_MULTIPOINT) );
                                              
    if( GetOption(S57O_ADD_SOUNDG_DEPTH) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_ADD_SOUNDG_DEPTH,
                             GetOption(S57O_ADD_SOUNDG_DEPTH));
                                              
    if( GetOption(S57O_PRESERVE_EMPTY_NUMBERS) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_PRESERVE_EMPTY_NUMBERS,
                             GetOption(S57O_PRESERVE_EMPTY_NUMBERS) );
                                              
    if( GetOption(S57O_RETURN_PRIMITIVES) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_RETURN_PRIMITIVES,
                             GetOption(S57O_RETURN_PRIMITIVES) );
                                              
    if( GetOption(S57O_RETURN_LINKAGES) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_RETURN_LINKAGES,
                             GetOption(S57O_RETURN_LINKAGES) );
                                              
    if( GetOption(S57O_RETURN_DSID) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_RETURN_DSID,
                             GetOption(S57O_RETURN_DSID) );
                                              
    poModule->SetOptions( papszReaderOptions );
    CSLDestroy( papszReaderOptions );

/* -------------------------------------------------------------------- */
/*      Try opening.                                                    */
/*                                                                      */
/*      Eventually this should check for catalogs, and if found         */
/*      instantiate a whole series of modules.                          */
/* -------------------------------------------------------------------- */
    if( !poModule->Open( bTestOpen ) )
    {
        delete poModule;

        return FALSE;
    }

    int bSuccess = TRUE;

    nModules = 1;
    papoModules = (S57Reader **) CPLMalloc(sizeof(void*));
    papoModules[0] = poModule;
    
/* -------------------------------------------------------------------- */
/*      Add the header layers if they are called for.                   */
/* -------------------------------------------------------------------- */
    if( GetOption( S57O_RETURN_DSID ) == NULL 
        || CSLTestBoolean(GetOption( S57O_RETURN_DSID )) )
    {
        OGRFeatureDefn  *poDefn;

        poDefn = S57GenerateDSIDFeatureDefn();
        AddLayer( new OGRS57Layer( this, poDefn ) );
    }

/* -------------------------------------------------------------------- */
/*      Add the primitive layers if they are called for.                */
/* -------------------------------------------------------------------- */
    if( GetOption( S57O_RETURN_PRIMITIVES ) != NULL )
    {
        OGRFeatureDefn  *poDefn;

        poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VI, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VC, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VE, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VF, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );
    }

/* -------------------------------------------------------------------- */
/*      Initialize a layer for each type of geometry.  Eventually       */
/*      we will do this by object class.                                */
/* -------------------------------------------------------------------- */
    if( OGRS57Driver::GetS57Registrar() == NULL )
    {
        OGRFeatureDefn  *poDefn;

        poDefn = S57GenerateGeomFeatureDefn( wkbPoint, 
                                             poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );
    
        poDefn = S57GenerateGeomFeatureDefn( wkbLineString, 
                                             poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );
    
        poDefn = S57GenerateGeomFeatureDefn( wkbPolygon, 
                                             poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );
    
        poDefn = S57GenerateGeomFeatureDefn( wkbNone, 
                                             poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );
    }

/* -------------------------------------------------------------------- */
/*      Initialize a feature definition for each class that actually    */
/*      occurs in the dataset.                                          */
/* -------------------------------------------------------------------- */
    else
    {
        OGRFeatureDefn  *poDefn;
        int             *panClassCount;
        int             iClass, bGeneric = FALSE;

        for( iModule = 0; iModule < nModules; iModule++ )
            papoModules[iModule]->SetClassBased( OGRS57Driver::GetS57Registrar() );
        
        panClassCount = (int *) CPLCalloc(sizeof(int),MAX_CLASSES);

        for( iModule = 0; iModule < nModules; iModule++ )
        {
            bSuccess &= 
                papoModules[iModule]->CollectClassList(panClassCount,
                                                       MAX_CLASSES);
        }

        for( iClass = 0; iClass < MAX_CLASSES; iClass++ )
        {
            if( panClassCount[iClass] > 0 )
            {
                poDefn = 
                    S57GenerateObjectClassDefn( OGRS57Driver::GetS57Registrar(), 
                                                iClass, 
                                                poModule->GetOptionFlags() );

                if( poDefn != NULL )
                    AddLayer( new OGRS57Layer( this, poDefn, 
                                               panClassCount[iClass] ) );
                else
                {
                    bGeneric = TRUE;
                    CPLDebug( "S57", 
                              "Unable to find definition for OBJL=%d\n", 
                              iClass );
                }
            }
        }

        if( bGeneric )
        {
            poDefn = S57GenerateGeomFeatureDefn( wkbUnknown, 
                                                 poModule->GetOptionFlags() );
            AddLayer( new OGRS57Layer( this, poDefn ) );
        }
            
        CPLFree( panClassCount );
    }

/* -------------------------------------------------------------------- */
/*      Attach the layer definitions to each of the readers.            */
/* -------------------------------------------------------------------- */
    for( iModule = 0; iModule < nModules; iModule++ )
    {
        for( int iLayer = 0; iLayer < nLayers; iLayer++ )
        {
            papoModules[iModule]->AddFeatureDefn(
                papoLayers[iLayer]->GetLayerDefn() );
        }
    }
    
    return bSuccess;
}
Exemplo n.º 3
0
int OGRS57DataSource::Create( const char *pszFilename,
                              char **papszOptionsIn )
{
/* -------------------------------------------------------------------- */
/*      Instantiate the class registrar if possible.                    */
/* -------------------------------------------------------------------- */
    if( OGRS57Driver::GetS57Registrar() == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unable to load s57objectclasses.csv.  Unable to continue." );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Create the S-57 file with definition record.                    */
/* -------------------------------------------------------------------- */
    poWriter = new S57Writer();

    if( !poWriter->CreateS57File( pszFilename ) )
        return FALSE;

    poClassContentExplorer =
        new S57ClassContentExplorer( OGRS57Driver::GetS57Registrar() );

    poWriter->SetClassBased( OGRS57Driver::GetS57Registrar(),
                             poClassContentExplorer );
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Add the primitive layers if they are called for.                */
/* -------------------------------------------------------------------- */
    int nOptionFlags = S57M_RETURN_LINKAGES | S57M_LNAM_REFS;

    OGRFeatureDefn *poDefn
        = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VI, nOptionFlags );
    AddLayer( new OGRS57Layer( this, poDefn ) );

    poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VC, nOptionFlags );
    AddLayer( new OGRS57Layer( this, poDefn ) );

    poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VE, nOptionFlags );
    AddLayer( new OGRS57Layer( this, poDefn ) );

    poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VF, nOptionFlags );
    AddLayer( new OGRS57Layer( this, poDefn ) );

/* -------------------------------------------------------------------- */
/*      Initialize a feature definition for each object class.          */
/* -------------------------------------------------------------------- */
    poClassContentExplorer->Rewind();
    while( poClassContentExplorer->NextClass() )
    {
        poDefn =
            S57GenerateObjectClassDefn( OGRS57Driver::GetS57Registrar(),
                                        poClassContentExplorer,
                                        poClassContentExplorer->GetOBJL(),
                                        nOptionFlags );

        AddLayer( new OGRS57Layer( this, poDefn, 0,
                                   poClassContentExplorer->GetOBJL() ) );
    }

/* -------------------------------------------------------------------- */
/*      Write out "header" records.                                     */
/* -------------------------------------------------------------------- */
    int nEXPP = 1;
    int nINTU = 4;
    int nAGEN = 540;
    int nNOMR = 0;
    int nNOGR = 0;
    int nNOLR = 0;
    int nNOIN = 0;
    int nNOCN = 0;
    int nNOED = 0;
    const char *pszEXPP = CSLFetchNameValue( papszOptionsIn, "S57_EXPP" );
    const char *pszINTU = CSLFetchNameValue( papszOptionsIn, "S57_INTU" );
    const char *pszEDTN = CSLFetchNameValue( papszOptionsIn, "S57_EDTN" );
    const char *pszUPDN = CSLFetchNameValue( papszOptionsIn, "S57_UPDN" );
    const char *pszUADT = CSLFetchNameValue( papszOptionsIn, "S57_UADT" );
    const char *pszISDT = CSLFetchNameValue( papszOptionsIn, "S57_ISDT" );
    const char *pszSTED = CSLFetchNameValue( papszOptionsIn, "S57_STED" );
    const char *pszAGEN = CSLFetchNameValue( papszOptionsIn, "S57_AGEN" );
    const char *pszCOMT = CSLFetchNameValue( papszOptionsIn, "S57_COMT" );
    const char *pszNOMR = CSLFetchNameValue( papszOptionsIn, "S57_NOMR" );
    const char *pszNOGR = CSLFetchNameValue( papszOptionsIn, "S57_NOGR" );
    const char *pszNOLR = CSLFetchNameValue( papszOptionsIn, "S57_NOLR" );
    const char *pszNOIN = CSLFetchNameValue( papszOptionsIn, "S57_NOIN" );
    const char *pszNOCN = CSLFetchNameValue( papszOptionsIn, "S57_NOCN" );
    const char *pszNOED = CSLFetchNameValue( papszOptionsIn, "S57_NOED" );
    if (pszEXPP) nEXPP = atoi(pszEXPP);
    if (pszINTU) nINTU = atoi(pszINTU);
    if (pszAGEN) nAGEN = atoi(pszAGEN);
    if (pszNOMR) nNOMR = atoi(pszNOMR);
    if (pszNOGR) nNOGR = atoi(pszNOGR);
    if (pszNOLR) nNOLR = atoi(pszNOLR);
    if (pszNOIN) nNOIN = atoi(pszNOIN);
    if (pszNOCN) nNOCN = atoi(pszNOCN);
    if (pszNOED) nNOED = atoi(pszNOED);
    poWriter->WriteDSID( nEXPP, nINTU, CPLGetFilename( pszFilename ),
                         pszEDTN, pszUPDN, pszUADT, pszISDT, pszSTED, nAGEN,
                         pszCOMT, nNOMR, nNOGR, nNOLR, nNOIN, nNOCN, nNOED );

    int nHDAT = 2;
    int nVDAT = 17;
    int nSDAT = 23;
    int nCSCL = 52000;
    const char *pszHDAT = CSLFetchNameValue( papszOptionsIn, "S57_HDAT" );
    const char *pszVDAT = CSLFetchNameValue( papszOptionsIn, "S57_VDAT" );
    const char *pszSDAT = CSLFetchNameValue( papszOptionsIn, "S57_SDAT" );
    const char *pszCSCL = CSLFetchNameValue( papszOptionsIn, "S57_CSCL" );
    if (pszHDAT)
        nHDAT = atoi(pszHDAT);
    if (pszVDAT)
        nVDAT = atoi(pszVDAT);
    if (pszSDAT)
        nSDAT = atoi(pszSDAT);
    if (pszCSCL)
        nCSCL = atoi(pszCSCL);
    poWriter->WriteDSPM(nHDAT, nVDAT, nSDAT, nCSCL);

    return TRUE;
}
Exemplo n.º 4
0
int main( int nArgc, char ** papszArgv )

{
    char        **papszOptions = NULL;
    int         bReturnPrimitives = FALSE;
    char       *pszDataPath = NULL;
    
    if( nArgc < 2 )
    {
        printf( "Usage: s57dump [-pen] [-split] [-lnam] [-return-prim] [-no-update]\n"
                "               [-return-link] [-data <dirpath>] filename\n" );
        exit( 1 );
    }

/* -------------------------------------------------------------------- */
/*      Process commandline arguments.                                  */
/* -------------------------------------------------------------------- */
    for( int iArg = 1; iArg < nArgc-1; iArg++ )
    {
        if( EQUAL(papszArgv[iArg],"-split") )
            papszOptions =
                CSLSetNameValue( papszOptions, S57O_SPLIT_MULTIPOINT, "ON" );
        else if( EQUAL(papszArgv[iArg],"-data") )
            pszDataPath = papszArgv[++iArg];
        else if( EQUAL(papszArgv[iArg],"-no-update") )
            papszOptions =
                CSLSetNameValue( papszOptions, S57O_UPDATES, "OFF" );
        else if( EQUAL(papszArgv[iArg],"-pen") )
            papszOptions =
                CSLSetNameValue( papszOptions, S57O_PRESERVE_EMPTY_NUMBERS,
                                 "ON" );
        else if( EQUALN(papszArgv[iArg],"-return-prim",12) )
        {
            papszOptions =
                CSLSetNameValue( papszOptions, S57O_RETURN_PRIMITIVES,
                                 "ON" );
            bReturnPrimitives = TRUE;
        }
        else if( EQUALN(papszArgv[iArg],"-lnam",4) )
            papszOptions =
                CSLSetNameValue( papszOptions, S57O_LNAM_REFS, "ON" );
        else if( EQUALN(papszArgv[iArg],"-return-link",12) )
            papszOptions =
                CSLSetNameValue( papszOptions, S57O_RETURN_LINKAGES, "ON" );
    }
    
/* -------------------------------------------------------------------- */
/*      Load the class definitions into the registrar.                  */
/* -------------------------------------------------------------------- */
    S57ClassRegistrar   oRegistrar;
    int                 bRegistrarLoaded;

    bRegistrarLoaded = oRegistrar.LoadInfo( pszDataPath, NULL, TRUE );

    S57ClassContentExplorer *poClassContentExplorer = NULL;
    if (bRegistrarLoaded)
        poClassContentExplorer = new S57ClassContentExplorer(&oRegistrar);
            
/* -------------------------------------------------------------------- */
/*      Get a list of candidate files.                                  */
/* -------------------------------------------------------------------- */
    char        **papszFiles;
    int         iFile;

    papszFiles = S57FileCollector( papszArgv[nArgc-1] );

    for( iFile = 0; papszFiles != NULL && papszFiles[iFile] != NULL; iFile++ )
    {
        printf( "Found: %s\n", papszFiles[iFile] );
    }

    for( iFile = 0; papszFiles != NULL && papszFiles[iFile] != NULL; iFile++ )
    {
        printf( "<------------------------------------------------------------------------->\n" );
        printf( "\nFile: %s\n\n", papszFiles[iFile] );
        
        S57Reader       oReader( papszFiles[iFile] );

        oReader.SetOptions( papszOptions );
        
        int             nOptionFlags = oReader.GetOptionFlags();

        if( !oReader.Open( FALSE ) )
            continue;

        if( bRegistrarLoaded )
        {
            int bGeneric = FALSE;
            std::vector<int> anClassList;
            unsigned int i;
            oReader.CollectClassList(anClassList);

            oReader.SetClassBased( &oRegistrar, poClassContentExplorer );

            printf( "Classes found:\n" );
            for( i = 0; i < anClassList.size(); i++ )
            {
                if( anClassList[i] == 0 )
                    continue;
                
                if( poClassContentExplorer->SelectClass( i ) )
                {
                    printf( "%d: %s/%s\n",
                            i,
                            poClassContentExplorer->GetAcronym(),
                            poClassContentExplorer->GetDescription() );
                    
                    oReader.AddFeatureDefn(
                        S57GenerateObjectClassDefn( &oRegistrar, 
                                                    poClassContentExplorer,
                                                    i, nOptionFlags ) );
                }
                else
                {
                    printf( "%d: unrecognised ... treat as generic.\n", i );
                    bGeneric = TRUE;
                }
            }

            if( bGeneric )
            {
                oReader.AddFeatureDefn(
                    S57GenerateGeomFeatureDefn( wkbUnknown, nOptionFlags ) );
            }
        }
        else
        {
            oReader.AddFeatureDefn(
                S57GenerateGeomFeatureDefn( wkbPoint, nOptionFlags ) );
            oReader.AddFeatureDefn(
                S57GenerateGeomFeatureDefn( wkbLineString, nOptionFlags ) );
            oReader.AddFeatureDefn(
                S57GenerateGeomFeatureDefn( wkbPolygon, nOptionFlags ) );
            oReader.AddFeatureDefn(
                S57GenerateGeomFeatureDefn( wkbNone, nOptionFlags ) );
        }

        if( bReturnPrimitives )
        {
            oReader.AddFeatureDefn( 
                S57GenerateVectorPrimitiveFeatureDefn( RCNM_VI, nOptionFlags));
            oReader.AddFeatureDefn( 
                S57GenerateVectorPrimitiveFeatureDefn( RCNM_VC, nOptionFlags));
            oReader.AddFeatureDefn( 
                S57GenerateVectorPrimitiveFeatureDefn( RCNM_VE, nOptionFlags));
            oReader.AddFeatureDefn( 
                S57GenerateVectorPrimitiveFeatureDefn( RCNM_VF, nOptionFlags));
        }
    
        oReader.AddFeatureDefn( S57GenerateDSIDFeatureDefn() );

        OGRFeature      *poFeature;
        int             nFeatures = 0;
        DDFModule       oUpdate;

        while( (poFeature = oReader.ReadNextFeature()) != NULL )
        {
            poFeature->DumpReadable( stdout );
            nFeatures++;
            delete poFeature;
        }

        printf( "Feature Count: %d\n", nFeatures );
    }

    return 0;
}
Exemplo n.º 5
0
int OGRS57DataSource::Open( const char * pszFilename )

{
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Setup reader options.                                           */
/* -------------------------------------------------------------------- */
    char **papszReaderOptions = NULL;

    if( GetOption(S57O_LNAM_REFS) == NULL )
        papszReaderOptions = CSLSetNameValue( papszReaderOptions,
                                              S57O_LNAM_REFS, "ON" );
    else
        papszReaderOptions =
            CSLSetNameValue( papszReaderOptions, S57O_LNAM_REFS,
                             GetOption(S57O_LNAM_REFS) );

    if( GetOption(S57O_UPDATES) != NULL )
        papszReaderOptions =
            CSLSetNameValue( papszReaderOptions, S57O_UPDATES,
                             GetOption(S57O_UPDATES));

    if( GetOption(S57O_SPLIT_MULTIPOINT) != NULL )
        papszReaderOptions =
            CSLSetNameValue( papszReaderOptions, S57O_SPLIT_MULTIPOINT,
                             GetOption(S57O_SPLIT_MULTIPOINT) );

    if( GetOption(S57O_ADD_SOUNDG_DEPTH) != NULL )
        papszReaderOptions =
            CSLSetNameValue( papszReaderOptions, S57O_ADD_SOUNDG_DEPTH,
                             GetOption(S57O_ADD_SOUNDG_DEPTH));

    if( GetOption(S57O_PRESERVE_EMPTY_NUMBERS) != NULL )
        papszReaderOptions =
            CSLSetNameValue( papszReaderOptions, S57O_PRESERVE_EMPTY_NUMBERS,
                             GetOption(S57O_PRESERVE_EMPTY_NUMBERS) );

    if( GetOption(S57O_RETURN_PRIMITIVES) != NULL )
        papszReaderOptions =
            CSLSetNameValue( papszReaderOptions, S57O_RETURN_PRIMITIVES,
                             GetOption(S57O_RETURN_PRIMITIVES) );

    if( GetOption(S57O_RETURN_LINKAGES) != NULL )
        papszReaderOptions =
            CSLSetNameValue( papszReaderOptions, S57O_RETURN_LINKAGES,
                             GetOption(S57O_RETURN_LINKAGES) );

    if( GetOption(S57O_RETURN_DSID) != NULL )
        papszReaderOptions =
            CSLSetNameValue( papszReaderOptions, S57O_RETURN_DSID,
                             GetOption(S57O_RETURN_DSID) );

    if( GetOption(S57O_RECODE_BY_DSSI) != NULL )
        papszReaderOptions =
            CSLSetNameValue( papszReaderOptions, S57O_RECODE_BY_DSSI,
                             GetOption(S57O_RECODE_BY_DSSI) );

    S57Reader *poModule = new S57Reader( pszFilename );
    int bRet = poModule->SetOptions( papszReaderOptions );
    CSLDestroy( papszReaderOptions );

    if( !bRet )
    {
        delete poModule;
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Try opening.                                                    */
/*                                                                      */
/*      Eventually this should check for catalogs, and if found         */
/*      instantiate a whole series of modules.                          */
/* -------------------------------------------------------------------- */
    if( !poModule->Open( TRUE ) )
    {
        delete poModule;

        return FALSE;
    }

    bool bSuccess = true;

    nModules = 1;
    papoModules = static_cast<S57Reader **>( CPLMalloc(sizeof(void*)) );
    papoModules[0] = poModule;

/* -------------------------------------------------------------------- */
/*      Add the header layers if they are called for.                   */
/* -------------------------------------------------------------------- */
    if( GetOption( S57O_RETURN_DSID ) == NULL
        || CPLTestBool(GetOption( S57O_RETURN_DSID )) )
    {
        OGRFeatureDefn  *poDefn = S57GenerateDSIDFeatureDefn();
        AddLayer( new OGRS57Layer( this, poDefn ) );
    }

/* -------------------------------------------------------------------- */
/*      Add the primitive layers if they are called for.                */
/* -------------------------------------------------------------------- */
    if( GetOption( S57O_RETURN_PRIMITIVES ) != NULL )
    {
        OGRFeatureDefn  *poDefn
            = S57GenerateVectorPrimitiveFeatureDefn(
                RCNM_VI, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateVectorPrimitiveFeatureDefn(
            RCNM_VC, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateVectorPrimitiveFeatureDefn(
            RCNM_VE, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateVectorPrimitiveFeatureDefn(
            RCNM_VF, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );
    }

/* -------------------------------------------------------------------- */
/*      Initialize a layer for each type of geometry.  Eventually       */
/*      we will do this by object class.                                */
/* -------------------------------------------------------------------- */
    if( OGRS57Driver::GetS57Registrar() == NULL )
    {
        OGRFeatureDefn  *poDefn
            = S57GenerateGeomFeatureDefn( wkbPoint,
                                          poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateGeomFeatureDefn( wkbLineString,
                                             poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateGeomFeatureDefn( wkbPolygon,
                                             poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateGeomFeatureDefn( wkbNone,
                                             poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );
    }

/* -------------------------------------------------------------------- */
/*      Initialize a feature definition for each class that actually    */
/*      occurs in the dataset.                                          */
/* -------------------------------------------------------------------- */
    else
    {
        poClassContentExplorer =
            new S57ClassContentExplorer( OGRS57Driver::GetS57Registrar() );

        for( int iModule = 0; iModule < nModules; iModule++ )
            papoModules[iModule]->SetClassBased(
                OGRS57Driver::GetS57Registrar(), poClassContentExplorer );

        std::vector<int> anClassCount;

        for( int iModule = 0; iModule < nModules; iModule++ )
        {
            bSuccess &= CPL_TO_BOOL(
                papoModules[iModule]->CollectClassList(anClassCount) );
        }

        bool bGeneric = false;

        for( unsigned int iClass = 0; iClass < anClassCount.size(); iClass++ )
        {
            if( anClassCount[iClass] > 0 )
            {
                OGRFeatureDefn  *poDefn =
                    S57GenerateObjectClassDefn( OGRS57Driver::GetS57Registrar(),
                                                poClassContentExplorer,
                                                iClass,
                                                poModule->GetOptionFlags() );

                if( poDefn != NULL )
                    AddLayer( new OGRS57Layer( this, poDefn,
                                               anClassCount[iClass] ) );
                else
                {
                    bGeneric = true;
                    CPLDebug( "S57",
                              "Unable to find definition for OBJL=%d\n",
                              iClass );
                }
            }
        }

        if( bGeneric )
        {
            OGRFeatureDefn  *poDefn
                = S57GenerateGeomFeatureDefn( wkbUnknown,
                                              poModule->GetOptionFlags() );
            AddLayer( new OGRS57Layer( this, poDefn ) );
        }
    }

/* -------------------------------------------------------------------- */
/*      Attach the layer definitions to each of the readers.            */
/* -------------------------------------------------------------------- */
    for( int iModule = 0; iModule < nModules; iModule++ )
    {
        for( int iLayer = 0; iLayer < nLayers; iLayer++ )
        {
            papoModules[iModule]->AddFeatureDefn(
                papoLayers[iLayer]->GetLayerDefn() );
        }
    }

    return bSuccess;
}