Files
envi-code/SourceCode/Code2026/tg_shs/shs_siteplan/InterStruct.cpp
T
2026-09-28 15:28:50 +08:00

522 lines
14 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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()
}
}