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

📄 mitab_mapcoordblock.cpp

📁 GIS系统支持库Geospatial Data Abstraction Library代码.GDAL is a translator library for raster geospatial dat
💻 CPP
📖 第 1 页 / 共 2 页
字号:
int     TABMAPCoordBlock::ReadCoordSecHdrs(GBool bCompressed,                                            GBool bV450Hdr,                                           int numSections,                                           TABMAPCoordSecHdr *pasHdrs,                                           GInt32    &numVerticesTotal){    int i, nTotalHdrSizeUncompressed;    CPLErrorReset();    /*-------------------------------------------------------------     * Note about header+vertices size vs compressed coordinates:     * The uncompressed header sections are actually 16 bytes, but the     * offset calculations are based on prior decompression of the      * coordinates.  Our coordinate offset calculations have     * to take this fact into account.     * Also, V450 header section uses int32 instead of int16 for numVertices     * and we add another 2 bytes to align with a 4 bytes boundary.     *------------------------------------------------------------*/    if (bV450Hdr)        nTotalHdrSizeUncompressed = 28 * numSections;    else        nTotalHdrSizeUncompressed = 24 * numSections;    numVerticesTotal = 0;    for(i=0; i<numSections; i++)    {        /*-------------------------------------------------------------         * Read the coord. section header blocks         *------------------------------------------------------------*/        if (bV450Hdr)            pasHdrs[i].numVertices = ReadInt32();        else            pasHdrs[i].numVertices = ReadInt16();        pasHdrs[i].numHoles = ReadInt16();        ReadIntCoord(bCompressed, pasHdrs[i].nXMin, pasHdrs[i].nYMin);        ReadIntCoord(bCompressed, pasHdrs[i].nXMax, pasHdrs[i].nYMax);        pasHdrs[i].nDataOffset = ReadInt32();        if (CPLGetLastErrorType() != 0)            return -1;        numVerticesTotal += pasHdrs[i].numVertices;        pasHdrs[i].nVertexOffset = (pasHdrs[i].nDataOffset -                                     nTotalHdrSizeUncompressed ) / 8;#ifdef TABDUMP        printf("pasHdrs[%d] = { numVertices = %d, numHoles = %d, \n"               "                nXMin=%d, nYMin=%d, nXMax=%d, nYMax=%d,\n"               "                nDataOffset=%d, nVertexOffset=%d }\n",               i, pasHdrs[i].numVertices, pasHdrs[i].numHoles,                pasHdrs[i].nXMin, pasHdrs[i].nYMin, pasHdrs[i].nXMax,                pasHdrs[i].nYMax, pasHdrs[i].nDataOffset,                pasHdrs[i].nVertexOffset);        printf("                dX = %d, dY = %d  (center = %d , %d)\n",               pasHdrs[i].nXMax - pasHdrs[i].nXMin,               pasHdrs[i].nYMax - pasHdrs[i].nYMin,               m_nComprOrgX, m_nComprOrgY);#endif    }    for(i=0; i<numSections; i++)    {        /*-------------------------------------------------------------         * Make sure all coordinates are grouped together         * (Well... at least check that all the vertex indices are enclosed         * inside the [0..numVerticesTotal] range.)         *------------------------------------------------------------*/        if ( pasHdrs[i].nVertexOffset < 0 ||              (pasHdrs[i].nVertexOffset +                           pasHdrs[i].numVertices ) > numVerticesTotal)        {            CPLError(CE_Failure, CPLE_AssertionFailed,                     "Unsupported case or corrupt file: MULTIPLINE/REGION "                     "object vertices do not appear to be grouped together.");            return -1;        }    }    return 0;}/********************************************************************** *                   TABMAPObjectBlock::WriteCoordSecHdrs() * * Write a set of coordinate section headers for PLINE MULTIPLE or REGIONs. * pasHdrs should point to an array of numSections TABMAPCoordSecHdr  * structures that have been properly initialized. * * In V450 the numVertices is stored on an int32 instead of an int16 * * At the end of the call, this TABMAPCoordBlock object will be ready to * receive the coordinate data. * * Returns 0 if succesful or -1 if an error happened, in which case  * CPLError() will have been called. **********************************************************************/int     TABMAPCoordBlock::WriteCoordSecHdrs(GBool bV450Hdr,                                            int numSections,                                            TABMAPCoordSecHdr *pasHdrs,                                            GBool bCompressed /*=FALSE*/){    int i;    CPLErrorReset();    for(i=0; i<numSections; i++)    {        /*-------------------------------------------------------------         * Write the coord. section header blocks         *------------------------------------------------------------*/        if (bV450Hdr)            WriteInt32(pasHdrs[i].numVertices);        else            WriteInt16(pasHdrs[i].numVertices);        WriteInt16(pasHdrs[i].numHoles);        WriteIntCoord(pasHdrs[i].nXMin, pasHdrs[i].nYMin, bCompressed);        WriteIntCoord(pasHdrs[i].nXMax, pasHdrs[i].nYMax, bCompressed);        WriteInt32(pasHdrs[i].nDataOffset);        if (CPLGetLastErrorType() == CE_Failure )            return -1;    }    return 0;}/********************************************************************** *                   TABMAPCoordBlock::WriteIntCoord() * * Write a pair of integer coordinates values to the current position in the * the block. * * Returns 0 if succesful or -1 if an error happened, in which case  * CPLError() will have been called. **********************************************************************/int     TABMAPCoordBlock::WriteIntCoord(GInt32 nX, GInt32 nY,                                        GBool bCompressed /*=FALSE*/){    if ((!bCompressed && (WriteInt32(nX) != 0 || WriteInt32(nY) != 0 ) ) ||        (bCompressed && (WriteInt16(nX - m_nComprOrgX) != 0 ||                         WriteInt16(nY - m_nComprOrgY) != 0) ) )    {        return -1;    }    /*-----------------------------------------------------------------     * Update block MBR     *----------------------------------------------------------------*/    //__TODO__ Do we still need to track the block MBR???    if (nX < m_nMinX)        m_nMinX = nX;    if (nX > m_nMaxX)        m_nMaxX = nX;        if (nY < m_nMinY)        m_nMinY = nY;    if (nY > m_nMaxY)        m_nMaxY = nY;        /*-------------------------------------------------------------     * Also keep track of current feature MBR.     *------------------------------------------------------------*/    if (nX < m_nFeatureXMin)        m_nFeatureXMin = nX;    if (nX > m_nFeatureXMax)        m_nFeatureXMax = nX;    if (nY < m_nFeatureYMin)        m_nFeatureYMin = nY;    if (nY > m_nFeatureYMax)        m_nFeatureYMax = nY;    return 0;}/********************************************************************** *                   TABMAPCoordBlock::SetMAPBlockManagerRef() * * Pass a reference to the block manager object for the file this  * block belongs to.  The block manager will be used by this object * when it needs to automatically allocate a new block. **********************************************************************/void TABMAPCoordBlock::SetMAPBlockManagerRef(TABBinBlockManager *poBlockMgr){    m_poBlockManagerRef = poBlockMgr;};/********************************************************************** *                   TABMAPCoordBlock::ReadBytes() * * Cover function for TABRawBinBlock::ReadBytes() that will automagically * load the next coordinate block in the chain before reading the  * requested bytes if we are at the end of the current block and if * m_nNextCoordBlock is a valid block. * * Then the control is passed to TABRawBinBlock::ReadBytes() to finish the * work: * Copy the number of bytes from the data block's internal buffer to * the user's buffer pointed by pabyDstBuf. * * Passing pabyDstBuf = NULL will only move the read pointer by the * specified number of bytes as if the copy had happened... but it  * won't crash. * * Returns 0 if succesful or -1 if an error happened, in which case  * CPLError() will have been called. **********************************************************************/int     TABMAPCoordBlock::ReadBytes(int numBytes, GByte *pabyDstBuf){    int nStatus;    if (m_pabyBuf &&         m_nCurPos >= (m_numDataBytes+MAP_COORD_HEADER_SIZE) &&         m_nNextCoordBlock > 0)    {        // We're at end of current block... advance to next block.        if ( (nStatus=GotoByteInFile(m_nNextCoordBlock)) != 0)        {            // Failed.... an error has already been reported.            return nStatus;        }        GotoByteInBlock(MAP_COORD_HEADER_SIZE); // Move pointer past header        m_numBlocksInChain++;    }    if (m_pabyBuf &&         m_nCurPos < (m_numDataBytes+MAP_COORD_HEADER_SIZE) &&         m_nCurPos+numBytes > (m_numDataBytes+MAP_COORD_HEADER_SIZE) &&         m_nNextCoordBlock > 0)    {        // Data overlaps on more than one block        // Read until end of this block and then recursively call ReadBytes()        // for the rest.        int numBytesInThisBlock =                       (m_numDataBytes+MAP_COORD_HEADER_SIZE)-m_nCurPos;        nStatus = TABRawBinBlock::ReadBytes(numBytesInThisBlock, pabyDstBuf);        if (nStatus == 0)            nStatus = TABMAPCoordBlock::ReadBytes(numBytes-numBytesInThisBlock,                                               pabyDstBuf+numBytesInThisBlock);        return nStatus;    }    return TABRawBinBlock::ReadBytes(numBytes, pabyDstBuf);}/********************************************************************** *                   TABMAPCoordBlock::WriteBytes() * * Cover function for TABRawBinBlock::WriteBytes() that will automagically * CommitToFile() the current block and create a new one if we are at  * the end of the current block. * * Then the control is passed to TABRawBinBlock::WriteBytes() to finish the * work. * * Passing pabySrcBuf = NULL will only move the write pointer by the * specified number of bytes as if the copy had happened... but it  * won't crash. * * Returns 0 if succesful or -1 if an error happened, in which case  * CPLError() will have been called. **********************************************************************/int  TABMAPCoordBlock::WriteBytes(int nBytesToWrite, GByte *pabySrcBuf){    if (m_eAccess == TABWrite && m_poBlockManagerRef &&        (m_nBlockSize - m_nCurPos) < nBytesToWrite)    {        if (nBytesToWrite <= (m_nBlockSize-MAP_COORD_HEADER_SIZE))        {            // Data won't fit in this block but can fit inside a single            // block, so we'll allocate a new block for it.  This will             // prevent us from overlapping coordinate values on 2 blocks, but            // still allows strings longer than one block (see 'else' below).            //            int nNewBlockOffset = m_poBlockManagerRef->AllocNewBlock();            SetNextCoordBlock(nNewBlockOffset);            if (CommitToFile() != 0 ||                InitNewBlock(m_fp, 512, nNewBlockOffset) != 0)            {                // An error message should have already been reported.                return -1;            }            m_numBlocksInChain++;        }        else        {            // Data to write is longer than one block... so we'll have to            // split it over multiple block through multiple calls.            //            int nStatus = 0;            while(nStatus == 0 && nBytesToWrite > 0)            {                int nBytes = m_nBlockSize-MAP_COORD_HEADER_SIZE;                if ( (m_nBlockSize - m_nCurPos) > 0 )                {                    // Use free room in current block                    nBytes = (m_nBlockSize - m_nCurPos);                }                nBytes = MIN(nBytes, nBytesToWrite);                // The following call will result in a new block being                 // allocated in the if() block above.                nStatus = TABMAPCoordBlock::WriteBytes(nBytes,                                                        pabySrcBuf);                nBytesToWrite -= nBytes;                pabySrcBuf += nBytes;            }            return nStatus;        }    }    if (m_nCurPos >= MAP_COORD_HEADER_SIZE)    {        // Keep track of Coordinate data... this means ignore header bytes        // that could be written.        m_nTotalDataSize += nBytesToWrite;        m_nFeatureDataSize += nBytesToWrite;    }    return TABRawBinBlock::WriteBytes(nBytesToWrite, pabySrcBuf);}/********************************************************************** *                   TABMAPCoordBlock::StartNewFeature() * * Reset all member vars that are used to keep track of data size * and MBR for the current feature.  This is info is not needed by * the coord blocks themselves, but it helps a lot the callers to * have this class take care of that for them. * * See Also: GetFeatureDataSize() and GetFeatureMBR() **********************************************************************/void TABMAPCoordBlock::StartNewFeature(){    m_nFeatureDataSize = 0;    m_nFeatureXMin = 1000000000;    m_nFeatureYMin = 1000000000;    m_nFeatureXMax = -1000000000;    m_nFeatureYMax = -1000000000;}/********************************************************************** *                   TABMAPCoordBlock::GetFeatureMBR() * * Return the MBR of all the coords written using WriteIntCoord() since * the last call to StartNewFeature(). **********************************************************************/void TABMAPCoordBlock::GetFeatureMBR(GInt32 &nXMin, GInt32 &nYMin,                                      GInt32 &nXMax, GInt32 &nYMax){    nXMin = m_nFeatureXMin;    nYMin = m_nFeatureYMin;    nXMax = m_nFeatureXMax;    nYMax = m_nFeatureYMax; }/********************************************************************** *                   TABMAPCoordBlock::Dump() * * Dump block contents... available only in DEBUG mode. **********************************************************************/#ifdef DEBUGvoid TABMAPCoordBlock::Dump(FILE *fpOut /*=NULL*/){    if (fpOut == NULL)        fpOut = stdout;    fprintf(fpOut, "----- TABMAPCoordBlock::Dump() -----\n");    if (m_pabyBuf == NULL)    {        fprintf(fpOut, "Block has not been initialized yet.");    }    else    {        fprintf(fpOut,"Coordinate Block (type %d) at offset %d.\n",                                                  m_nBlockType, m_nFileOffset);        fprintf(fpOut,"  m_numDataBytes        = %d\n", m_numDataBytes);        fprintf(fpOut,"  m_nNextCoordBlock     = %d\n", m_nNextCoordBlock);    }    fflush(fpOut);}#endif // DEBUG

⌨️ 快捷键说明

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