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

📄 mitab_mapobjectblock.cpp

📁 mitab,读取MapInfo的地图文件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    return 0;
}

/**********************************************************************
 *                   TABMAPObjectBlock::ReadCoord()
 *
 * Read the next pair of integer coordinates value from the block, and
 * apply the translation relative to to the center of the data block
 * if bCompressed=TRUE.
 *
 * This means that the returned coordinates are always absolute integer
 * coordinates, even when the source coords are in compressed form.
 *
 * Returns 0 if succesful or -1 if an error happened, in which case 
 * CPLError() will have been called.
 **********************************************************************/
int     TABMAPObjectBlock::ReadIntCoord(GBool bCompressed, 
                                        GInt32 &nX, GInt32 &nY)
{
    if (bCompressed)
    {   
        nX = m_nCenterX + ReadInt16();
        nY = m_nCenterY + ReadInt16();
    }
    else
    {
        nX = ReadInt32();
        nY = ReadInt32();
    }

    if (CPLGetLastErrorNo() != 0)
        return -1;

    return 0;
}

/**********************************************************************
 *                   TABMAPObjectBlock::WriteIntCoord()
 *
 * Write a pair of integer coordinates values to the current position in the
 * the block.  If bCompr=TRUE then the coordinates are written relative to
 * the object block center... otherwise they're written as 32 bits int.
 *
 * This function does not maintain the block's MBR and center... it is 
 * assumed to have been set before the first call to WriteIntCoord()
 *
 * Returns 0 if succesful or -1 if an error happened, in which case 
 * CPLError() will have been called.
 **********************************************************************/
int     TABMAPObjectBlock::WriteIntCoord(GInt32 nX, GInt32 nY,
                                         GBool bCompressed /*=FALSE*/)
{

    /*-----------------------------------------------------------------
     * Write coords to the file.
     *----------------------------------------------------------------*/
    if ((!bCompressed && (WriteInt32(nX) != 0 || WriteInt32(nY) != 0 ) ) ||
        (bCompressed && (WriteInt16(nX - m_nCenterX) != 0 ||
                         WriteInt16(nY - m_nCenterY) != 0) ) )
    {
        return -1;
    }

    return 0;
}

/**********************************************************************
 *                   TABMAPObjectBlock::WriteIntMBRCoord()
 *
 * Write 2 pairs of integer coordinates values to the current position 
 * in the the block after making sure that min values are smaller than
 * max values.  Use this function to write MBR coordinates for an object.
 *
 * If bCompr=TRUE then the coordinates are written relative to
 * the object block center... otherwise they're written as 32 bits int.
 *
 * This function does not maintain the block's MBR and center... it is 
 * assumed to have been set before the first call to WriteIntCoord()
 *
 * Returns 0 if succesful or -1 if an error happened, in which case 
 * CPLError() will have been called.
 **********************************************************************/
int     TABMAPObjectBlock::WriteIntMBRCoord(GInt32 nXMin, GInt32 nYMin,
                                            GInt32 nXMax, GInt32 nYMax,
                                            GBool bCompressed /*=FALSE*/)
{
    if (WriteIntCoord(MIN(nXMin, nXMax), MIN(nYMin, nYMax),
                      bCompressed) != 0 ||
        WriteIntCoord(MAX(nXMin, nXMax), MAX(nYMin, nYMax), 
                      bCompressed) != 0 )
    {
        return -1;
    }

    return 0;
}


/**********************************************************************
 *                   TABMAPObjectBlock::UpdateMBR()
 *
 * Update the block's MBR and center.
 *
 * Returns 0 if succesful or -1 if an error happened, in which case 
 * CPLError() will have been called.
 **********************************************************************/
int     TABMAPObjectBlock::UpdateMBR(GInt32 nX, GInt32 nY)
{

    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;
    
    m_nCenterX = (m_nMinX + m_nMaxX) /2;
    m_nCenterY = (m_nMinY + m_nMaxY) /2;
    
    return 0;
}

/**********************************************************************
 *                   TABMAPObjectBlock::AddCoordBlockRef()
 *
 * Update the first/last coord block fields in this object to contain
 * the specified block address.
 **********************************************************************/
void     TABMAPObjectBlock::AddCoordBlockRef(GInt32 nNewBlockAddress)
{
    /*-----------------------------------------------------------------
     * Normally, new blocks are added to the end of the list, except
     * the first one which is the beginning and the end of the list at 
     * the same time.
     *----------------------------------------------------------------*/
    if (m_nFirstCoordBlock == 0)
        m_nFirstCoordBlock = nNewBlockAddress;

    m_nLastCoordBlock = nNewBlockAddress;
}

