📄 mitab_tabfile.cpp
字号:
m_poDefn = new OGRFeatureDefn(pszFeatureClassName); CPLFree(pszFeatureClassName); // Ref count defaults to 0... set it to 1 m_poDefn->Reference(); /*------------------------------------------------------------- * Scan for fields. *------------------------------------------------------------*/ numLines = CSLCount(m_papszTABFile); for(iLine=0; iLine<numLines; iLine++) { /*------------------------------------------------------------- * Tokenize the next .TAB line, and check first keyword *------------------------------------------------------------*/ const char *pszStr = m_papszTABFile[iLine]; while(*pszStr != '\0' && isspace(*pszStr)) pszStr++; if (EQUALN(pszStr, "Fields", 6)) { /*--------------------------------------------------------- * We found the list of table fields *--------------------------------------------------------*/ int iField, numFields; numFields = atoi(pszStr+7); if (numFields < 1 || numFields > 2048 || iLine+numFields >= numLines) { CPLError(CE_Failure, CPLE_FileIO, "Invalid number of fields (%s) at line %d in file %s", pszStr+7, iLine+1, m_pszFname); CSLDestroy(papszTok); return -1; } // Alloc the array to keep track of indexed fields m_panIndexNo = (int *)CPLCalloc(numFields, sizeof(int)); iLine++; poFieldDefn = NULL; for(iField=0; iField<numFields; iField++, iLine++) { /*----------------------------------------------------- * For each field definition found in the .TAB: * Pass the info to the DAT file object. It will validate * the info with what is found in the .DAT header, and will * also use this info later to interpret field values. * * We also create the OGRFieldDefn at the same time to * initialize the OGRFeatureDefn *----------------------------------------------------*/ CSLDestroy(papszTok); papszTok = CSLTokenizeStringComplex(m_papszTABFile[iLine], " \t(),;", TRUE, FALSE); numTok = CSLCount(papszTok); nStatus = -1; CPLAssert(m_poDefn); if (numTok >= 3 && EQUAL(papszTok[1], "char")) { /*------------------------------------------------- * CHAR type *------------------------------------------------*/ nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField, papszTok[0], TABFChar, atoi(papszTok[2]), 0); poFieldDefn = new OGRFieldDefn(papszTok[0], OFTString); poFieldDefn->SetWidth(atoi(papszTok[2])); } else if (numTok >= 2 && EQUAL(papszTok[1], "integer")) { /*------------------------------------------------- * INTEGER type *------------------------------------------------*/ nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField, papszTok[0], TABFInteger, 0, 0); poFieldDefn = new OGRFieldDefn(papszTok[0], OFTInteger); } else if (numTok >= 2 && EQUAL(papszTok[1], "smallint")) { /*------------------------------------------------- * SMALLINT type *------------------------------------------------*/ nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField, papszTok[0], TABFSmallInt, 0, 0); poFieldDefn = new OGRFieldDefn(papszTok[0], OFTInteger); } else if (numTok >= 4 && EQUAL(papszTok[1], "decimal")) { /*------------------------------------------------- * DECIMAL type *------------------------------------------------*/ nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField, papszTok[0], TABFDecimal, atoi(papszTok[2]), atoi(papszTok[3])); poFieldDefn = new OGRFieldDefn(papszTok[0], OFTReal); poFieldDefn->SetWidth(atoi(papszTok[2])); poFieldDefn->SetPrecision(atoi(papszTok[3])); } else if (numTok >= 2 && EQUAL(papszTok[1], "float")) { /*------------------------------------------------- * FLOAT type *------------------------------------------------*/ nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField, papszTok[0], TABFFloat, 0, 0); poFieldDefn = new OGRFieldDefn(papszTok[0], OFTReal); } else if (numTok >= 2 && EQUAL(papszTok[1], "date")) { /*------------------------------------------------- * DATE type (returned as a string: "DD/MM/YYYY") *------------------------------------------------*/ nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField, papszTok[0], TABFDate, 0, 0); poFieldDefn = new OGRFieldDefn(papszTok[0], OFTString); poFieldDefn->SetWidth(10); } else if (numTok >= 2 && EQUAL(papszTok[1], "logical")) { /*------------------------------------------------- * LOGICAL type (value "T" or "F") *------------------------------------------------*/ nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField, papszTok[0], TABFLogical, 0, 0); poFieldDefn = new OGRFieldDefn(papszTok[0], OFTString); poFieldDefn->SetWidth(1); } else nStatus = -1; // Unrecognized field type or line corrupt if (nStatus != 0) { CPLError(CE_Failure, CPLE_FileIO, "Failed to parse field definition at line %d in file %s", iLine+1, m_pszFname); CSLDestroy(papszTok); return -1; } /*----------------------------------------------------- * Keep track of index number if present *----------------------------------------------------*/ if (numTok >= 4 && EQUAL(papszTok[numTok-2], "index")) { m_panIndexNo[iField] = atoi(papszTok[numTok-1]); } else { m_panIndexNo[iField] = 0; } /*----------------------------------------------------- * Add the FieldDefn to the FeatureDefn and continue with * the next one. *----------------------------------------------------*/ m_poDefn->AddFieldDefn(poFieldDefn); // AddFieldDenf() takes a copy, so we delete the original if (poFieldDefn) delete poFieldDefn; poFieldDefn = NULL; } /*--------------------------------------------------------- * OK, we're done... end the loop now. *--------------------------------------------------------*/ break; }/* end of fields section*/ else { // Simply Ignore unrecognized lines } } CSLDestroy(papszTok); if (m_poDefn->GetFieldCount() == 0) { 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::WriteTABFile() * * Generate the .TAB file using mainly the attribute fields definition. * * This private method should be used only during the Close() call with * write access mode. * * Returns 0 on success, -1 on error. **********************************************************************/int TABFile::WriteTABFile(){ FILE *fp; if (m_eAccessMode != TABWrite) { CPLError(CE_Failure, CPLE_NotSupported, "WriteTABFile() can be used only with Write access."); return -1; } if ( (fp = VSIFOpen(m_pszFname, "wt")) != NULL) { fprintf(fp, "!table\n"); fprintf(fp, "!version %d\n", m_nVersion); fprintf(fp, "!charset %s\n", m_pszCharset); fprintf(fp, "\n"); if (m_poDefn && m_poDefn->GetFieldCount() > 0) { int iField; OGRFieldDefn *poFieldDefn; const char *pszFieldType; fprintf(fp, "Definition Table\n"); fprintf(fp, " Type NATIVE Charset \"%s\"\n", m_pszCharset); fprintf(fp, " Fields %d\n", m_poDefn->GetFieldCount()); for(iField=0; iField<m_poDefn->GetFieldCount(); iField++) { poFieldDefn = m_poDefn->GetFieldDefn(iField); switch(GetNativeFieldType(iField)) { case TABFChar: pszFieldType = CPLSPrintf("Char (%d)", poFieldDefn->GetWidth()); break; case TABFDecimal: pszFieldType = CPLSPrintf("Decimal (%d,%d)", poFieldDefn->GetWidth(), poFieldDefn->GetPrecision()); break; case TABFInteger: pszFieldType = "Integer"; break; case TABFSmallInt: pszFieldType = "SmallInt"; break; case TABFFloat: pszFieldType = "Float"; break; case TABFLogical: pszFieldType = "Logical"; break; case TABFDate: pszFieldType = "Date"; break; default: // Unsupported field type!!! This should never happen. CPLError(CE_Failure, CPLE_AssertionFailed, "WriteTABFile(): Unsupported field type"); VSIFClose(fp); return -1; } if (GetFieldIndexNumber(iField) == 0) { fprintf(fp, " %s %s ;\n", poFieldDefn->GetNameRef(), pszFieldType ); } else { fprintf(fp, " %s %s Index %d ;\n", poFieldDefn->GetNameRef(), pszFieldType, GetFieldIndexNumber(iField) ); } } } else { fprintf(fp, "Definition Table\n"); fprintf(fp, " Type NATIVE Charset \"%s\"\n", m_pszCharset); fprintf(fp, " Fields 1\n"); fprintf(fp, " FID Integer ;\n" ); } VSIFClose(fp); } else { CPLError(CE_Failure, CPLE_FileIO, "Failed to create file `%s'", m_pszFname); return -1; } return 0;}/********************************************************************** * TABFile::Close() * * Close current file, and release all memory used. * * Returns 0 on success, -1 on error. **********************************************************************/int TABFile::Close(){ // Commit the latest changes to the file... // In Write access, it's time to write the .TAB file. if (m_eAccessMode == TABWrite && m_poMAPFile) { // First update file version number... int nMapObjVersion = m_poMAPFile->GetMinTABFileVersion(); m_nVersion = MAX(m_nVersion, nMapObjVersion); WriteTABFile(); } if (m_poMAPFile) { m_poMAPFile->Close(); delete m_poMAPFile; m_poMAPFile = NULL; } if (m_poDATFile) { m_poDATFile->Close(); delete m_poDATFile; m_poDATFile = NULL; } if (m_poINDFile)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -