Files
envi-code/SourceCode/Code2026/tg_shs/shs_siteplan/InterStruct.cpp
T

522 lines
15 KiB
C++
Raw Normal View History

2026-10-04 00:04:20 +08:00
#include "stdafx.h"
2026-09-28 15:28:50 +08:00
#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);
2026-10-04 00:04:20 +08:00
ClearFlag(eFlagAttached);// 没有关联,初始设置无关联
2026-09-28 15:28:50 +08:00
SetAttachedStruct(NULL);
2026-10-04 00:04:20 +08:00
SetPara(FALSE); // 不平行的
2026-09-28 15:28:50 +08:00
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())
2026-10-04 00:04:20 +08:00
{ // 两个都还没有绘制,才需要重新绘制。
2026-09-28 15:28:50 +08:00
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;
}
2026-10-04 00:04:20 +08:00
// 需要检测自己的bAttach标志,并且假如成功创建后,别人的Attach标志。
2026-09-28 15:28:50 +08:00
void CLineInterStruct::CreateNew()
{
ASSERT(IsMidRoad());
2026-10-04 00:04:20 +08:00
// 如果设置了creatFlag, 或者 没有设置CreatFlag,但是对应的实体已经被删除了,都要重新建立该interStruct线
2026-09-28 15:28:50 +08:00
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;
}
2026-10-04 00:04:20 +08:00
// 检测thisInterStruct是否位于pInter1和pInter2之间。
// 本函数用于检测所得到的线是否是两条道路的中线。
2026-09-28 15:28:50 +08:00
BOOL CLineInterStruct::IsMidofInterStruct(CLineInterStruct *pInter1, CLineInterStruct *pInter2) const
{
if ((pInter1 == NULL) || (pInter2 == NULL))
return FALSE;
2026-10-04 00:04:20 +08:00
// 1、this.interPoint 在pInter1和pInter2之间。
// interPoint求向两条边的垂线,这两个向量的方向相反(点积<0)
2026-09-28 15:28:50 +08:00
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)
2026-10-04 00:04:20 +08:00
return FALSE; // 代表点不在两条道路中间
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
// 2、this Inter的方向跟pInter1,和pInter2的方向相同。
2026-09-28 15:28:50 +08:00
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))
2026-10-04 00:04:20 +08:00
{ // 开始创建
2026-09-28 15:28:50 +08:00
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;
}
2026-10-04 00:04:20 +08:00
// 检测thisInterStruct是否位于pInter1和pInter2之间。
// 本函数用于检测本线(中线)是否是两条道路的中线。
2026-09-28 15:28:50 +08:00
BOOL CArcInterStruct::IsMidofInterStruct(CArcInterStruct *pInter1, CArcInterStruct *pInter2) const
{
if ((pInter1 == NULL) || (pInter2 == NULL))
return FALSE;
2026-10-04 00:04:20 +08:00
// 算法:
//1、通过圆弧的半径和圆心来筛选,即:中线半径在pInter1和pInter2之间,圆心相同
//2、通过交点处角度筛选:中线在该点处的切线方向在另外两个边之间。
2026-09-28 15:28:50 +08:00
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);
2026-10-04 00:04:20 +08:00
// 通过圆心和半径来筛选,要求:圆心相同,中线半径在两个pInter之间
2026-09-28 15:28:50 +08:00
if (!thisArc.center().isEqualTo(arc1.center(), tol) || !thisArc.center().isEqualTo(arc2.center(), tol))
return FALSE;
if (thisArc.radius() > dBigRadius && thisArc.radius() < dSamllRadius)
return FALSE;
2026-10-04 00:04:20 +08:00
// 角度
2026-09-28 15:28:50 +08:00
double dAnglethis = this->Direction().angle();
double dangle1 = pInter1->Direction().angle();
double dangle2 = pInter2->Direction().angle();
2026-10-04 00:04:20 +08:00
// 角度近似相同
2026-09-28 15:28:50 +08:00
if (SameAngle(dAnglethis, dangle1, 0.1) || SameAngle(dAnglethis, dangle2, 0.1))
return TRUE;
2026-10-04 00:04:20 +08:00
// CAD中的圆弧都是逆时针的
2026-09-28 15:28:50 +08:00
if (AngleInClock(false, dangle1, dangle2) > PI)
SWAP(dangle1, dangle2);
2026-10-04 00:04:20 +08:00
// 角度在二者之间。
2026-09-28 15:28:50 +08:00
if (AngleInClock(false, dangle1, dAnglethis) < AngleInClock(false, dangle1, dangle2))
return TRUE;
else
return FALSE;
}
2026-10-04 00:04:20 +08:00
// 构造CLineInterStruct。
2026-09-28 15:28:50 +08:00
CLineInterStruct* ConInterStruct(const AcGeLineSeg2d &lineEdge, bool bStart, const CRoad &road, CLineCADEntEdgeAdapter &ent, AcGeTol &geTol,
BOOL bPara, BOOL bMid, BOOL bComplexOut, EPointAtRoadInDir eComplexPos)
{
2026-10-04 00:04:20 +08:00
CLineInterStruct *pLineInterStruct = new CLineInterStruct(ent); // ent构造
AcGePoint2d ptInter = bStart ? lineEdge.startPoint() : lineEdge.endPoint(); // 交点
2026-09-28 15:28:50 +08:00
pLineInterStruct->SetInterLine(lineEdge); //
pLineInterStruct->SetStart(bStart);
2026-10-04 00:04:20 +08:00
pLineInterStruct->SetInEdge(ent.Line().isOn(ptInter, geTol)); // 交点是否在原始边线上
2026-09-28 15:28:50 +08:00
if (!bComplexOut)
pLineInterStruct->SetPostion(road.PointAtRoadInDir(ptInter));
else
pLineInterStruct->SetPostion(eComplexPos);
2026-10-04 00:04:20 +08:00
pLineInterStruct->SetInterPoint(ptInter); // 设置交点。
2026-09-28 15:28:50 +08:00
pLineInterStruct->SetAttachedStruct(NULL);
if (bMid)
2026-10-04 00:04:20 +08:00
pLineInterStruct->SetMidFlag(); // 中线标记
2026-09-28 15:28:50 +08:00
pLineInterStruct->SetPara(bPara);
if (bComplexOut)
2026-10-04 00:04:20 +08:00
pLineInterStruct->SetComplexOutFlag(); // 复杂外交线标记
2026-09-28 15:28:50 +08:00
return pLineInterStruct;
}
2026-10-04 00:04:20 +08:00
// 构造CArcInterStruct结构
2026-09-28 15:28:50 +08:00
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()
}
}