OGRDataSource *FGdbDriver::Open( const char* pszFilename, int bUpdate ) { // First check if we have to do any work. int nLen = strlen(pszFilename); if(! ((nLen >= 4 && EQUAL(pszFilename + nLen - 4, ".gdb")) || (nLen >= 5 && EQUAL(pszFilename + nLen - 5, ".gdb/"))) ) return NULL; long hr; /* Check that the filename is really a directory, to avoid confusion with */ /* Garmin MapSource - gdb format which can be a problem when the FileGDB */ /* driver is loaded as a plugin, and loaded before the GPSBabel driver */ /* (http://trac.osgeo.org/osgeo4w/ticket/245) */ VSIStatBuf stat; if( CPLStat( pszFilename, &stat ) != 0 || !VSI_ISDIR(stat.st_mode) ) { return NULL; } Geodatabase* pGeoDatabase = NULL; FGdbDatabaseConnection* pConnection = oMapConnections[pszFilename]; if( pConnection != NULL ) { pGeoDatabase = pConnection->m_pGeodatabase; pConnection->m_nRefCount ++; CPLDebug("FileGDB", "ref_count of %s = %d now", pszFilename, pConnection->m_nRefCount); } else { pGeoDatabase = new Geodatabase; hr = ::OpenGeodatabase(StringToWString(pszFilename), *pGeoDatabase); if (FAILED(hr) || pGeoDatabase == NULL) { delete pGeoDatabase; GDBErr(hr, "Failed to open Geodatabase"); return NULL; } CPLDebug("FileGDB", "Really opening %s", pszFilename); oMapConnections[pszFilename] = new FGdbDatabaseConnection(pGeoDatabase); } FGdbDataSource* pDS; pDS = new FGdbDataSource(this); if(!pDS->Open( pGeoDatabase, pszFilename, bUpdate ) ) { delete pDS; return NULL; } else return pDS; }
OGRDataSource* FGdbDriver::CreateDataSource( const char * conn, char **papszOptions) { long hr; Geodatabase *pGeodatabase; std::wstring wconn = StringToWString(conn); int bUpdate = TRUE; // If we're creating, we must be writing. VSIStatBuf stat; /* We don't support options yet, so warn if they send us some */ if ( papszOptions ) { /* TODO: warning, ignoring options */ } /* Only accept names of form "filename.gdb" and */ /* also .gdb.zip to be able to return FGDB with MapServer OGR output (#4199) */ const char* pszExt = CPLGetExtension(conn); if ( !(EQUAL(pszExt,"gdb") || EQUAL(pszExt, "zip")) ) { CPLError( CE_Failure, CPLE_AppDefined, "FGDB data source name must use 'gdb' extension.\n" ); return NULL; } /* Don't try to create on top of something already there */ if( CPLStat( conn, &stat ) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "%s already exists.\n", conn ); return NULL; } /* Try to create the geodatabase */ pGeodatabase = new Geodatabase; // Create on heap so we can store it in the Datasource hr = CreateGeodatabase(wconn, *pGeodatabase); /* Handle creation errors */ if ( S_OK != hr ) { const char *errstr = "Error creating geodatabase (%s).\n"; if ( hr == -2147220653 ) errstr = "File already exists (%s).\n"; delete pGeodatabase; CPLError( CE_Failure, CPLE_AppDefined, errstr, conn ); return NULL; } oMapConnections[conn] = new FGdbDatabaseConnection(pGeodatabase); /* Ready to embed the Geodatabase in an OGR Datasource */ FGdbDataSource* pDS = new FGdbDataSource(this); if ( ! pDS->Open(pGeodatabase, conn, bUpdate) ) { delete pDS; return NULL; } else return pDS; }
int OGRTigerDataSource::Create( const char *pszNameIn, char **papszOptions ) { VSIStatBuf stat; /* -------------------------------------------------------------------- */ /* Try to create directory if it doesn't already exist. */ /* -------------------------------------------------------------------- */ if( CPLStat( pszNameIn, &stat ) != 0 ) { VSIMkdir( pszNameIn, 0755 ); } if( CPLStat( pszNameIn, &stat ) != 0 || !VSI_ISDIR(stat.st_mode) ) { CPLError( CE_Failure, CPLE_AppDefined, "%s is not a directory, nor can be directly created as one.", pszName ); return FALSE; } /* -------------------------------------------------------------------- */ /* Store various information. */ /* -------------------------------------------------------------------- */ pszPath = CPLStrdup( pszNameIn ); pszName = CPLStrdup( pszNameIn ); bWriteMode = TRUE; SetOptionList( papszOptions ); /* -------------------------------------------------------------------- */ /* Work out the version. */ /* -------------------------------------------------------------------- */ // nVersionCode = 1000; /* census 2000 */ nVersionCode = 1002; /* census 2002 */ if( GetOption("VERSION") != NULL ) { nVersionCode = atoi(GetOption("VERSION")); nVersionCode = MAX(0,MIN(9999,nVersionCode)); } nVersion = TigerClassifyVersion(nVersionCode); return TRUE; }
int OGRGeoconceptDataSource::Open( const char* pszName, int bTestOpen, int bUpdate ) { VSIStatBuf stat; /* -------------------------------------------------------------------- */ /* Is the given path a directory or a regular file? */ /* -------------------------------------------------------------------- */ if( CPLStat( pszName, &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, Geoconcept access failed.", pszName ); } return FALSE; } if( VSI_ISDIR(stat.st_mode) ) { CPLDebug( "GEOCONCEPT", "%s is a directory, Geoconcept access is not yet supported.", pszName ); return FALSE; } if( VSI_ISREG(stat.st_mode) ) { _bSingleNewFile= FALSE; _bUpdate= bUpdate; _pszName= CPLStrdup( pszName ); if( !LoadFile( _bUpdate? "a+t":"rt" ) ) { CPLDebug( "GEOCONCEPT", "Failed to open Geoconcept %s." " It may be corrupt.", pszName ); return FALSE; } return TRUE; } return _nLayers > 0; }
void *DTEDCreatePtStream( const char *pszPath, int nLevel ) { DTEDPtStream *psStream; int i; VSIStatBuf sStat; /* -------------------------------------------------------------------- */ /* Does the target directory already exist? If not try to */ /* create it. */ /* -------------------------------------------------------------------- */ if( CPLStat( pszPath, &sStat ) != 0 ) { if( VSIMkdir( pszPath, 0755 ) != 0 ) { #ifndef AVOID_CPL CPLError( CE_Failure, CPLE_OpenFailed, "Unable to find, or create directory `%s'.", pszPath ); #endif return NULL; } } /* -------------------------------------------------------------------- */ /* Create the stream and initialize it. */ /* -------------------------------------------------------------------- */ psStream = (DTEDPtStream *) CPLCalloc( sizeof(DTEDPtStream), 1 ); psStream->nLevel = nLevel; psStream->pszPath = CPLStrdup( pszPath ); psStream->nOpenFiles = 0; psStream->pasCF = NULL; psStream->nLastFile = -1; for( i = 0; i < DTEDMD_MAX+1; i++ ) psStream->apszMetadata[i] = NULL; if( nLevel == 0 ) psStream->dfPixelSize = 1.0 / 120.0; else if( nLevel == 1 ) psStream->dfPixelSize = 1.0 / 1200.0; else if( nLevel == 2 ) psStream->dfPixelSize = 1.0 / 3600.0; else psStream->dfPixelSize = 1.0 / 3600.0; return (void *) psStream; }
int OGRGRASSDataSource::Open( const char * pszNewName, int /*bUpdate*/, int bTestOpen, int /*bSingleNewFileIn*/ ) { VSIStatBuf stat; CPLAssert( nLayers == 0 ); pszName = CPLStrdup( pszNewName ); // Released by destructor /* -------------------------------------------------------------------- */ /* Do the given path contains 'vector' and 'head'? */ /* -------------------------------------------------------------------- */ if ( strstr(pszName,"vector") == NULL || strstr(pszName,"head") == NULL ) { if( !bTestOpen ) { CPLError( CE_Failure, CPLE_AppDefined, "%s is not GRASS vector, access failed.\n", pszName ); } return FALSE; } /* -------------------------------------------------------------------- */ /* Is the given a regular file? */ /* -------------------------------------------------------------------- */ if( CPLStat( pszName, &stat ) != 0 || !VSI_ISREG(stat.st_mode) ) { if( !bTestOpen ) { CPLError( CE_Failure, CPLE_AppDefined, "%s is not GRASS vector, access failed.\n", pszName ); } return FALSE; } /* -------------------------------------------------------------------- */ /* Parse datasource name */ /* -------------------------------------------------------------------- */ if ( !SplitPath(pszName, &pszGisdbase, &pszLocation, &pszMapset, &pszMap) ) { if( !bTestOpen ) { CPLError( CE_Failure, CPLE_AppDefined, "%s is not GRASS datasource name, access failed.\n", pszName ); } return FALSE; } CPLDebug ( "GRASS", "Gisdbase: %s", pszGisdbase ); CPLDebug ( "GRASS", "Location: %s", pszLocation ); CPLDebug ( "GRASS", "Mapset: %s", pszMapset ); CPLDebug ( "GRASS", "Map: %s", pszMap ); /* -------------------------------------------------------------------- */ /* Init GRASS library */ /* -------------------------------------------------------------------- */ // GISBASE is path to the directory where GRASS is installed, // it is necessary because there are database drivers. if ( !getenv( "GISBASE" ) ) { static char* gisbaseEnv = NULL; const char *gisbase = GRASS_GISBASE; CPLError( CE_Warning, CPLE_AppDefined, "GRASS warning: GISBASE " "environment variable was not set, using:\n%s", gisbase ); char buf[2000]; snprintf ( buf, sizeof(buf), "GISBASE=%s", gisbase ); buf[sizeof(buf)-1] = '\0'; CPLFree(gisbaseEnv); gisbaseEnv = CPLStrdup ( buf ); putenv( gisbaseEnv ); } // Don't use GISRC file and read/write GRASS variables // (from location G_VAR_GISRC) to memory only. G_set_gisrc_mode ( G_GISRC_MODE_MEMORY ); // Init GRASS libraries (required). G_no_gisinit() doesn't check // write permissions for mapset compare to G_gisinit() G_no_gisinit(); // Set error function G_set_error_routine ( (GrassErrorHandler) Grass2OGRErrorHook ); /* -------------------------------------------------------------------- */ /* Set GRASS variables */ /* -------------------------------------------------------------------- */ G__setenv( "GISDBASE", pszGisdbase ); G__setenv( "LOCATION_NAME", pszLocation ); G__setenv( "MAPSET", pszMapset); G_reset_mapsets(); G_add_mapset_to_search_path ( pszMapset ); /* -------------------------------------------------------------------- */ /* Open GRASS vector map */ /* -------------------------------------------------------------------- */ #if GRASS_VERSION_MAJOR < 7 Vect_set_fatal_error ( GV_FATAL_PRINT ); // Print error and continue #endif Vect_set_open_level (2); int level = Vect_open_old ( &map, pszMap, pszMapset); if ( level < 2 ) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot open GRASS vector %s on level 2.\n", pszName ); return FALSE; } CPLDebug ( "GRASS", "Num lines = %d", Vect_get_num_lines(&map) ); /* -------------------------------------------------------------------- */ /* Build a list of layers. */ /* -------------------------------------------------------------------- */ int ncidx = Vect_cidx_get_num_fields ( &map ); CPLDebug ( "GRASS", "Num layers = %d", ncidx ); for ( int i = 0; i < ncidx; i++ ) { // Create the layer object OGRGRASSLayer *poLayer = new OGRGRASSLayer( i, &map ); // Add layer to data source layer list papoLayers = (OGRGRASSLayer **) CPLRealloc( papoLayers, sizeof(OGRGRASSLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; } bOpened = TRUE; return TRUE; }
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; }
OGRDataSource *OGRGeoconceptDriver::CreateDataSource( const char* pszName, char** papszOptions ) { VSIStatBuf stat; int bSingleNewFile = FALSE; if( pszName==NULL || strlen(pszName)==0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid datasource name (null or empty)"); return NULL; } /* -------------------------------------------------------------------- */ /* Is the target a valid existing directory? */ /* -------------------------------------------------------------------- */ if( CPLStat( pszName, &stat ) == 0 ) { if( !VSI_ISDIR(stat.st_mode) ) { CPLError( CE_Failure, CPLE_AppDefined, "%s is not a valid existing directory.", pszName ); return NULL; } } /* -------------------------------------------------------------------- */ /* Does it end with the extension .gxt indicating the user likely */ /* wants to create a single file set? */ /* -------------------------------------------------------------------- */ else if( EQUAL(CPLGetExtension(pszName),"gxt") || EQUAL(CPLGetExtension(pszName),"txt") ) { bSingleNewFile = TRUE; } /* -------------------------------------------------------------------- */ /* Otherwise try to create a new directory. */ /* -------------------------------------------------------------------- */ else { VSIStatBuf sStat; if( VSIStat( pszName, &sStat ) == 0 ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create datasource named %s, " "but that is an existing directory.", pszName ); return NULL; } } /* -------------------------------------------------------------------- */ /* Return a new OGRDataSource() */ /* -------------------------------------------------------------------- */ OGRGeoconceptDataSource *poDS = NULL; poDS = new OGRGeoconceptDataSource(); if( !poDS->Create( pszName, papszOptions ) ) { delete poDS; return NULL; } return poDS; }
int OGRGeoPackageDataSource::Open(const char * pszFilename, int bUpdate ) { int i; OGRErr err; CPLAssert( m_nLayers == 0 ); CPLAssert( m_poDb == NULL ); CPLAssert( m_pszFileName == NULL ); m_bUpdate = bUpdate; /* Requirement 3: File name has to end in "gpkg" */ /* http://opengis.github.io/geopackage/#_file_extension_name */ int nLen = strlen(pszFilename); if(! (nLen >= 5 && EQUAL(pszFilename + nLen - 5, ".gpkg")) ) return FALSE; /* Check that the filename exists and is a file */ VSIStatBuf stat; if( CPLStat( pszFilename, &stat ) != 0 || !VSI_ISREG(stat.st_mode) ) return FALSE; /* Requirement 2: A GeoPackage SHALL contain 0x47503130 ("GP10" in ASCII) */ /* in the application id */ /* http://opengis.github.io/geopackage/#_file_format */ if ( ! CheckApplicationId(pszFilename) ) { CPLError( CE_Failure, CPLE_AppDefined, "bad application_id on '%s'", pszFilename); return FALSE; } /* See if we can open the SQLite database */ int rc = sqlite3_open( pszFilename, &m_poDb ); if ( rc != SQLITE_OK ) { m_poDb = NULL; CPLError( CE_Failure, CPLE_OpenFailed, "sqlite3_open(%s) failed: %s", pszFilename, sqlite3_errmsg( m_poDb ) ); return FALSE; } /* Filename is good, store it for future reference */ m_pszFileName = CPLStrdup( pszFilename ); /* Requirement 6: The SQLite PRAGMA integrity_check SQL command SHALL return “ok” */ /* http://opengis.github.io/geopackage/#_file_integrity */ if ( OGRERR_NONE != PragmaCheck("integrity_check", "ok", 1) ) { CPLError( CE_Failure, CPLE_AppDefined, "pragma integrity_check on '%s' failed", pszFilename); return FALSE; } /* Requirement 7: The SQLite PRAGMA foreign_key_check() SQL with no */ /* parameter value SHALL return an empty result set */ /* http://opengis.github.io/geopackage/#_file_integrity */ if ( OGRERR_NONE != PragmaCheck("foreign_key_check", "", 0) ) { CPLError( CE_Failure, CPLE_AppDefined, "pragma foreign_key_check on '%s' failed", pszFilename); return FALSE; } /* OGR UTF-8 capability, we'll advertise UTF-8 support if we have it */ if ( OGRERR_NONE == PragmaCheck("encoding", "UTF-8", 1) ) { m_bUtf8 = TRUE; } else { m_bUtf8 = FALSE; } /* Check for requirement metadata tables */ /* Requirement 10: gpkg_spatial_ref_sys must exist */ /* Requirement 13: gpkg_contents must exist */ /* Requirement 21: gpkg_geometry_columns must exist */ static std::string aosGpkgTables[] = { "gpkg_geometry_columns", "gpkg_spatial_ref_sys", "gpkg_contents" }; for ( i = 0; i < 3; i++ ) { SQLResult oResult; char *pszSQL = sqlite3_mprintf("pragma table_info('%s')", aosGpkgTables[i].c_str()); err = SQLQuery(m_poDb, pszSQL, &oResult); sqlite3_free(pszSQL); if ( err != OGRERR_NONE ) return FALSE; if ( oResult.nRowCount <= 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "required GeoPackage table '%s' is missing", aosGpkgTables[i].c_str()); SQLResultFree(&oResult); return FALSE; } SQLResultFree(&oResult); } /* Load layer definitions for all tables in gpkg_contents & gpkg_geometry_columns */ SQLResult oResult; std::string osSQL = "SELECT c.table_name, c.identifier, c.min_x, c.min_y, c.max_x, c.max_y " "FROM gpkg_geometry_columns g JOIN gpkg_contents c ON (g.table_name = c.table_name)" "WHERE c.data_type = 'features'"; err = SQLQuery(m_poDb, osSQL.c_str(), &oResult); if ( err != OGRERR_NONE ) { SQLResultFree(&oResult); return FALSE; } if ( oResult.nRowCount > 0 ) { m_papoLayers = (OGRLayer**)CPLMalloc(sizeof(OGRGeoPackageLayer*) * oResult.nRowCount); for ( i = 0; i < oResult.nRowCount; i++ ) { const char *pszTableName = SQLResultGetValue(&oResult, 0, i); if ( ! pszTableName ) { CPLError(CE_Warning, CPLE_AppDefined, "unable to read table name for layer(%d)", i); continue; } OGRGeoPackageLayer *poLayer = new OGRGeoPackageLayer(this, pszTableName); if( OGRERR_NONE != poLayer->ReadTableDefinition() ) { delete poLayer; CPLError(CE_Warning, CPLE_AppDefined, "unable to read table definition for '%s'", pszTableName); continue; } m_papoLayers[m_nLayers++] = poLayer; } } SQLResultFree(&oResult); 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; }
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; }
OGRDataSource *OGRShapeDriver::CreateDataSource( const char * pszName, CPL_UNUSED char **papszOptions ) { VSIStatBuf stat; int bSingleNewFile = FALSE; /* -------------------------------------------------------------------- */ /* Is the target a valid existing directory? */ /* -------------------------------------------------------------------- */ if( CPLStat( pszName, &stat ) == 0 ) { if( !VSI_ISDIR(stat.st_mode) ) { CPLError( CE_Failure, CPLE_AppDefined, "%s is not a directory.\n", pszName ); return NULL; } } /* -------------------------------------------------------------------- */ /* Does it end in the extension .shp indicating the user likely */ /* wants to create a single file set? */ /* -------------------------------------------------------------------- */ else if( EQUAL(CPLGetExtension(pszName),"shp") || EQUAL(CPLGetExtension(pszName),"dbf") ) { bSingleNewFile = TRUE; } /* -------------------------------------------------------------------- */ /* Otherwise try to create a new directory. */ /* -------------------------------------------------------------------- */ else { if( VSIMkdir( pszName, 0755 ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to create directory %s\n" "for shapefile datastore.\n", pszName ); return NULL; } } /* -------------------------------------------------------------------- */ /* Return a new OGRDataSource() */ /* -------------------------------------------------------------------- */ OGRShapeDataSource *poDS = NULL; poDS = new OGRShapeDataSource(); if( !poDS->Open( pszName, TRUE, FALSE, bSingleNewFile ) ) { delete poDS; return NULL; } else return poDS; }
OGRDataSource *FGdbDriver::Open( const char* pszFilename, int bUpdate ) { // First check if we have to do any work. size_t nLen = strlen(pszFilename); if(! ((nLen >= 4 && EQUAL(pszFilename + nLen - 4, ".gdb")) || (nLen >= 5 && EQUAL(pszFilename + nLen - 5, ".gdb/"))) ) return NULL; long hr; /* Check that the filename is really a directory, to avoid confusion with */ /* Garmin MapSource - gdb format which can be a problem when the FileGDB */ /* driver is loaded as a plugin, and loaded before the GPSBabel driver */ /* (http://trac.osgeo.org/osgeo4w/ticket/245) */ VSIStatBuf stat; if( CPLStat( pszFilename, &stat ) != 0 || !VSI_ISDIR(stat.st_mode) ) { return NULL; } CPLMutexHolderD(&hMutex); FGdbDatabaseConnection* pConnection = oMapConnections[pszFilename]; if( pConnection != NULL ) { if( pConnection->IsFIDHackInProgress() ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open geodatabase at the moment since it is in 'FID hack mode'"); return NULL; } pConnection->m_nRefCount ++; CPLDebug("FileGDB", "ref_count of %s = %d now", pszFilename, pConnection->m_nRefCount); } else { Geodatabase* pGeoDatabase = new Geodatabase; hr = ::OpenGeodatabase(StringToWString(pszFilename), *pGeoDatabase); if (FAILED(hr)) { delete pGeoDatabase; if( OGRGetDriverByName("OpenFileGDB") != NULL && bUpdate == FALSE ) { std::wstring fgdb_error_desc_w; std::string fgdb_error_desc("Unknown error"); fgdbError er; er = FileGDBAPI::ErrorInfo::GetErrorDescription(static_cast<fgdbError>(hr), fgdb_error_desc_w); if ( er == S_OK ) { fgdb_error_desc = WStringToString(fgdb_error_desc_w); } CPLDebug("FileGDB", "Cannot open %s with FileGDB driver: %s. Failing silently so OpenFileGDB can be tried", pszFilename, fgdb_error_desc.c_str()); } else { GDBErr(hr, "Failed to open Geodatabase"); } oMapConnections.erase(pszFilename); return NULL; } CPLDebug("FileGDB", "Really opening %s", pszFilename); pConnection = new FGdbDatabaseConnection(pszFilename, pGeoDatabase); oMapConnections[pszFilename] = pConnection; } FGdbDataSource* pDS; pDS = new FGdbDataSource(this, pConnection); if(!pDS->Open( pszFilename, bUpdate, NULL ) ) { delete pDS; return NULL; } else { OGRMutexedDataSource* poMutexedDS = new OGRMutexedDataSource(pDS, TRUE, hMutex, TRUE); if( bUpdate ) return OGRCreateEmulatedTransactionDataSourceWrapper(poMutexedDS, this, TRUE, FALSE); else return poMutexedDS; } }
int OGRNASDataSource::Open( const char * pszNewName, int bTestOpen ) { FILE *fp; char szHeader[8192]; /* -------------------------------------------------------------------- */ /* Open the source file. */ /* -------------------------------------------------------------------- */ fp = VSIFOpen( pszNewName, "r" ); if( fp == NULL ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open NAS file `%s'.", pszNewName ); return FALSE; } /* -------------------------------------------------------------------- */ /* If we aren't sure it is NAS, load a header chunk and check */ /* for signs it is NAS */ /* -------------------------------------------------------------------- */ 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-length 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 NAS tree root element */ /* -------------------------------------------------------------------- */ if( szPtr[0] != '<' || strstr(szPtr,"opengis.net/gml") == NULL || (strstr(szPtr,"NAS-Operationen.xsd") == NULL && strstr(szPtr,"NAS-Operationen_optional.xsd") == NULL && strstr(szPtr,"AAA-Fachschema.xsd") == NULL ) ) { /*CPLDebug( "NAS", "Skipping. No chevrons of NAS found [%s]\n", szPtr );*/ VSIFClose( fp ); return FALSE; } } /* -------------------------------------------------------------------- */ /* We assume now that it is NAS. Close and instantiate a */ /* NASReader on it. */ /* -------------------------------------------------------------------- */ VSIFClose( fp ); poReader = CreateNASReader(); if( poReader == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "File %s appears to be NAS but the NAS reader can't\n" "be instantiated, likely because Xerces support wasn't\n" "configured in.", pszNewName ); return FALSE; } poReader->SetSourceFile( pszNewName ); pszName = CPLStrdup( pszNewName ); /* -------------------------------------------------------------------- */ /* Can we find a NAS Feature Schema (.gfs) for the input file? */ /* -------------------------------------------------------------------- */ const char *pszGFSFilename; VSIStatBuf sGFSStatBuf, sNASStatBuf; int bHaveSchema = FALSE; pszGFSFilename = CPLResetExtension( pszNewName, "gfs" ); if( CPLStat( pszGFSFilename, &sGFSStatBuf ) == 0 ) { CPLStat( pszNewName, &sNASStatBuf ); if( 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 ) { // 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->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; }
int OGRNTFDataSource::Open( const char * pszFilename, int bTestOpen, char ** papszLimitedFileList ) { VSIStatBuf stat; char **papszFileList = NULL; 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, NTF access failed.\n", pszFilename ); return FALSE; } /* -------------------------------------------------------------------- */ /* Build a list of filenames we figure are NTF files. */ /* -------------------------------------------------------------------- */ if( VSI_ISREG(stat.st_mode) ) { papszFileList = CSLAddString( NULL, pszFilename ); } else { char **candidateFileList = CPLReadDir( pszFilename ); int i; for( i = 0; candidateFileList != NULL && candidateFileList[i] != NULL; i++ ) { if( papszLimitedFileList != NULL && CSLFindString(papszLimitedFileList, candidateFileList[i]) == -1 ) { continue; } if( strlen(candidateFileList[i]) > 4 && EQUALN(candidateFileList[i] + strlen(candidateFileList[i])-4, ".ntf",4) ) { char fullFilename[2048]; sprintf( fullFilename, "%s%c%s", pszFilename, #ifdef WIN32 '\\', #else '/', #endif candidateFileList[i] ); papszFileList = CSLAddString( papszFileList, fullFilename ); } } CSLDestroy( candidateFileList ); if( CSLCount(papszFileList) == 0 ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_OpenFailed, "No candidate NTF files (.ntf) 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 NTF 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. */ /* -------------------------------------------------------------------- */ int i; papoNTFFileReader = (NTFFileReader **) CPLCalloc(sizeof(void*), CSLCount(papszFileList)); for( i = 0; papszFileList[i] != NULL; i++ ) { if( bTestOpen ) { char szHeader[80]; FILE *fp; int j; fp = VSIFOpen( papszFileList[i], "rb" ); if( fp == NULL ) continue; if( VSIFRead( szHeader, 80, 1, fp ) < 1 ) { VSIFClose( fp ); continue; } VSIFClose( fp ); if( !EQUALN(szHeader,"01",2) ) continue; for( j = 0; j < 80; j++ ) { if( szHeader[j] == 10 || szHeader[j] == 13 ) break; } if( j == 80 || szHeader[j-1] != '%' ) continue; } NTFFileReader *poFR; poFR = new NTFFileReader( this ); if( !poFR->Open( papszFileList[i] ) ) { delete poFR; CSLDestroy( papszFileList ); return FALSE; } poFR->SetBaseFID( nNTFFileCount * 1000000 + 1 ); poFR->Close(); EnsureTileNameUnique( poFR ); papoNTFFileReader[nNTFFileCount++] = poFR; } CSLDestroy( papszFileList ); if( nNTFFileCount == 0 ) return FALSE; /* -------------------------------------------------------------------- */ /* Establish generic layers. */ /* -------------------------------------------------------------------- */ EstablishGenericLayers(); /* -------------------------------------------------------------------- */ /* Loop over all the files, collecting a unique feature class */ /* listing. */ /* -------------------------------------------------------------------- */ for( int iSrcFile = 0; iSrcFile < nNTFFileCount; iSrcFile++ ) { NTFFileReader *poSrcReader = papoNTFFileReader[iSrcFile]; for( int iSrcFC = 0; iSrcFC < poSrcReader->GetFCCount(); iSrcFC++ ) { int iDstFC; char *pszSrcFCName, *pszSrcFCNum; poSrcReader->GetFeatureClass( iSrcFC, &pszSrcFCNum, &pszSrcFCName); for( iDstFC = 0; iDstFC < nFCCount; iDstFC++ ) { if( EQUAL(pszSrcFCNum,papszFCNum[iDstFC]) ) break; } if( iDstFC >= nFCCount ) { nFCCount++; papszFCNum = CSLAddString(papszFCNum,pszSrcFCNum); papszFCName = CSLAddString(papszFCName,pszSrcFCName); } } } /* -------------------------------------------------------------------- */ /* Create a new layer specifically for feature classes. */ /* -------------------------------------------------------------------- */ if( nFCCount > 0 ) poFCLayer = new OGRNTFFeatureClassLayer( this ); else poFCLayer = NULL; return TRUE; }