/**********************************************************************
 *                   TABMAPObjectBlock::SetMBR()
 *
 * Set the MBR for the current block.
 **********************************************************************/
void TABMAPObjectBlock::SetMBR(GInt32 nXMin, GInt32 nYMin, 
                               GInt32 nXMax, GInt32 nYMax)
{
    m_nMinX = nXMin;
    m_nMinY = nYMin;
    m_nMaxX = nXMax;
    m_nMaxY = nYMax; 

    m_nCenterX = (m_nMinX + m_nMaxX) /2;
    m_nCenterY = (m_nMinY + m_nMaxY) /2;
}

/**********************************************************************
 *                   TABMAPObjectBlock::GetMBR()
 *
 * Return the MBR for the current block.
 **********************************************************************/
void TABMAPObjectBlock::GetMBR(GInt32 &nXMin, GInt32 &nYMin, 
                               GInt32 &nXMax, GInt32 &nYMax)
{
    nXMin = m_nMinX;
    nYMin = m_nMinY;
    nXMax = m_nMaxX;
    nYMax = m_nMaxY; 
}


/**********************************************************************
 *                   TABMAPObjectBlock::PrepareNewObject()
 *
 * Prepare this block to receive this new object. We only reserve space for
 * it in this call. Actual data will be written only when CommitNewObject()
 * is called.
 *
 * Returns the position at which the new object starts
 **********************************************************************/
int     TABMAPObjectBlock::PrepareNewObject(TABMAPObjHdr *poObjHdr)
{
    int nStartAddress = 0;

    // Nothing to do for NONE objects
    if (poObjHdr->m_nType == TAB_GEOM_NONE)
    {
        return 0;
    }

    // Maintain MBR of this object block.
    UpdateMBR(poObjHdr->m_nMinX, poObjHdr->m_nMinY);
    UpdateMBR(poObjHdr->m_nMaxX, poObjHdr->m_nMaxY);
   
    /*-----------------------------------------------------------------
     * Keep track of object type, ID and start address for use by
     * CommitNewObject()
     *----------------------------------------------------------------*/
    nStartAddress = GetFirstUnusedByteOffset();
    GotoByteInFile(nStartAddress);
    m_nCurObjectOffset = nStartAddress - GetStartAddress();

    m_nCurObjectType = poObjHdr->m_nType;
    m_nCurObjectId   = poObjHdr->m_nId;

    return nStartAddress;
}

/**********************************************************************
 *                   TABMAPObjectBlock::CommitCurObjData()
 *
 * Write the ObjHdr to this block. This is usually called after 
 * PrepareNewObject() once all members of the ObjHdr have
 * been set.
 *
 * Returns 0 if succesful or -1 if an error happened, in which case 
 * CPLError() will have been called.
 **********************************************************************/
int     TABMAPObjectBlock::CommitNewObject(TABMAPObjHdr *poObjHdr)
{
    int nStatus = 0;

    // Nothing to do for NONE objects
    if (poObjHdr->m_nType == TAB_GEOM_NONE)
    {
        return 0;
    }

    CPLAssert(m_nCurObjectId == poObjHdr->m_nId);
    GotoByteInBlock(m_nCurObjectOffset);

    nStatus = poObjHdr->WriteObj(this);

    if (nStatus == 0)
        m_numDataBytes = m_nSizeUsed - MAP_OBJECT_HEADER_SIZE;

    return nStatus;
}

/**********************************************************************
 *                   TABMAPObjectBlock::Dump()
 *
 * Dump block contents... available only in DEBUG mode.
 **********************************************************************/
#ifdef DEBUG

void TABMAPObjectBlock::Dump(FILE *fpOut, GBool bDetails)
{
    CPLErrorReset();

    if (fpOut == NULL)
        fpOut = stdout;

    fprintf(fpOut, "----- TABMAPObjectBlock::Dump() -----\n");
    if (m_pabyBuf == NULL)
    {
        fprintf(fpOut, "Block has not been initialized yet.");
    }
    else
    {
        fprintf(fpOut,"Object Data Block (type %d) at offset %d.\n", 
                                                m_nBlockType, m_nFileOffset);
        fprintf(fpOut,"  m_numDataBytes        = %d\n", m_numDataBytes);
        fprintf(fpOut,"  m_nCenterX            = %d\n", m_nCenterX);
        fprintf(fpOut,"  m_nCenterY            = %d\n", m_nCenterY);
        fprintf(fpOut,"  m_nFirstCoordBlock    = %d\n", m_nFirstCoordBlock);
        fprintf(fpOut,"  m_nLastCoordBlock     = %d\n", m_nLastCoordBlock);
    }

    if (bDetails)
    {
        /* We need the mapfile's header block */
        TABRawBinBlock *poBlock;
        TABMAPHeaderBlock *poHeader;
        TABMAPObjHdr *poObjHdr;

        poBlock = TABCreateMAPBlockFromFile(m_fp, 0, 512);
        if (poBlock==NULL || poBlock->GetBlockClass() != TABMAP_HEADER_BLOCK)
        {
            CPLError(CE_Failure, CPLE_AssertionFailed, 
                     "Failed reading header block.");
            return;
        }
        poHeader = (TABMAPHeaderBlock *)poBlock;

        Rewind();
        while((poObjHdr = TABMAPObjHdr::ReadNextObj(this, poHeader)) != NULL)
        {
            fprintf(fpOut, 
                    "   object id=%d, type=%d, offset=%d (%d), size=%d\n"
                    "          MBR=(%d, %d, %d, %d)\n",
                    m_nCurObjectId, m_nCurObjectType, m_nCurObjectOffset,
                    m_nFileOffset + m_nCurObjectOffset,
                    poHeader->GetMapObjectSize( m_nCurObjectType ),
                    poObjHdr->m_nMinX, poObjHdr->m_nMinY,
                    poObjHdr->m_nMaxX,poObjHdr->m_nMaxY);
            delete poObjHdr;
        }

        delete poHeader;
    }

    fflush(fpOut);
}

#endif // DEBUG



/*=====================================================================
 *                      class TABMAPObjHdr and family
 *====================================================================*/

/**********************************************************************
 *                   class TABMAPObjHdr
 *
 * Virtual base class... contains static methods used to allocate instance
 * of the derived classes.
 *
 **********************************************************************/


/**********************************************************************
 *                    TABMAPObjHdr::NewObj()
 *
 * Alloc a new object of specified type or NULL for NONE types or if type 
 * is not supported.
 **********************************************************************/
TABMAPObjHdr *TABMAPObjHdr::NewObj(GByte nNewObjType, GInt32 nId /*=0*/)
{
    TABMAPObjHdr *poObj = NULL;

    switch(nNewObjType)
    {
      case TAB_GEOM_NONE:
        poObj = new TABMAPObjNone;
        break;
      case TAB_GEOM_SYMBOL_C:
      case TAB_GEOM_SYMBOL:
        poObj = new TABMAPObjPoint;
        break;
      case TAB_GEOM_FONTSYMBOL_C:
      case TAB_GEOM_FONTSYMBOL:
        poObj = new TABMAPObjFontPoint;
        break;
      case TAB_GEOM_CUSTOMSYMBOL_C:
      case TAB_GEOM_CUSTOMSYMBOL:
        poObj = new TABMAPObjCustomPoint;
        break;
      case TAB_GEOM_LINE_C:
      case TAB_GEOM_LINE:
        poObj = new TABMAPObjLine;
        break;
      case TAB_GEOM_PLINE_C:
      case TAB_GEOM_PLINE:
      case TAB_GEOM_REGION_C:
      case TAB_GEOM_REGION:
      case TAB_GEOM_MULTIPLINE_C:
      case TAB_GEOM_MULTIPLINE:
      case TAB_GEOM_V450_REGION_C:
      case TAB_GEOM_V450_REGION:
      case TAB_GEOM_V450_MULTIPLINE_C:
      case TAB_GEOM_V450_MULTIPLINE:
      case TAB_GEOM_V800_REGION_C:
      case TAB_GEOM_V800_REGION:
      case TAB_GEOM_V800_MULTIPLINE_C:
      case TAB_GEOM_V800_MULTIPLINE:
        poObj = new TABMAPObjPLine;
        break;
      case TAB_GEOM_ARC_C:
      case TAB_GEOM_ARC:
        poObj = new TABMAPObjArc;
        break;
      case TAB_GEOM_RECT_C:
      case TAB_GEOM_RECT:
      case TAB_GEOM_ROUNDRECT_C:
      case TAB_GEOM_ROUNDRECT:

⌨️ 快捷键说明

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