📄 miffile.cpp
字号:
// miffile.cpp: implementation of the MIFFile class.///*===================================================================== * class MIFFile *====================================================================*/#include "miffile.h"#include "ugk_errhandle.h"#include "ugk_memopr.h"#include "ugk_string.h"#include "tabpoint.h"#include "tabfontpoint.h"#include "tabcustompoint.h"#include "tabpolyline.h"#include "tabregion.h"#include "tabarc.h"#include "tabtext.h"#include "tabrectangle.h"#include "tabellipse.h"#include "tabmultipoint.h"/********************************************************************** * MIFFile::MIFFile() * * Constructor. **********************************************************************/MIFFile::MIFFile(){ m_pszFname = NULL; m_pszVersion = NULL; m_pszCharset = NULL; // Tab is default delimiter in MIF spec if not explicitly specified. Use // that by default for read mode. In write mode, we will use "," as // delimiter since it's more common than tab (we do this in Open()) m_pszDelimiter = UGKStrdup("\t"); m_pszUnique = NULL; m_pszIndex = NULL; m_pszCoordSys = NULL; m_paeFieldType = NULL; m_pabFieldIndexed = NULL; m_pabFieldUnique = NULL; m_dfXMultiplier = 1.0; m_dfYMultiplier = 1.0; m_dfXDisplacement = 0.0; m_dfYDisplacement = 0.0; m_poMIDFile = NULL; m_poMIFFile = NULL; m_nPreloadedId = 0; m_poDefn = NULL; m_nCurFeatureId = 0; m_nFeatureCount = 0; m_nWriteFeatureId = -1; m_poCurFeature = NULL; m_bPreParsed = FALSE; m_nAttribut = 0; m_bHeaderWrote = FALSE; m_nPoints = m_nLines = m_nRegions = m_nTexts = 0; m_bExtentsSet = FALSE;}/********************************************************************** * MIFFile::~MIFFile() * * Destructor. **********************************************************************/MIFFile::~MIFFile(){ Close();}/********************************************************************** * MIFFile::Open() * * Returns 0 on success, -1 on error. **********************************************************************/int MIFFile::Open(const char *pszFname, const char *pszAccess, UGKBool bTestOpenNoError /*=FALSE*/ ){ char *pszTmpFname = NULL; int nFnameLen = 0; UGKErrorReset(); if (m_poMIDFile) { UGKError(ET_Failure, UGKErr_FileIO, "Open() failed: object already contains an open file"); return -1; } /*----------------------------------------------------------------- * Validate access mode *----------------------------------------------------------------*/ if (EQUALN(pszAccess, "r", 1)) { m_eAccessMode = TABRead; pszAccess = "rt"; } else if (EQUALN(pszAccess, "w", 1)) { m_eAccessMode = TABWrite; pszAccess = "wt"; // In write mode, use "," as delimiter since it's more common than tab UGK_Free(m_pszDelimiter); m_pszDelimiter = UGKStrdup(","); } else { if (!bTestOpenNoError) UGKError(ET_Failure, UGKErr_FileIO, "Open() failed: access mode \"%s\" not supported", pszAccess); else UGKErrorReset(); return -1; } /*----------------------------------------------------------------- * Make sure filename has a .MIF or .MID extension... *----------------------------------------------------------------*/ m_pszFname = UGKStrdup(pszFname); nFnameLen = strlen(m_pszFname); if (nFnameLen > 4 && (strcmp(m_pszFname+nFnameLen-4, ".MID")==0 || strcmp(m_pszFname+nFnameLen-4, ".MIF")==0 ) ) strcpy(m_pszFname+nFnameLen-4, ".MIF"); else if (nFnameLen > 4 && (EQUAL(m_pszFname+nFnameLen-4, ".mid") || EQUAL(m_pszFname+nFnameLen-4, ".mif") ) ) strcpy(m_pszFname+nFnameLen-4, ".mif"); else { if (!bTestOpenNoError) UGKError(ET_Failure, UGKErr_FileIO, "Open() failed for %s: invalid filename extension", m_pszFname); else UGKErrorReset(); UGK_Free(m_pszFname); return -1; } pszTmpFname = UGKStrdup(m_pszFname); /*----------------------------------------------------------------- * Open .MIF file *----------------------------------------------------------------*/#ifndef WIN32APP /*----------------------------------------------------------------- * On Unix, make sure extension uses the right cases * We do it even for write access because if a file with the same * extension already exists we want to overwrite it. *----------------------------------------------------------------*/ TABAdjustFilenameExtension(pszTmpFname);#endif m_poMIFFile = new MIDDATAFile; if (m_poMIFFile->Open(pszTmpFname, pszAccess) != 0) { if (!bTestOpenNoError) UGKError(ET_Failure, UGKErr_NotSupported, "Unable to open %s.", pszTmpFname); else UGKErrorReset(); UGK_Free(pszTmpFname); Close(); return -1; } /*----------------------------------------------------------------- * Open .MID file *----------------------------------------------------------------*/ if (nFnameLen > 4 && strcmp(pszTmpFname+nFnameLen-4, ".MIF")==0) strcpy(pszTmpFname+nFnameLen-4, ".MID"); else strcpy(pszTmpFname+nFnameLen-4, ".mid");#ifndef WIN32APP TABAdjustFilenameExtension(pszTmpFname);#endif m_poMIDFile = new MIDDATAFile; if (m_poMIDFile->Open(pszTmpFname, pszAccess) !=0) { if (!bTestOpenNoError) UGKError(ET_Failure, UGKErr_NotSupported, "Unable to open %s.", pszTmpFname); else UGKErrorReset(); UGK_Free(pszTmpFname); Close(); return -1; } UGK_Free(pszTmpFname); pszTmpFname = NULL; /*----------------------------------------------------------------- * Read MIF File Header *----------------------------------------------------------------*/ if (m_eAccessMode == TABRead && ParseMIFHeader() != 0) { Close(); if (!bTestOpenNoError) UGKError(ET_Failure, UGKErr_NotSupported, "Failed parsing header in %s.", m_pszFname); else UGKErrorReset(); return -1; } /*----------------------------------------------------------------- * In write access, set some defaults *----------------------------------------------------------------*/ if (m_eAccessMode == TABWrite) { m_pszVersion = UGKStrdup("300"); m_pszCharset = UGKStrdup("Neutral"); } /* Put the MID file at the correct location, on the first feature */ if (m_eAccessMode == TABRead && (m_poMIDFile->GetLine() == NULL)) { Close(); if (bTestOpenNoError) UGKErrorReset(); return -1; } m_poMIFFile->SetTranslation(m_dfXMultiplier,m_dfYMultiplier, m_dfXDisplacement, m_dfYDisplacement); m_poMIDFile->SetTranslation(m_dfXMultiplier,m_dfYMultiplier, m_dfXDisplacement, m_dfYDisplacement); m_poMIFFile->SetDelimiter(m_pszDelimiter); m_poMIDFile->SetDelimiter(m_pszDelimiter); /*------------------------------------------------------------- * Set geometry type if the geometry objects are uniform. *------------------------------------------------------------*/ int numPoints=0, numRegions=0, numTexts=0, numLines=0; if( GetFeatureCountByType( numPoints, numLines, numRegions, numTexts, FALSE ) == 0 ) { numPoints += numTexts; if( numPoints > 0 && numLines == 0 && numRegions == 0 ) m_poDefn->SetGeomType( wkbPoint ); else if( numPoints == 0 && numLines > 0 && numRegions == 0 ) m_poDefn->SetGeomType( wkbLineString ); else if( numPoints == 0 && numLines == 0 && numRegions > 0 ) m_poDefn->SetGeomType( wkbPolygon ); else /* we leave it unknown indicating a mixture */; } return 0;}/********************************************************************** * MIFFile::ParseMIFHeader() * * Scan the header of a MIF file, and store any useful information into * class members. The main piece of information being the fields * definition that we use to build the UGKFeatureDefn for this file. * * This private method should be used only during the Open() call. * * Returns 0 on success, -1 on error. **********************************************************************/int MIFFile::ParseMIFHeader(){ UGKBool bColumns = FALSE; int nColumns = 0; UGKBool bCoordSys = FALSE; char *pszTmp; const char *pszLine; char **papszToken; char *pszFeatureClassName = TABGetBasename(m_pszFname); m_poDefn = new UGKFeatureDefn(pszFeatureClassName); UGK_Free(pszFeatureClassName); // Ref count defaults to 0... set it to 1 m_poDefn->Reference(); if (m_eAccessMode != TABRead) { UGKError(ET_Failure, UGKErr_NotSupported, "ParseMIDFile() can be used only with Read access."); return -1; } /*----------------------------------------------------------------- * Parse header until we find the "Data" line *----------------------------------------------------------------*/ while (((pszLine = m_poMIFFile->GetLine()) != NULL) && !(EQUALN(pszLine,"Data",4))) { while(pszLine && *pszLine == ' ') pszLine++; // skip leading spaces if (EQUALN(pszLine,"VERSION",7)) { papszToken = TokenizeStringComplex(pszLine," ()\t",TRUE,FALSE); bColumns = FALSE; bCoordSys = FALSE; if (CountOfList(papszToken) == 2) m_pszVersion = UGKStrdup(papszToken[1]); FreeStrList(papszToken); } else if (EQUALN(pszLine,"CHARSET",7)) { papszToken = TokenizeStringComplex(pszLine," ()\t",TRUE,FALSE); bColumns = FALSE; bCoordSys = FALSE; if (CountOfList(papszToken) == 2) m_pszCharset = UGKStrdup(papszToken[1]); FreeStrList(papszToken); } else if (EQUALN(pszLine,"DELIMITER",9)) { papszToken = TokenizeStringComplex(pszLine," ()\t",TRUE,FALSE); bColumns = FALSE; bCoordSys = FALSE; if (CountOfList(papszToken) == 2) { UGK_Free(m_pszDelimiter); m_pszDelimiter = UGKStrdup(papszToken[1]); } FreeStrList(papszToken); } else if (EQUALN(pszLine,"UNIQUE",6)) { bColumns = FALSE; bCoordSys = FALSE; m_pszUnique = UGKStrdup(pszLine + 6); } else if (EQUALN(pszLine,"INDEX",5)) { bColumns = FALSE; bCoordSys = FALSE; m_pszIndex = UGKStrdup(pszLine + 5); } else if (EQUALN(pszLine,"COORDSYS",8) ) { bCoordSys = TRUE; m_pszCoordSys = UGKStrdup(pszLine + 9); // Extract bounds if present char **papszFields; papszFields = TokenizeStringComplex(m_pszCoordSys, " ,()\t", TRUE, FALSE ); int iBounds = FindStrInList( papszFields, "Bounds" ); if (iBounds >= 0 && iBounds + 4 < CountOfList(papszFields)) { m_dXMin = atof(papszFields[++iBounds]); m_dYMin = atof(papszFields[++iBounds]); m_dXMax = atof(papszFields[++iBounds]); m_dYMax = atof(papszFields[++iBounds]); m_bBoundsSet = TRUE; } FreeStrList( papszFields ); } else if (EQUALN(pszLine,"TRANSFORM",9)) { papszToken = TokenizeStringComplex(pszLine," ,\t",TRUE,FALSE); bColumns = FALSE; bCoordSys = FALSE; if (CountOfList(papszToken) == 5) { m_dfXMultiplier = atof(papszToken[1]); m_dfYMultiplier = atof(papszToken[2]); m_dfXDisplacement = atof(papszToken[3]); m_dfYDisplacement = atof(papszToken[4]); if (m_dfXMultiplier == 0.0) m_dfXMultiplier = 1.0; if (m_dfYMultiplier == 0.0) m_dfYMultiplier = 1.0; } FreeStrList(papszToken); } else if (EQUALN(pszLine,"COLUMNS",7)) { papszToken = TokenizeStringComplex(pszLine," ()\t",TRUE,FALSE); bCoordSys = FALSE; bColumns = TRUE; if (CountOfList(papszToken) == 2) { nColumns = atoi(papszToken[1]); m_nAttribut = nColumns; } else { bColumns = FALSE; m_nAttribut = 0; } FreeStrList(papszToken); } else if (bColumns == TRUE && nColumns >0) { if (nColumns == 0) { // Permit to 0 columns bColumns = FALSE; } else if (AddFields(pszLine) == 0) { nColumns--; if (nColumns == 0) bColumns = FALSE; } else { bColumns = FALSE; } } else if (bCoordSys == TRUE) { pszTmp = m_pszCoordSys; m_pszCoordSys = UGKStrdup(UGKSPrintf("%s %s",m_pszCoordSys, pszLine)); UGK_Free(pszTmp); //printf("Reading CoordSys\n"); // Reading CoordSys } } if ((pszLine = m_poMIFFile->GetLastLine()) == NULL || EQUALN(m_poMIFFile->GetLastLine(),"DATA",4) == FALSE) { UGKError(ET_Failure, UGKErr_NotSupported, "DATA keyword not found in %s. File may be corrupt.", m_pszFname); return -1; } /*----------------------------------------------------------------- * Move pointer to first line of first object *----------------------------------------------------------------*/ while (((pszLine = m_poMIFFile->GetLine()) != NULL) && m_poMIFFile->IsValidFeature(pszLine) == FALSE) ; /*----------------------------------------------------------------- * Check for Unique and Indexed flags *----------------------------------------------------------------*/ if (m_pszIndex)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -