📄 mitab_mapcoordblock.cpp
字号:
* that follows the current one.
**********************************************************************/
void TABMAPCoordBlock::SetNextCoordBlock(GInt32 nNextCoordBlockAddress)
{
m_nNextCoordBlock = nNextCoordBlockAddress;
}
/**********************************************************************
* TABMAPObjectBlock::SetComprCoordOrigin()
*
* Set the Compressed integer coordinates space origin to be used when
* reading compressed coordinates using ReadIntCoord().
**********************************************************************/
void TABMAPCoordBlock::SetComprCoordOrigin(GInt32 nX, GInt32 nY)
{
m_nComprOrgX = nX;
m_nComprOrgY = nY;
}
/**********************************************************************
* TABMAPObjectBlock::ReadIntCoord()
*
* Read the next pair of integer coordinates value from the block, and
* apply the translation relative to the origin of the coord. space
* previously set using SetComprCoordOrigin() 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 TABMAPCoordBlock::ReadIntCoord(GBool bCompressed,
GInt32 &nX, GInt32 &nY)
{
if (bCompressed)
{
nX = m_nComprOrgX + ReadInt16();
nY = m_nComprOrgY + ReadInt16();
}
else
{
nX = ReadInt32();
nY = ReadInt32();
}
if (CPLGetLastErrorType() == CE_Failure)
return -1;
return 0;
}
/**********************************************************************
* TABMAPObjectBlock::ReadIntCoords()
*
* Read the specified number of pairs of X,Y integer coordinates values
* from the block, and apply the translation relative to the origin of
* the coord. space previously set using SetComprCoordOrigin() if
* bCompressed=TRUE.
*
* This means that the returned coordinates are always absolute integer
* coordinates, even when the source coords are in compressed form.
*
* panXY should point to an array big enough to receive the specified
* number of coordinates.
*
* Returns 0 if succesful or -1 if an error happened, in which case
* CPLError() will have been called.
**********************************************************************/
int TABMAPCoordBlock::ReadIntCoords(GBool bCompressed, int numCoordPairs,
GInt32 *panXY)
{
int i, numValues = numCoordPairs*2;
if (bCompressed)
{
for(i=0; i<numValues; i+=2)
{
panXY[i] = m_nComprOrgX + ReadInt16();
panXY[i+1] = m_nComprOrgY + ReadInt16();
if (CPLGetLastErrorType() != 0)
return -1;
}
}
else
{
for(i=0; i<numValues; i+=2)
{
panXY[i] = ReadInt32();
panXY[i+1] = ReadInt32();
if (CPLGetLastErrorType() != 0)
return -1;
}
}
return 0;
}
/**********************************************************************
* TABMAPObjectBlock::ReadCoordSecHdrs()
*
* Read a set of coordinate section headers for PLINE MULTIPLE or REGIONs
* and store the result in the array of structures pasHdrs[]. It is assumed
* that pasHdrs points to an allocated array of at least numSections
* TABMAPCoordSecHdr structures.
*
* The function will also set the values of numVerticesTotal to the
* total number of coordinates in the object (the sum of all sections
* headers read).
*
* At the end of the call, this TABMAPCoordBlock object will be located
* at the beginning of the coordinate data.
*
* In V450 the numVertices is stored on an int32 instead of an int16
*
* In V800 the numHoles is stored on an int32 instead of an int16
*
* IMPORTANT: This function makes the assumption that coordinates for all
* the sections are grouped together immediately after the
* last section header block (i.e. that the coord. data is not
* located all over the place). If it is not the case then
* an error will be produced and the code to read region and
* multipline objects will have to be updated.
*
* Returns 0 if succesful or -1 if an error happened, in which case
* CPLError() will have been called.
**********************************************************************/
int TABMAPCoordBlock::ReadCoordSecHdrs(GBool bCompressed,
int nVersion,
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.
* V800 header section uses int32 for numHoles but there is no need
* for the 2 alignment bytes so the size is the same as V450
*------------------------------------------------------------*/
if (nVersion >= 450)
nTotalHdrSizeUncompressed = 28 * numSections;
else
nTotalHdrSizeUncompressed = 24 * numSections;
numVerticesTotal = 0;
for(i=0; i<numSections; i++)
{
/*-------------------------------------------------------------
* Read the coord. section header blocks
*------------------------------------------------------------*/
#ifdef TABDUMP
int nHdrAddress = GetCurAddress();
#endif
if (nVersion >= 450)
pasHdrs[i].numVertices = ReadInt32();
else
pasHdrs[i].numVertices = ReadInt16();
if (nVersion >= 800)
pasHdrs[i].numHoles = ReadInt32();
else
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("READING pasHdrs[%d] @ %d = \n"
" { numVertices = %d, numHoles = %d, \n"
" nXMin=%d, nYMin=%d, nXMax=%d, nYMax=%d,\n"
" nDataOffset=%d, nVertexOffset=%d }\n",
i, nHdrAddress, 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
*
* In V800 the numHoles 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(int nVersion,
int numSections,
TABMAPCoordSecHdr *pasHdrs,
GBool bCompressed /*=FALSE*/)
{
int i;
CPLErrorReset();
for(i=0; i<numSections; i++)
{
/*-------------------------------------------------------------
* Write the coord. section header blocks
*------------------------------------------------------------*/
#ifdef TABDUMP
printf("WRITING pasHdrs[%d] @ %d = \n"
" { numVertices = %d, numHoles = %d, \n"
" nXMin=%d, nYMin=%d, nXMax=%d, nYMax=%d,\n"
" nDataOffset=%d, nVertexOffset=%d }\n",
i, GetCurAddress(), 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
if (nVersion >= 450)
WriteInt32(pasHdrs[i].numVertices);
else
WriteInt16(pasHdrs[i].numVertices);
if (nVersion >= 800)
WriteInt32(pasHdrs[i].numHoles);
else
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*/)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -