📄 mitab_imapinfofile.cpp
字号:
/********************************************************************** * $Id: mitab_imapinfofile.cpp,v 1.19 2004/06/30 20:29:04 dmorissette Exp $ * * Name: mitab_imapinfo * Project: MapInfo mid/mif Tab Read/Write library * Language: C++ * Purpose: Implementation of the IMapInfoFile class, super class of * of MIFFile and TABFile * Author: Daniel Morissette, dmorissette@dmsolutions.ca * ********************************************************************** * Copyright (c) 1999-2001, Daniel Morissette * * 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_imapinfofile.cpp,v $ * Revision 1.19 2004/06/30 20:29:04 dmorissette * Fixed refs to old address danmo@videotron.ca * * Revision 1.18 2003/12/19 07:55:55 fwarmerdam * treat 3D features as 2D on write * * Revision 1.17 2001/09/14 19:14:43 warmerda * added attribute query support * * Revision 1.16 2001/09/14 03:23:55 warmerda * Substantial upgrade to support spatial queries using spatial indexes * * Revision 1.15 2001/07/03 23:11:21 daniel * Test for NULL geometries if spatial filter enabled in GetNextFeature(). * * Revision 1.14 2001/03/09 04:16:02 daniel * Added TABSeamless for reading seamless TAB files * * Revision 1.13 2001/02/27 19:59:05 daniel * Enabled spatial filter in IMapInfoFile::GetNextFeature(), and avoid * unnecessary feature cloning in GetNextFeature() and GetFeature() * * Revision 1.12 2001/02/06 22:03:24 warmerda * fixed memory leak of whole features in CreateFeature * * Revision 1.11 2001/01/23 21:23:42 daniel * Added projection bounds lookup table, called from TABFile::SetProjInfo() * * Revision 1.10 2001/01/22 16:03:58 warmerda * expanded tabs * * Revision 1.9 2000/11/30 20:27:56 warmerda * make variable length string fields 254 wide, not 255 * * Revision 1.8 2000/02/28 03:11:35 warmerda * fix support for zero width fields * * Revision 1.7 2000/02/02 20:14:03 warmerda * made safer when encountering geometryless features * * Revision 1.6 2000/01/26 18:17:35 warmerda * added CreateField method * * Revision 1.5 2000/01/15 22:30:44 daniel * Switch to MIT/X-Consortium OpenSource license * * Revision 1.4 2000/01/11 19:06:25 daniel * Added support for conversion of collections in CreateFeature() * * Revision 1.3 1999/12/14 02:14:50 daniel * Added static SmartOpen() method + TABView support * * Revision 1.2 1999/11/08 19:15:44 stephane * Add headers method * * Revision 1.1 1999/11/08 04:17:27 stephane * First Revision * **********************************************************************/#include "mitab.h"#include "mitab_utils.h"#include <ctype.h> /* isspace() *//********************************************************************** * IMapInfoFile::IMapInfoFile() * * Constructor. **********************************************************************/IMapInfoFile::IMapInfoFile(){ m_nCurFeatureId = 0; m_poCurFeature = NULL; m_bBoundsSet = FALSE;}/********************************************************************** * IMapInfoFile::~IMapInfoFile() * * Destructor. **********************************************************************/IMapInfoFile::~IMapInfoFile(){ if (m_poCurFeature) { delete m_poCurFeature; m_poCurFeature = NULL; }}/********************************************************************** * IMapInfoFile::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. **********************************************************************/IMapInfoFile *IMapInfoFile::SmartOpen(const char *pszFname, GBool bTestOpenNoError /*=FALSE*/){ IMapInfoFile *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 = CPLStrdup(pszFname); GBool bFoundFields = FALSE, bFoundView=FALSE, bFoundSeamless=FALSE; TABAdjustFilenameExtension(pszAdjFname); fp = VSIFOpen(pszAdjFname, "r"); while(fp && (pszLine = CPLReadLine(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) VSIFClose(fp); CPLFree(pszAdjFname); } /*----------------------------------------------------------------- * Perform the open() call *----------------------------------------------------------------*/ if (poFile && poFile->Open(pszFname, "r", bTestOpenNoError) != 0) { delete poFile; poFile = NULL; } if (!bTestOpenNoError && poFile == NULL) { CPLError(CE_Failure, CPLE_FileIO, "%s could not be opened as a MapInfo dataset.", pszFname); } return poFile;}/********************************************************************** * IMapInfoFile::GetNextFeature() * * Standard OGR GetNextFeature implementation. This methode is used * to retreive the next OGRFeature. **********************************************************************/OGRFeature *IMapInfoFile::GetNextFeature(){ OGRFeature *poFeatureRef; OGRGeometry *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 ))) && (m_poAttrQuery == NULL || m_poAttrQuery->Evaluate( poFeatureRef )) ) { // Avoid cloning feature... return the copy owned by the class CPLAssert(poFeatureRef == m_poCurFeature); m_poCurFeature = NULL; return poFeatureRef; } } return NULL;}/********************************************************************** * IMapInfoFile::CreateFeature() * * Standard OGR CreateFeature implementation. This methode is used * to create a new feature in current dataset **********************************************************************/OGRErr IMapInfoFile::CreateFeature(OGRFeature *poFeature){ TABFeature *poTABFeature; OGRGeometry *poGeom; OGRwkbGeometryType eGType; OGRErr 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: { OGRErr eStatus = OGRERR_NONE; int i; OGRGeometryCollection *poColl = (OGRGeometryCollection*)poGeom; OGRFeature *poTmpFeature = poFeature->Clone(); for (i=0; eStatus==OGRERR_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 = OGRERR_NONE; else eErr = OGRERR_FAILURE; delete poTABFeature; return eErr;}/********************************************************************** * IMapInfoFile::GetFeature() * * Standard OGR GetFeature implementation. This methode is used * to get the wanted (nFeatureId) feature, a NULL value will be * returned on error. **********************************************************************/OGRFeature *IMapInfoFile::GetFeature(long nFeatureId){ OGRFeature *poFeatureRef; poFeatureRef = GetFeatureRef(nFeatureId); if (poFeatureRef) { // Avoid cloning feature... return the copy owned by the class CPLAssert(poFeatureRef == m_poCurFeature); m_poCurFeature = NULL; return poFeatureRef; } else return NULL;}/************************************************************************//* CreateField() *//* *//* Create a native field based on a generic OGR definition. *//************************************************************************/OGRErr IMapInfoFile::CreateField( OGRFieldDefn *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 = MIN(254,nWidth); } else { CPLError( CE_Failure, CPLE_AppDefined, "IMapInfoFile::CreateField() called with unsupported field" " type %d.\n" "Note that Mapinfo files don't support list field types.\n", poField->GetType() ); return OGRERR_FAILURE; } if( AddFieldNative( poField->GetNameRef(), eTABType, nWidth, poField->GetPrecision() ) > -1 ) return OGRERR_NONE; else return OGRERR_FAILURE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -