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

📄 mitab_mapfile.cpp

📁 mitab,读取MapInfo的地图文件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
         * can be used to return only NONE geometries.
         *----------------------------------------------------------------*/
        m_fp = NULL;
        m_nCurObjType = TAB_GEOM_NONE;

        /* Create a false header block that will return default
         * values for projection and coordsys conversion stuff...
         */
        m_poHeader = new TABMAPHeaderBlock(m_eAccessMode);
        m_poHeader->InitNewBlock(NULL, 512, 0 );

        return 1;
    }
    else
    {
        CPLError(CE_Failure, CPLE_FileIO,
                 "Open() failed for %s", pszFname);
        return -1;
    }

    /*-----------------------------------------------------------------
     * File appears to be valid... set the various class members
     *----------------------------------------------------------------*/
    m_fp = fp;
    m_poHeader = (TABMAPHeaderBlock*)poBlock;
    m_pszFname = CPLStrdup(pszFname);

    /*-----------------------------------------------------------------
     * Create a TABMAPObjectBlock, in READ mode only.
     *
     * In WRITE mode, the object block will be created only when needed.
     * We do not create the object block in the open() call because
     * files that contained only "NONE" geometries ended up with empty
     * object and spatial index blocks.
     *----------------------------------------------------------------*/

    if (m_eAccessMode == TABRead)
    {
        m_poCurObjBlock = new TABMAPObjectBlock(m_eAccessMode);
        m_poCurObjBlock->InitNewBlock(m_fp, 512);
    }
    else
    {
        m_poCurObjBlock = NULL;
    }

    /*-----------------------------------------------------------------
     * Open associated .ID (object id index) file
     *----------------------------------------------------------------*/
    m_poIdIndex = new TABIDFile;
    if (m_poIdIndex->Open(pszFname, pszAccess) != 0)
    {
        // Failed... an error has already been reported
        Close();
        return -1;
    }

    /*-----------------------------------------------------------------
     * Default Coord filter is the MBR of the whole file
     * This is currently unused but could eventually be used to handle
     * spatial filters more efficiently.
     *----------------------------------------------------------------*/
    if (m_eAccessMode == TABRead)
    {
        ResetCoordFilter();
    }

    /*-----------------------------------------------------------------
     * We could scan a file through its quad tree index... but we don't!
     *
     * In read mode, we just ignore the spatial index.
     *
     * In write mode the index is created and maintained as new object
     * blocks are added inside CommitObjBlock().
     *----------------------------------------------------------------*/
    m_poSpIndex = NULL;

    /*-----------------------------------------------------------------
     * Initialization of the Drawing Tools table will be done automatically
     * as Read/Write calls are done later.
     *----------------------------------------------------------------*/
    m_poToolDefTable = NULL;

    /*-----------------------------------------------------------------
     * Make sure all previous calls succeded.
     *----------------------------------------------------------------*/
    if (CPLGetLastErrorNo() != 0)
    {
        // Open Failed... an error has already been reported
        Close();
        return -1;
    }

    return 0;
}

/**********************************************************************
 *                   TABMAPFile::Close()
 *
 * Close current file, and release all memory used.
 *
 * Returns 0 on success, -1 on error.
 **********************************************************************/
int TABMAPFile::Close()
{
    // Check if file is opened... it is possible to have a fake header
    // without an actual file attached to it.
    if (m_fp == NULL && m_poHeader == NULL)
        return 0;

    /*----------------------------------------------------------------
     * Write access: commit latest changes to the file.
     *---------------------------------------------------------------*/
    if (m_eAccessMode == TABWrite)
    {
        // Start by committing current object and coord blocks
        // Nothing happens if none has been created yet.
        CommitObjAndCoordBlocks(FALSE);

        // Write the drawing tools definitions now.
        CommitDrawingTools();

        // Commit spatial index blocks
        CommitSpatialIndex();

        // Update header fields and commit
        if (m_poHeader)
        {
            // OK, with V450 files, objects are not limited to 32k nodes
            // any more, and this means that m_nMaxCoordBufSize can become
            // huge, and actually more huge than can be held in memory.
            // MapInfo counts m_nMaxCoordBufSize=0 for V450 objects, but 
            // until this is cleanly implented, we will just prevent 
            // m_nMaxCoordBufSizefrom going beyond 512k in V450 files.
            if (m_nMinTABVersion >= 450)
            {
                m_poHeader->m_nMaxCoordBufSize = 
                                 MIN(m_poHeader->m_nMaxCoordBufSize, 512*1024);
            }

            // Write Ref to beginning of the chain of garbage blocks
            m_poHeader->m_nFirstGarbageBlock = 
                m_oBlockManager.GetFirstGarbageBlock();

            m_poHeader->CommitToFile();
        }
    }
    
    // Check for overflow of internal coordinates and produce a warning
    // if that happened...
    if (m_poHeader && m_poHeader->m_bIntBoundsOverflow)
    {
        double dBoundsMinX, dBoundsMinY, dBoundsMaxX, dBoundsMaxY;
        Int2Coordsys(-1000000000, -1000000000, dBoundsMinX, dBoundsMinY);
        Int2Coordsys(1000000000, 1000000000, dBoundsMaxX, dBoundsMaxY);

        CPLError(CE_Warning, TAB_WarningBoundsOverflow,
                 "Some objects were written outside of the file's "
                 "predefined bounds.\n"
                 "These objects may have invalid coordinates when the file "
                 "is reopened.\n"
                 "Predefined bounds: (%.15g,%.15g)-(%.15g,%.15g)\n",
                 dBoundsMinX, dBoundsMinY, dBoundsMaxX, dBoundsMaxY );
    }

    // Delete all structures 
    if (m_poHeader)
        delete m_poHeader;
    m_poHeader = NULL;

    if (m_poIdIndex)
    {
        m_poIdIndex->Close();
        delete m_poIdIndex;
        m_poIdIndex = NULL;
    }

    if (m_poCurObjBlock)
    {
        delete m_poCurObjBlock;
        m_poCurObjBlock = NULL;
        m_nCurObjPtr = -1;
        m_nCurObjType = -1;
        m_nCurObjId = -1;
    }

    if (m_poCurCoordBlock)
    {
        delete m_poCurCoordBlock;
        m_poCurCoordBlock = NULL;
    }

    if (m_poSpIndex)
    {
        delete m_poSpIndex;
        m_poSpIndex = NULL;
        m_poSpIndexLeaf = NULL;
    }

    if (m_poToolDefTable)
    {
        delete m_poToolDefTable;
        m_poToolDefTable = NULL;
    }

    // Close file
    if (m_fp)
        VSIFClose(m_fp);
    m_fp = NULL;

    CPLFree(m_pszFname);
    m_pszFname = NULL;

    return 0;
}


/**********************************************************************
 *                   TABMAPFile::SetQuickSpatialIndexMode()
 *
 * Select "quick spatial index mode". 
 *
 * The default behavior of MITAB is to generate an optimized spatial index,
 * but this results in slower write speed. 
 *
 * Applications that want faster write speed and do not care
 * about the performance of spatial queries on the resulting file can
 * use SetQuickSpatialIndexMode() to require the creation of a non-optimal
 * spatial index (actually emulating the type of spatial index produced
 * by MITAB before version 1.6.0). In this mode writing files can be 
 * about 5 times faster, but spatial queries can be up to 30 times slower.
 *
 * Returns 0 on success, -1 on error.
 **********************************************************************/
int TABMAPFile::SetQuickSpatialIndexMode(GBool bQuickSpatialIndexMode/*=TRUE*/)
{
    if (m_eAccessMode != TABWrite)
    {
        CPLError(CE_Failure, CPLE_AssertionFailed,
                 "SetQuickSpatialIndexMode() failed: file not opened for write access.");
        return -1;
    }

    if (m_poCurObjBlock != NULL || m_poSpIndex != NULL)
    {
        CPLError(CE_Failure, CPLE_AssertionFailed,
                 "SetQuickSpatialIndexMode() must be called before writing the first object.");
        return -1;
    }

    m_bQuickSpatialIndexMode = bQuickSpatialIndexMode;

    return 0;
}

/************************************************************************/
/*                             PushBlock()                              */
/*                                                                      */
/*      Install a new block (object or spatial) as being current -      */
/*      whatever that means.  This method is only intended to ever      */
/*      be called from LoadNextMatchingObjectBlock().                   */
/************************************************************************/

TABRawBinBlock *TABMAPFile::PushBlock( int nFileOffset )

{
    TABRawBinBlock *poBlock;

    poBlock = GetIndexObjectBlock( nFileOffset );
    if( poBlock == NULL )
        return NULL;

    if( poBlock->GetBlockType() == TABMAP_INDEX_BLOCK )
    {
        TABMAPIndexBlock *poIndex = (TABMAPIndexBlock *) poBlock;

        if( m_poSpIndexLeaf == NULL )
        {
            m_poSpIndexLeaf = m_poSpIndex = poIndex;
        }
        else
        {
            CPLAssert( 
                m_poSpIndexLeaf->GetEntry(
                    m_poSpIndexLeaf->GetCurChildIndex())->nBlockPtr 
                == nFileOffset );

            m_poSpIndexLeaf->SetCurChildRef( poIndex, 
                                         m_poSpIndexLeaf->GetCurChildIndex() );
            poIndex->SetParentRef( m_poSpIndexLeaf );
            m_poSpIndexLeaf = poIndex;
        }
    }
    else
    {
        CPLAssert( poBlock->GetBlockType() == TABMAP_OBJECT_BLOCK );
        
        if( m_poCurObjBlock != NULL )
            delete m_poCurObjBlock;

        m_poCurObjBlock = (TABMAPObjectBlock *) poBlock;

        m_nCurObjPtr = nFileOffset;
        m_nCurObjType = 0;
        m_nCurObjId   = -1;
    }

    return poBlock;
}

/************************************************************************/
/*                    LoadNextMatchingObjectBlock()                     */
/*                                                                      */
/*      Advance through the spatial indices till the next object        */
/*      block is loaded that matching the spatial query extents.        */
/************************************************************************/

int TABMAPFile::LoadNextMatchingObjectBlock( int bFirstObject )

{
    // If we are just starting, verify the stack is empty.
    if( bFirstObject )
    {
        CPLAssert( m_poSpIndex == NULL && m_poSpIndexLeaf == NULL );

        if( PushBlock( m_poHeader->m_nFirstIndexBlock ) == NULL )
            return FALSE;

        if( m_poSpIndex == NULL )
        {
            CPLAssert( m_poCurObjBlock != NULL );
            return TRUE;
        }
    }

    while( m_poSpIndexLeaf != NULL )
    {
        int     iEntry = m_poSpIndexLeaf->GetCurChildIndex();

⌨️ 快捷键说明

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