int OGRCSVDataSource::Open( const char * pszFilename, int bUpdateIn, int bForceOpen ) { pszName = CPLStrdup( pszFilename ); bUpdate = bUpdateIn; if (bUpdateIn && bForceOpen && EQUAL(pszFilename, "/vsistdout/")) return TRUE; /* For writable /vsizip/, do nothing more */ if (bUpdateIn && bForceOpen && strncmp(pszFilename, "/vsizip/", 8) == 0) return TRUE; CPLString osFilename(pszFilename); CPLString osBaseFilename = CPLGetFilename(pszFilename); CPLString osExt = GetRealExtension(osFilename); pszFilename = NULL; int bIgnoreExtension = EQUALN(osFilename, "CSV:", 4); int bUSGeonamesFile = FALSE; int bGeonamesOrgFile = FALSE; if (bIgnoreExtension) { osFilename = osFilename + 4; } /* Those are *not* real .XLS files, but text file with tab as column separator */ if (EQUAL(osBaseFilename, "NfdcFacilities.xls") || EQUAL(osBaseFilename, "NfdcRunways.xls") || EQUAL(osBaseFilename, "NfdcRemarks.xls") || EQUAL(osBaseFilename, "NfdcSchedules.xls")) { if (bUpdateIn) return FALSE; bIgnoreExtension = TRUE; } else if ((EQUALN(osBaseFilename, "NationalFile_", 13) || EQUALN(osBaseFilename, "POP_PLACES_", 11) || EQUALN(osBaseFilename, "HIST_FEATURES_", 14) || EQUALN(osBaseFilename, "US_CONCISE_", 11) || EQUALN(osBaseFilename, "AllNames_", 9) || EQUALN(osBaseFilename, "Feature_Description_History_", 28) || EQUALN(osBaseFilename, "ANTARCTICA_", 11) || EQUALN(osBaseFilename, "GOVT_UNITS_", 11) || EQUALN(osBaseFilename, "NationalFedCodes_", 17) || EQUALN(osBaseFilename, "AllStates_", 10) || EQUALN(osBaseFilename, "AllStatesFedCodes_", 18) || (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_Features_", 10)) || (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_FedCodes_", 10))) && (EQUAL(osExt, "txt") || EQUAL(osExt, "zip")) ) { if (bUpdateIn) return FALSE; bIgnoreExtension = TRUE; bUSGeonamesFile = TRUE; if (EQUAL(osExt, "zip") && strstr(osFilename, "/vsizip/") == NULL ) { osFilename = "/vsizip/" + osFilename; } } else if (EQUAL(osBaseFilename, "allCountries.txt") || EQUAL(osBaseFilename, "allCountries.zip")) { if (bUpdateIn) return FALSE; bIgnoreExtension = TRUE; bGeonamesOrgFile = TRUE; if (EQUAL(osExt, "zip") && strstr(osFilename, "/vsizip/") == NULL ) { osFilename = "/vsizip/" + osFilename; } } /* -------------------------------------------------------------------- */ /* Determine what sort of object this is. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; if( VSIStatExL( osFilename, &sStatBuf, VSI_STAT_NATURE_FLAG ) != 0 ) return FALSE; /* -------------------------------------------------------------------- */ /* Is this a single CSV file? */ /* -------------------------------------------------------------------- */ if( VSI_ISREG(sStatBuf.st_mode) && (bIgnoreExtension || EQUAL(osExt,"csv") || EQUAL(osExt,"tsv")) ) { if (EQUAL(CPLGetFilename(osFilename), "NfdcFacilities.xls")) { return OpenTable( osFilename, "ARP"); } else if (EQUAL(CPLGetFilename(osFilename), "NfdcRunways.xls")) { OpenTable( osFilename, "BaseEndPhysical"); OpenTable( osFilename, "BaseEndDisplaced"); OpenTable( osFilename, "ReciprocalEndPhysical"); OpenTable( osFilename, "ReciprocalEndDisplaced"); return nLayers != 0; } else if (bUSGeonamesFile) { /* GNIS specific */ if (EQUALN(osBaseFilename, "NationalFedCodes_", 17) || EQUALN(osBaseFilename, "AllStatesFedCodes_", 18) || EQUALN(osBaseFilename, "ANTARCTICA_", 11) || (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_FedCodes_", 10))) { OpenTable( osFilename, NULL, "PRIMARY"); } else if (EQUALN(osBaseFilename, "GOVT_UNITS_", 11) || EQUALN(osBaseFilename, "Feature_Description_History_", 28)) { OpenTable( osFilename, NULL, ""); } else { OpenTable( osFilename, NULL, "PRIM"); OpenTable( osFilename, NULL, "SOURCE"); } return nLayers != 0; } return OpenTable( osFilename ); } /* -------------------------------------------------------------------- */ /* Is this a single a ZIP file with only a CSV file inside ? */ /* -------------------------------------------------------------------- */ if( strncmp(osFilename, "/vsizip/", 8) == 0 && EQUAL(osExt, "zip") && VSI_ISREG(sStatBuf.st_mode) ) { char** papszFiles = VSIReadDir(osFilename); if (CSLCount(papszFiles) != 1 || !EQUAL(CPLGetExtension(papszFiles[0]), "CSV")) { CSLDestroy(papszFiles); return FALSE; } osFilename = CPLFormFilename(osFilename, papszFiles[0], NULL); CSLDestroy(papszFiles); return OpenTable( osFilename ); } /* -------------------------------------------------------------------- */ /* Otherwise it has to be a directory. */ /* -------------------------------------------------------------------- */ if( !VSI_ISDIR(sStatBuf.st_mode) ) return FALSE; /* -------------------------------------------------------------------- */ /* Scan through for entries ending in .csv. */ /* -------------------------------------------------------------------- */ int nNotCSVCount = 0, i; char **papszNames = CPLReadDir( osFilename ); for( i = 0; papszNames != NULL && papszNames[i] != NULL; i++ ) { CPLString oSubFilename = CPLFormFilename( osFilename, papszNames[i], NULL ); if( EQUAL(papszNames[i],".") || EQUAL(papszNames[i],"..") ) continue; if (EQUAL(CPLGetExtension(oSubFilename),"csvt")) continue; if( VSIStatL( oSubFilename, &sStatBuf ) != 0 || !VSI_ISREG(sStatBuf.st_mode) ) { nNotCSVCount++; continue; } if (EQUAL(CPLGetExtension(oSubFilename),"csv")) { if( !OpenTable( oSubFilename ) ) { CPLDebug("CSV", "Cannot open %s", oSubFilename.c_str()); nNotCSVCount++; continue; } } /* GNIS specific */ else if ( strlen(papszNames[i]) > 2 && EQUALN(papszNames[i]+2, "_Features_", 10) && EQUAL(CPLGetExtension(papszNames[i]), "txt") ) { int bRet = OpenTable( oSubFilename, NULL, "PRIM"); bRet |= OpenTable( oSubFilename, NULL, "SOURCE"); if ( !bRet ) { CPLDebug("CSV", "Cannot open %s", oSubFilename.c_str()); nNotCSVCount++; continue; } } /* GNIS specific */ else if ( strlen(papszNames[i]) > 2 && EQUALN(papszNames[i]+2, "_FedCodes_", 10) && EQUAL(CPLGetExtension(papszNames[i]), "txt") ) { if ( !OpenTable( oSubFilename, NULL, "PRIMARY") ) { CPLDebug("CSV", "Cannot open %s", oSubFilename.c_str()); nNotCSVCount++; continue; } } else { nNotCSVCount++; continue; } } CSLDestroy( papszNames ); /* -------------------------------------------------------------------- */ /* We presume that this is indeed intended to be a CSV */ /* datasource if over half the files were .csv files. */ /* -------------------------------------------------------------------- */ return bForceOpen || nNotCSVCount < nLayers; }
int OGRShapeDataSource::Open( const char * pszNewName, int bUpdate, int bTestOpen, int bForceSingleFileDataSource ) { VSIStatBufL stat; CPLAssert( nLayers == 0 ); pszName = CPLStrdup( pszNewName ); bDSUpdate = bUpdate; bSingleFileDataSource = bForceSingleFileDataSource; /* -------------------------------------------------------------------- */ /* If bSingleFileDataSource is TRUE we don't try to do anything else. */ /* This is only utilized when the OGRShapeDriver::Create() */ /* method wants to create a stub OGRShapeDataSource for a */ /* single shapefile. The driver will take care of creating the */ /* file by calling CreateLayer(). */ /* -------------------------------------------------------------------- */ if( bSingleFileDataSource ) return TRUE; /* -------------------------------------------------------------------- */ /* Is the given path a directory or a regular file? */ /* -------------------------------------------------------------------- */ if( VSIStatExL( pszNewName, &stat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG ) != 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, Shape access failed.\n", pszNewName ); return FALSE; } /* -------------------------------------------------------------------- */ /* Build a list of filenames we figure are Shape files. */ /* -------------------------------------------------------------------- */ if( VSI_ISREG(stat.st_mode) ) { if( !OpenFile( pszNewName, bUpdate, bTestOpen ) ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open shapefile %s.\n" "It may be corrupt or read-only file accessed in update mode.\n", pszNewName ); return FALSE; } bSingleFileDataSource = TRUE; return TRUE; } else { char **papszCandidates = CPLReadDir( pszNewName ); int iCan, nCandidateCount = CSLCount( papszCandidates ); int bMightBeOldCoverage = FALSE; for( iCan = 0; iCan < nCandidateCount; iCan++ ) { char *pszFilename; const char *pszCandidate = papszCandidates[iCan]; if( EQUAL(pszCandidate,"ARC") ) bMightBeOldCoverage = TRUE; if( strlen(pszCandidate) < 4 || !EQUAL(pszCandidate+strlen(pszCandidate)-4,".shp") ) continue; pszFilename = CPLStrdup(CPLFormFilename(pszNewName, pszCandidate, NULL)); if( !OpenFile( pszFilename, bUpdate, bTestOpen ) && !bTestOpen ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open shapefile %s.\n" "It may be corrupt or read-only file accessed in update mode.\n", pszFilename ); CPLFree( pszFilename ); return FALSE; } CPLFree( pszFilename ); } // Try and .dbf files without apparent associated shapefiles. for( iCan = 0; iCan < nCandidateCount; iCan++ ) { char *pszFilename; const char *pszCandidate = papszCandidates[iCan]; const char *pszLayerName; int iLayer, bGotAlready = FALSE; // We don't consume .dbf files in a directory that looks like // an old style Arc/Info (for PC?) that unless we found at least // some shapefiles. See Bug 493. if( bMightBeOldCoverage && nLayers == 0 ) continue; if( strlen(pszCandidate) < 4 || !EQUAL(pszCandidate+strlen(pszCandidate)-4,".dbf") ) continue; pszLayerName = CPLGetBasename(pszCandidate); for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszLayerName, GetLayer(iLayer)->GetLayerDefn()->GetName()) ) bGotAlready = TRUE; } if( bGotAlready ) continue; // We don't want to access .dbf files with an associated .tab // file, or it will never get recognised as a mapinfo dataset. int iCan2, bFoundTAB = FALSE; for( iCan2 = 0; iCan2 < nCandidateCount; iCan2++ ) { const char *pszCandidate2 = papszCandidates[iCan2]; if( EQUALN(pszCandidate2,pszLayerName,strlen(pszLayerName)) && EQUAL(pszCandidate2 + strlen(pszLayerName), ".tab") ) bFoundTAB = TRUE; } if( bFoundTAB ) continue; pszFilename = CPLStrdup(CPLFormFilename(pszNewName, pszCandidate, NULL)); if( !OpenFile( pszFilename, bUpdate, bTestOpen ) && !bTestOpen ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open dbf file %s.\n" "It may be corrupt or read-only file accessed in update mode.\n", pszFilename ); CPLFree( pszFilename ); return FALSE; } CPLFree( pszFilename ); } CSLDestroy( papszCandidates ); if( !bTestOpen && nLayers == 0 && !bUpdate ) { CPLError( CE_Failure, CPLE_OpenFailed, "No Shapefiles found in directory %s\n", pszNewName ); } } return nLayers > 0 || bUpdate; }
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 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 " "enviroment 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 */ /* -------------------------------------------------------------------- */ Vect_set_fatal_error ( GV_FATAL_PRINT ); // Print error and continue 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; 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 OGRTABDataSource::Open( const char * pszName, int bTestOpen ) { VSIStatBuf stat; CPLAssert( m_pszName == NULL ); m_pszName = CPLStrdup( pszName ); /* -------------------------------------------------------------------- */ /* Is this a file or directory? */ /* -------------------------------------------------------------------- */ if( VSIStat( pszName, &stat ) != 0 || (!VSI_ISDIR(stat.st_mode) && !VSI_ISREG(stat.st_mode)) ) { if( !bTestOpen ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s is not a file or directory.\n" "Unable to open as a Mapinfo dataset.\n", pszName ); } return FALSE; } /* -------------------------------------------------------------------- */ /* If it is a file, try to open as a Mapinfo file. */ /* -------------------------------------------------------------------- */ if( VSI_ISREG(stat.st_mode) ) { IMapInfoFile *poFile; poFile = IMapInfoFile::SmartOpen( pszName, bTestOpen ); if( poFile == NULL ) return FALSE; m_nLayerCount = 1; m_papoLayers = (IMapInfoFile **) CPLMalloc(sizeof(void*)); m_papoLayers[0] = poFile; m_pszDirectory = CPLStrdup( CPLGetPath(pszName) ); } /* -------------------------------------------------------------------- */ /* Otherwise, we need to scan the whole directory for files */ /* ending in .tab or .mif. */ /* -------------------------------------------------------------------- */ else { char **papszFileList = CPLReadDir( pszName ); m_pszDirectory = CPLStrdup( pszName ); for( int iFile = 0; papszFileList != NULL && papszFileList[iFile] != NULL; iFile++ ) { IMapInfoFile *poFile; const char *pszExtension = CPLGetExtension(papszFileList[iFile]); char *pszSubFilename; if( !EQUAL(pszExtension,"tab") && !EQUAL(pszExtension,"mif") ) continue; pszSubFilename = CPLStrdup( CPLFormFilename( m_pszDirectory, papszFileList[iFile], NULL )); poFile = IMapInfoFile::SmartOpen( pszSubFilename, bTestOpen ); CPLFree( pszSubFilename ); if( poFile == NULL ) { CSLDestroy( papszFileList ); return FALSE; } m_nLayerCount++; m_papoLayers = (IMapInfoFile **) CPLRealloc(m_papoLayers,sizeof(void*)*m_nLayerCount); m_papoLayers[m_nLayerCount-1] = poFile; } CSLDestroy( papszFileList ); if( m_nLayerCount == 0 ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_OpenFailed, "No mapinfo files found in directory %s.\n", m_pszDirectory ); return FALSE; } } return TRUE; }
int OGRGPSBabelDataSource::Open( const char * pszDatasourceName, int bUpdateIn) { int bExplicitFeatures = FALSE; int bWaypoints = TRUE, bTracks = TRUE, bRoutes = TRUE; if (bUpdateIn) { CPLError(CE_Failure, CPLE_NotSupported, "OGR/GPSBabel driver does not support opening a file in update mode"); return FALSE; } if (!EQUALN(pszDatasourceName, "GPSBABEL:", 9)) { VSIStatBufL sStatBuf; if( VSIStatL( pszDatasourceName, &sStatBuf ) != 0 ||!VSI_ISREG(sStatBuf.st_mode) ) return FALSE; VSILFILE* fp = VSIFOpenL(pszDatasourceName, "rb"); if (fp == NULL) return FALSE; char szHeader[1024 + 1]; memset(szHeader, 0, 1024+1); VSIFReadL(szHeader, 1, 1024, fp); if (memcmp(szHeader, "MsRcd", 5) == 0) pszGPSBabelDriverName = CPLStrdup("mapsource"); else if (memcmp(szHeader, "MsRcf", 5) == 0) pszGPSBabelDriverName = CPLStrdup("gdb"); else if (strstr(szHeader, "<osm") != NULL) pszGPSBabelDriverName = CPLStrdup("osm"); else if (strstr(szHeader, "$GPGSA") != NULL || strstr(szHeader, "$GPGGA") != NULL) pszGPSBabelDriverName = CPLStrdup("nmea"); else if (EQUALN(szHeader, "OziExplorer",11)) pszGPSBabelDriverName = CPLStrdup("ozi"); else if (strstr(szHeader, "Grid") && strstr(szHeader, "Datum") && strstr(szHeader, "Header")) pszGPSBabelDriverName = CPLStrdup("garmin_txt"); else if (szHeader[0] == 13 && szHeader[10] == 'M' && szHeader[11] == 'S' && (szHeader[12] >= '0' && szHeader[12] <= '9') && (szHeader[13] >= '0' && szHeader[13] <= '9') && szHeader[12] * 10 + szHeader[13] >= 30 && (szHeader[14] == 1 || szHeader[14] == 2) && szHeader[15] == 0 && szHeader[16] == 0 && szHeader[17] == 0) pszGPSBabelDriverName = CPLStrdup("mapsend"); else if (strstr(szHeader, "$PMGNWPL") != NULL || strstr(szHeader, "$PMGNRTE") != NULL) pszGPSBabelDriverName = CPLStrdup("magellan"); VSIFCloseL(fp); if (pszGPSBabelDriverName == NULL) { return FALSE; } pszFilename = CPLStrdup(pszDatasourceName); } pszName = CPLStrdup( pszDatasourceName ); if (pszGPSBabelDriverName == NULL) { const char* pszSep = strchr(pszDatasourceName + 9, ':'); if (pszSep == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Wrong syntax. Expected GPSBabel:driver_name:file_name"); return FALSE; } pszGPSBabelDriverName = CPLStrdup(pszDatasourceName + 9); *(strchr(pszGPSBabelDriverName, ':')) = '\0'; /* A bit of validation to avoid command line injection */ if (!IsValidDriverName(pszGPSBabelDriverName)) return FALSE; /* Parse optionnal features= option */ if (EQUALN(pszSep+1, "features=", 9)) { const char* pszNextSep = strchr(pszSep+1, ':'); if (pszNextSep == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Wrong syntax. Expected GPSBabel:driver_name[,options]*:[features=waypoints,tracks,routes:]file_name"); return FALSE; } char* pszFeatures = CPLStrdup(pszSep+1+9); *strchr(pszFeatures, ':') = 0; char** papszTokens = CSLTokenizeString(pszFeatures); char** papszIter = papszTokens; int bErr = FALSE; bExplicitFeatures = TRUE; bWaypoints = bTracks = bRoutes = FALSE; while(papszIter && *papszIter) { if (EQUAL(*papszIter, "waypoints")) bWaypoints = TRUE; else if (EQUAL(*papszIter, "tracks")) bTracks = TRUE; else if (EQUAL(*papszIter, "routes")) bRoutes = TRUE; else { CPLError(CE_Failure, CPLE_AppDefined, "Wrong value for 'features' options"); bErr = TRUE; } papszIter ++; } CSLDestroy(papszTokens); CPLFree(pszFeatures); if (bErr) return FALSE; pszSep = pszNextSep; } pszFilename = CPLStrdup(pszSep+1); } const char* pszOptionUseTempFile = CPLGetConfigOption("USE_TEMPFILE", NULL); if (pszOptionUseTempFile && CSLTestBoolean(pszOptionUseTempFile)) osTmpFileName = CPLGenerateTempFilename(NULL); else osTmpFileName.Printf("/vsimem/ogrgpsbabeldatasource_%p", this); int nRet = FALSE; if (IsSpecialFile(pszFilename)) { /* Special file : don't try to open it */ char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, pszFilename); VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); nRet = ForkAndPipe(argv, NULL, tmpfp); VSIFCloseL(tmpfp); tmpfp = NULL; CSLDestroy(argv); argv = NULL; } else { VSILFILE* fp = VSIFOpenL(pszFilename, "rb"); if (fp == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open file %s", pszFilename); return FALSE; } char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, "-"); VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); CPLPushErrorHandler(CPLQuietErrorHandler); nRet = ForkAndPipe(argv, fp, tmpfp); CPLPopErrorHandler(); CSLDestroy(argv); argv = NULL; CPLErr nLastErrorType = CPLGetLastErrorType(); int nLastErrorNo = CPLGetLastErrorNo(); CPLString osLastErrorMsg = CPLGetLastErrorMsg(); VSIFCloseL(tmpfp); tmpfp = NULL; VSIFCloseL(fp); fp = NULL; if (!nRet) { if (strstr(osLastErrorMsg.c_str(), "This format cannot be used in piped commands") == NULL) { CPLError(nLastErrorType, nLastErrorNo, "%s", osLastErrorMsg.c_str()); } else { VSIStatBuf sStatBuf; if (VSIStat(pszFilename, &sStatBuf) != 0) { CPLError(CE_Failure, CPLE_NotSupported, "Driver %s only supports real (non virtual) files", pszGPSBabelDriverName); return FALSE; } /* Try without piping in */ argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, pszFilename); tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); nRet = ForkAndPipe(argv, NULL, tmpfp); VSIFCloseL(tmpfp); tmpfp = NULL; CSLDestroy(argv); argv = NULL; } } } if (nRet) { poGPXDS = OGRSFDriverRegistrar::Open(osTmpFileName.c_str()); if (poGPXDS) { OGRLayer* poLayer; if (bWaypoints) { poLayer = poGPXDS->GetLayerByName("waypoints"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } if (bRoutes) { poLayer = poGPXDS->GetLayerByName("routes"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; poLayer = poGPXDS->GetLayerByName("route_points"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } if (bTracks) { poLayer = poGPXDS->GetLayerByName("tracks"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; poLayer = poGPXDS->GetLayerByName("track_points"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } } } return nLayers > 0; }
CPLErr GDALPamDataset::TryLoadXML() { CPLXMLNode *psTree = NULL; PamInitialize(); /* -------------------------------------------------------------------- */ /* Clear dirty flag. Generally when we get to this point is */ /* from a call at the end of the Open() method, and some calls */ /* may have already marked the PAM info as dirty (for instance */ /* setting metadata), but really everything to this point is */ /* reproducable, and so the PAM info shouldn't really be */ /* thought of as dirty. */ /* -------------------------------------------------------------------- */ nPamFlags &= ~GPF_DIRTY; /* -------------------------------------------------------------------- */ /* Try reading the file. */ /* -------------------------------------------------------------------- */ if( !BuildPamFilename() ) return CE_None; VSIStatBufL sStatBuf; if( VSIStatL( psPam->pszPamFilename, &sStatBuf ) == 0 && VSI_ISREG( sStatBuf.st_mode ) ) { CPLErrorReset(); CPLPushErrorHandler( CPLQuietErrorHandler ); psTree = CPLParseXMLFile( psPam->pszPamFilename ); CPLPopErrorHandler(); } /* -------------------------------------------------------------------- */ /* If we are looking for a subdataset, search for it's subtree */ /* now. */ /* -------------------------------------------------------------------- */ if( psTree && psPam->osSubdatasetName.size() ) { CPLXMLNode *psSubTree; for( psSubTree = psTree->psChild; psSubTree != NULL; psSubTree = psSubTree->psNext ) { if( psSubTree->eType != CXT_Element || !EQUAL(psSubTree->pszValue,"Subdataset") ) continue; if( !EQUAL(CPLGetXMLValue( psSubTree, "name", "" ), psPam->osSubdatasetName) ) continue; psSubTree = CPLGetXMLNode( psSubTree, "PAMDataset" ); break; } if( psSubTree != NULL ) psSubTree = CPLCloneXMLTree( psSubTree ); CPLDestroyXMLNode( psTree ); psTree = psSubTree; } /* -------------------------------------------------------------------- */ /* If we fail, try .aux. */ /* -------------------------------------------------------------------- */ if( psTree == NULL ) return TryLoadAux(); /* -------------------------------------------------------------------- */ /* Initialize ourselves from this XML tree. */ /* -------------------------------------------------------------------- */ CPLErr eErr; CPLString osVRTPath(CPLGetPath(psPam->pszPamFilename)); eErr = XMLInit( psTree, osVRTPath ); CPLDestroyXMLNode( psTree ); if( eErr != CE_None ) PamClear(); return eErr; }
int OGRCSVDataSource::Open( const char * pszFilename, int bUpdateIn, int bForceOpen ) { pszName = CPLStrdup( pszFilename ); bUpdate = bUpdateIn; /* -------------------------------------------------------------------- */ /* Determine what sort of object this is. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; if( VSIStatL( pszFilename, &sStatBuf ) != 0 ) return FALSE; /* -------------------------------------------------------------------- */ /* Is this a single CSV file? */ /* -------------------------------------------------------------------- */ if( VSI_ISREG(sStatBuf.st_mode) && strlen(pszFilename) > 4 && EQUAL(pszFilename+strlen(pszFilename)-4,".csv") ) return OpenTable( pszFilename ); /* -------------------------------------------------------------------- */ /* Otherwise it has to be a directory. */ /* -------------------------------------------------------------------- */ if( !VSI_ISDIR(sStatBuf.st_mode) ) return FALSE; /* -------------------------------------------------------------------- */ /* Scan through for entries ending in .csv. */ /* -------------------------------------------------------------------- */ int nNotCSVCount = 0, i; char **papszNames = CPLReadDir( pszFilename ); for( i = 0; papszNames != NULL && papszNames[i] != NULL; i++ ) { CPLString oSubFilename = CPLFormFilename( pszFilename, papszNames[i], NULL ); if( EQUAL(papszNames[i],".") || EQUAL(papszNames[i],"..") ) continue; if (EQUAL(CPLGetExtension(oSubFilename),"csvt")) continue; if( VSIStatL( oSubFilename, &sStatBuf ) != 0 || !VSI_ISREG(sStatBuf.st_mode) || !EQUAL(CPLGetExtension(oSubFilename),"csv") ) { nNotCSVCount++; continue; } if( !OpenTable( oSubFilename ) ) { CSLDestroy( papszNames ); nNotCSVCount++; return FALSE; } } CSLDestroy( papszNames ); /* -------------------------------------------------------------------- */ /* We presume that this is indeed intended to be a CSV */ /* datasource if over half the files were .csv files. */ /* -------------------------------------------------------------------- */ return bForceOpen || nNotCSVCount < nLayers; }
GDALOpenInfo::GDALOpenInfo( const char * pszFilenameIn, GDALAccess eAccessIn, char **papszSiblingsIn ) { /* -------------------------------------------------------------------- */ /* Ensure that C: is treated as C:\ so we can stat it on */ /* Windows. Similar to what is done in CPLStat(). */ /* -------------------------------------------------------------------- */ #ifdef WIN32 if( strlen(pszFilenameIn) == 2 && pszFilenameIn[1] == ':' ) { char szAltPath[10]; strcpy( szAltPath, pszFilenameIn ); strcat( szAltPath, "\\" ); pszFilename = CPLStrdup( szAltPath ); } else #endif pszFilename = CPLStrdup( pszFilenameIn ); /* -------------------------------------------------------------------- */ /* Initialize. */ /* -------------------------------------------------------------------- */ nHeaderBytes = 0; pabyHeader = NULL; bIsDirectory = FALSE; bStatOK = FALSE; eAccess = eAccessIn; fp = NULL; #ifdef HAVE_READLINK int bHasRetried = FALSE; #endif /* -------------------------------------------------------------------- */ /* Collect information about the file. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStat; #ifdef HAVE_READLINK retry: #endif if( VSIStatExL( pszFilename, &sStat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG ) == 0 ) { bStatOK = TRUE; if( VSI_ISREG( sStat.st_mode ) ) { pabyHeader = (GByte *) CPLCalloc(1025,1); fp = VSIFOpen( pszFilename, "rb" ); if( fp != NULL ) { nHeaderBytes = (int) VSIFRead( pabyHeader, 1, 1024, fp ); VSIRewind( fp ); } /* XXX: ENOENT is used to catch the case of virtual filesystem * when we do not have a real file with such a name. Under some * circumstances EINVAL reported instead of ENOENT in Windows * (for filenames containing colon, e.g. "smth://name"). * See also: #2437 */ else if( errno == 27 /* "File to large" */ || errno == ENOENT || errno == EINVAL #ifdef EOVERFLOW || errno == EOVERFLOW #else || errno == 75 /* Linux EOVERFLOW */ || errno == 79 /* Solaris EOVERFLOW */ #endif ) { VSILFILE* fpL = VSIFOpenL( pszFilename, "rb" ); if( fpL != NULL ) { nHeaderBytes = (int) VSIFReadL( pabyHeader, 1, 1024, fpL ); VSIFCloseL( fpL ); } } } else if( VSI_ISDIR( sStat.st_mode ) ) bIsDirectory = TRUE; } #ifdef HAVE_READLINK else if (!bHasRetried) { /* If someone creates a file with "ln -sf /vsicurl/http://download.osgeo.org/gdal/data/gtiff/utm.tif my_remote_utm.tif" */ /* we will be able to open it by passing my_remote_utm.tif */ /* This helps a lot for GDAL based readers that only provide file explorers to open datasets */ char szPointerFilename[2048]; int nBytes = readlink(pszFilename, szPointerFilename, sizeof(szPointerFilename)); if (nBytes != -1) { szPointerFilename[MIN(nBytes, (int)sizeof(szPointerFilename)-1)] = 0; CPLFree(pszFilename); pszFilename = CPLStrdup(szPointerFilename); papszSiblingsIn = NULL; bHasRetried = TRUE; goto retry; } } #endif /* -------------------------------------------------------------------- */ /* Capture sibling list either from passed in values, or by */ /* scanning for them. */ /* -------------------------------------------------------------------- */ if( papszSiblingsIn != NULL ) { papszSiblingFiles = CSLDuplicate( papszSiblingsIn ); } else if( bStatOK && !bIsDirectory ) { const char* pszOptionVal = CPLGetConfigOption( "GDAL_DISABLE_READDIR_ON_OPEN", "NO" ); if (EQUAL(pszOptionVal, "EMPTY_DIR")) { papszSiblingFiles = CSLAddString( NULL, CPLGetFilename(pszFilename) ); } else if( CSLTestBoolean(pszOptionVal) ) { /* skip reading the directory */ papszSiblingFiles = NULL; } else { CPLString osDir = CPLGetDirname( pszFilename ); papszSiblingFiles = VSIReadDir( osDir ); /* Small optimization to avoid unnecessary stat'ing from PAux or ENVI */ /* drivers. The MBTiles driver needs no companion file. */ if( papszSiblingFiles == NULL && strncmp(pszFilename, "/vsicurl/", 9) == 0 && EQUAL(CPLGetExtension( pszFilename ),"mbtiles") ) { papszSiblingFiles = CSLAddString( NULL, CPLGetFilename(pszFilename) ); } } } else papszSiblingFiles = NULL; }
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; }