📄 mitab_ogr_datasource.cpp
字号:
/********************************************************************** * $Id: mitab_ogr_datasource.cpp,v 1.11 2006/01/27 14:27:35 fwarmerdam Exp $ * * Name: mitab_ogr_datasource.cpp * Project: MapInfo Mid/Mif, Tab ogr support * Language: C++ * Purpose: Implementation of OGRTABDataSource. * Author: Stephane Villeneuve, stephane.v@videotron.ca * and Frank Warmerdam, warmerdam@pobox.com * ********************************************************************** * Copyright (c) 1999, 2000, 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_ogr_datasource.cpp,v $ * Revision 1.11 2006/01/27 14:27:35 fwarmerdam * fixed ogr bounds setting problems (bug 1198) * * Revision 1.10 2005/09/20 04:40:02 fwarmerdam * fixed CPLReadDir memory leak * * Revision 1.9 2004/10/15 01:52:30 fwarmerdam * Modified CreateLayer() to use -1000,-1000,1000,1000 bounds for GEOGCS * much like in mitab_bounds.cpp. This ensures that geographic files in * the range 0-360 works as well as -180 to 180. * * Revision 1.8 2004/07/07 15:42:46 fwarmerdam * fixed up some single layer creation issues * * Revision 1.7 2004/02/27 21:06:03 fwarmerdam * Better support for "single file" creation ... don't allow other layers to * be created. But *do* single file to satisfy the first layer creation request * made. Also, allow creating a datasource "on" an existing directory. * * Revision 1.6 2003/03/21 14:20:49 warmerda * fixed email * * Revision 1.5 2002/02/08 16:52:16 warmerda * added support for FORMAT=MIF option for creating layers * * Revision 1.4 2001/02/06 22:13:54 warmerda * fixed memory leak in OGRTABDataSource::CreateLayer() * * Revision 1.3 2001/01/22 16:03:58 warmerda * expanded tabs * * Revision 1.2 2000/07/04 01:46:23 warmerda * Avoid warnings on unused arguments. * * Revision 1.1 2000/01/26 18:17:09 warmerda * New * **********************************************************************/#include "mitab_ogr_driver.h"/*======================================================================= * OGRTABDataSource * * We need one single OGRDataSource/Driver set of classes to handle all * the MapInfo file types. They all deal with the IMapInfoFile abstract * class. *=====================================================================*//************************************************************************//* OGRTABDataSource() *//************************************************************************/OGRTABDataSource::OGRTABDataSource(){ m_pszName = NULL; m_pszDirectory = NULL; m_nLayerCount = 0; m_papoLayers = NULL; m_papszOptions = NULL; m_bCreateMIF = FALSE; m_bSingleFile = FALSE; m_bSingleLayerAlreadyCreated = FALSE;}/************************************************************************//* ~OGRTABDataSource() *//************************************************************************/OGRTABDataSource::~OGRTABDataSource(){ CPLFree( m_pszName ); CPLFree( m_pszDirectory ); for( int i = 0; i < m_nLayerCount; i++ ) delete m_papoLayers[i]; CPLFree( m_papoLayers ); CSLDestroy( m_papszOptions );}/************************************************************************//* Create() *//* *//* Create a new dataset (directory or file). *//************************************************************************/int OGRTABDataSource::Create( const char * pszName, char **papszOptions ){ VSIStatBuf sStat; CPLAssert( m_pszName == NULL ); m_pszName = CPLStrdup( pszName ); m_papszOptions = CSLDuplicate( papszOptions ); if( CSLFetchNameValue(papszOptions,"FORMAT") != NULL && EQUAL(CSLFetchNameValue(papszOptions,"FORMAT"),"MIF") ) m_bCreateMIF = TRUE; else if( EQUAL(CPLGetExtension(pszName),"mif") || EQUAL(CPLGetExtension(pszName),"mid") ) m_bCreateMIF = TRUE;/* -------------------------------------------------------------------- *//* Create a new empty directory. *//* -------------------------------------------------------------------- */ if( strlen(CPLGetExtension(pszName)) == 0 ) { if( VSIStat( pszName, &sStat ) == 0 ) { if( !VSI_ISDIR(sStat.st_mode) ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create dataset named %s,\n" "but that is an existing file.\n", pszName ); return FALSE; } } else { if( VSIMkdir( pszName, 0755 ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to create directory %s.\n", pszName ); return FALSE; } } m_pszDirectory = CPLStrdup(pszName); }/* -------------------------------------------------------------------- *//* Create a new single file. *//* -------------------------------------------------------------------- */ else { IMapInfoFile *poFile; if( m_bCreateMIF ) poFile = new MIFFile; else poFile = new TABFile; if( poFile->Open( pszName, "wb", FALSE ) != 0 ) { delete poFile; return FALSE; } m_nLayerCount = 1; m_papoLayers = (IMapInfoFile **) CPLMalloc(sizeof(void*)); m_papoLayers[0] = poFile; m_pszDirectory = CPLStrdup( CPLGetPath(pszName) ); m_bSingleFile = TRUE; } return TRUE;}/************************************************************************//* Open() *//* *//* Open an existing file, or directory of files. *//************************************************************************/int OGRTABDataSource::Open( const char * pszName, int bTestOpen ){ VSIStatBuf stat; CPLAssert( m_pszName == NULL ); m_pszName = CPLStrdup( pszName );/* -------------------------------------------------------------------- *//* Is this a file or directory? *//* -------------------------------------------------------------------- */ if( VSIStat( pszName, &stat ) != 0 || (!VSI_ISDIR(stat.st_mode) && !VSI_ISREG(stat.st_mode)) ) { if( !bTestOpen ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s is not a file or directory.\n" "Unable to open as a Mapinfo dataset.\n", pszName ); } return FALSE; }/* -------------------------------------------------------------------- *//* If it is a file, try to open as a Mapinfo file. *//* -------------------------------------------------------------------- */ if( VSI_ISREG(stat.st_mode) ) { IMapInfoFile *poFile; poFile = IMapInfoFile::SmartOpen( pszName, bTestOpen ); if( poFile == NULL ) return FALSE; m_nLayerCount = 1; m_papoLayers = (IMapInfoFile **) CPLMalloc(sizeof(void*)); m_papoLayers[0] = poFile; m_pszDirectory = CPLStrdup( CPLGetPath(pszName) ); }/* -------------------------------------------------------------------- *//* Otherwise, we need to scan the whole directory for files *//* ending in .tab or .mif. *//* -------------------------------------------------------------------- */ else { char **papszFileList = CPLReadDir( pszName ); m_pszDirectory = CPLStrdup( pszName ); for( int iFile = 0; papszFileList != NULL && papszFileList[iFile] != NULL; iFile++ ) { IMapInfoFile *poFile; const char *pszExtension = CPLGetExtension(papszFileList[iFile]); char *pszSubFilename; if( !EQUAL(pszExtension,"tab") && !EQUAL(pszExtension,"mif") ) continue; pszSubFilename = CPLStrdup( CPLFormFilename( m_pszDirectory, papszFileList[iFile], NULL )); poFile = IMapInfoFile::SmartOpen( pszSubFilename, bTestOpen ); CPLFree( pszSubFilename ); if( poFile == NULL ) { CSLDestroy( papszFileList ); return FALSE; } m_nLayerCount++; m_papoLayers = (IMapInfoFile **) CPLRealloc(m_papoLayers,sizeof(void*)*m_nLayerCount); m_papoLayers[m_nLayerCount-1] = poFile; } CSLDestroy( papszFileList ); if( m_nLayerCount == 0 ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_OpenFailed, "No mapinfo files found in directory %s.\n", m_pszDirectory ); return FALSE; } } return TRUE;}/************************************************************************//* GetLayerCount() *//************************************************************************/int OGRTABDataSource::GetLayerCount(){ if( m_bSingleFile && !m_bSingleLayerAlreadyCreated ) return 0; else return m_nLayerCount;}/************************************************************************//* GetLayer() *//************************************************************************/OGRLayer *OGRTABDataSource::GetLayer( int iLayer ){ if( iLayer < 0 || iLayer >= GetLayerCount() ) return NULL; else return m_papoLayers[iLayer];}/************************************************************************//* CreateLayer() *//************************************************************************/OGRLayer *OGRTABDataSource::CreateLayer( const char * pszLayerName, OGRSpatialReference *poSRSIn, OGRwkbGeometryType /* eGeomTypeIn */, char ** /* papszOptions */ ){ IMapInfoFile *poFile; char *pszFullFilename;/* -------------------------------------------------------------------- *//* If it's a single file mode file, then we may have already *//* instantiated the low level layer. We would just need to *//* reset the coordinate system and (potentially) bounds. *//* -------------------------------------------------------------------- */ if( m_bSingleFile ) { if( m_bSingleLayerAlreadyCreated ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to create new layers in this single file dataset."); return NULL; } m_bSingleLayerAlreadyCreated = TRUE; poFile = (IMapInfoFile *) m_papoLayers[0]; }/* -------------------------------------------------------------------- *//* We need to initially create the file, and add it as a layer. *//* -------------------------------------------------------------------- */ else { if( m_bCreateMIF ) { pszFullFilename = CPLStrdup( CPLFormFilename( m_pszDirectory, pszLayerName, "mif" ) ); poFile = new MIFFile; } else { pszFullFilename = CPLStrdup( CPLFormFilename( m_pszDirectory, pszLayerName, "tab" ) ); poFile = new TABFile; } if( poFile->Open( pszFullFilename, "wb", FALSE ) != 0 ) { CPLFree( pszFullFilename ); delete poFile; return FALSE; } m_nLayerCount++; m_papoLayers = (IMapInfoFile **) CPLRealloc(m_papoLayers,sizeof(void*)*m_nLayerCount); m_papoLayers[m_nLayerCount-1] = poFile; CPLFree( pszFullFilename ); }/* -------------------------------------------------------------------- *//* Assign the coordinate system (if provided) and set *//* reasonable bounds. *//* -------------------------------------------------------------------- */ if( poSRSIn != NULL ) poFile->SetSpatialRef( poSRSIn ); if( !poFile->IsBoundsSet() && !m_bCreateMIF ) { if( poSRSIn != NULL && poSRSIn->GetRoot() != NULL && EQUAL(poSRSIn->GetRoot()->GetValue(),"GEOGCS") ) poFile->SetBounds( -1000, -1000, 1000, 1000 ); else poFile->SetBounds( -30000000, -15000000, 30000000, 15000000 ); } return poFile;}/************************************************************************//* TestCapability() *//************************************************************************/int OGRTABDataSource::TestCapability( const char * pszCap ){ if( EQUAL(pszCap,ODsCCreateLayer) ) return !m_bSingleFile || !m_bSingleLayerAlreadyCreated; else return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -