📄 mitab_mapheaderblock.cpp
字号:
*/
if (m_nMAPVersionNumber <= 100)
{
m_XScale = m_YScale = pow(10.0, m_nCoordPrecision);
m_XDispl = m_YDispl = 0.0;
}
for(i=0; i<6; i++)
m_sProj.adProjParams[i] = ReadDouble();
m_sProj.dDatumShiftX = ReadDouble();
m_sProj.dDatumShiftY = ReadDouble();
m_sProj.dDatumShiftZ = ReadDouble();
for(i=0; i<5; i++)
{
/* In V.200 files, the next 5 datum params are unused and they
* sometimes contain junk bytes... in this case we set adDatumParams[]
* to 0 for the rest of the lib to be happy.
*/
m_sProj.adDatumParams[i] = ReadDouble();
if (m_nMAPVersionNumber <= 200)
m_sProj.adDatumParams[i] = 0.0;
}
m_sProj.nAffineFlag = 0;
if (m_nMAPVersionNumber >= 500 && m_nSizeUsed > 512)
{
// Read Affine parameters A,B,C,D,E,F
// only if version 500+ and block is larger than 512 bytes
int nInUse = ReadByte();
if (nInUse)
{
m_sProj.nAffineFlag = 1;
m_sProj.nAffineUnits = ReadByte();
GotoByteInBlock(0x0208); // Skip unused bytes
m_sProj.dAffineParamA = ReadDouble();
m_sProj.dAffineParamB = ReadDouble();
m_sProj.dAffineParamC = ReadDouble();
m_sProj.dAffineParamD = ReadDouble();
m_sProj.dAffineParamE = ReadDouble();
m_sProj.dAffineParamF = ReadDouble();
}
}
return 0;
}
/**********************************************************************
* TABMAPHeaderBlock::Int2Coordsys()
*
* Convert from long integer (internal) to coordinates system units
* as defined in the file's coordsys clause.
*
* Note that the false easting/northing and the conversion factor from
* datum to coordsys units are not included in the calculation.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPHeaderBlock::Int2Coordsys(GInt32 nX, GInt32 nY,
double &dX, double &dY)
{
if (m_pabyBuf == NULL)
return -1;
// For some obscure reason, some guy decided that it would be
// more fun to be able to define our own origin quadrant!
//
// In version 100 .tab files (version 400 .map), it is possible to have
// a quadrant 0 and it should be treated the same way as quadrant 3
if (m_nCoordOriginQuadrant==2 || m_nCoordOriginQuadrant==3 ||
m_nCoordOriginQuadrant==0 )
dX = -1.0 * (nX + m_XDispl) / m_XScale;
else
dX = (nX - m_XDispl) / m_XScale;
if (m_nCoordOriginQuadrant==3 || m_nCoordOriginQuadrant==4||
m_nCoordOriginQuadrant==0)
dY = -1.0 * (nY + m_YDispl) / m_YScale;
else
dY = (nY - m_YDispl) / m_YScale;
//printf("Int2Coordsys: (%d, %d) -> (%.10g, %.10g)\n", nX, nY, dX, dY);
return 0;
}
/**********************************************************************
* TABMAPHeaderBlock::Coordsys2Int()
*
* Convert from coordinates system units as defined in the file's
* coordsys clause to long integer (internal) coordinates.
*
* Note that the false easting/northing and the conversion factor from
* datum to coordsys units are not included in the calculation.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPHeaderBlock::Coordsys2Int(double dX, double dY,
GInt32 &nX, GInt32 &nY,
GBool bIgnoreOverflow /*=FALSE*/)
{
if (m_pabyBuf == NULL)
return -1;
// For some obscure reason, some guy decided that it would be
// more fun to be able to define our own origin quadrant!
//
// In version 100 .tab files (version 400 .map), it is possible to have
// a quadrant 0 and it should be treated the same way as quadrant 3
/*-----------------------------------------------------------------
* NOTE: double values must be used here, the limit of integer value
* have been reached some times due to the very big numbers used here.
*----------------------------------------------------------------*/
double dTempX, dTempY;
if (m_nCoordOriginQuadrant==2 || m_nCoordOriginQuadrant==3 ||
m_nCoordOriginQuadrant==0 )
dTempX = (double)(-1.0*dX*m_XScale - m_XDispl);
else
dTempX = (double)(dX*m_XScale + m_XDispl);
if (m_nCoordOriginQuadrant==3 || m_nCoordOriginQuadrant==4 ||
m_nCoordOriginQuadrant==0 )
dTempY = (double)(-1.0*dY*m_YScale - m_YDispl);
else
dTempY = (double)(dY*m_YScale + m_YDispl);
/*-----------------------------------------------------------------
* Make sure we'll never output coordinates outside of the valid
* integer coordinates range: (-1e9, -1e9) - (1e9, 1e9)
* Integer coordinates outside of that range will confuse MapInfo.
*----------------------------------------------------------------*/
GBool bIntBoundsOverflow = FALSE;
if (dTempX < -1000000000)
{
dTempX = -1000000000;
bIntBoundsOverflow = TRUE;
}
if (dTempX > 1000000000)
{
dTempX = 1000000000;
bIntBoundsOverflow = TRUE;
}
if (dTempY < -1000000000)
{
dTempY = -1000000000;
bIntBoundsOverflow = TRUE;
}
if (dTempY > 1000000000)
{
dTempY = 1000000000;
bIntBoundsOverflow = TRUE;
}
nX = (GInt32) ROUND_INT(dTempX);
nY = (GInt32) ROUND_INT(dTempY);
if (bIntBoundsOverflow && !bIgnoreOverflow)
{
m_bIntBoundsOverflow = TRUE;
#ifdef DEBUG
CPLError(CE_Warning, TAB_WarningBoundsOverflow,
"Integer bounds overflow: (%f, %f) -> (%d, %d)\n",
dX, dY, nX, nY);
#endif
}
return 0;
}
/**********************************************************************
* TABMAPHeaderBlock::ComprInt2Coordsys()
*
* Convert from compressed integer (internal) to coordinates system units
* as defined in the file's coordsys clause.
* The difference between long integer and compressed integer coords is
* that compressed coordinates are scaled displacement relative to an
* object centroid.
*
* Note that the false easting/northing and the conversion factor from
* datum to coordsys units are not included in the calculation.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPHeaderBlock::ComprInt2Coordsys(GInt32 nCenterX, GInt32 nCenterY,
int nDeltaX, int nDeltaY,
double &dX, double &dY)
{
if (m_pabyBuf == NULL)
return -1;
return Int2Coordsys(nCenterX+nDeltaX, nCenterY+nDeltaY, dX, dY);
}
/**********************************************************************
* TABMAPHeaderBlock::Int2CoordsysDist()
*
* Convert a pair of X and Y size (or distance) value from long integer
* (internal) to coordinates system units as defined in the file's
* coordsys clause.
*
* The difference with Int2Coordsys() is that this function only applies
* the scaling factor: it does not apply the displacement.
*
* Since the calculations on the X and Y values are independent, either
* one can be omitted (i.e. passed as 0)
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPHeaderBlock::Int2CoordsysDist(GInt32 nX, GInt32 nY,
double &dX, double &dY)
{
if (m_pabyBuf == NULL)
return -1;
dX = nX / m_XScale;
dY = nY / m_YScale;
return 0;
}
/**********************************************************************
* TABMAPHeaderBlock::Coordsys2IntDist()
*
* Convert a pair of X and Y size (or distance) values from coordinates
* system units as defined in the file's coordsys clause to long integer
* (internal) coordinates.
*
* The difference with Coordsys2Int() is that this function only applies
* the scaling factor: it does not apply the displacement.
*
* Since the calculations on the X and Y values are independent, either
* one can be omitted (i.e. passed as 0)
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPHeaderBlock::Coordsys2IntDist(double dX, double dY,
GInt32 &nX, GInt32 &nY)
{
if (m_pabyBuf == NULL)
return -1;
nX = (GInt32)(dX*m_XScale);
nY = (GInt32)(dY*m_YScale);
return 0;
}
/**********************************************************************
* TABMAPHeaderBlock::SetCoordsysBounds()
*
* Take projection coordinates bounds of the newly created dataset and
* compute new values for the X/Y Scales and X/Y displacement.
*
* This function must be called after creating a new dataset and before any
* of the coordinates conversion functions can be used.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPHeaderBlock::SetCoordsysBounds(double dXMin, double dYMin,
double dXMax, double dYMax)
{
//printf("SetCoordsysBounds(%10g, %10g, %10g, %10g)\n", dXMin, dYMin, dXMax, dYMax);
/*-----------------------------------------------------------------
* Check for 0-width or 0-height bounds
*----------------------------------------------------------------*/
if (dXMax == dXMin)
{
dXMin -= 1.0;
dXMax += 1.0;
}
if (dYMax == dYMin)
{
dYMin -= 1.0;
dYMax += 1.0;
}
/*-----------------------------------------------------------------
* X and Y scales are used to map coordsys coordinates to integer
* internal coordinates. We want to find the scale and displacement
* values that will result in an integer coordinate range of
* (-1e9, -1e9) - (1e9, 1e9)
*
* Note that we ALWAYS generate datasets with the OriginQuadrant = 1
* so that we avoid reverted X/Y axis complications, etc.
*----------------------------------------------------------------*/
m_XScale = 2e9 / (dXMax - dXMin);
m_YScale = 2e9 / (dYMax - dYMin);
m_XDispl = -1.0 * m_XScale * (dXMax + dXMin) / 2;
m_YDispl = -1.0 * m_YScale * (dYMax + dYMin) / 2;
m_nXMin = -1000000000;
m_nYMin = -1000000000;
m_nXMax = 1000000000;
m_nYMax = 1000000000;
return 0;
}
/**********************************************************************
* TABMAPHeaderBlock::GetMapObjectSize()
*
* Return the size of the object body for the specified object type.
* The value is looked up in the first 256 bytes of the header.
**********************************************************************/
int TABMAPHeaderBlock::GetMapObjectSize(int nObjType)
{
if (m_pabyBuf == NULL)
{
CPLError(CE_Failure, CPLE_AssertionFailed,
"Block has not been initialized yet!");
return -1;
}
if (nObjType < 0 || nObjType > 255)
{
CPLError(CE_Failure, CPLE_IllegalArg,
"Invalid object type %d", nObjType);
return -1;
}
// Byte 0x80 is set for objects that have coordinates inside type 3 blocks
return (m_pabyBuf[nObjType] & 0x7f);
}
/**********************************************************************
* TABMAPHeaderBlock::MapObjectUsesCoordBlock()
*
* Return TRUE if the specified map object type has coordinates stored
* inside type 3 coordinate blocks.
* The info is looked up in the first 256 bytes of the header.
**********************************************************************/
GBool TABMAPHeaderBlock::MapObjectUsesCoordBlock(int nObjType)
{
if (m_pabyBuf == NULL)
{
CPLError(CE_Failure, CPLE_AssertionFailed,
"Block has not been initialized yet!");
return FALSE;
}
if (nObjType < 0 || nObjType > 255)
{
CPLError(CE_Failure, CPLE_IllegalArg,
"Invalid object type %d", nObjType);
return FALSE;
}
// Byte 0x80 is set for objects that have coordinates inside type 3 blocks
return ((m_pabyBuf[nObjType] & 0x80) != 0) ? TRUE: FALSE;
}
/**********************************************************************
* TABMAPHeaderBlock::GetProjInfo()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -