📄 mapinfofile.cpp
字号:
// MapInfoFile.cpp: implementation of the MapInfoFile class.////////////////////////////////////////////////////////////////////////#include "mapinfofile.h"#include "ugk_errhandle.h"#include "ugk_memopr.h"#include "ugk_string.h"#include "miffile.h"#include "tabview.h"#include "tabseamless.h"#include "tabfile.h" #include "tabpoint.h"#include "tabregion.h"#include "tabpolyline.h"#include "ugkgeometrycollection.h" /********************************************************************** * MapInfoFile::MapInfoFile() * * Constructor. **********************************************************************/MapInfoFile::MapInfoFile(){ m_nCurFeatureId = 0; m_poCurFeature = NULL; m_bBoundsSet = FALSE;}/********************************************************************** * MapInfoFile::~MapInfoFile() * * Destructor. **********************************************************************/MapInfoFile::~MapInfoFile(){ if (m_poCurFeature) { delete m_poCurFeature; m_poCurFeature = NULL; }}/********************************************************************** * MapInfoFile::SmartOpen() * * Use this static method to automatically open any flavour of MapInfo * dataset. This method will detect the file type, create an object * of the right type, and open the file. * * Call GetFileClass() on the returned object if you need to find out * its exact type. (To access format-specific methods for instance) * * Returns the new object ptr. , or NULL if the open failed. **********************************************************************/MapInfoFile *MapInfoFile::SmartOpen(const char *pszFname, UGKBool bTestOpenNoError /*=FALSE*/){ MapInfoFile *poFile = NULL; int nLen = 0; if (pszFname) nLen = strlen(pszFname); if (nLen > 4 && (EQUAL(pszFname + nLen-4, ".MIF") || EQUAL(pszFname + nLen-4, ".MID") ) ) { /*------------------------------------------------------------- * MIF/MID file *------------------------------------------------------------*/ poFile = new MIFFile; } else if (nLen > 4 && EQUAL(pszFname + nLen-4, ".TAB")) { /*------------------------------------------------------------- * .TAB file ... is it a TABFileView or a TABFile? * We have to read the .tab header to find out. *------------------------------------------------------------*/ FILE *fp; const char *pszLine; char *pszAdjFname = UGKStrdup(pszFname); UGKBool bFoundFields = FALSE, bFoundView=FALSE, bFoundSeamless=FALSE; TABAdjustFilenameExtension(pszAdjFname); fp = fopen(pszAdjFname, "r"); while(fp && (pszLine = ReadLineFromTxt(fp)) != NULL) { while (isspace(*pszLine)) pszLine++; if (EQUALN(pszLine, "Fields", 6)) bFoundFields = TRUE; else if (EQUALN(pszLine, "create view", 11)) bFoundView = TRUE; else if (EQUALN(pszLine, "\"\\IsSeamless\" = \"TRUE\"", 21)) bFoundSeamless = TRUE; } if (bFoundView) poFile = new TABView; else if (bFoundFields && bFoundSeamless) poFile = new TABSeamless; else if (bFoundFields) poFile = new TABFile; if (fp) fclose(fp); UGK_Free(pszAdjFname); } /*----------------------------------------------------------------- * Perform the open() call *----------------------------------------------------------------*/ if (poFile && poFile->Open(pszFname, "r", bTestOpenNoError) != 0) { delete poFile; poFile = NULL; } if (!bTestOpenNoError && poFile == NULL) { UGKError(ET_Failure, UGKErr_FileIO, "%s could not be opened as a MapInfo dataset.", pszFname); } return poFile;}/********************************************************************** * MapInfoFile::GetNextFeature() * * Standard UGK GetNextFeature implementation. This methode is used * to retreive the next UGKFeature. **********************************************************************/UGKFeature *MapInfoFile::GetNextFeature(){ UGKFeature *poFeatureRef; UGKGeometry *poGeom; int nFeatureId; while( (nFeatureId = GetNextFeatureId(m_nCurFeatureId)) != -1 ) { poFeatureRef = GetFeatureRef(nFeatureId); if (poFeatureRef == NULL) return NULL; else if( (m_poFilterGeom == NULL || ((poGeom = poFeatureRef->GetGeometryRef()) != NULL && FilterGeometry( poGeom ))) ) { // Avoid cloning feature... return the copy owned by the class assert(poFeatureRef == m_poCurFeature); //m_poCurFeature = NULL; MOD--ZGQ --06/03/20 /* 这里将m_poCurFeature置为0后,在下次调用TABFile::GetFeatureRef()时,就不会把 m_poCurFeature指向的对象释放,从而导致内存泄漏 */ return poFeatureRef; } } return NULL;}/********************************************************************** * MapInfoFile::CreateFeature() * * Standard UGK CreateFeature implementation. This methode is used * to create a new feature in current dataset **********************************************************************/UGKErr MapInfoFile::CreateFeature(UGKFeature *poFeature){ TABFeature *poTABFeature; UGKGeometry *poGeom; UGKwkbGeometryType eGType; UGKErr eErr; /*----------------------------------------------------------------- * MITAB won't accept new features unless they are in a type derived * from TABFeature... so we have to do our best to map to the right * feature type based on the geometry type. *----------------------------------------------------------------*/ poGeom = poFeature->GetGeometryRef(); if( poGeom != NULL ) eGType = poGeom->getGeometryType(); else eGType = wkbNone; switch( wkbFlatten(eGType) ) { /*------------------------------------------------------------- * POINT *------------------------------------------------------------*/ case wkbPoint: poTABFeature = new TABPoint(poFeature->GetDefnRef()); break; /*------------------------------------------------------------- * REGION *------------------------------------------------------------*/ case wkbPolygon: case wkbMultiPolygon: poTABFeature = new TABRegion(poFeature->GetDefnRef()); break; /*------------------------------------------------------------- * LINE/PLINE/MULTIPLINE *------------------------------------------------------------*/ case wkbLineString: case wkbMultiLineString: poTABFeature = new TABPolyline(poFeature->GetDefnRef()); break; /*------------------------------------------------------------- * Collection types that are not directly supported... convert * to multiple features in output file through recursive calls. *------------------------------------------------------------*/ case wkbGeometryCollection: case wkbMultiPoint: { UGKErr eStatus = UGKERR_NONE; int i; UGKGeometryCollection *poColl = (UGKGeometryCollection*)poGeom; UGKFeature *poTmpFeature = poFeature->Clone(); for (i=0; eStatus==UGKERR_NONE && i<poColl->getNumGeometries(); i++) { poTmpFeature->SetGeometry(poColl->getGeometryRef(i)); eStatus = CreateFeature(poTmpFeature); } delete poTmpFeature; return eStatus; } break; /*------------------------------------------------------------- * Unsupported type.... convert to MapInfo geometry NONE *------------------------------------------------------------*/ case wkbUnknown: default: poTABFeature = new TABFeature(poFeature->GetDefnRef()); break; } if( poGeom != NULL ) poTABFeature->SetGeometryDirectly(poGeom->clone()); for (int i=0; i< poFeature->GetDefnRef()->GetFieldCount();i++) { poTABFeature->SetField(i,poFeature->GetRawFieldRef( i )); } if (SetFeature(poTABFeature) > -1) eErr = UGKERR_NONE; else eErr = UGKERR_FAILURE; delete poTABFeature; return eErr;}/********************************************************************** * MapInfoFile::GetFeature() * * Standard UGK GetFeature implementation. This methode is used * to get the wanted (nFeatureId) feature, a NULL value will be * returned on error. **********************************************************************/UGKFeature *MapInfoFile::GetFeature(long nFeatureId){ UGKFeature *poFeatureRef; poFeatureRef = GetFeatureRef(nFeatureId); if (poFeatureRef) { // Avoid cloning feature... return the copy owned by the class assert(poFeatureRef == m_poCurFeature); m_poCurFeature = NULL; return poFeatureRef; } else return NULL;}/************************************************************************//* CreateField() *//* *//* Create a native field based on a generic UGK definition. *//************************************************************************/UGKErr MapInfoFile::CreateField( UGKFieldDefn *poField, int bApproxOK ){ TABFieldType eTABType; int nWidth = poField->GetWidth(); if( poField->GetType() == OFTInteger ) { eTABType = TABFInteger; if( nWidth == 0 ) nWidth = 12; } else if( poField->GetType() == OFTReal ) { eTABType = TABFFloat; if( nWidth == 0 ) nWidth = 32; } else if( poField->GetType() == OFTString ) { eTABType = TABFChar; if( nWidth == 0 ) nWidth = 254; else nWidth = (254<nWidth) ? 254 : nWidth; } else { UGKError( ET_Failure, UGKErr_AppDefined, "IMapInfoFile::CreateField() called with unsupported field" " type %d.\n" "Note that Mapinfo files don't support list field types.\n", poField->GetType() ); return UGKERR_FAILURE; } if( AddFieldNative( poField->GetNameRef(), eTABType, nWidth, poField->GetPrecision() ) > -1 ) return UGKERR_NONE; else return UGKERR_FAILURE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -