#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 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); } }