tabmapcoordblock.cpp
来自「linux下一款GIS程序源码」· C++ 代码 · 共 757 行 · 第 1/2 页
CPP
757 行
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 (UGKGetLastErrorType() != 0) return -1; numVerticesTotal += pasHdrs[i].numVertices; //这里nVertexOffset表示此section的第一个顶点在[0..numVerticesTotal] //中的偏移位置 --见上面说明 pasHdrs[i].nVertexOffset = (pasHdrs[i].nDataOffset - nTotalHdrSizeUncompressed ) / 8; } 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) { UGKError(ET_Failure, UGKErr_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 * UGKError() will have been called. **********************************************************************/int TABMAPCoordBlock::WriteCoordSecHdrs(UGKBool bV450Hdr, int numSections, TABMAPCoordSecHdr *pasHdrs, UGKBool bCompressed /*=FALSE*/){ int i; UGKErrorReset(); 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 (UGKGetLastErrorType() == ET_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 * UGKError() will have been called. **********************************************************************/int TABMAPCoordBlock::WriteIntCoord(UGKInt32 nX, UGKInt32 nY, UGKBool 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 * UGKError() will have been called. **********************************************************************/int TABMAPCoordBlock::ReadBytes(int numBytes, UGKByte *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 * UGKError() will have been called. **********************************************************************/int TABMAPCoordBlock::WriteBytes(int nBytesToWrite, UGKByte *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(UGKInt32 &nXMin, UGKInt32 &nYMin, UGKInt32 &nXMax, UGKInt32 &nYMax){ nXMin = m_nFeatureXMin; nYMin = m_nFeatureYMin; nXMax = m_nFeatureXMax; nYMax = m_nFeatureYMax; }/********************************************************************** * TABMAPCoordBlock::Dump() * * Dump block contents... available only in DEBUG mode. **********************************************************************/void 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);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?