📄 mitab_mapobjectblock.cpp
字号:
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::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::AddObject() * * Add an object to be eventually writtent to this object. The poObjHdr * becomes owned by the TABMAPObjectBlock object and will be destroyed * once we're done with it. * * In write mode, an array of TABMAPObjHdr objects is maintained in memory * until the object is full, at which time the block center is recomputed * and all objects are written to the block. **********************************************************************/int TABMAPObjectBlock::AddObject(TABMAPObjHdr *poObjHdr){ // We do not store NONE objects if (poObjHdr->m_nType == TAB_GEOM_NONE) { delete poObjHdr; return 0; } if (m_papoObjHdr == NULL || m_numObjects%10 == 0) { // Realloc the array... by steps of 10 m_papoObjHdr = (TABMAPObjHdr**)CPLRealloc(m_papoObjHdr, (m_numObjects+10)* sizeof(TABMAPObjHdr*)); } m_papoObjHdr[m_numObjects++] = poObjHdr; // Maintain MBR of this object block. UpdateMBR(poObjHdr->m_nMinX, poObjHdr->m_nMinY); UpdateMBR(poObjHdr->m_nMaxX, poObjHdr->m_nMaxY); return 0;}/********************************************************************** * TABMAPObjectBlock::Dump() * * Dump block contents... available only in DEBUG mode. **********************************************************************/#ifdef DEBUGvoid TABMAPObjectBlock::Dump(FILE *fpOut, GBool bDetails){ 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; 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; while(AdvanceToNextObject(poHeader) != -1) { fprintf(fpOut, " object id=%d, type=%d, offset=%d (%d), size=%d \n", m_nCurObjectId, m_nCurObjectType, m_nCurObjectOffset, m_nFileOffset + m_nCurObjectOffset, poHeader->GetMapObjectSize( m_nCurObjectType ) ); } 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. * * __TODO__ * - Why are most of the ReadObj() methods not implemented??? * -> Because it's faster to not parse the whole object block all the time * but instead parse one object at a time in read mode... so there is * no real use for this class in read mode UNTIL we support random * update. * At this point, only TABRegion and TABPolyline make use of the * ReadObj() methods. **********************************************************************//********************************************************************** * 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: 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: case TAB_GEOM_ELLIPSE_C: case TAB_GEOM_ELLIPSE: poObj = new TABMAPObjRectEllipse; break; case TAB_GEOM_TEXT_C: case TAB_GEOM_TEXT: poObj = new TABMAPObjText; break; case TAB_GEOM_MULTIPOINT_C: case TAB_GEOM_MULTIPOINT: poObj = new TABMAPObjMultiPoint; break; case TAB_GEOM_COLLECTION_C: case TAB_GEOM_COLLECTION: poObj = new TABMAPObjCollection(); break; default: CPLError(CE_Failure, CPLE_AssertionFailed, "TABMAPObjHdr::NewObj(): Unsupported object type %d", nNewObjType); } if (poObj) { poObj->m_nType = nNewObjType; poObj->m_nId = nId; poObj->m_nMinX = poObj->m_nMinY = poObj->m_nMaxX = poObj->m_nMaxY = 0; } return poObj;}/********************************************************************** * TABMAPObjHdr::ReadNextObj() * * Read next object in this block and allocate/init a new object for it * if succesful. * Returns NULL in case of error or if we reached end of block. **********************************************************************/TABMAPObjHdr *TABMAPObjHdr::ReadNextObj(TABMAPObjectBlock *poObjBlock, TABMAPHeaderBlock *poHeader){ TABMAPObjHdr *poObjHdr = NULL; if (poObjBlock->AdvanceToNextObject(poHeader) != -1) { poObjHdr=TABMAPObjHdr::NewObj(poObjBlock->GetCurObjectType()); if (poObjHdr && ((poObjHdr->m_nId = poObjBlock->GetCurObjectId()) == -1 || poObjHdr->ReadObj(poObjBlock) != 0 ) ) { // Failed reading object in block... an error was already produced delete poObjHdr; return NULL; } } return poObjHdr;}/********************************************************************** * TABMAPObjHdr::IsCompressedType() * * Returns TRUE if the current object type uses compressed coordinates * or FALSE otherwise. **********************************************************************/GBool TABMAPObjHdr::IsCompressedType(){ // Compressed types are 1, 4, 7, etc. return ((m_nType % 3) == 1 ? TRUE : FALSE);}/********************************************************************** * TABMAPObjHdr::WriteObjTypeAndId() * * Writetype+object id information... should be called only by the derived * classes' WriteObj() methods. * * Returns 0 on success, -1 on error. **********************************************************************/int TABMAPObjHdr::WriteObjTypeAndId(TABMAPObjectBlock *poObjBlock){ poObjBlock->WriteByte(m_nType); return poObjBlock->WriteInt32(m_nId);}/********************************************************************** * TABMAPObjHdr::SetMBR() * **********************************************************************/void TABMAPObjHdr::SetMBR(GInt32 nMinX, GInt32 nMinY, GInt32 nMaxX, GInt32 nMaxY){ m_nMinX = MIN(nMinX, nMaxX); m_nMinY = MIN(nMinY, nMaxY); m_nMaxX = MAX(nMinX, nMaxX); m_nMaxY = MAX(nMinY, nMaxY);}/********************************************************************** * class TABMAPObjLine * * Applies to 2-points LINEs only **********************************************************************//********************************************************************** * TABMAPObjLine::ReadObj() * * Read Object information starting after the object id which should * have been read by TABMAPObjHdr::ReadNextObj() already. * This function should be called only by TABMAPObjHdr::ReadNextObj(). * * Returns 0 on success, -1 on error. **********************************************************************/int TABMAPObjLine::ReadObj(TABMAPObjectBlock *poObjBlock){ poObjBlock->ReadIntCoord(IsCompressedType(), m_nX1, m_nY1); poObjBlock->ReadIntCoord(IsCompressedType(), m_nX2, m_nY2); m_nPenId = poObjBlock->ReadByte(); // Pen index SetMBR(m_nX1, m_nY1, m_nX2, m_nY2); if (CPLGetLastErrorNo() != 0) return -1; return 0;}/********************************************************************** * TABMAPObjLine::WriteObj() * * Write Object information with the type+object id * * Returns 0 on success, -1 on error. **********************************************************************/int TABMAPObjLine::WriteObj(TABMAPObjectBlock *poObjBlock){ // Write object type and id TABMAPObjHdr::WriteObjTypeAndId(poObjBlock); poObjBlock->WriteIntCoord(m_nX1, m_nY1, IsCompressedType()); poObjBlock->WriteIntCoord(m_nX2, m_nY2, IsCompressedType()); poObjBlock->WriteByte(m_nPenId); // Pen index if (CPLGetLastErrorNo() != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -