void TigerFileBase::SetupVersion() { char aszRecordHead[6]; VSIFSeek( fpPrimary, 0, SEEK_SET ); VSIFRead( aszRecordHead, 1, 5, fpPrimary ); aszRecordHead[5] = '\0'; nVersionCode = atoi(aszRecordHead+1); VSIFSeek( fpPrimary, 0, SEEK_SET ); nVersion = TigerClassifyVersion( nVersionCode ); }
int OGRTigerDataSource::Create( const char *pszNameIn, char **papszOptionsIn ) { VSIStatBufL stat; /* -------------------------------------------------------------------- */ /* Try to create directory if it doesn't already exist. */ /* -------------------------------------------------------------------- */ if( VSIStatL( pszNameIn, &stat ) != 0 ) { VSIMkdir( pszNameIn, 0755 ); } if( VSIStatL( 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.", pszNameIn ); return FALSE; } /* -------------------------------------------------------------------- */ /* Store various information. */ /* -------------------------------------------------------------------- */ pszPath = CPLStrdup( pszNameIn ); pszName = CPLStrdup( pszNameIn ); bWriteMode = true; SetOptionList( papszOptionsIn ); /* -------------------------------------------------------------------- */ /* Work out the version. */ /* -------------------------------------------------------------------- */ // nVersionCode = 1000; /* census 2000 */ nVersionCode = 1002; /* census 2002 */ if( GetOption("VERSION") != nullptr ) { nVersionCode = atoi(GetOption("VERSION")); nVersionCode = std::max(0, std::min(9999, nVersionCode)); } nVersion = TigerClassifyVersion(nVersionCode); return TRUE; }
int OGRTigerDataSource::Open( const char * pszFilename, int bTestOpen, char ** papszLimitedFileList ) { pszName = CPLStrdup( pszFilename ); /* -------------------------------------------------------------------- */ /* Is the given path a directory or a regular file? */ /* -------------------------------------------------------------------- */ VSIStatBufL stat; if( VSIStatExL( pszFilename, &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, Tiger access failed.\n", pszFilename ); return FALSE; } /* -------------------------------------------------------------------- */ /* Build a list of filenames we figure are Tiger files. */ /* -------------------------------------------------------------------- */ char **papszFileList = nullptr; if( VSI_ISREG(stat.st_mode) ) { char szModule[128]; if( strlen(CPLGetFilename(pszFilename)) == 0 ) { return FALSE; } pszPath = CPLStrdup( CPLGetPath(pszFilename) ); strncpy( szModule, CPLGetFilename(pszFilename), sizeof(szModule)-1 ); /* Make sure the buffer is 0 terminated */ szModule[sizeof(szModule)-1] = '\0'; /* And now remove last character of filename */ szModule[strlen(szModule)-1] = '\0'; papszFileList = CSLAddString( papszFileList, szModule ); } else { char **candidateFileList = VSIReadDir( pszFilename ); pszPath = CPLStrdup( pszFilename ); for( int i = 0; candidateFileList != nullptr && candidateFileList[i] != nullptr; i++ ) { size_t nCandidateLen = strlen(candidateFileList[i]); if( papszLimitedFileList != nullptr && CSLFindString(papszLimitedFileList, CPLGetBasename(candidateFileList[i])) == -1 ) { continue; } if( nCandidateLen > 4 && candidateFileList[i][nCandidateLen-4] == '.' && candidateFileList[i][nCandidateLen-1] == '1') { char szModule[128]; snprintf( szModule, sizeof(szModule), "%s", candidateFileList[i] ); const size_t nLen = strlen(szModule); if( nLen ) szModule[nLen-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 ); CSLDestroy(papszFileList); 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 a lot of file handles when */ /* handling a whole directory. */ /* -------------------------------------------------------------------- */ papszModules = nullptr; for( int i = 0; papszFileList && papszFileList[i] != nullptr; i++ ) { if( bTestOpen || i == 0 ) { char *l_pszFilename = BuildFilename( papszFileList[i], "1" ); VSILFILE *fp = VSIFOpenL( l_pszFilename, "rb" ); CPLFree( l_pszFilename ); if( fp == nullptr ) continue; char szHeader[500] = {}; if( VSIFReadL( szHeader, sizeof(szHeader)-1, 1, fp ) < 1 ) { VSIFCloseL( fp ); continue; } VSIFCloseL( fp ); char *pszRecStart = szHeader; szHeader[sizeof(szHeader)-1] = '\0'; bool bIsGDT = false; if( STARTS_WITH_CI(pszRecStart, "Copyright (C)") && strstr(pszRecStart,"Geographic Data Tech") != nullptr ) { 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] != DIGIT_ZERO && !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 || papszModules == nullptr ) { 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? */ /* -------------------------------------------------------------------- */ const char *pszRequestedVersion = CPLGetConfigOption( "TIGER_VERSION", nullptr ); if( pszRequestedVersion != nullptr ) { if( STARTS_WITH_CI(pszRequestedVersion, "TIGER_") ) { int iCode = 1; // Used after for. for( ; 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; }