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

📄 tabmapfile.cpp

📁 linux下一款GIS程序源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 * Returns 0 on success, -1 on error. **********************************************************************/int   TABMAPFile::MoveToObjId(int nObjId){    int nFileOffset;    /*-----------------------------------------------------------------     * In read access mode, since the .MAP/.ID are optional, if the      * file is not opened then we can still act as if one existed and     * make any object id look like a TAB_GEOM_NONE     *----------------------------------------------------------------*/    if (m_fp == NULL && m_eAccessMode == TABRead)    {        assert(m_poIdIndex == NULL && m_poCurObjBlock == NULL);        m_nCurObjPtr = 0;        m_nCurObjId = nObjId;        m_nCurObjType = TAB_GEOM_NONE;        return 0;    }    if (m_poIdIndex == NULL || m_poCurObjBlock == NULL)    {        UGKError(ET_Failure, UGKErr_AssertionFailed,                  "MoveToObjId(): file not opened!");        m_nCurObjPtr = m_nCurObjId = m_nCurObjType = -1;        return -1;    }    /*-----------------------------------------------------------------     * Move map object pointer to the right location.  Fetch location     * from the index file, unless we are already pointing at it.     *----------------------------------------------------------------*/    if( m_nCurObjId == nObjId )        nFileOffset = m_nCurObjPtr;    else        nFileOffset = m_poIdIndex->GetObjPtr(nObjId);    if (nFileOffset == 0)    {        /*---------------------------------------------------------         * Object with no geometry... this is a valid case.         *--------------------------------------------------------*/        m_nCurObjPtr = 0;        m_nCurObjId = nObjId;        m_nCurObjType = TAB_GEOM_NONE;    }         //使当前对象块移动到包含指定的对象        else if ( m_poCurObjBlock->GotoByteInFile(nFileOffset) == 0)//$zgq    {        /*-------------------------------------------------------------         * OK, it worked, read the object type and row id.         *------------------------------------------------------------*/        m_nCurObjPtr = nFileOffset;        m_nCurObjType = m_poCurObjBlock->ReadByte();        m_nCurObjId   = m_poCurObjBlock->ReadInt32();        // Do a consistency check...        if (m_nCurObjId != nObjId)        {            UGKError(ET_Failure, UGKErr_FileIO,                  "Object ID from the .ID file (%d) differs from the value "                  "in the .MAP file (%d).  File may be corrupt.",                  nObjId, m_nCurObjId);            m_nCurObjPtr = m_nCurObjId = m_nCurObjType = -1;            return -1;        }    }    else    {        /*---------------------------------------------------------         * Failed positioning input file... CPLError has been called.         *--------------------------------------------------------*/        m_nCurObjPtr = m_nCurObjId = m_nCurObjType = -1;        return -1;    }    return 0;}/********************************************************************** *                   TABMAPFile::PrepareNewObj() * * Get ready to write a new object of the specified type and with the  * specified id.   * * m_poCurObjBlock will be set to be ready to receive the new object, and * a new block will be created if necessary (in which case the current  * block contents will be committed to disk, etc.)  The object type and  * row ID will be written to the m_poCurObjBlock, so it will be ready to * receive the first byte of data for this map object.   * * If this object type uses coordinate blocks, then the coordinate block * will be prepared to receive coordinates. * * This function will also take care of updating the .ID index entry for * the new object. * * Note that object ids are positive and start at 1. * * Returns 0 on success, -1 on error. **********************************************************************/int   TABMAPFile::PrepareNewObj(int nObjId, UGKByte nObjType){    int nObjSize;    m_nCurObjPtr = m_nCurObjId = m_nCurObjType = -1;    if (m_eAccessMode != TABWrite ||         m_poIdIndex == NULL || m_poHeader == NULL)    {        UGKError(ET_Failure, UGKErr_AssertionFailed,                  "PrepareNewObj() failed: file not opened for write access.");        return -1;    }    /*-----------------------------------------------------------------     * For objects with no geometry, we just update the .ID file and return     *----------------------------------------------------------------*/    if (nObjType == TAB_GEOM_NONE)    {        m_nCurObjType = nObjType;        m_nCurObjId   = nObjId;        m_nCurObjPtr  = 0;        m_poIdIndex->SetObjPtr(m_nCurObjId, 0);        return 0;    }    /*-----------------------------------------------------------------     * Update count of objects by type in the header block     *----------------------------------------------------------------*/    if (nObjType == TAB_GEOM_SYMBOL ||        nObjType == TAB_GEOM_FONTSYMBOL ||        nObjType == TAB_GEOM_CUSTOMSYMBOL ||        nObjType == TAB_GEOM_SYMBOL_C ||        nObjType == TAB_GEOM_FONTSYMBOL_C ||        nObjType == TAB_GEOM_CUSTOMSYMBOL_C)    {        m_poHeader->m_numPointObjects++;    }    else if (nObjType == TAB_GEOM_LINE ||             nObjType == TAB_GEOM_PLINE ||             nObjType == TAB_GEOM_MULTIPLINE ||             nObjType == TAB_GEOM_V450_MULTIPLINE ||             nObjType == TAB_GEOM_ARC ||             nObjType == TAB_GEOM_LINE_C ||             nObjType == TAB_GEOM_PLINE_C ||             nObjType == TAB_GEOM_MULTIPLINE_C ||             nObjType == TAB_GEOM_V450_MULTIPLINE_C ||             nObjType == TAB_GEOM_ARC_C)    {        m_poHeader->m_numLineObjects++;    }    else if (nObjType == TAB_GEOM_REGION ||             nObjType == TAB_GEOM_V450_REGION ||             nObjType == TAB_GEOM_RECT ||             nObjType == TAB_GEOM_ROUNDRECT ||             nObjType == TAB_GEOM_ELLIPSE ||             nObjType == TAB_GEOM_REGION_C ||             nObjType == TAB_GEOM_V450_REGION_C ||             nObjType == TAB_GEOM_RECT_C ||             nObjType == TAB_GEOM_ROUNDRECT_C ||             nObjType == TAB_GEOM_ELLIPSE_C)    {        m_poHeader->m_numRegionObjects++;    }    else if (nObjType == TAB_GEOM_TEXT ||             nObjType == TAB_GEOM_TEXT_C)    {        m_poHeader->m_numTextObjects++;    }    /*-----------------------------------------------------------------     * Check for V450-specific object types and minimum TAB file version number     *----------------------------------------------------------------*/    if (m_nMinTABVersion < 450 &&        (nObjType == TAB_GEOM_V450_REGION ||         nObjType == TAB_GEOM_V450_MULTIPLINE ||         nObjType == TAB_GEOM_V450_REGION_C ||         nObjType == TAB_GEOM_V450_MULTIPLINE_C) )    {        m_nMinTABVersion = 450;    }    /*-----------------------------------------------------------------     * Check for V460-specific object types (multipoint and collection)     *----------------------------------------------------------------*/    if (m_nMinTABVersion < 650 &&        (nObjType == TAB_GEOM_MULTIPOINT   ||         nObjType == TAB_GEOM_MULTIPOINT_C ||         nObjType == TAB_GEOM_COLLECTION   ||         nObjType == TAB_GEOM_COLLECTION_C    ) )    {        m_nMinTABVersion = 650;    }    /*-----------------------------------------------------------------     * OK, looks like we will need object block... check if it exists and     * create it if it has not been created yet (first time for this file).     * 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.     * Note: A coord block will be created only if needed later.     *----------------------------------------------------------------*/    if (m_poCurObjBlock == NULL)    {        m_poCurObjBlock = new TABMAPObjectBlock(m_eAccessMode);        int nBlockOffset = m_oBlockManager.AllocNewBlock();        m_poCurObjBlock->InitNewBlock(m_fp, 512, nBlockOffset);        // The reference to the first object block should         // actually go through the index blocks... this will be         // updated when file is closed.        m_poHeader->m_nFirstIndexBlock = nBlockOffset;    }    /*-----------------------------------------------------------------     * Fetch new object size, make sure there is enough room in obj.      * block for new object, and save/create a new one if necessary.     *----------------------------------------------------------------*/    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.     *----------------------------------------------------------------*/    if (m_poHeader->MapObjectUsesCoordBlock(m_nCurObjType))    {        if (m_poCurCoordBlock == NULL)        {            m_poCurCoordBlock = new TABMAPCoordBlock(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 (UGKGetLastErrorNo() != 0 && UGKGetLastErrorType() == ET_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(UGKBool 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)    {        UGKError(ET_Failure, UGKErr_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)    {        UGKInt32 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);

⌨️ 快捷键说明

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