?? mitab_tabview.cpp
字號:
/**********************************************************************
* $Id: mitab_tabview.cpp,v 1.18 2008/01/29 20:46:32 dmorissette Exp $
*
* Name: mitab_tabfile.cpp
* Project: MapInfo TAB Read/Write library
* Language: C++
* Purpose: Implementation of the TABView class, used to handle .TAB
* datasets composed of a number of .TAB files linked through
* indexed fields.
* Author: Daniel Morissette, dmorissette@dmsolutions.ca
*
**********************************************************************
* Copyright (c) 1999-2002, 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_tabview.cpp,v $
* Revision 1.18 2008/01/29 20:46:32 dmorissette
* Added support for v9 Time and DateTime fields (byg 1754)
*
* Revision 1.17 2007/06/21 14:00:23 dmorissette
* Added missing cast in isspace() calls to avoid failed assertion on Windows
* (MITAB bug 1737, GDAL ticket 1678))
*
* Revision 1.16 2007/06/12 13:52:38 dmorissette
* Added IMapInfoFile::SetCharset() method (bug 1734)
*
* Revision 1.15 2007/06/12 12:50:40 dmorissette
* Use Quick Spatial Index by default until bug 1732 is fixed (broken files
* produced by current coord block splitting technique).
*
* Revision 1.14 2007/03/21 21:15:56 dmorissette
* Added SetQuickSpatialIndexMode() which generates a non-optimal spatial
* index but results in faster write time (bug 1669)
*
* Revision 1.13 2004/06/30 20:29:04 dmorissette
* Fixed refs to old address danmo@videotron.ca
*
* Revision 1.12 2002/02/22 20:44:51 julien
* Prevent infinite loop with TABRelation by suppress the m_poCurFeature object
* from the class and setting it in the calling function and add GetFeature in
* the class. (bug 706)
*
* Revision 1.11 2002/01/10 05:13:22 daniel
* Prevent crash if .IND file is deleted (but 703)
*
* Revision 1.10 2002/01/10 04:52:58 daniel
* Support 'select * ...' syntax + 'open table..." directives with/without .tab
*
* Revision 1.9 2001/06/27 19:52:26 warmerda
* use VSIUnlink() instead of unlink()
*
* Revision 1.8 2001/03/15 03:57:51 daniel
* Added implementation for new OGRLayer::GetExtent(), returning data MBR.
*
* Revision 1.7 2000/09/28 16:39:44 warmerda
* avoid warnings for unused, and unitialized variables
*
* Revision 1.6 2000/02/28 17:12:22 daniel
* Write support for joined tables and indexed fields
*
* Revision 1.5 2000/01/15 22:30:45 daniel
* Switch to MIT/X-Consortium OpenSource license
*
* Revision 1.4 1999/12/19 17:40:16 daniel
* Init + delete m_poRelation properly
*
* Revision 1.3 1999/12/14 05:53:00 daniel
* Fixed compile warnings
*
* Revision 1.2 1999/12/14 04:04:10 daniel
* Added bforceFlags to GetBounds() and GetFeatureCountByType()
*
* Revision 1.1 1999/12/14 02:10:32 daniel
* Initial revision
*
**********************************************************************/
#include "mitab.h"
#include "mitab_utils.h"
#include <ctype.h> /* isspace() */
/*=====================================================================
* class TABView
*====================================================================*/
/**********************************************************************
* TABView::TABView()
*
* Constructor.
**********************************************************************/
TABView::TABView()
{
m_pszFname = NULL;
m_eAccessMode = TABRead;
m_papszTABFile = NULL;
m_pszVersion = NULL;
m_numTABFiles = 0;
m_papszTABFnames = NULL;
m_papoTABFiles = NULL;
m_nMainTableIndex = -1;
m_papszFieldNames = NULL;
m_papszWhereClause = NULL;
m_poRelation = NULL;
m_bRelFieldsCreated = FALSE;
}
/**********************************************************************
* TABView::~TABView()
*
* Destructor.
**********************************************************************/
TABView::~TABView()
{
Close();
}
int TABView::GetFeatureCount (int bForce)
{
if (m_nMainTableIndex != -1)
return m_papoTABFiles[m_nMainTableIndex]->GetFeatureCount( bForce );
return 0;
}
void TABView::ResetReading()
{
if (m_nMainTableIndex != -1)
m_papoTABFiles[m_nMainTableIndex]->ResetReading();
}
/**********************************************************************
* TABView::Open()
*
* Open a .TAB dataset and the associated files, and initialize the
* structures to be ready to read features from it.
*
* This class is used to open .TAB files that define a view on
* two other .TAB files. Regular .TAB datasets should be opened using
* the TABFile class instead.
*
* Set bTestOpenNoError=TRUE to silently return -1 with no error message
* if the file cannot be opened. This is intended to be used in the
* context of a TestOpen() function. The default value is FALSE which
* means that an error is reported if the file cannot be opened.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABView::Open(const char *pszFname, const char *pszAccess,
GBool bTestOpenNoError /*= FALSE*/ )
{
char nStatus = 0;
if (m_numTABFiles > 0)
{
CPLError(CE_Failure, CPLE_AssertionFailed,
"Open() failed: object already contains an open file");
return -1;
}
/*-----------------------------------------------------------------
* Validate access mode and call the right open method
*----------------------------------------------------------------*/
if (EQUALN(pszAccess, "r", 1))
{
m_eAccessMode = TABRead;
nStatus = OpenForRead(pszFname, bTestOpenNoError);
}
else if (EQUALN(pszAccess, "w", 1))
{
m_eAccessMode = TABWrite;
nStatus = OpenForWrite(pszFname);
}
else
{
CPLError(CE_Failure, CPLE_NotSupported,
"Open() failed: access mode \"%s\" not supported", pszAccess);
return -1;
}
return nStatus;
}
/**********************************************************************
* TABView::OpenForRead()
*
* Open for reading
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABView::OpenForRead(const char *pszFname,
GBool bTestOpenNoError /*= FALSE*/ )
{
char *pszPath = NULL;
int nFnameLen = 0;
m_eAccessMode = TABRead;
/*-----------------------------------------------------------------
* Read main .TAB (text) file
*----------------------------------------------------------------*/
m_pszFname = CPLStrdup(pszFname);
#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(m_pszFname);
#endif
/*-----------------------------------------------------------------
* Open .TAB file... since it's a small text file, we will just load
* it as a stringlist in memory.
*----------------------------------------------------------------*/
m_papszTABFile = TAB_CSLLoad(m_pszFname);
if (m_papszTABFile == NULL)
{
if (!bTestOpenNoError)
{
CPLError(CE_Failure, CPLE_FileIO,
"Failed opening %s.", m_pszFname);
}
CPLFree(m_pszFname);
return -1;
}
/*-------------------------------------------------------------
* Look for a line with the "create view" keyword.
* If there is no "create view", then we may have a valid .TAB file,
* but we do not support it in this class.
*------------------------------------------------------------*/
GBool bCreateViewFound = FALSE;
for (int i=0;
!bCreateViewFound && m_papszTABFile && m_papszTABFile[i];
i++)
{
const char *pszStr = m_papszTABFile[i];
while(*pszStr != '\0' && isspace((unsigned char)*pszStr))
pszStr++;
if (EQUALN(pszStr, "create view", 11))
bCreateViewFound = TRUE;
}
if ( !bCreateViewFound )
{
if (!bTestOpenNoError)
CPLError(CE_Failure, CPLE_NotSupported,
"%s contains no table view definition. "
"This type of .TAB file cannot be read by this library.",
m_pszFname);
else
CPLErrorReset();
CPLFree(m_pszFname);
return -1;
}
/*-----------------------------------------------------------------
* OK, this appears to be a valid TAB view dataset...
* Extract the path component from the main .TAB filename
* to build the filename of the sub-tables
*----------------------------------------------------------------*/
pszPath = CPLStrdup(m_pszFname);
nFnameLen = strlen(pszPath);
for( ; nFnameLen > 0; nFnameLen--)
{
if (pszPath[nFnameLen-1] == '/' ||
pszPath[nFnameLen-1] == '\\' )
{
break;
}
pszPath[nFnameLen-1] = '\0';
}
/*-----------------------------------------------------------------
* Extract the useful info from the TAB header
*----------------------------------------------------------------*/
if (ParseTABFile(pszPath, bTestOpenNoError) != 0)
{
// Failed parsing... an error has already been produced if necessary
CPLFree(pszPath);
Close();
return -1;
}
CPLFree(pszPath);
pszPath = NULL;
/*-----------------------------------------------------------------
* __TODO__ For now, we support only 2 files linked through a single
* field... so we'll do some validation first to make sure
* that what we found in the header respects these limitations.
*----------------------------------------------------------------*/
if (m_numTABFiles != 2)
{
if (!bTestOpenNoError)
CPLError(CE_Failure, CPLE_NotSupported,
"Open Failed: Dataset %s defines a view on %d tables. "
"This is not currently supported.",
m_pszFname, m_numTABFiles);
Close();
return -1;
}
/*-----------------------------------------------------------------
* Open all the tab files listed in the view
*----------------------------------------------------------------*/
m_papoTABFiles = (TABFile**)CPLCalloc(m_numTABFiles, sizeof(TABFile*));
for (int iFile=0; iFile < m_numTABFiles; iFile++)
{
#ifndef _WIN32
TABAdjustFilenameExtension(m_papszTABFnames[iFile]);
#endif
m_papoTABFiles[iFile] = new TABFile;
if ( m_papoTABFiles[iFile]->Open(m_papszTABFnames[iFile],
"rb", bTestOpenNoError) != 0)
{
// Open Failed... an error has already been reported, just return.
if (bTestOpenNoError)
CPLErrorReset();
Close();
return -1;
}
}
/*-----------------------------------------------------------------
* Create TABRelation... this will build FeatureDefn, etc.
* __TODO__ For now this assumes only 2 tables in the view...
*----------------------------------------------------------------*/
m_poRelation = new TABRelation;
CPLAssert(m_nMainTableIndex == 0);
CPLAssert(CSLCount(m_papszWhereClause) == 5);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -