📄 mitab_feature_mif.cpp
字号:
m_bRoundCorners = FALSE;
m_dRoundXRadius = 0.0;
m_dRoundYRadius = 0.0;
if (EQUALN(papszToken[0],"ROUNDRECT",9))
{
m_bRoundCorners = TRUE;
if (CSLCount(papszToken) == 6)
m_dRoundXRadius = m_dRoundYRadius = atof(papszToken[5])/2.0;
else
{
CSLDestroy(papszToken);
papszToken = CSLTokenizeString2(fp->GetLine(),
" \t", CSLT_HONOURSTRINGS);
if (CSLCount(papszToken) !=1 )
m_dRoundXRadius = m_dRoundYRadius = atof(papszToken[1])/2.0;
}
}
CSLDestroy(papszToken);
papszToken = NULL;
/*-----------------------------------------------------------------
* Create and fill geometry object
*----------------------------------------------------------------*/
poPolygon = new OGRPolygon;
poRing = new OGRLinearRing();
if (m_bRoundCorners && m_dRoundXRadius != 0.0 && m_dRoundYRadius != 0.0)
{
/*-------------------------------------------------------------
* For rounded rectangles, we generate arcs with 45 line
* segments for each corner. We start with lower-left corner
* and proceed counterclockwise
* We also have to make sure that rounding radius is not too
* large for the MBR however, we
* always return the true X/Y radius (not adjusted) since this
* is the way MapInfo seems to do it when a radius bigger than
* the MBR is passed from TBA to MIF.
*------------------------------------------------------------*/
double dXRadius = MIN(m_dRoundXRadius, (dXMax-dXMin)/2.0);
double dYRadius = MIN(m_dRoundYRadius, (dYMax-dYMin)/2.0);
TABGenerateArc(poRing, 45,
dXMin + dXRadius, dYMin + dYRadius, dXRadius, dYRadius,
PI, 3.0*PI/2.0);
TABGenerateArc(poRing, 45,
dXMax - dXRadius, dYMin + dYRadius, dXRadius, dYRadius,
3.0*PI/2.0, 2.0*PI);
TABGenerateArc(poRing, 45,
dXMax - dXRadius, dYMax - dYRadius, dXRadius, dYRadius,
0.0, PI/2.0);
TABGenerateArc(poRing, 45,
dXMin + dXRadius, dYMax - dYRadius, dXRadius, dYRadius,
PI/2.0, PI);
TABCloseRing(poRing);
}
else
{
poRing->addPoint(dXMin, dYMin);
poRing->addPoint(dXMax, dYMin);
poRing->addPoint(dXMax, dYMax);
poRing->addPoint(dXMin, dYMax);
poRing->addPoint(dXMin, dYMin);
}
poPolygon->addRingDirectly(poRing);
SetGeometryDirectly(poPolygon);
while (((pszLine = fp->GetLine()) != NULL) &&
fp->IsValidFeature(pszLine) == FALSE)
{
papszToken = CSLTokenizeStringComplex(pszLine,"() ,",
TRUE,FALSE);
if (CSLCount(papszToken) > 1)
{
if (EQUALN(papszToken[0],"PEN",3))
{
if (CSLCount(papszToken) == 4)
{
SetPenWidthMIF(atoi(papszToken[1]));
SetPenPattern(atoi(papszToken[2]));
SetPenColor(atoi(papszToken[3]));
}
}
else if (EQUALN(papszToken[0],"BRUSH", 5))
{
if (CSLCount(papszToken) >=3)
{
SetBrushFGColor(atoi(papszToken[2]));
SetBrushPattern(atoi(papszToken[1]));
if (CSLCount(papszToken) == 4)
SetBrushBGColor(atoi(papszToken[3]));
else
SetBrushTransparent(TRUE);
}
}
}
CSLDestroy(papszToken);
papszToken = NULL;
}
return 0;
}
/**********************************************************************
*
**********************************************************************/
int TABRectangle::WriteGeometryToMIFFile(MIDDATAFile *fp)
{
OGRGeometry *poGeom;
OGRPolygon *poPolygon;
OGREnvelope sEnvelope;
/*-----------------------------------------------------------------
* Fetch and validate geometry
*----------------------------------------------------------------*/
poGeom = GetGeometryRef();
if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPolygon)
poPolygon = (OGRPolygon*)poGeom;
else
{
CPLError(CE_Failure, CPLE_AssertionFailed,
"TABRectangle: Missing or Invalid Geometry!");
return -1;
}
/*-----------------------------------------------------------------
* Note that we will simply use the rectangle's MBR and don't really
* read the polygon geometry... this should be OK unless the
* polygon geometry was not really a rectangle.
*----------------------------------------------------------------*/
poPolygon->getEnvelope(&sEnvelope);
if (m_bRoundCorners == TRUE)
{
fp->WriteLine("Roundrect %.15g %.15g %.15g %.15g %.15g\n",
sEnvelope.MinX, sEnvelope.MinY,
sEnvelope.MaxX, sEnvelope.MaxY, m_dRoundXRadius*2.0);
}
else
{
fp->WriteLine("Rect %.15g %.15g %.15g %.15g\n",
sEnvelope.MinX, sEnvelope.MinY,
sEnvelope.MaxX, sEnvelope.MaxY);
}
if (GetPenPattern())
fp->WriteLine(" Pen (%d,%d,%d)\n",GetPenWidthMIF(),GetPenPattern(),
GetPenColor());
if (GetBrushPattern())
{
if (GetBrushTransparent() == 0)
fp->WriteLine(" Brush (%d,%d,%d)\n",GetBrushPattern(),
GetBrushFGColor(),GetBrushBGColor());
else
fp->WriteLine(" Brush (%d,%d)\n",GetBrushPattern(),
GetBrushFGColor());
}
return 0;
}
/**********************************************************************
*
**********************************************************************/
int TABEllipse::ReadGeometryFromMIFFile(MIDDATAFile *fp)
{
const char *pszLine;
char **papszToken;
double dXMin, dYMin, dXMax, dYMax;
OGRPolygon *poPolygon;
OGRLinearRing *poRing;
papszToken = CSLTokenizeString2(fp->GetLastLine(),
" \t", CSLT_HONOURSTRINGS);
if (CSLCount(papszToken) != 5)
{
CSLDestroy(papszToken);
return -1;
}
dXMin = fp->GetXTrans(atof(papszToken[1]));
dXMax = fp->GetXTrans(atof(papszToken[3]));
dYMin = fp->GetYTrans(atof(papszToken[2]));
dYMax = fp->GetYTrans(atof(papszToken[4]));
CSLDestroy(papszToken);
papszToken = NULL;
/*-----------------------------------------------------------------
* Save info about the ellipse def. inside class members
*----------------------------------------------------------------*/
m_dCenterX = (dXMin + dXMax) / 2.0;
m_dCenterY = (dYMin + dYMax) / 2.0;
m_dXRadius = ABS( (dXMax - dXMin) / 2.0 );
m_dYRadius = ABS( (dYMax - dYMin) / 2.0 );
SetMBR(dXMin, dYMin, dXMax, dYMax);
/*-----------------------------------------------------------------
* Create and fill geometry object
*----------------------------------------------------------------*/
poPolygon = new OGRPolygon;
poRing = new OGRLinearRing();
/*-----------------------------------------------------------------
* For the OGR geometry, we generate an ellipse with 2 degrees line
* segments.
*----------------------------------------------------------------*/
TABGenerateArc(poRing, 180,
m_dCenterX, m_dCenterY,
m_dXRadius, m_dYRadius,
0.0, 2.0*PI);
TABCloseRing(poRing);
poPolygon->addRingDirectly(poRing);
SetGeometryDirectly(poPolygon);
while (((pszLine = fp->GetLine()) != NULL) &&
fp->IsValidFeature(pszLine) == FALSE)
{
papszToken = CSLTokenizeStringComplex(pszLine,"() ,",
TRUE,FALSE);
if (CSLCount(papszToken) > 1)
{
if (EQUALN(papszToken[0],"PEN",3))
{
if (CSLCount(papszToken) == 4)
{
SetPenWidthMIF(atoi(papszToken[1]));
SetPenPattern(atoi(papszToken[2]));
SetPenColor(atoi(papszToken[3]));
}
}
else if (EQUALN(papszToken[0],"BRUSH", 5))
{
if (CSLCount(papszToken) >= 3)
{
SetBrushFGColor(atoi(papszToken[2]));
SetBrushPattern(atoi(papszToken[1]));
if (CSLCount(papszToken) == 4)
SetBrushBGColor(atoi(papszToken[3]));
else
SetBrushTransparent(TRUE);
}
}
}
CSLDestroy(papszToken);
papszToken = NULL;
}
return 0;
}
/**********************************************************************
*
**********************************************************************/
int TABEllipse::WriteGeometryToMIFFile(MIDDATAFile *fp)
{
OGRGeometry *poGeom;
OGREnvelope sEnvelope;
poGeom = GetGeometryRef();
if ( (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPolygon ) ||
(poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint ) )
poGeom->getEnvelope(&sEnvelope);
else
{
CPLError(CE_Failure, CPLE_AssertionFailed,
"TABEllipse: Missing or Invalid Geometry!");
return -1;
}
fp->WriteLine("Ellipse %.15g %.15g %.15g %.15g\n",sEnvelope.MinX, sEnvelope.MinY,
sEnvelope.MaxX,sEnvelope.MaxY);
if (GetPenPattern())
fp->WriteLine(" Pen (%d,%d,%d)\n",GetPenWidthMIF(),GetPenPattern(),
GetPenColor());
if (GetBrushPattern())
{
if (GetBrushTransparent() == 0)
fp->WriteLine(" Brush (%d,%d,%d)\n",GetBrushPattern(),
GetBrushFGColor(),GetBrushBGColor());
else
fp->WriteLine(" Brush (%d,%d)\n",GetBrushPattern(),
GetBrushFGColor());
}
return 0;
}
/**********************************************************************
*
**********************************************************************/
int TABArc::ReadGeometryFromMIFFile(MIDDATAFile *fp)
{
const char *pszLine;
OGRLineString *poLine;
char **papszToken;
double dXMin,dXMax, dYMin,dYMax;
int numPts;
papszToken = CSLTokenizeString2(fp->GetLastLine(),
" \t", CSLT_HONOURSTRINGS);
if (CSLCount(papszToken) == 5)
{
dXMin = fp->GetXTrans(atof(papszToken[1]));
dXMax = fp->GetXTrans(atof(papszToken[3]));
dYMin = fp->GetYTrans(atof(papszToken[2]));
dYMax = fp->GetYTrans(atof(papszToken[4]));
CSLDestroy(papszToken);
papszToken = CSLTokenizeString2(fp->GetLine(),
" \t", CSLT_HONOURSTRINGS);
if (CSLCount(papszToken) != 2)
{
CSLDestroy(papszToken);
return -1;
}
m_dStartAngle = atof(papszToken[0]);
m_dEndAngle = atof(papszToken[1]);
}
else if (CSLCount(papszToken) == 7)
{
dXMin = fp->GetXTrans(atof(papszToken[1]));
dXMax = fp->GetXTrans(atof(papszToken[3]));
dYMin = fp->GetYTrans(atof(papszToken[2]));
dYMax = fp->GetYTrans(atof(papszToken[4]));
m_dStartAngle = atof(papszToken[5]);
m_dEndAngle = atof(papszToken[6]);
}
else
{
CSLDestroy(papszToken);
return -1;
}
CSLDestroy(papszToken);
papszToken = NULL;
/*-------------------------------------------------------------
* Start/End angles
* Since the angles are specified for integer coordinates, and
* that these coordinates can have the X axis reversed, we have to
* adjust the angle values for the change in the X axis
* direction.
*
* This should be necessary only when X axis is flipped.
* __TODO__ Why is order of start/end values reversed as well???
*------------------------------------------------------------*/
if (fp->GetXMultiplier() <= 0.0)
{
m_dStartAngle = 360.0 - m_dStartAngle;
m_dEndAngle = 360.0 - m_dEndAngle;
}
m_dCenterX = (dXMin + dXMax) / 2.0;
m_dCenterY = (dYMin + dYMax) / 2.0;
m_dXRadius = ABS( (dXMax - dXMin) / 2.0 );
m_dYRadius = ABS( (dYMax - dYMin) / 2.0 );
/*-----------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -