📄 mitab_tabview.cpp
字号:
/************************************************************************//* TestCapability() *//************************************************************************/int TABView::TestCapability( const char * pszCap ){ if( EQUAL(pszCap,OLCRandomRead) ) return TRUE; else if( EQUAL(pszCap,OLCSequentialWrite)) return TRUE; else if( EQUAL(pszCap,OLCRandomWrite)) return FALSE; else if( EQUAL(pszCap,OLCFastFeatureCount) ) return m_poFilterGeom == NULL; else if( EQUAL(pszCap,OLCFastSpatialFilter) ) return FALSE; else if( EQUAL(pszCap,OLCFastGetExtent) ) return TRUE; else return FALSE;}/********************************************************************** * TABView::Dump() * * Dump block contents... available only in DEBUG mode. **********************************************************************/#ifdef DEBUGvoid TABView::Dump(FILE *fpOut /*=NULL*/){ if (fpOut == NULL) fpOut = stdout; fprintf(fpOut, "----- TABView::Dump() -----\n"); if (m_numTABFiles > 0) { fprintf(fpOut, "File is not opened.\n"); } else { fprintf(fpOut, "File is opened: %s\n", m_pszFname); fprintf(fpOut, "View contains %d tables\n", m_numTABFiles); } fflush(fpOut);}#endif // DEBUG/*===================================================================== * class TABRelation *====================================================================*//********************************************************************** * TABRelation::TABRelation() * * Constructor. **********************************************************************/TABRelation::TABRelation(){ m_poMainTable = NULL; m_pszMainFieldName = NULL; m_nMainFieldNo = -1; m_poRelTable = NULL; m_pszRelFieldName = NULL; m_nRelFieldNo = -1; m_nRelFieldIndexNo = -1; m_poRelINDFileRef = NULL; m_nUniqueRecordNo = 0; m_panMainTableFieldMap = NULL; m_panRelTableFieldMap = NULL; m_poDefn = NULL;}/********************************************************************** * TABRelation::~TABRelation() * * Destructor. **********************************************************************/TABRelation::~TABRelation(){ ResetAllMembers();}/********************************************************************** * TABRelation::ResetAllMembers() * * Reset all class members. **********************************************************************/void TABRelation::ResetAllMembers(){ m_poMainTable = NULL; CPLFree(m_pszMainFieldName); m_pszMainFieldName = NULL; m_nMainFieldNo = -1; m_poRelTable = NULL; CPLFree(m_pszRelFieldName); m_pszRelFieldName = NULL; m_nRelFieldNo = -1; m_nRelFieldIndexNo = -1; m_nUniqueRecordNo = 0; // No need to close m_poRelINDFileRef since we only got a ref. to it m_poRelINDFileRef = NULL; CPLFree(m_panMainTableFieldMap); m_panMainTableFieldMap = NULL; CPLFree(m_panRelTableFieldMap); m_panRelTableFieldMap = NULL; /*----------------------------------------------------------------- * Note: we have to check the reference count before deleting m_poDefn *----------------------------------------------------------------*/ if (m_poDefn && m_poDefn->Dereference() == 0) delete m_poDefn; m_poDefn = NULL;}/********************************************************************** * TABRelation::Init() * * Set the details of the relation: the main and related tables, the fields * through which they will be connected, and the list of fields to select. * After this call, we are ready to read data records. * * For write access, Init() is called with pszMain/RelFieldName and * **papszSelectedFields passed as NULL. They will have to be set through * other methods before a first feature can be written. * * A new OGRFeatureDefn is also built for the combined tables. * * Returns 0 on success, or -1 or error. **********************************************************************/int TABRelation::Init(const char *pszViewName, TABFile *poMainTable, TABFile *poRelTable, const char *pszMainFieldName, const char *pszRelFieldName, char **papszSelectedFields){ if (poMainTable == NULL || poRelTable == NULL) return -1; // We'll need the feature Defn later... OGRFeatureDefn *poMainDefn, *poRelDefn; poMainDefn = poMainTable->GetLayerDefn(); poRelDefn = poRelTable->GetLayerDefn(); /*----------------------------------------------------------------- * Keep info for later use about source tables, etc. *----------------------------------------------------------------*/ ResetAllMembers(); m_poMainTable = poMainTable; if (pszMainFieldName) { m_pszMainFieldName = CPLStrdup(pszMainFieldName); m_nMainFieldNo = poMainDefn->GetFieldIndex(pszMainFieldName); } m_poRelTable = poRelTable; if (pszRelFieldName) { m_pszRelFieldName = CPLStrdup(pszRelFieldName); m_nRelFieldNo = poRelDefn->GetFieldIndex(pszRelFieldName); m_nRelFieldIndexNo = poRelTable->GetFieldIndexNumber(m_nRelFieldNo); m_poRelINDFileRef = poRelTable->GetINDFileRef(); if (m_nRelFieldIndexNo >= 0 && m_poRelINDFileRef == NULL) { CPLError(CE_Failure, CPLE_FileIO, "Field %s is indexed but the .IND file is missing.", pszRelFieldName); return -1; } } /*----------------------------------------------------------------- * Init field maps. For each field in each table, a -1 means that * the field is not selected, and a value >=0 is the index of the * field in the view's FeatureDefn *----------------------------------------------------------------*/ int i; int numFields1 = (poMainDefn?poMainDefn->GetFieldCount():0); int numFields2 = (poRelDefn?poRelDefn->GetFieldCount():0); m_panMainTableFieldMap = (int*)CPLMalloc((numFields1+1)*sizeof(int)); for(i=0; i<numFields1; i++) m_panMainTableFieldMap[i] = -1; m_panRelTableFieldMap = (int*)CPLMalloc((numFields2+1)*sizeof(int)); for(i=0; i<numFields2; i++) m_panRelTableFieldMap[i] = -1; /*----------------------------------------------------------------- * If selectedFields = "*" then select all fields from both tables *----------------------------------------------------------------*/ if (CSLCount(papszSelectedFields) == 1 && EQUAL(papszSelectedFields[0], "*") ) { CSLDestroy(papszSelectedFields); papszSelectedFields = NULL; for(i=0; i<numFields1; i++) { OGRFieldDefn *poFieldDefn = poMainDefn->GetFieldDefn(i); papszSelectedFields = CSLAddString(papszSelectedFields, poFieldDefn->GetNameRef()); } for(i=0; i<numFields2; i++) { OGRFieldDefn *poFieldDefn = poRelDefn->GetFieldDefn(i); if (CSLFindString(papszSelectedFields, poFieldDefn->GetNameRef()) != -1) continue; // Avoid duplicate field name in view papszSelectedFields = CSLAddString(papszSelectedFields, poFieldDefn->GetNameRef()); } } /*----------------------------------------------------------------- * Create new FeatureDefn and copy selected fields definitions * while updating the appropriate field maps. *----------------------------------------------------------------*/ int nIndex, numSelFields = CSLCount(papszSelectedFields); OGRFieldDefn *poFieldDefn; m_poDefn = new OGRFeatureDefn(pszViewName); // Ref count defaults to 0... set it to 1 m_poDefn->Reference(); for(i=0; i<numSelFields ; i++) { if (poMainDefn && (nIndex=poMainDefn->GetFieldIndex(papszSelectedFields[i])) >=0) { /* Field from the main table */ poFieldDefn = poMainDefn->GetFieldDefn(nIndex); m_poDefn->AddFieldDefn(poFieldDefn); m_panMainTableFieldMap[nIndex] = m_poDefn->GetFieldCount()-1; } else if (poRelDefn && (nIndex=poRelDefn->GetFieldIndex(papszSelectedFields[i]))>=0) { /* Field from the related table */ poFieldDefn = poRelDefn->GetFieldDefn(nIndex); m_poDefn->AddFieldDefn(poFieldDefn); m_panRelTableFieldMap[nIndex] = m_poDefn->GetFieldCount()-1; } else { // Hummm... field does not exist... likely an unsupported feature! // At least send a warning and ignore the field. CPLError(CE_Warning, CPLE_IllegalArg, "Selected Field %s not found in source tables %s and %s", papszSelectedFields[i], poMainDefn->GetName(), poRelDefn->GetName()); } } return 0;}/********************************************************************** * TABRelation::CreateRelFields() * * For write access, create the integer fields in each table that will * link them, and setup everything to be ready to write the first feature. * * This function should be called just before writing the first feature. * * Returns 0 on success, or -1 or error. **********************************************************************/int TABRelation::CreateRelFields(){ int i; /*----------------------------------------------------------------- * Create the field in each table. * The default name is "MI_refnum" but if a field with the same name * already exists then we'll try to generate a unique name. *----------------------------------------------------------------*/ m_pszMainFieldName = CPLStrdup("MI_Refnum "); strcpy(m_pszMainFieldName, "MI_Refnum"); i = 1; while(m_poDefn->GetFieldIndex(m_pszMainFieldName) >= 0) { sprintf(m_pszMainFieldName, "MI_Refnum_%d", i++); } m_pszRelFieldName = CPLStrdup(m_pszMainFieldName); m_nMainFieldNo = m_nRelFieldNo = -1; if (m_poMainTable->AddFieldNative(m_pszMainFieldName, TABFInteger, 0, 0) == 0) m_nMainFieldNo = m_poMainTable->GetLayerDefn()->GetFieldCount()-1; if (m_poRelTable->AddFieldNative(m_pszRelFieldName, TABFInteger, 0, 0) == 0) m_nRelFieldNo = m_poRelTable->GetLayerDefn()->GetFieldCount()-1; if (m_nMainFieldNo == -1 || m_nRelFieldNo == -1) return -1; if (m_poMainTable->SetFieldIndexed(m_nMainFieldNo) == -1) return -1; if ((m_nRelFieldIndexNo=m_poRelTable->SetFieldIndexed(m_nRelFieldNo)) ==-1) return -1; m_poRelINDFileRef = m_poRelTable->GetINDFileRef(); /*----------------------------------------------------------------- * Update field maps *----------------------------------------------------------------*/ OGRFeatureDefn *poMainDefn, *poRelDefn; poMainDefn = m_poMainTable->GetLayerDefn(); poRelDefn = m_poRelTable->GetLayerDefn(); m_panMainTableFieldMap = (int*)CPLRealloc(m_panMainTableFieldMap, poMainDefn->GetFieldCount()*sizeof(int)); m_panMainTableFieldMap[poMainDefn->GetFieldCount()-1] = -1; m_panRelTableFieldMap = (int*)CPLRealloc(m_panRelTableFieldMap, poRelDefn->GetFieldCount()*sizeof(int)); m_panRelTableFieldMap[poRelDefn->GetFieldCount()-1] = -1; /*----------------------------------------------------------------- * Make sure the first unique field (in poRelTable) is indexed since * it is the one against which we will try to match records. *----------------------------------------------------------------*/ if ( m_poRelTable->SetFieldIndexed(0) == -1) return -1; return 0;}/********************************************************************** * TABRelation::GetFeature() * * Fill and return a TABFeature object for the specified feature id. * * The retuned pointer is a new TABFeature that will have to be freed * by the caller. * * Returns NULL if the specified feature id does not exist of if an * error happened. In any case, CPLError() will have been called to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -