📄 tabview.cpp
字号:
/*----------------------------------------------------------------- * Create TABRelation... *----------------------------------------------------------------*/ m_poRelation = new TABRelation; if ( m_poRelation->Init(pszBasename, m_papoTABFiles[0], m_papoTABFiles[1], NULL, NULL, NULL) != 0 ) { // An error should already have been reported UGK_Free(pszPath); UGK_Free(pszBasename); Close(); return -1; } UGK_Free(pszPath); UGK_Free(pszBasename); return 0;}/********************************************************************** * TABView::ParseTABFile() * * Scan the lines of the TAB file, and store any useful information into * class members. The main piece of information being the sub-table * names, and the list of fields to include in the view that we will * use to build the UGKFeatureDefn for this file. * * It is assumed that the TAB header file is already loaded in m_papszTABFile * * This private method should be used only during the Open() call. * * Returns 0 on success, -1 on error. **********************************************************************/int TABView::ParseTABFile(const char *pszDatasetPath, UGKBool bTestOpenNoError /*=FALSE*/){ int iLine, numLines; char **papszTok=NULL; UGKBool bInsideTableDef = FALSE; if (m_eAccessMode != TABRead) { UGKError(ET_Failure, UGKErr_AssertionFailed, "ParseTABFile() can be used only with Read access."); return -1; } numLines = CountOfList(m_papszTABFile); for(iLine=0; iLine<numLines; iLine++) { /*------------------------------------------------------------- * Tokenize the next .TAB line, and check first keyword *------------------------------------------------------------*/ FreeStrList(papszTok); papszTok = TokenizeStringComplex(m_papszTABFile[iLine], " \t(),;", TRUE, FALSE); if (CountOfList(papszTok) < 2) continue; // All interesting lines have at least 2 tokens if (EQUAL(papszTok[0], "!version")) { m_pszVersion = UGKStrdup(papszTok[1]); } else if (EQUAL(papszTok[0], "!charset")) { m_pszCharset = UGKStrdup(papszTok[1]); } else if (EQUAL(papszTok[0], "open") && EQUAL(papszTok[1], "table") && CountOfList(papszTok) >= 3) { // Source table name may be either "filename" or "filename.tab" int nLen = strlen(papszTok[2]); if (nLen > 4 && EQUAL(papszTok[2]+nLen-4, ".tab")) papszTok[2][nLen-4] = '\0'; m_papszTABFnames = AppendPrintf(m_papszTABFnames, "%s%s.tab", pszDatasetPath, papszTok[2]); } else if (EQUAL(papszTok[0], "create") && EQUAL(papszTok[1], "view") ) { bInsideTableDef = TRUE; } else if (bInsideTableDef && (EQUAL(papszTok[0],"Select"))) { /*--------------------------------------------------------- * We found the list of table fields (comma-delimited list) *--------------------------------------------------------*/ int iTok; for(iTok=1; papszTok[iTok] != NULL; iTok++) m_papszFieldNames = AddStringToList(m_papszFieldNames, papszTok[iTok]); } else if (bInsideTableDef && (EQUAL(papszTok[0],"where"))) { /*--------------------------------------------------------- * We found the where clause that relates the 2 tables * Something in the form: * where table1.field1=table2.field2 * The tokenized array will contain: * {"where", "table1", "field1", "table2", "field2"} *--------------------------------------------------------*/ m_papszWhereClause =TokenizeStringComplex(m_papszTABFile[iLine], " \t(),;=.", TRUE, FALSE); /*--------------------------------------------------------- * For now we are very limiting on the format of the WHERE * clause... we will be more permitting as we learn more about * what it can contain... (I don't want to implement a full SQL * parser here!!!). If you encountered this error, * (and are reading this!) please report the test dataset * that produced the error and I'll see if we can support it. *--------------------------------------------------------*/ if (CountOfList( m_papszWhereClause ) != 5) { if (!bTestOpenNoError) UGKError(ET_Failure, UGKErr_NotSupported, "WHERE clause in %s is not in a supported format: \"%s\"", m_pszFname, m_papszTABFile[iLine]); return -1; } } else { // Simply Ignore unrecognized lines } } FreeStrList(papszTok); /*----------------------------------------------------------------- * The main table is the one from which we read the geometries, etc... * For now we assume it is always the first one in the list *----------------------------------------------------------------*/ m_nMainTableIndex = 0; /*----------------------------------------------------------------- * Make sure all required class members are set *----------------------------------------------------------------*/ m_numTABFiles = CountOfList(m_papszTABFnames); if (m_pszCharset == NULL) m_pszCharset = UGKStrdup("Neutral"); if (m_pszVersion == NULL) m_pszVersion = UGKStrdup("100"); if (CountOfList(m_papszFieldNames) == 0 ) { if (!bTestOpenNoError) UGKError(ET_Failure, UGKErr_NotSupported, "%s: header contains no table field definition. " "This type of .TAB file cannot be read by this library.", m_pszFname); return -1; } if (CountOfList(m_papszWhereClause) == 0 ) { if (!bTestOpenNoError) UGKError(ET_Failure, UGKErr_NotSupported, "%s: WHERE clause not found or missing in header. " "This type of .TAB file cannot be read by this library.", m_pszFname); return -1; } return 0;}/********************************************************************** * TABView::WriteTABFile() * * Generate the TAB header file. This is usually done during the * Close() call. * * Returns 0 on success, -1 on error. **********************************************************************/int TABView::WriteTABFile(){ FILE *fp; assert(m_eAccessMode == TABWrite); assert(m_numTABFiles == 2); assert(GetLayerDefn()); char *pszTable = TABGetBasename(m_pszFname); char *pszTable1 = TABGetBasename(m_papszTABFnames[0]); char *pszTable2 = TABGetBasename(m_papszTABFnames[1]); if ( (fp = fopen(m_pszFname, "wt")) != NULL) { // Version is always 100, no matter what the sub-table's version is fprintf(fp, "!Table\n"); fprintf(fp, "!Version 100\n"); fprintf(fp, "Open Table \"%s\" Hide\n", pszTable1); fprintf(fp, "Open Table \"%s\" Hide\n", pszTable2); fprintf(fp, "\n"); fprintf(fp, "Create View %s As\n", pszTable); fprintf(fp, "Select "); UGKFeatureDefn *poDefn = GetLayerDefn(); for(int iField=0; iField<poDefn->GetFieldCount(); iField++) { UGKFieldDefn *poFieldDefn = poDefn->GetFieldDefn(iField); if (iField == 0) fprintf(fp, "%s", poFieldDefn->GetNameRef()); else fprintf(fp, ",%s", poFieldDefn->GetNameRef()); } fprintf(fp, "\n"); fprintf(fp, "From %s, %s\n", pszTable2, pszTable1); fprintf(fp, "Where %s.%s=%s.%s\n", pszTable2, m_poRelation->GetRelFieldName(), pszTable1, m_poRelation->GetMainFieldName()); fclose(fp); } else { UGKError(ET_Failure, UGKErr_FileIO, "Failed to create file `%s'", m_pszFname); return -1; } UGK_Free(pszTable); UGK_Free(pszTable1); UGK_Free(pszTable2); return 0;}/********************************************************************** * TABView::Close() * * Close current file, and release all memory used. * * Returns 0 on success, -1 on error. **********************************************************************/int TABView::Close(){ // In write access, the main .TAB file has not been written yet. if (m_eAccessMode == TABWrite && m_poRelation) WriteTABFile(); for(int i=0; m_papoTABFiles && i<m_numTABFiles; i++) { if (m_papoTABFiles[i]) delete m_papoTABFiles[i]; // Automatically closes. } UGK_Free(m_papoTABFiles); m_papoTABFiles = NULL; m_numTABFiles = 0; /*----------------------------------------------------------------- * __TODO__ OK, MapInfo does not like to see a .map and .id file * attached to the second table, even if they're empty. * We'll use a little hack to delete them now, but eventually we * should avoid creating them at all. *----------------------------------------------------------------*/ if (m_eAccessMode == TABWrite && m_pszFname) { m_pszFname[strlen(m_pszFname)-4] = '\0'; char *pszFile = UGKStrdup(UGKSPrintf("%s2.map", m_pszFname)); TABAdjustFilenameExtension(pszFile); unlink(pszFile); sprintf(pszFile, "%s2.id", m_pszFname); TABAdjustFilenameExtension(pszFile); unlink(pszFile); UGK_Free(pszFile); } // End of hack! UGK_Free(m_pszFname); m_pszFname = NULL; FreeStrList(m_papszTABFile); m_papszTABFile = NULL; UGK_Free(m_pszVersion); m_pszVersion = NULL; UGK_Free(m_pszCharset); m_pszCharset = NULL; FreeStrList(m_papszTABFnames); m_papszTABFnames = NULL; FreeStrList(m_papszFieldNames); m_papszFieldNames = NULL; FreeStrList(m_papszWhereClause); m_papszWhereClause = NULL; m_nMainTableIndex = -1; if (m_poRelation) delete m_poRelation; m_poRelation = NULL; m_bRelFieldsCreated = FALSE; return 0;}/********************************************************************** * TABView::GetNextFeatureId() * * Returns feature id that follows nPrevId, or -1 if it is the * last feature id. Pass nPrevId=-1 to fetch the first valid feature id. **********************************************************************/int TABView::GetNextFeatureId(int nPrevId){ if (m_nMainTableIndex != -1) return m_papoTABFiles[m_nMainTableIndex]->GetNextFeatureId(nPrevId); return -1;}/********************************************************************** * TABView::GetFeatureRef() * * Fill and return a TABFeature object for the specified feature id. * * The retruned pointer is a reference to an object owned and maintained * by this TABView object. It should not be altered or freed by the * caller and its contents is guaranteed to be valid only until the next * call to GetFeatureRef() or Close(). * * Returns NULL if the specified feature id does not exist of if an * error happened. In any case, CPLError() will have been called to * report the reason of the failure. **********************************************************************/TABFeature *TABView::GetFeatureRef(int nFeatureId){ /*----------------------------------------------------------------- * Make sure file is opened *----------------------------------------------------------------*/ if (m_poRelation == NULL) { UGKError(ET_Failure, UGKErr_IllegalArg, "GetFeatureRef() failed: file is not opened!");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -