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

1004 lines
29 KiB
C++
Raw Normal View History

2026-09-28 15:28:50 +08:00
#include "stdafx.h"
#include "RoadArith.h"
#include "RoolBackNew.h"
#include "RoadEdgeCreater.h"
#include "RoadDataCenterNew.h"
// 带附加数据的排序
typedef int (*PSortFun)(const void *p1, const void *p2);
class SortClass
{
static void *s_pDataExtra;
public:
static void SetExtraData(void *pExtraData){s_pDataExtra = pExtraData;}
static void* GetExtraDAta(){return s_pDataExtra;}
static void LGHSort(void *pData, size_t size, size_t nCount, PSortFun pSort, void *pExtraData)
{
SetExtraData(pExtraData);
qsort(pData, size, nCount, pSort);
s_pDataExtra = NULL;
}
};
void *SortClass::s_pDataExtra = NULL;
// RoadEdgeCreater构造函数
CRoadEdgeCreater::CRoadEdgeCreater(const CRoad *pRoad,
AcAryInterStructPointer &leftInterStruct, AcAryInterStructPointer &rightInterStruct,
AcAryInterStructPointer &leftInterStructIn, AcAryInterStructPointer &rightInterStructIn,
AcAryInterStructPointer &leftInterStructMid, AcAryInterStructPointer &rightInterStructMid,
CFilterMode &leftFilterMode, CFilterMode &rightFiltMode)
: m_pRoad(pRoad),
m_arLeftInterStruct(leftInterStruct), m_arRightInterStruct(rightInterStruct),
m_arleftInterStructIn(leftInterStructIn), m_arrightInterStructIn(rightInterStructIn),
m_arLeftMidInterStruct(leftInterStructMid), m_arRightMidInterStuct(rightInterStructMid),
m_filterModeLeft(leftFilterMode), m_filterModeRight(rightFiltMode)
{
ASSERT(m_pRoad != NULL);
}
// RoadEdgeCreater析构函数
CRoadEdgeCreater::~CRoadEdgeCreater(void)
{
}
void CRoadEdgeCreater::AddInterCircle(AcGeCircArc2d &arc, BOOL bMid)
{
if (!bMid)
m_arInterCircle.append(arc);
else
m_arMidInterCircle.append(arc);
}
void CRoadEdgeCreater::DrawInterCircle()
{
for (int i = 0; i < (int)m_arInterCircle.length(); i++)
{
AcDbArc *pArc = new AcDbArc;
SetLayer(&(GeArcToDbSys(m_arInterCircle[i], *pArc)), eRoadEdgeType);
RoolBackAddNewData(pArc);
}
if (IsDrawMid())
{
for (i = 0;i < (int)m_arMidInterCircle.length(); i++)
{
AcDbArc *pArc = new AcDbArc;
SetLayer(&(GeArcToDbSys(m_arMidInterCircle[i], *pArc)), eRoadMidType);
RoolBackAddNewData(pArc);
}
}
}
void CRoadEdgeCreater::DrawInterStruct()
{
AcAryInterStructPointer arPInterStruct;
if (IsDrawMid())
{
arPInterStruct.append(m_arLeftMidInterStruct);
arPInterStruct.append(m_arRightMidInterStuct);
}
for (int i = 0; i < (int)arPInterStruct.length(); i++)
{
arPInterStruct[i]->EraseOldObject();
arPInterStruct[i]->CreateNew();
}
ClearAcaryAll(arPInterStruct);
ClearAcaryAll(m_arLeftInterStruct);
ClearAcaryAll(m_arRightInterStruct);
ClearAcaryAll(m_arLeftMidInterStruct);
ClearAcaryAll(m_arRightMidInterStuct);
ClearAcaryAll(m_arMidInterstructDump);
}
// 测试道路的另一个拐角是否能够执行
bool CRoadEdgeCreater::TestOtherEdgeOfCorner(bool bIsLeft, bool bIsStart)
{
CInterStruct* pInStruct = GetInterStructInside(!bIsLeft, bIsStart);
CInterStruct* pOutStruct = GetInterStructOutside(!bIsLeft, bIsStart);
// 道路非拐角
if (pInStruct == NULL && pOutStruct == NULL)
return false;
else
return true;
}
BOOL CRoadEdgeCreater::IsOutInterStuctPair(CInterStruct *pInter1, CInterStruct *pInter2)
{
BOOL b1 = pInter1 != NULL ? pInter1->IsInEdge() : FALSE;
BOOL b2 = pInter2 != NULL ? pInter2->IsInEdge() : FALSE;
return !b1 && !b2;
}
int CRoadEdgeCreater::GetInterStructRealIn(const AcAryInterStructPointer &arInterAll,
const CFilterMode &filterMode,
AcAryInterStructPointer &arInterRealIn)
{
ClearAcaryAll(arInterRealIn);
arInterRealIn.append(arInterAll);
if (arInterRealIn.length() > 0 && !filterMode.KeepFirst())
arInterRealIn.removeFirst();
if (arInterRealIn.length() > 0 && !KeepLast(arInterAll, filterMode))
arInterRealIn.removeLast();
return (int)arInterRealIn.length();
}
// 获取边线处理的内interStruct.
// 规则:如果有最外边的一端需要删除,则返回该紧邻的interStruct,否则,如果有两个或两个以上的外边的interStruct(eStartOut,eEndOut),则返回里边的interStruct
CInterStruct* CRoadEdgeCreater::GetInterStructInside(bool bLeft, bool bStart)const
{
AcAryInterStructPointer &arInterAll = bLeft ? m_arLeftInterStruct : m_arRightInterStruct;
AcAryInterStructPointer &arInterIn = bLeft ? m_arleftInterStructIn : m_arrightInterStructIn;
const CFilterMode &filter = bLeft ? m_filterModeLeft : m_filterModeRight;
if (bStart)
{
if (!filter.KeepFirst())
{
ASSERT(!arInterIn.isEmpty());
return arInterIn.first();
}
else
{
int nIndex = 0;
CInterStruct* pInter = AntiFindFirstInterStruct(arInterAll, eRoadStartOut, nIndex);
if (nIndex == 0)
return NULL;
return pInter;
}
}
else
{
if (!KeepLast(arInterIn, filter))
{
ASSERT(!arInterIn.isEmpty());
return arInterIn.last();
}
else
{
int nIndex = 0;
CInterStruct *pInter = FindFirstInterStruct(arInterAll, eRoadEndOut, nIndex);
if (nIndex == (int)arInterAll.length() - 1)
return NULL;
return pInter;
}
}
}
CInterStruct* CRoadEdgeCreater::GetInterStructOutside(bool bLeft, bool bStart) const
{
AcAryInterStructPointer &arInterStruct = bLeft ? m_arLeftInterStruct : m_arRightInterStruct;
int index = 0;
if (bStart)
return FindFirstInterStruct(arInterStruct, eRoadStartOut, index);
else
return AntiFindFirstInterStruct(arInterStruct, eRoadEndOut, index);
}
// 查找匹配的第一个interStruct,如果没有则返回空
CInterStruct* CRoadEdgeCreater::FindFirstInterStruct(const AcAryInterStructPointer &arInterStruct,
EPointAtRoadInDir eAtRoadDir,
int &nIndex)
{
for (int i = 0; i < (int)arInterStruct.length(); i++)
{
if (arInterStruct[i]->Position() == eAtRoadDir)
{
nIndex = i;
return arInterStruct[i];
}
}
nIndex = -1;
return NULL;
}
// 反向查找匹配的第一个interStruct,如果没有则返回空
CInterStruct* CRoadEdgeCreater::AntiFindFirstInterStruct(const AcAryInterStructPointer &arInterStruct,
EPointAtRoadInDir eAtRoadDir,
int &nIndex)
{
for (int i = (int)arInterStruct.length() - 1; i > -1; i--)
{
if (arInterStruct[i]->Position() == eAtRoadDir)
{
nIndex = i;
return arInterStruct[i];
}
}
nIndex = -1;
return NULL;
}
BOOL CRoadEdgeCreater::KeepLast(const AcAryInterStructPointer &arInterStructIn, const CFilterMode &filterMode)
{
return EvenNum((int)arInterStructIn.length()) ? filterMode.KeepFirst() : !filterMode.KeepFirst();
}
// pInterStruct跟lineSeg执行倒角
// pInterStruct:倒角线1;RoadEdge:倒角线2 ,,,,cirArc:倒角圆弧
// ret:是否能够执行倒角,倒角之后,pInterStruct和RoadEdge都发生裁剪,cirArc被返回
bool InterCircle(CInterStruct *pInterStruct,
AcGeLineSeg2d &roadEdge, bool bStart,
double dRadius, AcGeCircArc2d &cirArc)
{
if (pInterStruct->ToLineInter() != NULL)
{
CLineInterStruct *pLineInter = pInterStruct->ToLineInter();
AcGeLineSeg2d lineDump = pLineInter->InterLine();
if (CRoadArith::InterCircleLineAndLine(&lineDump, pLineInter->IsStart(), &roadEdge, bStart, dRadius, cirArc))
{
pLineInter->SetInterLine(lineDump);
return true;
}
}
else
{
CArcInterStruct *pArcInter = pInterStruct->ToArcInter();
AcGeCircArc2d arcDump = pArcInter->InterArc();
if (CRoadArith::InterCircleArcAndLine(&arcDump, pArcInter->IsStart(), &roadEdge, bStart, dRadius, cirArc))
{
pArcInter->SetInterArc(arcDump);
return true;
}
}
return false;
}
// pInterStruct跟arc执行倒角
// pInterStruct:倒角线1;RoadEdge:倒角线2 ,,,,cirArc:倒角圆弧
// ret:是否能够执行倒角,倒角之后,pInterStruct和RoadEdge都发生裁剪,cirArc被返回
bool InterCircle(CInterStruct *pInterStruct,
AcGeCircArc2d &roadEdge, bool bStart,
double dRadius, AcGeCircArc2d &cirArc)
{
if (pInterStruct->ToLineInter() != NULL)
{
CLineInterStruct *pLineInter = pInterStruct->ToLineInter();
AcGeLineSeg2d lineDump = pLineInter->InterLine();
if (CRoadArith::InterCircleLineAndArc(&lineDump, pLineInter->IsStart(), &roadEdge, bStart, dRadius, cirArc))
{
pLineInter->SetInterLine(lineDump);
return true;
}
}
else
{
CArcInterStruct *pArcInter = pInterStruct->ToArcInter();
AcGeCircArc2d arcDump = pArcInter->InterArc();
if (CRoadArith::InterCircleArcAndArc(&arcDump, pArcInter->IsStart(), &roadEdge, bStart, dRadius, cirArc))
{
pArcInter->SetInterArc(arcDump);
return true;
}
}
return false;
}
// 计算拐角的外交点,并且设置pInterStruct和lineEdge;
// 由于interStrcut可能会被截取,因此要判断交点距离原始边是否合适
// 注意:此函数采用原始单线路段跟当前道路边线做误差检测。
bool InterWithRoadEdge(CInterStruct *pInterStruct, AcGeLineSeg2d &lineEdge, bool bStart,
AcGePoint2d &interPoint, double dTol)
{
// 各取延长线,计算交点,判断从多个交点中取的一个合适的交点,相交
AcGeLineSeg2d lineEdgeExtend = ExtendLine(lineEdge, bStart, dTol);
if (pInterStruct->ToLineInter() != NULL)
{
CLineInterStruct *pLineInter = pInterStruct->ToLineInter();
ASSERT(pLineInter != NULL);
// AcGeLineSeg2d lineInter = pLineInter->InterLine();
AcGeLineSeg2d lineInter = pLineInter->OriginLine();
AcGeLineSeg2d lineInterExtend = ExtendLine(lineInter, pLineInter->IsStart(), dTol);
// 相交判定
if (lineInterExtend.intersectWith(lineEdgeExtend, interPoint))
{
ResetLine(lineInter, pLineInter->IsStart(), interPoint);
ResetLine(lineEdge, bStart, interPoint);
pLineInter->SetInterLine(lineInter);
}
else
return false;
}
else
{
CArcInterStruct *pArcInter = pInterStruct->ToArcInter();
ASSERT(pArcInter != NULL);
// AcGeCircArc2d arcInter = pArcInter->InterArc();
AcGeCircArc2d arcInter = pArcInter->OriginArc();
AcGeCircArc2d arcInterExtend = ExtendArc(arcInter, pArcInter->IsStart(), dTol);
AcGePoint2d interPt1, interPt2;
int nNum = 0;
if (arcInterExtend.intersectWith(lineEdgeExtend, nNum, interPt1, interPt2))
{
if (nNum == 2)
{
if (!CRoadArith::TestProperPoint(lineEdge, bStart, arcInter, pArcInter->IsStart(), interPt1, interPt2, interPoint))
return false;
}
else // nNum == 1;
interPoint = interPt1;
ResetArc(arcInter, pArcInter->IsStart(), interPoint);
ResetLine(lineEdge, bStart, interPoint);
pArcInter->SetInterArc(arcInter);
}
else
return false;
}
return true;
}
// 注意:此函数采用原始单线路段跟当前道路边线做误差检测。
// 计算拐角的外交点,并且设置pInterStruct和arcEdge;
bool InterWithRoadEdge(CInterStruct *pInterStruct, AcGeCircArc2d &arcEdge, bool bStart,
AcGePoint2d &interPoint, double dTol)
{
AcGeCircArc2d arcEdgeExtend = ExtendArc(arcEdge, bStart, dTol);
int nNumInter = 0;
AcGePoint2d interPt1, interPt2;
if (pInterStruct->ToLineInter() != NULL)
{
CLineInterStruct *pLineInter = pInterStruct->ToLineInter();
ASSERT(pLineInter != NULL);
// AcGeLineSeg2d lineInter = pLineInter->InterLine();
AcGeLineSeg2d lineInter = pLineInter->OriginLine();
AcGeLineSeg2d lineInterExtend = ExtendLine(lineInter, pLineInter->IsStart(), dTol);
if (arcEdgeExtend.intersectWith(lineInterExtend, nNumInter, interPt1, interPt2))
{
if (nNumInter == 2)
{
if (!CRoadArith::TestProperPoint(lineInter, pLineInter->IsStart(), arcEdge, bStart, interPt1, interPt2, interPoint))
return false;
}
else // nNumInter == 1;
interPoint = interPt1;
ResetArc(arcEdge, bStart, interPoint);
ResetLine(lineInter, pLineInter->IsStart(), interPoint);
pLineInter->SetInterLine(lineInter);
}
else
return false;
}
else
{
CArcInterStruct *pArcInter = pInterStruct->ToArcInter();
ASSERT(pArcInter != NULL);
// AcGeCircArc2d arcInter = pArcInter->InterArc();
AcGeCircArc2d arcInter = pArcInter->OriginArc();
AcGeCircArc2d arcInterExtend = ExtendArc(arcInter, pArcInter->IsStart(), dTol);
if (arcEdgeExtend.intersectWith(arcInterExtend, nNumInter, interPt1, interPt2))
{
if (nNumInter == 2)
{
if (!CRoadArith::TestProperPoint(arcEdge, bStart, arcInter, pArcInter->IsStart(), interPt1, interPt2, interPoint))
return false;
}
else
interPoint = interPt1;
ResetArc(arcEdge, bStart, interPoint);
ResetArc(arcInter, pArcInter->IsStart(), interPoint);
pArcInter->SetInterArc(arcInter);
}
else
return false;
}
return true;
}
// 两路相交的外边线如果需要同圆心倒角的话,需要先求取外交线的倒角半径,然后使用该倒角半径做倒角处理。
// 求取外交线倒角半径的方法是:取内交线的交点,然后取该交点到两条外边线的最大距离,这个距离再加上原始半径即为外倒角半径
// 备注:使用该方法处理,如果遇到等宽道路,则同圆心倒角依旧同圆心,如果遇到非等宽道路,则保证倒角处理的结果具有可用性,但是与内边线并非同圆心
double OutRadius(double dInRadius, CInterStruct *pInterStruct, const AcGeLineSeg2d &interLine,
const AcGePoint2d &interPoint) // interPoint:内边线的焦点
{
// dRadius1:点距离interStruct的焦点
double dRadius1 = pInterStruct->DistanceTo(interPoint);
double dRadius2 = interLine.distanceTo(interPoint);
return MAX(dRadius1, dRadius2) + dInRadius;
}
double OutRadius(double dInRadius, CInterStruct *pInterStruct, const AcGeCircArc2d &interArc,
const AcGePoint2d &interPoint)
{
double dRadius1 = pInterStruct->DistanceTo(interPoint);
double dRadius2 = interArc.distanceTo(interPoint);
return MAX(dRadius1, dRadius2) + dInRadius;
}
// 生成道路边线
void CRoadEdgeCreater::ReSetEdge(const AcGePoint2d &point, bool bStart, AcGeLineSeg2d &lineEdge)
{
ResetLine(lineEdge, bStart, point);
}
// 生成道路边线
void CRoadEdgeCreater::ReSetEdge(const AcGePoint2d &point, bool bStart, AcGeCircArc2d &arcEdge)
{
ResetArc(arcEdge, bStart, point);
}
void CRoadEdgeCreater::FilterMidRoad(AcAryInterStructPointer &arMidInterStruct)
{
for (int i = (int)arMidInterStruct.length() - 1; i >= 0; i--)
{
if (m_pRoad->IsInExtendRoad(arMidInterStruct[i])) // 被道路所包括的中线。
{
arMidInterStruct[i]->SetCreateFlag();
arMidInterStruct.removeAt(i);
}
}
}
void CRoadEdgeCreater::FilterMidRoad()
{
m_arMidInterstructDump.append(m_arLeftMidInterStruct);
m_arMidInterstructDump.append(m_arRightMidInterStuct);
FilterMidRoad(m_arLeftMidInterStruct);
FilterMidRoad(m_arRightMidInterStuct);
}
//
int CRoadEdgeCreater::LenBetweenElement(AcAryInterStructPointer &arCurrInterStruct,
CInterStruct *pInterStructInside,
CInterStruct *pInterStructOutside)
{
int pos1 = -1, pos2 = -1;
for (int i = 0; i < (int)arCurrInterStruct.length(); i++)
{
if (arCurrInterStruct[i] == pInterStructInside)
pos1 = i;
if (arCurrInterStruct[i] == pInterStructOutside)
pos2 = i;
if (pos1 != -1&& pos2 != -1)
break;
}
if (pos1 == -1 || pos2 == -1)
return -1;
else
return (pos1 - pos2) > 0 ? pos1 - pos2 : pos2 - pos1;
}
void RemoveCornerMidLine(const AcGeVector2d &vecRem, const AcGePoint2d &ptInter, AcAryInterStructPointer &arMidInter)
{
if (arMidInter.length() == 0)
return;
if (arMidInter[0]->ToLineInter() != NULL)
{
CRoadDataCenterNew::SortInterStructsSimp(arMidInter[0]->ToLineInter()->OriginLine(), true, arMidInter);
}
else if (arMidInter[0]->ToArcInter() != NULL)
{
CRoadDataCenterNew::SortInterStructsSimp(arMidInter[0]->ToArcInter()->OriginArc(), true, arMidInter);
}
// 比较ptInter处,上下两个节点的方向跟vecRem相同的,那一段则全部设置为删除标记
for (int i = 0; i < (long)arMidInter.length(); i++)
{
if ((arMidInter[i]->InterPoint() == ptInter) &&
(i + 1 != arMidInter.length()) &&
(arMidInter[i+1]->InterPoint() == ptInter))
{
AcGeVector2d vecDir1 = arMidInter[i]->Direction();
if (vecDir1.dotProduct(vecRem) > 0.0)
{ // 0~i设置删除标记。
for (int j = 0; j <= i; ++j)
{
arMidInter[j]->SetEraseFlag(TRUE);
arMidInter[j]->SetCreateFlag(); // 该条线被删除,所以其他线需要绘制
}
}
else
{ // i + 1~length设置删除标记
for (int j = i+1; j < (long)arMidInter.length(); ++j)
{
arMidInter[j]->SetEraseFlag(TRUE);
arMidInter[j]->SetCreateFlag(); // 该条线被删除,所以其他线需要绘制
}
}
}
}
}
//
template <class TRoadEdge>
void MakeACornerTem(bool bIsLeft, bool bIsStart,
TRoadEdge &leftEdge, TRoadEdge &rightEdge, TRoadEdge &midEdge,
CRoadEdgeCreater *pThisCreater)
{
const CRoad* pRoad = pThisCreater->m_pRoad;
// 获取道路里边的interStruct
CInterStruct *pInterStructInside = pThisCreater->GetInterStructInside(bIsLeft, bIsStart);
// 获取道路某侧外边的interStruct
CInterStruct *pInterStructOutside = pThisCreater->GetInterStructOutside(bIsLeft, bIsStart);
// pInterInside And pInterOutSide是Attached; 这个时候不处理。
if ((pInterStructInside != NULL) && (pInterStructInside->AttachedStruct() != NULL) && (pInterStructInside->AttachedStruct() == pInterStructOutside))
{
pInterStructOutside = NULL;
if (pInterStructInside->Position() != eInEdge)
pInterStructInside = NULL;
}
// 中线interStruct;
AcAryInterStructPointer *pArMidInter = bIsLeft ? &(pThisCreater->m_arLeftMidInterStruct) : &(pThisCreater->m_arRightMidInterStuct);
// 要处理的两个路边,pEdgeInSide, pEdgeOutSide;
// 拐角处理的时候,道路的两条边,一条在处理的内侧,一条在外侧
TRoadEdge *pEdgeInside = bIsLeft ? &leftEdge : &rightEdge;
TRoadEdge *pEdgeOutside = bIsLeft ? &rightEdge : &leftEdge;
bool bEdgeDirection = bIsStart;
BOOL bInterInside = FALSE, bInterOutSide = FALSE;
if (pInterStructInside != NULL) // 这两个都不会是空的
{
if (pInterStructInside->IsComplexOut()) // 复杂内实体,不可能。
return;
// 先设置路边跟interStruct相交
pThisCreater->ReSetEdge(pInterStructInside->InterPoint(), bEdgeDirection, *pEdgeInside);
// 处理倒角
if (pRoad->NeedInterCircle())
{
bInterInside = TRUE;
}
// interStruct生成;
pInterStructInside->SetCreateFlag();
}
// 存在外边线,并且道路另一侧对应处方没有内外边线,并且本外边线不是paraInter,并且内侧外边线和外侧外边线之间没有其他外边线
AcAryInterStructPointer &arCurrInterStruct = bIsLeft ? pThisCreater->m_arLeftInterStruct : pThisCreater->m_arRightInterStruct;
if (pInterStructOutside != NULL
&& !pThisCreater->TestOtherEdgeOfCorner(bIsLeft, bIsStart)
&& !pInterStructOutside->IsPara()
&& CRoadEdgeCreater::LenBetweenElement(arCurrInterStruct, pInterStructInside, pInterStructOutside) == 1)
{
AcGePoint2d ptInter;
bool bIntered = true;
if (pInterStructInside != NULL)
{// 如果不相交,直接生成IngerStruct,道路不需要处理(在生成路边的时候,才需要生成道路的这根边线)
if (pInterStructOutside->IsComplexOut())
ptInter = pInterStructOutside->InterPoint();
else if (!InterWithRoadEdge(pInterStructOutside, *pEdgeOutside, bEdgeDirection, ptInter, pRoad->TolForSplit()))
{
bIntered = false;
}
}
else
{
bIntered = false;
}
if (bIntered)
{
// 设置双线道路的边线。但不生成
pThisCreater->ReSetEdge(ptInter, bEdgeDirection, *pEdgeOutside);
if (pRoad->NeedInterCircle())
{
bInterOutSide = TRUE;
}
}
// 生成interStruct边线
pInterStructOutside->SetCreateFlag();
// 处理道路倒角的时候。处理中线:
if (pThisCreater->IsDrawMid() && !pArMidInter->isEmpty() && pInterStructInside != NULL)
{
int index = -1;
int nNum = 0;
for (int i = 0; i < (int)pArMidInter->length(); i++)
{
// 检测,只有一条中线在拐角中间的时候,才处理该道路中线。
if (pArMidInter->at(i)->IsMidofInterStruct(pInterStructInside, pInterStructOutside))
{
index = i;
nNum++;
}
}
if (nNum == 1)
{// 有且只有一个结构体在他们中间
ASSERT(index > -1 && index < (int)pArMidInter->length());
CInterStruct *pInterStruct = pArMidInter->at(index);
pThisCreater->ReSetEdge(pInterStruct->InterPoint(), bEdgeDirection, midEdge); // 先设置这个道路的中线。
if (pRoad->NeedInterCircle()) // 中线是否需要倒角
{
double dRadius = pRoad->CirRadius();
if (pRoad->NeedSameCenter())
dRadius = OutRadius(dRadius, pInterStruct, midEdge, pInterStructInside->InterPoint());
AcGeCircArc2d cirArc;
if (InterCircle(pInterStruct, midEdge, bEdgeDirection, dRadius, cirArc))
pThisCreater->AddInterCircle(cirArc, true);
}
// 中线处理完毕之后,需要删除掉边角的一些短线(如果还有的话)
// 1/删除方向
AcGeVector2d vecRem;
if (bIsLeft)
vecRem = pRoad->RightDirection(pInterStruct->InterPoint());
else
vecRem = pRoad->LeftDirection(pInterStruct->InterPoint());
//
// AcAryInterStructPointer aryMidInterAll;
// aryMidInterAll.append(pThisCreater->m_arLeftMidInterStruct);
// aryMidInterAll.append(pThisCreater->m_arRightMidInterStuct);
RemoveCornerMidLine(vecRem, pInterStruct->InterPoint(), pInterStruct->GetOriginAdapter()->GetInterStructPointer());
pInterStruct->SetCreateFlag();
}
}
}
if (bInterInside)
{
AcGeCircArc2d cirArc;
if (InterCircle(pInterStructInside, *pEdgeInside, bEdgeDirection, pRoad->CirRadius(), cirArc))
{
// 生成对应的倒角圆弧
pThisCreater->AddInterCircle(cirArc);
}
}
if (bInterOutSide)
{
double dRadius = pRoad->CirRadius();
if (pRoad->NeedSameCenter())
dRadius = OutRadius(dRadius, pInterStructOutside, *pEdgeOutside, pInterStructInside->InterPoint());
AcGeCircArc2d cirArc;
if (InterCircle(pInterStructOutside, *pEdgeOutside, bEdgeDirection, dRadius, cirArc))
{
pThisCreater->AddInterCircle(cirArc);
}
}
}
//////////////////////////////////////////////////////////////////////////
// lineRoad
CLineRoadEdgeCreater::CLineRoadEdgeCreater(const CRoad *pRoad,
AcAryInterStructPointer &leftInterStruct,
AcAryInterStructPointer &rightInterStruct,
AcAryInterStructPointer &leftInterStructin,
AcAryInterStructPointer &rightInterStructin,
AcAryInterStructPointer &leftInterStructMid,
AcAryInterStructPointer &rightInterStructMid,
CFilterMode &leftFilterMode, CFilterMode &rightFiltMode)
:CRoadEdgeCreater(pRoad, leftInterStruct, rightInterStruct, leftInterStructin, rightInterStructin, leftInterStructMid, rightInterStructMid, leftFilterMode, rightFiltMode)
{
CLineRoad *pArcRoad = (CLineRoad*)pRoad;
m_leftedge = pArcRoad->LeftLine();
m_rightEdge = pArcRoad->RightLine();
m_midEdge = pArcRoad->MidLine();
}
// 生成道路,道路的左边线,右边线,以及修正跟道路发生相交的其他道路线
void CLineRoadEdgeCreater::MakeRoad()
{
AcAryInterStructPointer aryInterStructRealIn;
// GetLeft
if (GetInterStructRealIn(m_arleftInterStructIn, m_filterModeLeft, aryInterStructRealIn) > 0)
MakeRoadIn(aryInterStructRealIn, m_leftedge);
// GetRight
if (GetInterStructRealIn(m_arrightInterStructIn, m_filterModeRight, aryInterStructRealIn) > 0)
MakeRoadIn(aryInterStructRealIn, m_rightEdge);
DrawRoadEdge(); // 绘制路边,绘制倒角
DrawInterCircle();
DrawInterStruct();
DrawMid();
}
// 处理道路拐角
void CLineRoadEdgeCreater::MakeCorner()
{
FilterMidRoad();
MakeACorner(true, true); // 左边,起点
MakeACorner(true, false); // 左边终点
MakeACorner(false, true); //
MakeACorner(false, false) ;//
}
// 处理道路的中间部分(不包括拐角)
// arInterStruct是处理之后跟道路中间相交的部分
void CLineRoadEdgeCreater::MakeRoadIn(AcAryInterStructPointer &arInterStructRealIn, AcGeLineSeg2d &edge)
{
// left Road
// 留、删、留、删....
for (int i = 0; i < (int)arInterStructRealIn.length(); i++)
{
AcGePoint2d ptPrev, ptNext;
if (i == 0)
ptPrev = edge.startPoint();
else
ptPrev = arInterStructRealIn[i-1]->InterPoint();
if (i == (int)arInterStructRealIn.length()-1)
ptNext = edge.endPoint();
else
ptNext = arInterStructRealIn[i+1]->InterPoint();
CInterStruct *pNextInter = NULL, *pPrevInter = NULL;
if (i > 0) pPrevInter = arInterStructRealIn[i - 1];
if (i < (int)arInterStructRealIn.length() - 1) pNextInter = arInterStructRealIn[i+1];
if (EvenNum(i))
{ // 保留
if (IsOutInterStuctPair(arInterStructRealIn[i], pNextInter))
continue;
AcGeLineSeg2d roadLine(edge.startPoint(), arInterStructRealIn[i]->InterPoint());
AcGeCircArc2d cirarc;
if (m_pRoad->NeedInterCircle())
{ // 执行倒角
if (InterCircle(arInterStructRealIn[i], roadLine, false, m_pRoad->CirRadius(), cirarc))
{
AddInterCircle(cirarc);
}
}
// 生成道路线,并且修改既有道路线
AddEdge(roadLine);
edge.set(roadLine.endPoint(), edge.endPoint());
// 重新生成这个道路边线
arInterStructRealIn[i]->SetCreateFlag();
}
else
{ // 删除
if (IsOutInterStuctPair(arInterStructRealIn[i], pPrevInter))
continue;
AcGeLineSeg2d roadLine(arInterStructRealIn[i]->InterPoint(), ptNext);
AcGeCircArc2d cirarc;
if (m_pRoad->NeedInterCircle())
{ // 执行倒角,这里只执行同半径倒角,因为是路中的交点
if (InterCircle(arInterStructRealIn[i], roadLine, true, m_pRoad->CirRadius(), cirarc))
{
AddInterCircle(cirarc);
}
}
// 修改既有道路线,但不生成
edge.set(roadLine.startPoint(), edge.endPoint());
// 重新生成这个道路边线
arInterStructRealIn[i]->SetCreateFlag();
}
}
}
// 生成直线道路拐角
// bIsLeft:是否左边路边, bIsStart:是否起始端
void CLineRoadEdgeCreater::MakeACorner(bool bIsLeft, bool bIsStart)
{
MakeACornerTem(bIsLeft, bIsStart, m_leftedge, m_rightEdge, m_midEdge, this);
}
// 添加道路边线
void CLineRoadEdgeCreater::AddEdge(AcGeLineSeg2d &lineSeg)
{
m_edgeAry.append(lineSeg);
}
void CLineRoadEdgeCreater::DrawRoadEdge()
{
m_edgeAry.append(m_leftedge);
m_edgeAry.append(m_rightEdge);
for (int i = 0; i < (int)m_edgeAry.length(); i++)
{
const AcGeLineSeg2d &lineseg = m_edgeAry[i];
AcDbLine *pLine = GeLineToDbLineSys(lineseg);
SetLayer(pLine, eRoadEdgeType);
RoolBackAddNewData(pLine);
}
}
void CLineRoadEdgeCreater::DrawMid()
{
if (m_pRoad->IsDrawMid())
{
AcDbLine *pLine = GeLineToDbLineSys(m_midEdge);
SetLayer(pLine, eRoadMidType);
RoolBackAddNewData(pLine);
}
}
//////////////////////////////////////////////////////////////////////////
// arc Road
CArcRoadEdgeCreater::CArcRoadEdgeCreater(const CRoad *pRoad,
AcAryInterStructPointer &leftInterStruct, AcAryInterStructPointer &rightInterStruct,
AcAryInterStructPointer &leftInterStructin, AcAryInterStructPointer &rightInterStructin,
AcAryInterStructPointer &leftInterStructMid, AcAryInterStructPointer &rightInterStructMid,
CFilterMode &leftFilterMode, CFilterMode &rightFiltMode)
:CRoadEdgeCreater(pRoad, leftInterStruct, rightInterStruct, leftInterStructin, rightInterStructin, leftInterStructMid, rightInterStructMid, leftFilterMode, rightFiltMode)
{
CArcRoad *pArcRoad = (CArcRoad*)pRoad;
m_leftedge = pArcRoad->LeftArc();
m_rightEdge = pArcRoad->RightArc();
m_midEdge = pArcRoad->MidArc();
}
void CArcRoadEdgeCreater::MakeRoad()
{
AcAryInterStructPointer aryInterStructRealIn;
// GetLeft
if (GetInterStructRealIn(m_arleftInterStructIn, m_filterModeLeft, aryInterStructRealIn) > 0)
MakeRoadIn(aryInterStructRealIn, m_leftedge);
// GetRight
if (GetInterStructRealIn(m_arrightInterStructIn, m_filterModeRight, aryInterStructRealIn) > 0)
MakeRoadIn(aryInterStructRealIn, m_rightEdge);
DrawRoadEdge();
DrawInterCircle();
DrawInterStruct();
DrawMid();
}
void CArcRoadEdgeCreater::MakeCorner()
{
FilterMidRoad();
MakeACorner(true, true); // 左边,起点
MakeACorner(true, false); // 左边,终点
MakeACorner(false, true); // 右边,起点
MakeACorner(false, false) ;// 右边,终点
}
// 处理对应的道路拐角
void CArcRoadEdgeCreater::MakeACorner(bool bIsLeft, bool bIsStart)
{
MakeACornerTem(bIsLeft, bIsStart, m_leftedge, m_rightEdge, m_midEdge, this);
}
// 生成道路边线(内部的)
void CArcRoadEdgeCreater::MakeRoadIn(AcAryInterStructPointer &arInterStructRealIn, AcGeCircArc2d& edge)
{
for (int i = 0; i < (int)arInterStructRealIn.length(); i++)
{
AcGePoint2d ptPrev, ptNext, ptCurr; // ptPrev用来处理interStruct之前的路段,ptNext用来处理interStruct之后的路段
ptCurr = arInterStructRealIn[i]->InterPoint();
if (i == 0)
ptPrev = edge.startPoint();
else
ptPrev = arInterStructRealIn[i-1]->InterPoint();
if (i == (int)arInterStructRealIn.length() - 1)
ptNext = edge.endPoint();
else
ptNext = arInterStructRealIn[i+1]->InterPoint();
CInterStruct *pNextInter = NULL, *pPrevInter = NULL;
if (i > 0) pPrevInter = arInterStructRealIn[i - 1];
if (i < (int)arInterStructRealIn.length() - 1) pNextInter = arInterStructRealIn[i+1];
if (EvenNum(i))
{ // 保留
if (IsOutInterStuctPair(arInterStructRealIn[i], pNextInter))
continue;
AcGeCircArc2d roadPrev = ConNewArc(edge, edge.startPoint(), ptCurr);
AcGeCircArc2d cirarc;
if (m_pRoad->NeedInterCircle())
{ // 执行倒角
if (InterCircle(arInterStructRealIn[i], roadPrev, false, m_pRoad->CirRadius(), cirarc))
{
AddInterCircle(cirarc);
}
}
// 生成道路线,并且修改既有道路线
AddEdge(roadPrev);
// edge.set(roadLine.endPoint(), edge.endPoint());
edge = ConNewArc(edge, ptCurr, edge.endPoint());
// 重新生成这个道路边线
arInterStructRealIn[i]->SetCreateFlag();
}
else
{ // 删除
if (IsOutInterStuctPair(arInterStructRealIn[i], pPrevInter))
continue;
AcGeCircArc2d roadNext = ConNewArc(edge, ptCurr, ptNext);
AcGeCircArc2d cirarc;
if (m_pRoad->NeedInterCircle())
{ // 执行倒角
if (InterCircle(arInterStructRealIn[i], roadNext, true, m_pRoad->CirRadius(), cirarc))
{
AddInterCircle(cirarc);
}
}
// 修改既有道路线,但不生成,下一个循环的时候,生成道路边线
// edge.set(roadLine.endPoint(), edge.endPoint());
edge = ConNewArc(edge, roadNext.startPoint(), edge.endPoint());
// 重新生成这个道路边线
arInterStructRealIn[i]->SetCreateFlag();
}
}
}
// 添加道路边线
void CArcRoadEdgeCreater::AddEdge(AcGeCircArc2d &arc)
{
m_edgeAry.append(arc);
}
void CArcRoadEdgeCreater::DrawRoadEdge()
{
m_edgeAry.append(m_leftedge);
m_edgeAry.append(m_rightEdge);
for (int i = 0; i < (int)m_edgeAry.length(); i++)
{
const AcGeCircArc2d &arc = m_edgeAry[i];
AcDbArc *pArc = new AcDbArc();
GeArcToDbSys(arc, *pArc);
SetLayer(pArc, eRoadEdgeType);
RoolBackAddNewData(pArc);
}
}
void CArcRoadEdgeCreater::DrawMid()
{
if (IsDrawMid())
{
AcDbArc *pArc = new AcDbArc();
GeArcToDbSys(m_midEdge, *pArc);
SetLayer(pArc, eRoadMidType);
RoolBackAddNewData(pArc);
}
}