📄 mitab_miffile.cpp
字号:
/********************************************************************** * $Id: mitab_miffile.cpp,v 1.38 2004/02/27 21:04:14 fwarmerdam Exp $ * * Name: mitab_miffile.cpp * Project: MapInfo TAB Read/Write library * Language: C++ * Purpose: Implementation of the MIDFile class. * To be used by external programs to handle reading/writing of * features from/to MID/MIF datasets. * Author: Stephane Villeneuve, stephane.v@videotron.ca * ********************************************************************** * Copyright (c) 1999-2003, Stephane Villeneuve * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ********************************************************************** * * $Log: mitab_miffile.cpp,v $ * Revision 1.38 2004/02/27 21:04:14 fwarmerdam * dont write MIF header if file is readonly - gdal bugzilla 509 * * Revision 1.37 2003/12/19 07:54:50 fwarmerdam * write mif header on close if not already written out * * Revision 1.36 2003/08/13 02:49:02 dmorissette * Use tab as default delimiter if not explicitly specified (Anthony D, bug 37) * * Revision 1.35 2003/01/30 22:42:39 daniel * Fixed crash in ParseMIFHeader() when .mif doesn't contain a DATA line * * Revision 1.34 2002/09/23 12:53:29 warmerda * fix memory leak of m_pszIndex * * Revision 1.33 2002/05/08 15:10:48 julien * Implement MIFFile::SetMIFCoordSys in mitab_capi.cpp (Bug 984) * * Revision 1.32 2002/04/26 14:16:49 julien * Finishing the implementation of Multipoint (support for MIF) * * Revision 1.31 2001/09/19 21:39:15 warmerda * get extents efficiently * * Revision 1.30 2001/09/19 14:31:22 warmerda * added m_nPreloadedId to keep track of preloaded line * * Revision 1.29 2001/09/14 19:14:43 warmerda * added attribute query support * * Revision 1.28 2001/08/10 17:49:01 warmerda * fixed a few memory leaks * * Revision 1.27 2001/03/15 03:57:51 daniel * Added implementation for new OGRLayer::GetExtent(), returning data MBR. * * Revision 1.26 2001/03/09 04:14:19 daniel * Fixed problem creating new files with mixed case extensions (e.g. ".Tab") * * Revision 1.25 2001/03/09 03:51:48 daniel * Fixed writing MIF header: missing break; for decimal fields * * Revision 1.24 2001/02/27 19:59:05 daniel * Enabled spatial filter in IMapInfoFile::GetNextFeature(), and avoid * unnecessary feature cloning in GetNextFeature() and GetFeature() * * Revision 1.23 2001/01/23 21:23:42 daniel * Added projection bounds lookup table, called from TABFile::SetProjInfo() * * Revision 1.22 2001/01/22 16:03:58 warmerda * expanded tabs * * Revision 1.21 2000/12/15 05:38:38 daniel * Produce Warning instead of an error when nWidth>254 in AddFieldNative() * * Revision 1.20 2000/11/14 06:15:37 daniel * Handle '\t' as spaces in parsing, and fixed GotoFeature() to avoid calling * ResetReading() when reading forward. * * Revision 1.19 2000/07/04 01:50:40 warmerda * Removed unprotected debugging printf. * * Revision 1.18 2000/06/28 00:32:04 warmerda * Make GetFeatureCountByType() actually work if bForce is TRUE * Collect detailed (by feature type) feature counts in PreParse(). * * Revision 1.17 2000/04/27 15:46:25 daniel * Make SetFeatureDefn() use AddFieldNative(), scan field names for invalid * chars, and map field width=0 (variable length in OGR) to valid defaults * * Revision 1.16 2000/03/27 03:37:59 daniel * Handle bounds in CoordSys for read and write, + handle point SYMBOL line as * optional + fixed reading of bounds in PreParseFile() * * Revision 1.15 2000/02/28 17:05:06 daniel * Added support for index and unique directives for read and write * * Revision 1.14 2000/01/28 07:32:25 daniel * Validate char field width (must be <= 254 chars) * * Revision 1.13 2000/01/24 19:51:33 warmerda * AddFieldNative should not fail for read-only datasets * * Revision 1.12 2000/01/18 23:13:41 daniel * Implemented AddFieldNative() * * ... * * Revision 1.1 1999/11/08 04:16:07 stephane * First Revision * **********************************************************************/#include "mitab.h"#include "mitab_utils.h"#include <ctype.h>/*===================================================================== * class MIFFile *====================================================================*//********************************************************************** * 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 = CPLStrdup("\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_poSpatialRef = 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, GBool bTestOpenNoError /*=FALSE*/ ){ char *pszTmpFname = NULL; int nFnameLen = 0; CPLErrorReset(); if (m_poMIDFile) { CPLError(CE_Failure, CPLE_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 CPLFree(m_pszDelimiter); m_pszDelimiter = CPLStrdup(","); } else { if (!bTestOpenNoError) CPLError(CE_Failure, CPLE_FileIO, "Open() failed: access mode \"%s\" not supported", pszAccess); else CPLErrorReset(); return -1; } /*----------------------------------------------------------------- * Make sure filename has a .MIF or .MID extension... *----------------------------------------------------------------*/ m_pszFname = CPLStrdup(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) CPLError(CE_Failure, CPLE_FileIO, "Open() failed for %s: invalid filename extension", m_pszFname); else CPLErrorReset(); CPLFree(m_pszFname); return -1; } pszTmpFname = CPLStrdup(m_pszFname); /*----------------------------------------------------------------- * Open .MIF file *----------------------------------------------------------------*/#ifndef _WIN32 /*----------------------------------------------------------------- * 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) CPLError(CE_Failure, CPLE_NotSupported, "Unable to open %s.", pszTmpFname); else CPLErrorReset(); CPLFree(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 _WIN32 TABAdjustFilenameExtension(pszTmpFname);#endif m_poMIDFile = new MIDDATAFile; if (m_poMIDFile->Open(pszTmpFname, pszAccess) !=0) { if (!bTestOpenNoError) CPLError(CE_Failure, CPLE_NotSupported, "Unable to open %s.", pszTmpFname); else CPLErrorReset(); CPLFree(pszTmpFname); Close(); return -1; } CPLFree(pszTmpFname); pszTmpFname = NULL; /*----------------------------------------------------------------- * Read MIF File Header *----------------------------------------------------------------*/ if (m_eAccessMode == TABRead && ParseMIFHeader() != 0) { Close(); if (!bTestOpenNoError) CPLError(CE_Failure, CPLE_NotSupported, "Failed parsing header in %s.", m_pszFname); else CPLErrorReset(); return -1; } /*----------------------------------------------------------------- * In write access, set some defaults *----------------------------------------------------------------*/ if (m_eAccessMode == TABWrite) { m_pszVersion = CPLStrdup("300"); m_pszCharset = CPLStrdup("Neutral"); } /* Put the MID file at the correct location, on the first feature */ if (m_eAccessMode == TABRead && (m_poMIDFile->GetLine() == NULL)) { Close(); if (bTestOpenNoError) CPLErrorReset(); 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() *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -