⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mitab_tabseamless.cpp

📁 mitab,读取MapInfo的地图文件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/**********************************************************************
 * $Id: mitab_tabseamless.cpp,v 1.7 2007/06/21 14:00:23 dmorissette Exp $
 *
 * Name:     mitab_tabseamless.cpp
 * Project:  MapInfo TAB Read/Write library
 * Language: C++
 * Purpose:  Implementation of the TABSeamless class, used to handle seamless
 *           .TAB datasets.
 * Author:   Daniel Morissette, dmorissette@dmsolutions.ca
 *
 **********************************************************************
 * Copyright (c) 1999-2004, 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_tabseamless.cpp,v $
 * Revision 1.7  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.6  2004/06/30 20:29:04  dmorissette
 * Fixed refs to old address danmo@videotron.ca
 *
 * Revision 1.5  2004/03/12 16:29:05  dmorissette
 * Fixed 2 memory leaks (bug 283)
 *
 * Revision 1.4  2002/06/28 18:32:37  julien
 * Add SetSpatialFilter() in TABSeamless class (Bug 164, MapServer)
 * Use double for comparison in Coordsys2Int() in mitab_mapheaderblock.cpp
 *
 * Revision 1.3  2001/09/19 14:21:36  daniel
 * On Unix: replace '\\' in file path read from tab index with '/'
 *
 * Revision 1.2  2001/03/15 03:57:51  daniel
 * Added implementation for new OGRLayer::GetExtent(), returning data MBR.
 *
 * Revision 1.1  2001/03/09 04:38:04  danmo
 * Update from master - version 1.1.0
 *
 * Revision 1.1  2001/03/09 04:16:02  daniel
 * Added TABSeamless for reading seamless TAB files
 *
 **********************************************************************/

#include "mitab.h"
#include "mitab_utils.h"

#include <ctype.h>      /* isspace() */

/*=====================================================================
 *                      class TABSeamless
 *
 * Support for seamless vector datasets.
 *
 * The current implementation has some limitations (base assumptions):
 *  - Read-only
 *  - Base tables can only be of type TABFile
 *  - Feature Ids are build using the id of the base table in the main
 *    index table and the actual feature id of each object inside the base
 *    tables.  Since we are limited to 32 bits for feature ids, this implies
 *    a limit on the (number of base tables) * (features/table)
 *    The current implementation can support up to 2047 (0x7ff) base tables
 *    and a max of 1048575 (0xfffff) features per base table.
 *  - Only relative paths are supported for base tables names.
 *    
 *====================================================================*/


/**********************************************************************
 *                   TABSeamless::TABSeamless()
 *
 * Constructor.
 **********************************************************************/
TABSeamless::TABSeamless()
{
    m_pszFname = NULL;
    m_pszPath = NULL;
    m_eAccessMode = TABRead;
    m_poFeatureDefnRef = NULL;
    m_poCurFeature = NULL;
    m_nCurFeatureId = -1;
    
    m_poIndexTable = NULL;
    m_nTableNameField = -1;
    m_nCurBaseTableId = -1;
    m_poCurBaseTable = NULL;
    m_bEOF = FALSE;
}

/**********************************************************************
 *                   TABSeamless::~TABSeamless()
 *
 * Destructor.
 **********************************************************************/
TABSeamless::~TABSeamless()
{
    Close();
}


void TABSeamless::ResetReading()
{
    if (m_poIndexTable)
        OpenBaseTable(-1);  // Asking for first table resets everything
}


/**********************************************************************
 *                   TABSeamless::Open()
 *
 * Open a seamless .TAB dataset and initialize the structures to be ready
 * to read features from it.
 *
 * Seamless .TAB files are composed of a main .TAB file in which each 
 * feature is the MBR of a base table.
 *
 * 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 TABSeamless::Open(const char *pszFname, const char *pszAccess,
                      GBool bTestOpenNoError /*= FALSE*/ )
{
    char nStatus = 0;
   
    if (m_poIndexTable)
    {
        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
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "Open() failed: access mode \"%s\" not supported", pszAccess);
        return -1;
    }

    return nStatus;
}


/**********************************************************************
 *                   TABSeamless::OpenForRead()
 *
 * Open for reading
 *
 * Returns 0 on success, -1 on error.
 **********************************************************************/
int TABSeamless::OpenForRead(const char *pszFname, 
                             GBool bTestOpenNoError /*= FALSE*/ )
{
    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.
     *----------------------------------------------------------------*/
    char **papszTABFile = TAB_CSLLoad(m_pszFname);
    if (papszTABFile == NULL)
    {
        if (!bTestOpenNoError)
        {
            CPLError(CE_Failure, CPLE_FileIO,
                     "Failed opening %s.", m_pszFname);
        }
        
        CPLFree(m_pszFname);
        CSLDestroy(papszTABFile);
        return -1;
    }

    /*-------------------------------------------------------------
     * Look for a metadata line with "\IsSeamless" = "TRUE".
     * If there is no such line, then we may have a valid .TAB file,
     * but we do not support it in this class.
     *------------------------------------------------------------*/
    GBool bSeamlessFound = FALSE;
    for (int i=0; !bSeamlessFound && papszTABFile && papszTABFile[i]; i++)
    {
        const char *pszStr = papszTABFile[i];
        while(*pszStr != '\0' && isspace((unsigned char)*pszStr))
            pszStr++;
        if (EQUALN(pszStr, "\"\\IsSeamless\" = \"TRUE\"", 21))
            bSeamlessFound = TRUE;
    }
    CSLDestroy(papszTABFile);

    if ( !bSeamlessFound )
    {
        if (!bTestOpenNoError)
            CPLError(CE_Failure, CPLE_NotSupported,
                     "%s does not appear to be a Seamless TAB File.  "
                     "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 seamless TAB dataset...
     * Extract the path component from the main .TAB filename
     * to build the filename of the base tables
     *----------------------------------------------------------------*/
    m_pszPath = CPLStrdup(m_pszFname);
    nFnameLen = strlen(m_pszPath);
    for( ; nFnameLen > 0; nFnameLen--)
    {
        if (m_pszPath[nFnameLen-1] == '/' || 
            m_pszPath[nFnameLen-1] == '\\' )
        {
            break;
        }
        m_pszPath[nFnameLen-1] = '\0';
    }

    /*-----------------------------------------------------------------
     * Open the main Index table and look for the "Table" field that
     * should contain the path to the base table for each rectangle MBR
     *----------------------------------------------------------------*/
    m_poIndexTable = new TABFile;
    if (m_poIndexTable->Open(m_pszFname, "rb", bTestOpenNoError) != 0)
    {
        // Open Failed... an error has already been reported, just return.
        if (bTestOpenNoError)
            CPLErrorReset();
        Close();
        return -1;
    }

    OGRFeatureDefn *poDefn = m_poIndexTable->GetLayerDefn();
    if (poDefn == NULL ||
        (m_nTableNameField = poDefn->GetFieldIndex("Table")) == -1)
    {
        if (!bTestOpenNoError)
            CPLError(CE_Failure, CPLE_NotSupported,
                     "Open Failed: Field 'Table' not found in Seamless "
                     "Dataset '%s'.  This is type of file not currently "
                     "supported.",
                     m_pszFname);
        Close();
        return -1;        
    }

    /*-----------------------------------------------------------------
     * Check number of features in index table to make sure we won't
     * overflow the number of bytes used for table ids in the encoded
     * feature ids.  We currently use 12 bits for table id + 20 bits for FID
     *----------------------------------------------------------------*/
    if (m_poIndexTable->GetFeatureCount(FALSE) > 0x7ff)
    {
        if (!bTestOpenNoError)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -