522 lines
14 KiB
C++
522 lines
14 KiB
C++
#include "stdafx.h"
|
||
#include "commonRoad.h"
|
||
#include "RoolBackNew.h"
|
||
#include "Road.h"
|
||
#include <dbgroup.h>
|
||
#include "InterStruct.h"
|
||
|
||
CInterStruct::CInterStruct(void)
|
||
{
|
||
m_dwFlag = 0;
|
||
SetInEdge(TRUE);
|
||
ClearFlag(eFlagComplexOut);
|
||
SetShortFlag(false);
|
||
SetDoneFlag(false);
|
||
SetInRoadFlag(false);
|
||
SetFlag(eFlagEdgeOrMid);
|
||
ClearFlag(eFlagAttached);// 没有关联,初始设置无关联
|
||
SetAttachedStruct(NULL);
|
||
SetPara(FALSE); // 不平行的
|
||
SetDrawed(FALSE);
|
||
}
|
||
|
||
CInterStruct::~CInterStruct(void)
|
||
{
|
||
}
|
||
|
||
BOOL CInterStruct::IsMidofInterStruct(CInterStruct *pInter1, CInterStruct *pInter2) const
|
||
{
|
||
if (this->ToLineInter() != NULL)
|
||
{
|
||
return this->ToLineInter()->IsMidofInterStruct(pInter1->ToLineInter(), pInter2->ToLineInter());
|
||
}
|
||
else
|
||
{
|
||
return this->ToArcInter()->IsMidofInterStruct(pInter1->ToArcInter(), pInter2->ToArcInter());
|
||
}
|
||
}
|
||
|
||
BOOL CInterStruct::IsNeedCreate(const CCADEntEdgeAdapter &entThis) const
|
||
{
|
||
if (IsErased())
|
||
return FALSE;
|
||
if (IsAttached())
|
||
{ // 两个都还没有绘制,才需要重新绘制。
|
||
return !IsDrawed() && !AttachedStruct()->IsDrawed();//
|
||
}
|
||
else
|
||
// return IsDone();
|
||
return entThis.NeedReCreate() && !IsInRoad();
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
// CLineInterStruct
|
||
|
||
CLineInterStruct::CLineInterStruct(CLineCADEntEdgeAdapter &lineEnt)
|
||
: m_lineEnt(lineEnt), CInterStruct()
|
||
{
|
||
lineEnt.AddInterStruct(this);
|
||
}
|
||
CLineInterStruct::~CLineInterStruct(void){}
|
||
|
||
AcGeLineSeg2d CLineInterStruct::OriginLine() const
|
||
{
|
||
return m_lineEnt.Line();
|
||
}
|
||
AcGeLineSeg2d CLineInterStruct::InterLine() const
|
||
{
|
||
return m_interLine;
|
||
}
|
||
void CLineInterStruct::SetInterLine(const AcGeLineSeg2d &line)
|
||
{
|
||
m_interLine = line;
|
||
}
|
||
|
||
CLineInterStruct* CLineInterStruct::ToLineInter() const
|
||
{
|
||
return (CLineInterStruct*)this;
|
||
}
|
||
|
||
// 需要检测自己的bAttach标志,并且假如成功创建后,别人的Attach标志。
|
||
void CLineInterStruct::CreateNew()
|
||
{
|
||
ASSERT(IsMidRoad());
|
||
// 如果设置了creatFlag, 或者 没有设置CreatFlag,但是对应的实体已经被删除了,都要重新建立该interStruct线
|
||
if (IsNeedCreate(m_lineEnt))
|
||
{ //
|
||
AcDbLine *pLine = NULL;
|
||
if (m_pInterStructAttached != NULL)
|
||
{
|
||
CLineInterStruct* pLineInterAttached = (CLineInterStruct*)m_pInterStructAttached;
|
||
AcGePoint2d ptStart = IsStart() ? m_interLine.startPoint() : pLineInterAttached->InterLine().startPoint();
|
||
AcGePoint2d ptEnd = !IsStart() ? InterLine().endPoint() : pLineInterAttached->InterLine().endPoint();
|
||
pLine = GeLineToDbLineSys(AcGeLineSeg2d(ptStart, ptEnd));
|
||
m_pInterStructAttached->BeAttached();
|
||
}
|
||
else
|
||
pLine = GeLineToDbLineSys(m_interLine);
|
||
|
||
SetLayer(pLine, eRoadMidType);
|
||
RoolBackAddNewData(pLine);
|
||
SetDrawed(TRUE);
|
||
}
|
||
}
|
||
|
||
void CLineInterStruct::EraseOldObject()
|
||
{
|
||
if (m_lineEnt.NeedReCreate())
|
||
m_lineEnt.RoolBackErase();
|
||
}
|
||
|
||
double CLineInterStruct::Lenth() const
|
||
{
|
||
return m_interLine.startPoint().distanceTo(m_interLine.endPoint());
|
||
}
|
||
|
||
double CLineInterStruct::DistanceTo(const AcGePoint2d &pt) const
|
||
{
|
||
return m_interLine.distanceTo(pt);
|
||
}
|
||
|
||
void CLineInterStruct::SetCreateFlag()
|
||
{
|
||
m_lineEnt.SetReCreateFlag();
|
||
SetDoneFlag(true);
|
||
};
|
||
|
||
|
||
AcGeVector2d CLineInterStruct::Direction() const
|
||
{
|
||
if (IsStart())
|
||
{
|
||
return InterLine().direction();
|
||
}
|
||
else
|
||
return -InterLine().direction();
|
||
}
|
||
|
||
BOOL CLineInterStruct::CombinInterStrcutInSequence(CInterStruct *pInterNext)
|
||
{
|
||
ASSERT(pInterNext->ToLineInter() != NULL);
|
||
CLineInterStruct *pLineNext = (CLineInterStruct*)pInterNext;
|
||
ASSERT((&m_lineEnt) == (&(pLineNext->m_lineEnt)));
|
||
|
||
if((this->InterLine().endPoint().distanceTo(pLineNext->InterLine().startPoint()) > 1.0))
|
||
return FALSE;
|
||
|
||
AcGePoint2d ptStart = InterLine().startPoint() ;
|
||
AcGePoint2d ptEnd = pLineNext->InterLine().endPoint() ;
|
||
|
||
SetInterLine(AcGeLineSeg2d(ptStart, ptEnd));
|
||
|
||
return TRUE;
|
||
}
|
||
BOOL CLineInterStruct::CombinAttachInterStruct()
|
||
{
|
||
ASSERT(AttachedStruct() != NULL);
|
||
|
||
CLineInterStruct *pLineAttached = (CLineInterStruct*)AttachedStruct();
|
||
|
||
CLineInterStruct *pLineInter1 = IsStart() ? this : pLineAttached;
|
||
CLineInterStruct *pLineInter2 = IsStart() ? pLineAttached : this;
|
||
|
||
AcGePoint2d ptStart, ptEnd;
|
||
if (pLineInter1->IsDone() && pLineInter2->IsDone())
|
||
{
|
||
ptStart = pLineInter1->InterLine().startPoint() ;
|
||
ptEnd = pLineInter2->InterLine().endPoint();
|
||
SetInterLine(AcGeLineSeg2d(ptStart, ptEnd));
|
||
}
|
||
else if (pLineInter1->IsDone() || pLineInter2->IsDone())
|
||
{
|
||
ptStart = pLineInter1->IsDone() ? pLineInter1->InterLine().startPoint() : pLineInter1->OriginLine().startPoint();
|
||
ptEnd = pLineInter2->IsDone() ? pLineInter2->InterLine().endPoint() : pLineInter2->OriginLine().endPoint();
|
||
SetInterLine(AcGeLineSeg2d(ptStart, ptEnd));
|
||
this->SetDoneFlag(true);
|
||
}
|
||
else
|
||
{
|
||
// do nothing
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void CLineInterStruct::SimpleCreate()
|
||
{
|
||
AcDbLine *pLine = NULL;
|
||
pLine = GeLineToDbLineSys(InterLine());
|
||
|
||
SetLayer(pLine, IsEdge() ? eRoadEdgeType : eRoadMidType);
|
||
RoolBackAddNewData(pLine);
|
||
}
|
||
|
||
CLineInterStruct CLineInterStruct::DumpStruct()
|
||
{
|
||
CLineCADEntEdgeAdapter lineAdapter;
|
||
CLineInterStruct lineInter(lineAdapter);
|
||
return lineInter;
|
||
}
|
||
|
||
// 检测thisInterStruct是否位于pInter1和pInter2之间。
|
||
// 本函数用于检测所得到的线是否是两条道路的中线。
|
||
BOOL CLineInterStruct::IsMidofInterStruct(CLineInterStruct *pInter1, CLineInterStruct *pInter2) const
|
||
{
|
||
if ((pInter1 == NULL) || (pInter2 == NULL))
|
||
return FALSE;
|
||
|
||
// 1、this.interPoint 在pInter1和pInter2之间。
|
||
// interPoint求向两条边的垂线,这两个向量的方向相反(点积<0)
|
||
AcGeLine2d line1 = ToLine(pInter1->InterLine());
|
||
AcGeLine2d line2 = ToLine(pInter2->InterLine());
|
||
AcGePoint2d ptPerp1 = line1.closestPointTo(InterPoint());
|
||
AcGePoint2d ptperp2 = line2.closestPointTo(InterPoint());
|
||
AcGeVector2d vecToInter1 = InterPoint() - ptPerp1;
|
||
AcGeVector2d vecToInter2 = InterPoint() - ptperp2;
|
||
|
||
if (vecToInter1.dotProduct(vecToInter2) > 0)
|
||
return FALSE; // 代表点不在两条道路中间
|
||
|
||
// 2、this Inter的方向跟pInter1,和pInter2的方向相同。
|
||
AcGeVector2d vecInter = this->Direction();
|
||
|
||
if ((vecInter.dotProduct(pInter1->Direction()) > 1e-6) && (vecInter.dotProduct(pInter2->Direction()) > 1e-6))
|
||
return TRUE;
|
||
else
|
||
return FALSE;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
// CArcInterStruct
|
||
CArcInterStruct::CArcInterStruct(CArcCADEntEdgeAdapter &arcEnt)
|
||
: m_arcEnt(arcEnt), CInterStruct()
|
||
{
|
||
arcEnt.AddInterStruct(this);
|
||
}
|
||
CArcInterStruct::~CArcInterStruct(void){}
|
||
|
||
AcGeCircArc2d CArcInterStruct::OriginArc() const
|
||
{
|
||
return m_arcEnt.Arc();
|
||
}
|
||
AcGeCircArc2d CArcInterStruct::InterArc() const
|
||
{
|
||
return m_interArc;
|
||
}
|
||
void CArcInterStruct::SetInterArc(const AcGeCircArc2d &arc)
|
||
{
|
||
m_interArc = arc;
|
||
}
|
||
|
||
void CArcInterStruct::CreateNew()
|
||
{
|
||
ASSERT(IsMidRoad());
|
||
if (IsNeedCreate(m_arcEnt))
|
||
{ // 开始创建
|
||
AcDbArc *pArc = new AcDbArc();
|
||
if (m_pInterStructAttached != NULL)
|
||
{
|
||
CArcInterStruct* pArcInterAttached = (CArcInterStruct*)m_pInterStructAttached;
|
||
AcGePoint2d ptStart = IsStart() ? InterArc().startPoint() : pArcInterAttached->InterArc().startPoint();
|
||
AcGePoint2d ptEnd = !IsStart() ? InterArc().endPoint() : pArcInterAttached->InterArc().endPoint();
|
||
GeArcToDbSys(ConNewArc(m_interArc, ptStart, ptEnd), *pArc);
|
||
m_pInterStructAttached->BeAttached();
|
||
}
|
||
else
|
||
GeArcToDbSys(m_interArc, *pArc);
|
||
|
||
SetLayer(pArc, IsEdge() ? eRoadEdgeType : eRoadMidType);
|
||
|
||
RoolBackAddNewData(pArc);
|
||
SetDrawed(TRUE);
|
||
}
|
||
}
|
||
|
||
void CArcInterStruct::EraseOldObject()
|
||
{
|
||
if (m_arcEnt.NeedReCreate())
|
||
m_arcEnt.RoolBackErase();
|
||
}
|
||
|
||
void CArcInterStruct::SetCreateFlag()
|
||
{
|
||
m_arcEnt.SetReCreateFlag();
|
||
SetDoneFlag(true);
|
||
}
|
||
|
||
CArcInterStruct* CArcInterStruct::ToArcInter( ) const
|
||
{
|
||
return (CArcInterStruct*)this;
|
||
}
|
||
|
||
double CArcInterStruct::Lenth() const
|
||
{
|
||
return m_interArc.length(m_interArc.startAng(), m_interArc.endAng());
|
||
}
|
||
|
||
double CArcInterStruct::DistanceTo(const AcGePoint2d &pt) const
|
||
{
|
||
return m_interArc.distanceTo(pt);
|
||
}
|
||
|
||
AcGeVector2d CArcInterStruct::Direction() const
|
||
{
|
||
return IsStart() ? TanVecOfArcStartPoint(InterArc()) : TanVecOfArcEndPoint(InterArc());
|
||
}
|
||
|
||
|
||
BOOL CArcInterStruct::CombinInterStrcutInSequence(CInterStruct *pInterNext)
|
||
{
|
||
ASSERT(pInterNext->ToArcInter() != NULL);
|
||
CArcInterStruct *pArcNext = pInterNext->ToArcInter();
|
||
ASSERT((&m_arcEnt) == (&(pArcNext->m_arcEnt)));
|
||
|
||
if(this->InterArc().endPoint().distanceTo(pArcNext->InterArc().startPoint()) > 1.0)
|
||
return FALSE;
|
||
|
||
AcGePoint2d ptStart = InterArc().startPoint() ;
|
||
AcGePoint2d ptEnd = pArcNext->InterArc().endPoint() ;
|
||
SetInterArc(ConNewArc(InterArc(), ptStart, ptEnd));
|
||
return TRUE;
|
||
}
|
||
BOOL CArcInterStruct::CombinAttachInterStruct()
|
||
{
|
||
ASSERT(AttachedStruct() != NULL);
|
||
|
||
CArcInterStruct *pArcAttached = AttachedStruct()->ToArcInter();
|
||
|
||
CArcInterStruct *pArcInter1 = IsStart() ? this : pArcAttached;
|
||
CArcInterStruct *pArcInter2 = IsStart() ? pArcAttached : this;
|
||
|
||
AcGePoint2d ptStart, ptEnd;
|
||
if (pArcInter1->IsDone() && pArcInter2->IsDone())
|
||
{
|
||
ptStart = pArcInter1->InterArc().startPoint() ;
|
||
ptEnd = pArcInter2->InterArc().endPoint();
|
||
SetInterArc(ConNewArc(InterArc(), ptStart, ptEnd));
|
||
}
|
||
else if (pArcInter1->IsDone() || pArcInter2->IsDone())
|
||
{
|
||
ptStart = pArcInter1->IsDone() ? pArcInter1->InterArc().startPoint() : pArcInter1->OriginArc().startPoint();
|
||
ptEnd = pArcInter2->IsDone() ? pArcInter2->InterArc().endPoint() : pArcInter2->OriginArc().endPoint();
|
||
SetInterArc(ConNewArc(InterArc(), ptStart, ptEnd));
|
||
this->SetDoneFlag(true);
|
||
}
|
||
else
|
||
{
|
||
// do nothing
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void CArcInterStruct::SimpleCreate()
|
||
{
|
||
AcDbArc *pArc = new AcDbArc;
|
||
GeArcToDbSys(InterArc(), *pArc);
|
||
|
||
SetLayer(pArc, IsEdge() ? eRoadEdgeType : eRoadMidType);
|
||
RoolBackAddNewData(pArc);
|
||
}
|
||
|
||
CArcInterStruct CArcInterStruct::DumpStruct()
|
||
{
|
||
CArcCADEntEdgeAdapter arcAdatper;
|
||
CArcInterStruct arcInter(arcAdatper);
|
||
return arcInter;
|
||
}
|
||
|
||
// 检测thisInterStruct是否位于pInter1和pInter2之间。
|
||
// 本函数用于检测本线(中线)是否是两条道路的中线。
|
||
BOOL CArcInterStruct::IsMidofInterStruct(CArcInterStruct *pInter1, CArcInterStruct *pInter2) const
|
||
{
|
||
if ((pInter1 == NULL) || (pInter2 == NULL))
|
||
return FALSE;
|
||
|
||
// 算法:
|
||
//1、通过圆弧的半径和圆心来筛选,即:中线半径在pInter1和pInter2之间,圆心相同
|
||
//2、通过交点处角度筛选:中线在该点处的切线方向在另外两个边之间。
|
||
AcGeCircArc2d thisArc = InterArc();
|
||
AcGeCircArc2d arc1 = pInter1->InterArc();
|
||
AcGeCircArc2d arc2 = pInter2->InterArc();
|
||
|
||
double dBigRadius = arc1.radius();
|
||
double dSamllRadius = arc2.radius();
|
||
if (dBigRadius < dSamllRadius)
|
||
SWAP(dBigRadius, dSamllRadius);
|
||
|
||
AcGeTol tol;
|
||
tol.setEqualPoint(1.0);
|
||
tol.setEqualVector(1.0);
|
||
// 通过圆心和半径来筛选,要求:圆心相同,中线半径在两个pInter之间
|
||
if (!thisArc.center().isEqualTo(arc1.center(), tol) || !thisArc.center().isEqualTo(arc2.center(), tol))
|
||
return FALSE;
|
||
if (thisArc.radius() > dBigRadius && thisArc.radius() < dSamllRadius)
|
||
return FALSE;
|
||
|
||
// 角度
|
||
double dAnglethis = this->Direction().angle();
|
||
double dangle1 = pInter1->Direction().angle();
|
||
double dangle2 = pInter2->Direction().angle();
|
||
|
||
// 角度近似相同
|
||
if (SameAngle(dAnglethis, dangle1, 0.1) || SameAngle(dAnglethis, dangle2, 0.1))
|
||
return TRUE;
|
||
|
||
// CAD中的圆弧都是逆时针的
|
||
if (AngleInClock(false, dangle1, dangle2) > PI)
|
||
SWAP(dangle1, dangle2);
|
||
|
||
// 角度在二者之间。
|
||
if (AngleInClock(false, dangle1, dAnglethis) < AngleInClock(false, dangle1, dangle2))
|
||
return TRUE;
|
||
else
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
|
||
// 构造CLineInterStruct。
|
||
CLineInterStruct* ConInterStruct(const AcGeLineSeg2d &lineEdge, bool bStart, const CRoad &road, CLineCADEntEdgeAdapter &ent, AcGeTol &geTol,
|
||
BOOL bPara, BOOL bMid, BOOL bComplexOut, EPointAtRoadInDir eComplexPos)
|
||
{
|
||
CLineInterStruct *pLineInterStruct = new CLineInterStruct(ent); // ent构造
|
||
AcGePoint2d ptInter = bStart ? lineEdge.startPoint() : lineEdge.endPoint(); // 交点
|
||
pLineInterStruct->SetInterLine(lineEdge); //
|
||
pLineInterStruct->SetStart(bStart);
|
||
pLineInterStruct->SetInEdge(ent.Line().isOn(ptInter, geTol)); // 交点是否在原始边线上
|
||
if (!bComplexOut)
|
||
pLineInterStruct->SetPostion(road.PointAtRoadInDir(ptInter));
|
||
else
|
||
pLineInterStruct->SetPostion(eComplexPos);
|
||
pLineInterStruct->SetInterPoint(ptInter); // 设置交点。
|
||
pLineInterStruct->SetAttachedStruct(NULL);
|
||
if (bMid)
|
||
pLineInterStruct->SetMidFlag(); // 中线标记
|
||
pLineInterStruct->SetPara(bPara);
|
||
if (bComplexOut)
|
||
pLineInterStruct->SetComplexOutFlag(); // 复杂外交线标记
|
||
|
||
return pLineInterStruct;
|
||
}
|
||
|
||
|
||
// 构造CArcInterStruct结构
|
||
CArcInterStruct* ConInterStruct(const AcGeCircArc2d &arcEdge, bool bStart, const CRoad &road, CArcCADEntEdgeAdapter &ent, AcGeTol &geTol,
|
||
BOOL bPara, BOOL bMid, BOOL bComplexOut, EPointAtRoadInDir eComplexPos)
|
||
{
|
||
CArcInterStruct *pArcInterStruct = new CArcInterStruct(ent);
|
||
AcGePoint2d ptInter = bStart ? arcEdge.startPoint() : arcEdge.endPoint();
|
||
pArcInterStruct->SetInterArc(arcEdge); //
|
||
pArcInterStruct->SetStart(bStart);
|
||
pArcInterStruct->SetInEdge(ent.Arc().isOn(ptInter, geTol));
|
||
if (!bComplexOut)
|
||
pArcInterStruct->SetPostion(road.PointAtRoadInDir(ptInter));
|
||
else
|
||
pArcInterStruct->SetPostion(eComplexPos);
|
||
pArcInterStruct->SetInterPoint(ptInter);
|
||
pArcInterStruct->SetAttachedStruct(NULL);
|
||
if (bMid)
|
||
pArcInterStruct->SetMidFlag();
|
||
pArcInterStruct->SetPara(bPara);
|
||
if (bComplexOut)
|
||
pArcInterStruct->SetComplexOutFlag();
|
||
|
||
return pArcInterStruct;
|
||
}
|
||
|
||
CLineInterStruct* ConInterStructInRoad(const AcGeLineSeg2d &lineEdge, CLineCADEntEdgeAdapter &ent)
|
||
{
|
||
CLineInterStruct *pLineInter = new CLineInterStruct(ent);
|
||
pLineInter->SetInterLine(lineEdge);
|
||
pLineInter->SetInRoadFlag(true);
|
||
|
||
return pLineInter;
|
||
}
|
||
|
||
CArcInterStruct* ConInterStructInRoad(const AcGeCircArc2d &arcEdge, CArcCADEntEdgeAdapter &ent)
|
||
{
|
||
CArcInterStruct *pArcInter = new CArcInterStruct(ent);
|
||
pArcInter->SetInterArc(arcEdge);
|
||
pArcInter->SetInRoadFlag(true);
|
||
|
||
return pArcInter;
|
||
}
|
||
|
||
void CLineInterStruct::SimpleCreateForLandScape()
|
||
{
|
||
AcDbLine *pLine = NULL;
|
||
pLine = GeLineToDbLineSys(InterLine());
|
||
pLine->setVisibility(m_bIsVisible);
|
||
AcDbObjectId idLayer = InitLayer(LAY_LSCP_ROAD);
|
||
pLine->setLayer(idLayer);
|
||
AcDbObjectId objectid = RoolBackAddNewData(pLine);
|
||
if (m_GroupId.isValid())
|
||
{
|
||
OPENOBJ_BEGIN(m_GroupId, AcDb::kForWrite, AcDbGroup, pGroup)
|
||
if (pGroup)
|
||
{
|
||
pGroup->append(objectid);
|
||
}
|
||
OPENOBJ_END()
|
||
}
|
||
}
|
||
|
||
void CArcInterStruct::SimpleCreateForLandScape()
|
||
{
|
||
AcDbArc *pArc = new AcDbArc;
|
||
GeArcToDbSys(InterArc(), *pArc);
|
||
pArc->setVisibility(m_bIsVisible);
|
||
AcDbObjectId idLayer = InitLayer(LAY_LSCP_ROAD);
|
||
pArc->setLayer(idLayer);
|
||
AcDbObjectId objectid = RoolBackAddNewData(pArc);
|
||
if (m_GroupId.isValid())
|
||
{
|
||
OPENOBJ_BEGIN(m_GroupId, AcDb::kForWrite, AcDbGroup, pGroup)
|
||
if (pGroup)
|
||
{
|
||
pGroup->append(objectid);
|
||
}
|
||
OPENOBJ_END()
|
||
}
|
||
} |