📄 mitab_tabview.cpp
字号:
* report the reason of the failure. * * __TODO__ The current implementation fetches the features from each table * and creates a 3rd feature to merge them. There would be room for * optimization, at least by avoiding the duplication of the geometry * which can be big sometimes... but this would imply changes at the * lower-level in the lib. and we won't go there yet. **********************************************************************/TABFeature *TABRelation::GetFeature(int nFeatureId){ TABFeature *poMainFeature; TABFeature *poCurFeature; /*----------------------------------------------------------------- * Make sure init() has been called *----------------------------------------------------------------*/ if (m_poMainTable == NULL || m_poRelTable == NULL) { CPLError(CE_Failure, CPLE_IllegalArg, "GetFeatureRef() failed: object not initialized yet!"); return NULL; } /*----------------------------------------------------------------- * Read main feature and create a new one of the right type *----------------------------------------------------------------*/ if ((poMainFeature = m_poMainTable->GetFeatureRef(nFeatureId)) == NULL) { // Feature cannot be read from main table... // an error has already been reported. return NULL; } poCurFeature = poMainFeature->CloneTABFeature(m_poDefn); /*----------------------------------------------------------------- * Keep track of FID and copy the geometry *----------------------------------------------------------------*/ poCurFeature->SetFID(nFeatureId); if (poCurFeature->GetFeatureClass() != TABFCNoGeomFeature) { OGRGeometry *poGeom; poGeom = poMainFeature->GetGeometryRef(); poCurFeature->SetGeometry(poGeom); } /*----------------------------------------------------------------- * Fetch feature from related table * * __TODO__ Right now we support only many-to-1 relationships, but * it might be possible to have several related entries * for a single key, and in this case we should return * one new feature for each of them. *----------------------------------------------------------------*/ TABFeature *poRelFeature=NULL; GByte *pKey = BuildFieldKey(poMainFeature, m_nMainFieldNo, m_poMainTable->GetNativeFieldType(m_nMainFieldNo), m_nRelFieldIndexNo); int i; int nRelFeatureId = m_poRelINDFileRef->FindFirst(m_nRelFieldIndexNo, pKey); if (nRelFeatureId > 0) poRelFeature = m_poRelTable->GetFeatureRef(nRelFeatureId); /*----------------------------------------------------------------- * Copy fields from poMainFeature *----------------------------------------------------------------*/ for(i=0; i<poMainFeature->GetFieldCount(); i++) { if (m_panMainTableFieldMap[i] != -1) { poCurFeature->SetField(m_panMainTableFieldMap[i], poMainFeature->GetRawFieldRef(i)); } } /*----------------------------------------------------------------- * Copy fields from poRelFeature... * * NOTE: For now, if no corresponding feature is found in RelTable * then we will just leave the corresponding fields unset. *----------------------------------------------------------------*/ for(i=0; poRelFeature && i<poRelFeature->GetFieldCount(); i++) { if (m_panRelTableFieldMap[i] != -1) { poCurFeature->SetField(m_panRelTableFieldMap[i], poRelFeature->GetRawFieldRef(i)); } } return poCurFeature;}/********************************************************************** * TABRelation::BuildFieldKey() * * Return the index key for the specified field in poFeature. * Simply maps the call to the proper method in the TABINDFile class. * * Returns a reference to a TABINDFile internal buffer that should not * be freed by the caller. **********************************************************************/GByte *TABRelation::BuildFieldKey(TABFeature *poFeature, int nFieldNo, TABFieldType eType, int nIndexNo){ GByte *pKey = NULL; switch(eType) { case TABFChar: pKey = m_poRelINDFileRef->BuildKey(nIndexNo, poFeature->GetFieldAsString(nFieldNo)); break; case TABFDecimal: case TABFFloat: pKey = m_poRelINDFileRef->BuildKey(nIndexNo, poFeature->GetFieldAsDouble(nFieldNo)); break; case TABFInteger: case TABFSmallInt: case TABFDate: case TABFLogical: default: pKey = m_poRelINDFileRef->BuildKey(nIndexNo, poFeature->GetFieldAsInteger(nFieldNo)); break; } return pKey;}/********************************************************************** * TABRelation::GetNativeFieldType() * * Returns the native MapInfo field type for the specified field. * * Returns TABFUnknown if file is not opened, or if specified field index is * invalid. * * Note that field ids are positive and start at 0. **********************************************************************/TABFieldType TABRelation::GetNativeFieldType(int nFieldId){ int i, numFields; if (m_poMainTable==NULL || m_poRelTable==NULL || m_panMainTableFieldMap==NULL || m_panRelTableFieldMap==NULL) return TABFUnknown; /*----------------------------------------------------------------- * Look for nFieldId in the field maps and call the corresponding * TAB file's GetNativeFieldType() *----------------------------------------------------------------*/ numFields = m_poMainTable->GetLayerDefn()->GetFieldCount(); for(i=0; i<numFields; i++) { if (m_panMainTableFieldMap[i] == nFieldId) { return m_poMainTable->GetNativeFieldType(i); } } numFields = m_poRelTable->GetLayerDefn()->GetFieldCount(); for(i=0; i<numFields; i++) { if (m_panRelTableFieldMap[i] == nFieldId) { return m_poRelTable->GetNativeFieldType(i); } } return TABFUnknown;}/********************************************************************** * TABRelation::AddFieldNative() * * Create a new field using a native mapinfo data type... this is an * alternative to defining fields through the OGR interface. * This function should be called after creating a new dataset, but before * writing the first feature. * * This function will build/update the OGRFeatureDefn that will have to be * used when writing features to this dataset. * * A reference to the OGRFeatureDefn can be obtained using GetLayerDefn(). * * Returns 0 on success, -1 on error. **********************************************************************/int TABRelation::AddFieldNative(const char *pszName, TABFieldType eMapInfoType, int nWidth /*=0*/, int nPrecision /*=0*/, GBool bIndexed /*=FALSE*/, GBool bUnique/*=FALSE*/){ if (m_poMainTable==NULL || m_poRelTable==NULL || m_panMainTableFieldMap==NULL || m_panRelTableFieldMap==NULL) return -1; if (!bUnique) { /*------------------------------------------------------------- * Add field to poMainTable and to m_poDefn *------------------------------------------------------------*/ if (m_poMainTable->AddFieldNative(pszName, eMapInfoType, nWidth, nPrecision, bIndexed) != 0) return -1; OGRFeatureDefn *poMainDefn = m_poMainTable->GetLayerDefn(); m_panMainTableFieldMap = (int*)CPLRealloc(m_panMainTableFieldMap, poMainDefn->GetFieldCount()*sizeof(int)); m_poDefn->AddFieldDefn(poMainDefn->GetFieldDefn(poMainDefn-> GetFieldCount()-1)); m_panMainTableFieldMap[poMainDefn->GetFieldCount()-1] = m_poDefn->GetFieldCount()-1; } else { /*------------------------------------------------------------- * Add field to poRelTable and to m_poDefn *------------------------------------------------------------*/ if (m_poRelTable->AddFieldNative(pszName, eMapInfoType, nWidth, nPrecision, bIndexed) != 0) return -1; OGRFeatureDefn *poRelDefn = m_poRelTable->GetLayerDefn(); m_panRelTableFieldMap = (int*)CPLRealloc(m_panRelTableFieldMap, poRelDefn->GetFieldCount()*sizeof(int)); m_poDefn->AddFieldDefn(poRelDefn->GetFieldDefn(poRelDefn-> GetFieldCount()-1)); m_panRelTableFieldMap[poRelDefn->GetFieldCount()-1] = m_poDefn->GetFieldCount()-1; // The first field in this table must be indexed. if (poRelDefn->GetFieldCount() == 1) m_poRelTable->SetFieldIndexed(0); } return 0;}/********************************************************************** * TABRelation::IsFieldIndexed() * * Returns TRUE is specified field is indexed. * * Note that field ids are positive and start at 0. **********************************************************************/GBool TABRelation::IsFieldIndexed(int nFieldId){ int i, numFields; if (m_poMainTable==NULL || m_poRelTable==NULL || m_panMainTableFieldMap==NULL || m_panRelTableFieldMap==NULL) return FALSE; /*----------------------------------------------------------------- * Look for nFieldId in the field maps and call the corresponding * TAB file's GetNativeFieldType() *----------------------------------------------------------------*/ numFields = m_poMainTable->GetLayerDefn()->GetFieldCount(); for(i=0; i<numFields; i++) { if (m_panMainTableFieldMap[i] == nFieldId) { return m_poMainTable->IsFieldIndexed(i); } } numFields = m_poRelTable->GetLayerDefn()->GetFieldCount(); for(i=0; i<numFields; i++) { if (m_panRelTableFieldMap[i] == nFieldId) { return m_poRelTable->IsFieldIndexed(i); } } return FALSE;}/********************************************************************** * TABRelation::SetFieldIndexed() * * Request that the specified field be indexed. This will create the .IND * file, etc. * * Note that field ids are positive and start at 0. * * Returns 0 on success, -1 on error. **********************************************************************/int TABRelation::SetFieldIndexed(int nFieldId){ int i, numFields; if (m_poMainTable==NULL || m_poRelTable==NULL || m_panMainTableFieldMap==NULL || m_panRelTableFieldMap==NULL) return -1; /*----------------------------------------------------------------- * Look for nFieldId in the field maps and call the corresponding * TAB file's GetNativeFieldType() *----------------------------------------------------------------*/ numFields = m_poMainTable->GetLayerDefn()->GetFieldCount(); for(i=0; i<numFields; i++) { if (m_panMainTableFieldMap[i] == nFieldId) { return m_poMainTable->SetFieldIndexed(i); } } numFields = m_poRelTable->GetLayerDefn()->GetFieldCount(); for(i=0; i<numFields; i++) { if (m_panRelTableFieldMap[i] == nFieldId) { return m_poRelTable->SetFieldIndexed(i); } } return -1;}/********************************************************************** * TABRelation::IsFieldUnique() * * Returns TRUE is specified field is part of the unique table (poRelTable). * * Note that field ids are positive and start at 0. **********************************************************************/GBool TABRelation::IsFieldUnique(int nFieldId){ int i, numFields; if (m_poMainTable==NULL || m_poRelTable==NULL || m_panMainTableFieldMap==NULL || m_panRelTableFieldMap==NULL) return FALSE; /*----------------------------------------------------------------- * Look for nFieldId in the poRelTable field map *----------------------------------------------------------------*/ numFields = m_poRelTable->GetLayerDefn()->GetFieldCount(); for(i=0; i<numFields; i++) { if (m_panRelTableFieldMap[i] == nFieldId) { return TRUE; // If it's here then it is unique! } } return FALSE;}/********************************************************************** * TABRelation::SetFeature() * * Write a feature to this dataset. * * For now only sequential writes are supported (i.e. with nFeatureId=-1) * but eventually we should be able to do random access by specifying * a v
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -