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

1005 lines
29 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 "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);
}
}