?? mitab_tabfile.cpp
字號:
/*----------------------------------------------------------------- * On Unix, make sure extension uses the right cases * We do it even for write access because if a file with the same * extension already exists we want to overwrite it. *----------------------------------------------------------------*/ TABAdjustFilenameExtension(m_pszFname);#endif /*----------------------------------------------------------------- * Handle .TAB file... depends on access mode. *----------------------------------------------------------------*/ if (m_eAccessMode == TABRead) { /*------------------------------------------------------------- * Open .TAB file... since it's a small text file, we will just load * it as a stringlist in memory. *------------------------------------------------------------*/ m_papszTABFile = TAB_CSLLoad(m_pszFname); if (m_papszTABFile == NULL) { if (!bTestOpenNoError) { CPLError(CE_Failure, CPLE_FileIO, "Failed opening %s.", m_pszFname); } CPLFree(m_pszFname); m_pszFname = NULL; CSLDestroy(m_papszTABFile); m_papszTABFile = NULL; CPLFree( pszTmpFname ); return -1; } /*------------------------------------------------------------- * Do a first pass on the TAB header to establish the type of * dataset we have (NATIVE, DBF, etc.)... and also to know if * it is a supported type. *------------------------------------------------------------*/ if ( ParseTABFileFirstPass(bTestOpenNoError) != 0 ) { // No need to produce an error... it's already been done if // necessary... just cleanup and exit. CPLFree(m_pszFname); m_pszFname = NULL; CSLDestroy(m_papszTABFile); m_papszTABFile = NULL; CPLFree( pszTmpFname ); return -1; } } else { /*------------------------------------------------------------- * In Write access mode, the .TAB file will be written during the * Close() call... we will just set some defaults here. *------------------------------------------------------------*/ m_nVersion = 300; m_pszCharset = CPLStrdup("Neutral"); m_eTableType = TABTableNative; /*------------------------------------------------------------- * Do initial setup of feature definition. *------------------------------------------------------------*/ char *pszFeatureClassName = TABGetBasename(m_pszFname); m_poDefn = new OGRFeatureDefn(pszFeatureClassName); m_poDefn->Reference(); CPLFree(pszFeatureClassName); } /*----------------------------------------------------------------- * Open .DAT file (or .DBF) *----------------------------------------------------------------*/ if (nFnameLen > 4 && strcmp(pszTmpFname+nFnameLen-4, ".TAB")==0) { if (m_eTableType == TABTableDBF) strcpy(pszTmpFname+nFnameLen-4, ".DBF"); else // Default is NATIVE strcpy(pszTmpFname+nFnameLen-4, ".DAT"); } else { if (m_eTableType == TABTableDBF) strcpy(pszTmpFname+nFnameLen-4, ".dbf"); else // Default is NATIVE strcpy(pszTmpFname+nFnameLen-4, ".dat"); }#ifndef _WIN32 TABAdjustFilenameExtension(pszTmpFname);#endif m_poDATFile = new TABDATFile; if ( m_poDATFile->Open(pszTmpFname, pszAccess, m_eTableType) != 0) { // Open Failed... an error has already been reported, just return. CPLFree(pszTmpFname); Close(); if (bTestOpenNoError) CPLErrorReset(); return -1; } m_nLastFeatureId = m_poDATFile->GetNumRecords(); /*----------------------------------------------------------------- * Parse .TAB file field defs and build FeatureDefn (only in read access) *----------------------------------------------------------------*/ if (m_eAccessMode == TABRead && ParseTABFileFields() != 0) { // Failed... an error has already been reported, just return. CPLFree(pszTmpFname); Close(); if (bTestOpenNoError) CPLErrorReset(); return -1; } /*----------------------------------------------------------------- * Open .MAP (and .ID) file * Note that the .MAP and .ID files are optional. Failure to open them * is not an error... it simply means that all features will be returned * with NONE geometry. *----------------------------------------------------------------*/ if (nFnameLen > 4 && strcmp(pszTmpFname+nFnameLen-4, ".DAT")==0) strcpy(pszTmpFname+nFnameLen-4, ".MAP"); else strcpy(pszTmpFname+nFnameLen-4, ".map");#ifndef _WIN32 TABAdjustFilenameExtension(pszTmpFname);#endif m_poMAPFile = new TABMAPFile; if (m_eAccessMode == TABRead) { /*------------------------------------------------------------- * Read access: .MAP/.ID are optional... try to open but return * no error if files do not exist. *------------------------------------------------------------*/ if (m_poMAPFile->Open(pszTmpFname, pszAccess, TRUE) < 0) { // File exists, but Open Failed... // we have to produce an error message if (!bTestOpenNoError) CPLError(CE_Failure, CPLE_FileIO, "Open() failed for %s", pszTmpFname); else CPLErrorReset(); CPLFree(pszTmpFname); Close(); return -1; } /*------------------------------------------------------------- * Set geometry type if the geometry objects are uniform. *------------------------------------------------------------*/ int numPoints=0, numRegions=0, numTexts=0, numLines=0; GetFeatureCountByType( numPoints, numLines, numRegions, numTexts); numPoints += numTexts; if( numPoints > 0 && numLines == 0 && numRegions == 0 ) m_poDefn->SetGeomType( wkbPoint ); else if( numPoints == 0 && numLines > 0 && numRegions == 0 ) m_poDefn->SetGeomType( wkbLineString ); else /* we leave it unknown indicating a mixture */; } else if (m_poMAPFile->Open(pszTmpFname, pszAccess) != 0) { // Open Failed for write... // an error has already been reported, just return. CPLFree(pszTmpFname); Close(); if (bTestOpenNoError) CPLErrorReset(); return -1; } CPLFree(pszTmpFname); pszTmpFname = NULL; /*----------------------------------------------------------------- * __TODO__ we could probably call GetSpatialRef() here to force * parsing the projection information... this would allow us to * assignSpatialReference() on the geometries that we return. *----------------------------------------------------------------*/ return 0;}/********************************************************************** * TABFile::ParseTABFileFirstPass() * * Do a first pass in the TAB header file to establish the table type, etc. * and store any useful information into class members. * * This private method should be used only during the Open() call. * * Returns 0 on success, -1 on error. **********************************************************************/int TABFile::ParseTABFileFirstPass(GBool bTestOpenNoError){ int iLine, numLines, numFields = 0; char **papszTok=NULL; GBool bInsideTableDef = FALSE, bFoundTableFields=FALSE; if (m_eAccessMode != TABRead) { CPLError(CE_Failure, CPLE_NotSupported, "ParseTABFile() can be used only with Read access."); return -1; } numLines = CSLCount(m_papszTABFile); for(iLine=0; iLine<numLines; iLine++) { /*------------------------------------------------------------- * Tokenize the next .TAB line, and check first keyword *------------------------------------------------------------*/ CSLDestroy(papszTok); papszTok = CSLTokenizeStringComplex(m_papszTABFile[iLine], " \t(),;", TRUE, FALSE); if (CSLCount(papszTok) < 2) continue; // All interesting lines have at least 2 tokens if (EQUAL(papszTok[0], "!version")) { m_nVersion = atoi(papszTok[1]); if (m_nVersion == 100) { /* Version 100 files contain only the fields definition, * so we set default values for the other params. */ bInsideTableDef = TRUE; m_pszCharset = CPLStrdup("Neutral"); m_eTableType = TABTableNative; } } else if (EQUAL(papszTok[0], "!edit_version")) { /* Sometimes, V450 files have version 300 + edit_version 450 * for us version and edit_version are the same */ m_nVersion = atoi(papszTok[1]); } else if (EQUAL(papszTok[0], "!charset")) { m_pszCharset = CPLStrdup(papszTok[1]); } else if (EQUAL(papszTok[0], "Definition") && EQUAL(papszTok[1], "Table") ) { bInsideTableDef = TRUE; } else if (bInsideTableDef && !bFoundTableFields && (EQUAL(papszTok[0], "Type") || EQUAL(papszTok[0],"FORMAT:")) ) { if (EQUAL(papszTok[1], "NATIVE") || EQUAL(papszTok[1], "LINKED")) m_eTableType = TABTableNative; else if (EQUAL(papszTok[1], "DBF")) m_eTableType = TABTableDBF; else { // Type=ACCESS, or other unsupported type... cannot open! if (!bTestOpenNoError) CPLError(CE_Failure, CPLE_NotSupported, "Unsupported table type '%s' in file %s. " "This type of .TAB file cannot be read by this library.", papszTok[1], m_pszFname); CSLDestroy(papszTok); return -1; } } else if (bInsideTableDef && !bFoundTableFields && (EQUAL(papszTok[0],"Fields") || EQUAL(papszTok[0],"FIELDS:"))) { /*--------------------------------------------------------- * We found the list of table fields * Just remember number of fields... the field types will be * parsed inside ParseTABFileFields() later... *--------------------------------------------------------*/ bFoundTableFields = TRUE; numFields = atoi(papszTok[1]); if (numFields < 1 || numFields>2048 || iLine+numFields >= numLines) { if (!bTestOpenNoError) CPLError(CE_Failure, CPLE_FileIO, "Invalid number of fields (%s) at line %d in file %s", papszTok[1], iLine+1, m_pszFname); CSLDestroy(papszTok); return -1; } bInsideTableDef = FALSE; }/* end of fields section*/ else { // Simply Ignore unrecognized lines } } CSLDestroy(papszTok); if (m_pszCharset == NULL) m_pszCharset = CPLStrdup("Neutral"); if (numFields == 0) { if (!bTestOpenNoError) CPLError(CE_Failure, CPLE_NotSupported, "%s contains no table field definition. " "This type of .TAB file cannot be read by this library.", m_pszFname); return -1; } return 0;}/********************************************************************** * TABFile::ParseTABFileFields() * * Extract the field definition from the TAB header file, validate * with what we have in the previously opened .DAT or .DBF file, and * finally build the m_poDefn OGRFeatureDefn for this dataset. * * This private method should be used only during the Open() call and after * ParseTABFileFirstPass() has been called. * * Returns 0 on success, -1 on error. **********************************************************************/int TABFile::ParseTABFileFields(){
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -