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

📄 mitab_mapfile.cpp

📁 用于读取TAB、MIF、SHP文件的类
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    nObjSize = m_poHeader->GetMapObjectSize(nObjType);    if (m_poCurObjBlock->GetNumUnusedBytes() < nObjSize )    {        /*-------------------------------------------------------------         * OK, the new object won't fit in the current block.  Commit         * the current block to disk, and init a new one.         *         * __TODO__ To create an optimum file, we should split the object         * block at this point and update the index blocks... however the         * file should still be usable even if we don't do it.         *------------------------------------------------------------*/        CommitObjBlock(TRUE);    }    /*-----------------------------------------------------------------     * Init member vars and write new object type/id     *----------------------------------------------------------------*/    m_nCurObjType = nObjType;    m_nCurObjId   = nObjId;    m_nCurObjPtr = m_poCurObjBlock->GetFirstUnusedByteOffset();    m_poCurObjBlock->GotoByteInFile(m_nCurObjPtr);    m_poCurObjBlock->WriteByte(m_nCurObjType);    m_poCurObjBlock->WriteInt32(m_nCurObjId);    // Move write pointer to start location of next object (padding with zeros)    // Nothing will get written to the object block until CommitToFile()    // is called.    m_poCurObjBlock->WriteZeros(m_poHeader->GetMapObjectSize(nObjType) - 5);    /*-----------------------------------------------------------------     * Update .ID Index     *----------------------------------------------------------------*/    m_poIdIndex->SetObjPtr(m_nCurObjId, m_nCurObjPtr);    /*-----------------------------------------------------------------     * Prepare Coords block...      * create a new TABMAPCoordBlock if it was not done yet.     * Note that in write mode, TABCollections require read/write access     * to the coord block.     *----------------------------------------------------------------*/    if (m_poHeader->MapObjectUsesCoordBlock(m_nCurObjType))    {        if (m_poCurCoordBlock == NULL)        {            m_poCurCoordBlock = new TABMAPCoordBlock(m_eAccessMode==TABWrite?                                                     TABReadWrite:                                                      m_eAccessMode);            m_poCurCoordBlock->InitNewBlock(m_fp, 512,                                             m_oBlockManager.AllocNewBlock());            m_poCurCoordBlock->SetMAPBlockManagerRef(&m_oBlockManager);            // Set the references to this coord block in the MAPObjBlock            m_poCurObjBlock->AddCoordBlockRef(m_poCurCoordBlock->                                                           GetStartAddress());        }        if (m_poCurCoordBlock->GetNumUnusedBytes() < 4)        {            int nNewBlockOffset = m_oBlockManager.AllocNewBlock();            m_poCurCoordBlock->SetNextCoordBlock(nNewBlockOffset);            m_poCurCoordBlock->CommitToFile();            m_poCurCoordBlock->InitNewBlock(m_fp, 512, nNewBlockOffset);        }    }    if (CPLGetLastErrorNo() != 0 && CPLGetLastErrorType() == CE_Failure)        return -1;    return 0;}/********************************************************************** *                   TABMAPFile::CommitObjBlock() * * Commit the TABMAPObjBlock and TABMAPCoordBlock to disk after updating * the references to each other and in the TABMAPIndex block. * * After the Commit() call, the ObjBlock and others will be reinitialized * and ready to receive new objects. (only if bInitNewBlock==TRUE) * * Returns 0 on success, -1 on error. **********************************************************************/int TABMAPFile::CommitObjBlock(GBool bInitNewBlock /*=TRUE*/){    int nStatus = 0;    /*-----------------------------------------------------------------     * First check that a objBlock has been created.  It is possible to have     * no object block in files that contain only "NONE" geometries.     *----------------------------------------------------------------*/    if (m_poCurObjBlock == NULL)        return 0;     if (m_eAccessMode != TABWrite)    {        CPLError(CE_Failure, CPLE_AssertionFailed,                 "CommitObjBlock() failed: file not opened for write access.");        return -1;    }    /*-----------------------------------------------------------------     * We need to flush the coord block if there was one     * since a list of coord blocks can belong to only one obj. block     *----------------------------------------------------------------*/    if (m_poCurCoordBlock)    {        // Update the m_nMaxCoordBufSize member in the header block        //        int nTotalCoordSize = m_poCurCoordBlock->GetNumBlocksInChain()*512;        if (nTotalCoordSize > m_poHeader->m_nMaxCoordBufSize)            m_poHeader->m_nMaxCoordBufSize = nTotalCoordSize;        // Update the references to this coord block in the MAPObjBlock        //        m_poCurObjBlock->AddCoordBlockRef(m_poCurCoordBlock->                                                         GetStartAddress());        nStatus = m_poCurCoordBlock->CommitToFile();        delete m_poCurCoordBlock;        m_poCurCoordBlock = NULL;    }    /*-----------------------------------------------------------------     * Commit the obj block.     *----------------------------------------------------------------*/    if (nStatus == 0)        nStatus = m_poCurObjBlock->CommitToFile();    /*-----------------------------------------------------------------     * Update the spatial index     *     * Spatial index will be created here if it was not done yet.     *----------------------------------------------------------------*/    if (nStatus == 0)    {        GInt32 nXMin, nYMin, nXMax, nYMax;        if (m_poSpIndex == NULL)        {            // Spatial Index not created yet...            m_poSpIndex = new TABMAPIndexBlock(m_eAccessMode);            m_poSpIndex->InitNewBlock(m_fp, 512,                                       m_oBlockManager.AllocNewBlock());            m_poSpIndex->SetMAPBlockManagerRef(&m_oBlockManager);            m_poHeader->m_nFirstIndexBlock = m_poSpIndex->GetNodeBlockPtr();        }        m_poCurObjBlock->GetMBR(nXMin, nYMin, nXMax, nYMax);        nStatus = m_poSpIndex->AddEntry(nXMin, nYMin, nXMax, nYMax,                                        m_poCurObjBlock->GetStartAddress());        m_poHeader->m_nMaxSpIndexDepth = MAX(m_poHeader->m_nMaxSpIndexDepth,                                             m_poSpIndex->GetCurMaxDepth()+1);    }    /*-----------------------------------------------------------------     * Reinitialize the obj block only if requested     *----------------------------------------------------------------*/    if (bInitNewBlock && nStatus == 0)    {        nStatus = m_poCurObjBlock->InitNewBlock(m_fp,512,                                            m_oBlockManager.AllocNewBlock());    }    return nStatus;}/********************************************************************** *                   TABMAPFile::GetCurObjType() * * Return the MapInfo object type of the object that the m_poCurObjBlock * is pointing to.  This value is set after a call to MoveToObjId(). * * Returns a value >= 0 on success, -1 on error. **********************************************************************/int TABMAPFile::GetCurObjType(){    return m_nCurObjType;}/********************************************************************** *                   TABMAPFile::GetCurObjId() * * Return the MapInfo object id of the object that the m_poCurObjBlock * is pointing to.  This value is set after a call to MoveToObjId(). * * Returns a value >= 0 on success, -1 on error. **********************************************************************/int TABMAPFile::GetCurObjId(){    return m_nCurObjId;}/********************************************************************** *                   TABMAPFile::GetCurObjBlock() * * Return the m_poCurObjBlock.  If MoveToObjId() has previously been  * called then m_poCurObjBlock points to the beginning of the current  * object data. * * Returns a reference to an object owned by this TABMAPFile object, or * NULL on error. **********************************************************************/TABMAPObjectBlock *TABMAPFile::GetCurObjBlock(){    return m_poCurObjBlock;}/********************************************************************** *                   TABMAPFile::GetCurCoordBlock() * * Return the m_poCurCoordBlock.  This function should be used after  * PrepareNewObj() to get the reference to the coord block that has * just been initialized. * * Returns a reference to an object owned by this TABMAPFile object, or * NULL on error. **********************************************************************/TABMAPCoordBlock *TABMAPFile::GetCurCoordBlock(){    return m_poCurCoordBlock;}/********************************************************************** *                   TABMAPFile::GetCoordBlock() * * Return a TABMAPCoordBlock object ready to read coordinates from it. * The block that contains nFileOffset will automatically be * loaded, and if nFileOffset is the beginning of a new block then the * pointer will be moved to the beginning of the data. * * The contents of the returned object is only valid until the next call * to GetCoordBlock(). * * Returns a reference to an object owned by this TABMAPFile object, or * NULL on error. **********************************************************************/TABMAPCoordBlock *TABMAPFile::GetCoordBlock(int nFileOffset){    if (m_eAccessMode != TABRead)        return NULL;    if (m_poCurCoordBlock == NULL)    {        m_poCurCoordBlock = new TABMAPCoordBlock(m_eAccessMode);        m_poCurCoordBlock->InitNewBlock(m_fp, 512);    }    /*-----------------------------------------------------------------     * Use GotoByteInFile() to go to the requested location.  This will     * force loading the block if necessary and reading its header.     * If nFileOffset is at the beginning of the requested block, then     * we make sure to move the read pointer past the 8 bytes header     * to be ready to read coordinates data     *----------------------------------------------------------------*/    if ( m_poCurCoordBlock->GotoByteInFile(nFileOffset) != 0)    {        // Failed... an error has already been reported.        return NULL;    }    if (nFileOffset % 512 == 0)        m_poCurCoordBlock->GotoByteInBlock(8);      // Skip Header    return m_poCurCoordBlock;}/********************************************************************** *                   TABMAPFile::GetHeaderBlock() * * Return a reference to the MAP file's header block. * * The returned pointer is a reference to an object owned by this TABMAPFile * object and should not be deleted by the caller. * * Return NULL if file has not been opened yet. **********************************************************************/TABMAPHeaderBlock *TABMAPFile::GetHeaderBlock(){    return m_poHeader;}/********************************************************************** *                   TABMAPFile::GetIDFileRef() * * Return a reference to the .ID file attached to this .MAP file * * The returned pointer is a reference to an object owned by this TABMAPFile * object and should not be deleted by the caller. * * Return NULL if file has not been opened yet. **********************************************************************/TABIDFile *TABMAPFile::GetIDFileRef(){    return m_poIdIndex;}/********************************************************************** *                   TABMAPFile::GetIndexBlock() * * Return a reference to the requested index or object block.. * * Ownership of the returned block is turned over to the caller, who should * delete it when no longer needed.  The type of the block can be determined * with the GetBlockType() method.  * * @param nFileOffset the offset in the map file of the spatial index * block or object block to load. * * @return The requested TABMAPIndexBlock, TABMAPObjectBlock or NULL if the  * read fails for some reason. **********************************************************************/TABRawBinBlock *TABMAPFile::GetIndexObjectBlock( int nFileOffset ){    /*----------------------------------------------------------------     * Read from the file     *---------------------------------------------------------------*/    GByte abyData[512];    if (VSIFSeek(m_fp, nFileOffset, SEEK_SET) != 0         || VSIFRead(abyData, sizeof(GByte), 512, m_fp) != 512 )    {        CPLError(CE_Failure, CPLE_FileIO,                 "GetIndexBlock() failed reading %d bytes at offset %d.",                 512, nFileOffset);        return NULL;    }/* -------------------------------------------------------------------- *//*      Create and initialize depending on the block type.              *//* -------------------------------------------------------------------- */    int nBlockType = abyData[0];    TABRawBinBlock *poBlock;    if( nBlockType == TABMAP_INDEX_BLOCK )        poBlock = new TABMAPIndexBlock();    else        poBlock = new TABMAPObjectBlock();        if( poBlock->InitBlockFromData(abyData,512,TRUE,m_fp,nFileOffset) == -1 )    {        delete poBlock;        poBlock = NULL;    }    return poBlock;}/********************************************************************** *                   TABMAPFile::InitDrawingTools() * * Init the drawing tools for this file. * * In Read mode, this will load the drawing tools from the file. * * In Write mode, this function will init an empty the tool def table. * * Reutrns 0 on success, -1 on error. **********************************************************************/int TABMAPFile::InitDrawingTools()

⌨️ 快捷键说明

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