📄 tabarc.cpp
字号:
// tabarc.cpp: implementation of the TABArc class.////////////////////////////////////////////////////////////////////////#include "tabarc.h"#include "ugk_errhandle.h"#include "ugk_string.h"#include "ugklinestring.h"#include "tabmapobjarc.h"/********************************************************************** * TABArc::TABArc() * * Constructor. **********************************************************************/TABArc::TABArc( UGKFeatureDefn *poDefnIn ): TABFeature(poDefnIn){ m_dStartAngle = m_dEndAngle = 0.0; m_dCenterX = m_dCenterY = m_dXRadius = m_dYRadius = 0.0;}/********************************************************************** * TABArc::~TABArc() * * Destructor. **********************************************************************/TABArc::~TABArc(){}/********************************************************************** * TABArc::CloneTABFeature() * * Duplicate feature, including stuff specific to each TABFeature type. * * This method calls the generic TABFeature::CopyTABFeatureBase() and * then copies any members specific to its own type. **********************************************************************/TABFeature *TABArc::CloneTABFeature(UGKFeatureDefn *poNewDefn/*=NULL*/){ /*----------------------------------------------------------------- * Alloc new feature and copy the base stuff *----------------------------------------------------------------*/ TABArc *poNew = new TABArc(poNewDefn ? poNewDefn : GetDefnRef()); CopyTABFeatureBase(poNew); /*----------------------------------------------------------------- * And members specific to this class *----------------------------------------------------------------*/ // ITABFeaturePen *(poNew->GetPenDefRef()) = *GetPenDefRef(); poNew->SetStartAngle( GetStartAngle() ); poNew->SetEndAngle( GetEndAngle() ); poNew->m_dCenterX = m_dCenterX; poNew->m_dCenterY = m_dCenterY; poNew->m_dXRadius = m_dXRadius; poNew->m_dYRadius = m_dYRadius; return poNew;}/********************************************************************** * TABArc::ValidateMapInfoType() * * Check the feature's geometry part and return the corresponding * mapinfo object type code. The m_nMapInfoType member will also * be updated for further calls to GetMapInfoType(); * * Returns TAB_GEOM_NONE if the geometry is not compatible with what * is expected for this object class. **********************************************************************/int TABArc::ValidateMapInfoType(TABMAPFile *poMapFile /*=NULL*/){ UGKGeometry *poGeom; /*----------------------------------------------------------------- * Fetch and validate geometry *----------------------------------------------------------------*/ poGeom = GetGeometryRef(); if ( (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbLineString ) || (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint ) ) { m_nMapInfoType = TAB_GEOM_ARC; } else { UGKError(ET_Failure, UGKErr_AssertionFailed, "TABArc: Missing or Invalid Geometry!"); m_nMapInfoType = TAB_GEOM_NONE; } /*----------------------------------------------------------------- * Decide if coordinates should be compressed or not. *----------------------------------------------------------------*/ // __TODO__ For now we always write uncompressed for this class... // ValidateCoordType(poMapFile); return m_nMapInfoType;}/********************************************************************** * TABArc::ReadGeometryFromMAPFile() * * Fill the geometry and representation (color, etc...) part of the * feature from the contents of the .MAP object pointed to by poMAPFile. * * It is assumed that poMAPFile currently points to the beginning of * a map object. * * Returns 0 on success, -1 on error, in which case CPLError() will have * been called. **********************************************************************/int TABArc::ReadGeometryFromMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *poObjHdr){ UGKInt32 nX, nY; double dXMin, dYMin, dXMax, dYMax; UGKLineString *poLine; TABMAPObjectBlock *poObjBlock; UGKBool bComprCoord; int numPts; /*----------------------------------------------------------------- * Fetch and validate geometry type *----------------------------------------------------------------*/ m_nMapInfoType = poMapFile->GetCurObjType(); poObjBlock = poMapFile->GetCurObjBlock(); bComprCoord = (m_nMapInfoType == TAB_GEOM_ARC_C ); /*----------------------------------------------------------------- * Read object information *----------------------------------------------------------------*/ if (m_nMapInfoType == TAB_GEOM_ARC || m_nMapInfoType == TAB_GEOM_ARC_C ) { /*------------------------------------------------------------- * 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??? *------------------------------------------------------------*/ /*------------------------------------------------------------- * OK, Arc angles again!!!!!!!!!!!! * After some tests in 1999-11, it appeared that the angle values * ALWAYS had to be flipped (read order= end angle followed by * start angle), no matter which quadrant the file is in. * This does not make any sense, so I suspect that there is something * that we are missing here! * * 2000-01-14.... Again!!! Based on some sample data files: * File Ver Quadr ReflXAxis Read_Order Adjust_Angle * test_symb.tab 300 2 1 end,start X=yes Y=no * alltypes.tab: 300 1 0 start,end X=no Y=no * arcs.tab: 300 2 0 end,start X=yes Y=no * * Until we prove it wrong, the rule would be: * -> Quadrant 1 and 3, angles order = start, end * -> Quadrant 2 and 4, angles order = end, start * + Always adjust angles for x and y axis based on quadrant. * * This was confirmed using some more files in which the quadrant was * manually changed, but whether these are valid results is * discutable. * * The ReflectXAxis flag seems to have no effect here... *------------------------------------------------------------*/ /*------------------------------------------------------------- * In version 100 .tab files (version 400 .map), it is possible * to have a quadrant value of 0 and it should be treated the * same way as quadrant 3 *------------------------------------------------------------*/ if ( poMapFile->GetHeaderBlock()->m_nCoordOriginQuadrant==1 || poMapFile->GetHeaderBlock()->m_nCoordOriginQuadrant==3 || poMapFile->GetHeaderBlock()->m_nCoordOriginQuadrant==0 ) { // Quadrants 1 and 3 ... read order = start, end m_dStartAngle = poObjBlock->ReadInt16()/10.0; m_dEndAngle = poObjBlock->ReadInt16()/10.0; } else { // Quadrants 2 and 4 ... read order = end, start m_dEndAngle = poObjBlock->ReadInt16()/10.0; m_dStartAngle = poObjBlock->ReadInt16()/10.0; } if ( poMapFile->GetHeaderBlock()->m_nCoordOriginQuadrant==2 || poMapFile->GetHeaderBlock()->m_nCoordOriginQuadrant==3 || poMapFile->GetHeaderBlock()->m_nCoordOriginQuadrant==0 ) { // X axis direction is flipped... adjust angle m_dStartAngle = (m_dStartAngle<=180.0) ? (180.0-m_dStartAngle): (540.0-m_dStartAngle); m_dEndAngle = (m_dEndAngle<=180.0) ? (180.0-m_dEndAngle): (540.0-m_dEndAngle); } if (poMapFile->GetHeaderBlock()->m_nCoordOriginQuadrant==3 || poMapFile->GetHeaderBlock()->m_nCoordOriginQuadrant==4 || poMapFile->GetHeaderBlock()->m_nCoordOriginQuadrant==0 ) { // Y axis direction is flipped... this reverses angle direction // Unfortunately we never found any file that contains this case, // but this should be the behavior to expect!!! // // 2000-01-14: some files in which quadrant was set to 3 and 4 // manually seemed to confirm that this is the right thing to do. m_dStartAngle = 360.0 - m_dStartAngle; m_dEndAngle = 360.0 - m_dEndAngle; } // An arc is defined by its defining ellipse's MBR: poObjBlock->ReadIntCoord(bComprCoord, nX, nY); poMapFile->Int2Coordsys(nX, nY, dXMin, dYMin); poObjBlock->ReadIntCoord(bComprCoord, nX, nY); poMapFile->Int2Coordsys(nX, nY, dXMax, dYMax); 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 ); // Read the Arc's MBR and use that as this feature's MBR poObjBlock->ReadIntCoord(bComprCoord, nX, nY); poMapFile->Int2Coordsys(nX, nY, dXMin, dYMin); poObjBlock->ReadIntCoord(bComprCoord, nX, nY); poMapFile->Int2Coordsys(nX, nY, dXMax, dYMax); SetMBR(dXMin, dYMin, dXMax, dYMax); m_nPenDefIndex = poObjBlock->ReadByte(); // Pen index poMapFile->ReadPenDef(m_nPenDefIndex, &m_sPenDef); } else { UGKError(ET_Failure, UGKErr_AssertionFailed, "ReadGeometryFromMAPFile(): unsupported geometry type %d (0x%2.2x)", m_nMapInfoType, m_nMapInfoType); return -1; } /*----------------------------------------------------------------- * Create and fill geometry object * For the UGK geometry, we generate an arc with 2 degrees line * segments. *----------------------------------------------------------------*/ poLine = new UGKLineString; if (m_dEndAngle < m_dStartAngle) numPts = (int) ABS( ((m_dEndAngle+360.0)-m_dStartAngle)/2.0 ) + 1; else numPts = (int) ABS( (m_dEndAngle-m_dStartAngle)/2.0 ) + 1; numPts = MAX(2, numPts); TABGenerateArc(poLine, numPts, m_dCenterX, m_dCenterY, m_dXRadius, m_dYRadius, m_dStartAngle*PI/180.0, m_dEndAngle*PI/180.0); SetGeometryDirectly(poLine); return 0;}/********************************************************************** * TABArc::WriteGeometryToMAPFile() * * Write the geometry and representation (color, etc...) part of the * feature to the .MAP object pointed to by poMAPFile. * * It is assumed that poMAPFile currently points to a valid map object. * * Returns 0 on success, -1 on error, in which case CPLError() will have * been called. **********************************************************************/int TABArc::WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *poObjHdr){ UGKGeometry *poGeom; UGKEnvelope sEnvelope; /*----------------------------------------------------------------- * We assume that ValidateMapInfoType() was called already and that * the type in poObjHdr->m_nType is valid. *----------------------------------------------------------------*/ assert(m_nMapInfoType == poObjHdr->m_nType); /*----------------------------------------------------------------- * Fetch and validate geometry *----------------------------------------------------------------*/ poGeom = GetGeometryRef(); if ( (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbLineString ) ) { /*------------------------------------------------------------- * POLYGON geometry: * Note that we will simply use the ellipse's MBR and don't really * read the polygon geometry... this should be OK unless the * polygon geometry was not really an ellipse. * In the case of a polygon geometry. the m_dCenterX/Y values MUST * have been set by the caller. *------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -