1005 lines
29 KiB
C++
1005 lines
29 KiB
C++
#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);
|
||
}
|
||
}
|
||
|