#include "stdafx.h" #include "RoadDataCenterNew.h" #include "RoadFillterMgr.h" CRoadFillterMgr::CRoadFillterMgr(void) { } CRoadFillterMgr::~CRoadFillterMgr(void) { ReleaseMem(); } CString CRoadFillterMgr::PromptRadiusString(double dRadiusSys) { CString sRadius; if (g_bMeterUnitDraw) { sRadius.Format(_T("%.3f"), dRadiusSys); } else { sRadius.Format(_T("%d"), (int)dRadiusSys); } return sRadius; } CString CRoadFillterMgr::PromptSelectString(BOOL bSameCenter, double dRadiusMM) { //请框选要倒角的道路线或[同半径倒角(Q),当前:同圆心/倒角半径(R),当前:5000]<退出>: double dRadiusSys = _AS_SYS_UNIT(dRadiusMM); CString sRadius = PromptRadiusString(dRadiusSys); CString sPrompt; if (bSameCenter) { sPrompt.Format(_T("\n请框选要倒角的道路线或[同半径倒角(Q),当前:同圆心/倒角半径(R),当前:%s]<退出>:"), sRadius); } else { sPrompt.Format(_T("\n请框选要倒角的道路线或[同圆心倒角(Q),当前:同半径/倒角半径(R),当前:%s]<退出>:"), sRadius); } return sPrompt; } #define AddRoadData(id, arEnt, arEntAdatper, TCAdEntType, TCADEntAdapterType)\ {\ TCAdEntType *_pEnt = new TCAdEntType(id);\ arEnt.append(_pEnt);\ arEntAdatper.append(new TCADEntAdapterType(_pEnt));\ } // do Select,get data from CAD,把他们处理出适配器类型 BOOL CRoadFillterMgr::SelectRoad() { static double dRadiusMM = 5000.0; static BOOL bSameCenter = TRUE; CString sKeyFilType = _T("Q"); CString sKeyFilRadius = _T("R"); CString sKeyAll = _T("Q R"); CString strRoadLay = LAY_ROAD; CString strMidRoadLay = LAY_ROADDOTE; do { g_ssPickFirst.Free(); TCHAR chRet; TPickEntSet ssRes(SS_FREE); // TRBList rbList(RTDXF0, _T("LINE,ARC"), 8, _T("ROAD,ROAD_DOTE"), NULL); TRBList rbList(RTDXF0, _T("LINE,ARC"), 8, XString(_T("%s,%s"), LAY_ROAD, LAY_ROADDOTE), NULL); int nRet = SelectEntitiesOnce(PromptSelectString(bSameCenter, dRadiusMM), ssRes, rbList, (LPCTSTR)sKeyAll, chRet); switch (nRet) { case RTNORM: { for(long i=0; i < ssRes.Length(); i++) { Entity ent=ssRes[i]; OPENOBJ_BEGIN(ent, AcDb::kForWrite,AcDbEntity,pEnt); TCHAR* lay = pEnt->layer(); if (strRoadLay.CompareNoCase(pEnt->layer()) == 0) { // 道路图层, if (pEnt->isKindOf(AcDbLine::desc())) { // line型 pEnt->close(); AddRoadData(pEnt->id(), m_arEdgeLine, m_arEdgeLineAdapter, CLineCADEnt, CLineCADEntFilRoadAdapter); } else if (pEnt->isKindOf(AcDbArc::desc())) {// arc型 pEnt->close(); AddRoadData(pEnt->id(), m_arEdgeArc, m_arEdgeArcAdapter, CArcCADEnt, CArcCADEntFilRoadAdapter); } } else if (strMidRoadLay.CompareNoCase(pEnt->layer()) == 0) { // 中线图层 if (pEnt->isKindOf(AcDbLine::desc())) { pEnt->close(); AddRoadData(pEnt->id(), m_arMidLine, m_arMidLineAdapter, CLineCADEnt, CLineCADEntFilRoadAdapter); } else if (pEnt->isKindOf(AcDbArc::desc())) { pEnt->close(); AddRoadData(pEnt->id(), m_arMidArc, m_arMidArcAdapter, CArcCADEnt, CArcCADEntFilRoadAdapter); } } OPENOBJ_END(); } m_dRadius = dRadiusMM; m_bSameCenter = bSameCenter; return TRUE; } break; case RTKWORD: if (sKeyFilType.CompareNoCase(CString(chRet)) == 0) { // 切换选择模式 bSameCenter = !bSameCenter; } else if (sKeyFilRadius.CompareNoCase(CString(chRet)) == 0) { ads_real dreal; CString sPrompt; sPrompt.Format(_T("\n请输入倒角半径 <%s>: "), PromptRadiusString(_AS_SYS_UNIT(dRadiusMM))); int nrealGet = ads_getreal(sPrompt, &dreal); if (nrealGet == RTNORM) { dRadiusMM = _AS_MM(dreal); } else { if (nrealGet != RTNONE) return FALSE; } } else // 其他关键字,不可能。 { return FALSE; } //ASSERT(0); m_dRadius = dRadiusMM; m_bSameCenter = bSameCenter; break; default: return FALSE; break; } } while (true); return FALSE; } void CRoadFillterMgr::MakeFilroadConnect (ArLineFilroadAdapterPointer &arLineAdatper, ArArcFilroadAdapterPointer &arArcAdapter, ArFilroadConnectPointer &arConnect) { int i = 0, j = 0, iArLen1 = 0, iArLen2 = 0; ArFilroadConnectPointer arConnectDump; // 遍历直线Adapter for (i = 0, iArLen1 = (int)arLineAdatper.length(); i < iArLen1; i++) { if (arLineAdatper[i]->IsLinkOver()) continue; // 直线Adapter自身遍历 for (j = i + 1; j < iArLen1; j++) { if (arLineAdatper[j]->IsLinkOver()) continue; if (CFilroadConnect::CreateConnect(arLineAdatper[i], arLineAdatper[j], arConnectDump)) arConnect.append(arConnectDump); } // 遍历ArcAdapter for (j = 0, iArLen2 = (int)arArcAdapter.length(); j < iArLen2; j++) { if (arArcAdapter[j]->IsLinkOver()) continue; if (CFilroadConnect::CreateConnect(arLineAdatper[i], arArcAdapter[j], arConnectDump)) arConnect.append(arConnectDump); } } // ArcAdapter自身遍历 for (i = 0, iArLen1 = (int)arArcAdapter.length(); i < iArLen1; i++) { if (arArcAdapter[i]->IsLinkOver()) continue; for (j = i + 1; j < iArLen1; j++) { if (arArcAdapter[j]->IsLinkOver()) continue; if(CFilroadConnect::CreateConnect(arArcAdapter[i], arArcAdapter[j], arConnectDump)) arConnect.append(arConnectDump); } } } void CRoadFillterMgr::IdentifyOldFilterConnect(ArLineFilroadAdapterPointer &arLineAdatper, ArArcFilroadAdapterPointer &arArcAdapter, ArFilroadConnectPointer &arConnect) { // 遍历圆弧,查找两端都有相切连接的,把这三段设置为连接标记 int i = 0, j = 0, iArLen1 = 0, iArLen2 = 0; ArFilroadConnectPointer arConnectDump; // 遍历圆弧,查找两段都具有相切连接关系的情形 for (i = 0, iArLen1 = (int)arArcAdapter.length(); i < iArLen1; i++) { if (arArcAdapter[i]->IsLinkOver()) continue; // 跟圆弧相切的边线是起点重合,还是终点重合.. bool bStartLink1 = true, bStartLink2 = true; // 1跟圆弧起点相连,2跟圆弧终点相连 CCADEntFilRoadAdatper *pAdapter1 = NULL, *pAdapter2 = NULL; AcGePoint2d ptStart = arArcAdapter[i]->CurrSeg().startPoint(); AcGePoint2d ptEnd = arArcAdapter[i]->CurrSeg().endPoint(); AcGePoint2d ptCen = arArcAdapter[i]->CurrSeg().center(); AcGeVector2d vecStart = ptCen - ptStart; AcGeVector2d vecEnd = ptCen - ptEnd; double dVecStartLen = vecStart.length(); double dVecEndLen = vecEnd.length(); const double dTol = 1e-6; // 使用内积来判断垂直的时候,一定要考虑向量的模。这样才具有意义 // 遍历arLineAdapter; for (j = 0; j < (int)arLineAdatper.length(); j++) { if (arLineAdatper[j]->IsLinkOver()) continue; double dTempLen = arLineAdatper[j]->CurrSeg().length(); if (pAdapter1 == NULL) { if (ptStart.isEqualTo(arLineAdatper[j]->CurrSeg().startPoint()) && vecStart.dotProduct(arLineAdatper[j]->CurrSeg().direction()) < dTol * dVecStartLen * dTempLen) { // 点重合,并且在该点是相切的 pAdapter1 = arLineAdatper[j]; bStartLink1 = true; // 起点重合 } else if (ptStart.isEqualTo(arLineAdatper[j]->CurrSeg().endPoint()) && vecStart.dotProduct(arLineAdatper[j]->CurrSeg().direction()) < dTol * dVecStartLen * dTempLen) { pAdapter1 = arLineAdatper[j]; bStartLink1 = false; // 终点重合 } } if (pAdapter2 == NULL) { if (ptEnd.isEqualTo(arLineAdatper[j]->CurrSeg().startPoint()) && vecEnd.dotProduct(arLineAdatper[j]->CurrSeg().direction()) < dTol * dVecEndLen * dTempLen) { pAdapter2 = arLineAdatper[j]; bStartLink2 = true; } else if (ptEnd.isEqualTo(arLineAdatper[j]->CurrSeg().endPoint()) && vecEnd.dotProduct(arLineAdatper[j]->CurrSeg().direction()) < dTol * dVecEndLen * dTempLen) { pAdapter2 = arLineAdatper[j]; bStartLink2 = false; // 终点重合 } } if (pAdapter1 != NULL &&pAdapter2 != NULL) break; } // 遍历ArcAdapter AcGeVector2d vecStartPlumb(vecStart.y, -vecStart.x); AcGeVector2d vecEndPlumb(vecEnd.y, -vecEnd.x); for (j = 0, iArLen2 = (int)arArcAdapter.length(); j < iArLen2; j++) { if (pAdapter1 != NULL &&pAdapter2 != NULL) break; if (arArcAdapter[j]->IsLinkOver() || (j == i)) continue; AcGeVector2d vecThisStart = arArcAdapter[j]->CurrSeg().center() - arArcAdapter[j]->CurrSeg().startPoint(); AcGeVector2d vecThisEnd = arArcAdapter[j]->CurrSeg().center() - arArcAdapter[j]->CurrSeg().endPoint(); double dVecThisStartLen = vecThisEnd.length(); double dVecThisEndLen = vecThisEnd.length(); if (pAdapter1 == NULL) { if (ptStart.isEqualTo(arArcAdapter[j]->CurrSeg().startPoint()) && vecStartPlumb.dotProduct(vecThisStart) < dTol * dVecStartLen * dVecThisStartLen) { // 点重合,并且在该点是相切的 pAdapter1 = arArcAdapter[j]; bStartLink1 = true; // 起点重合 } else if (ptStart.isEqualTo(arArcAdapter[j]->CurrSeg().endPoint()) && vecStartPlumb.dotProduct(vecThisEnd) < dTol * dVecStartLen * dVecThisEndLen) { pAdapter1 = arArcAdapter[j]; bStartLink1 = false; // 终点重合 } } if (pAdapter2 == NULL) { if (ptEnd.isEqualTo(arArcAdapter[j]->CurrSeg().startPoint()) && vecEndPlumb.dotProduct(vecThisStart) < dTol * dVecEndLen * dVecThisStartLen) { pAdapter2 = arArcAdapter[j]; bStartLink2 = true; } else if (ptEnd.isEqualTo(arArcAdapter[j]->CurrSeg().endPoint()) && vecEndPlumb.dotProduct(vecThisEnd) < dTol * dVecEndLen * dVecThisEndLen) { pAdapter2 = arArcAdapter[j]; bStartLink2 = false; // 终点重合 } } if (pAdapter1 != NULL &&pAdapter2 != NULL) break; } if (pAdapter1 != NULL && pAdapter2 != NULL) { // 找到了这么两个东西,建立这两个的链接关系 arArcAdapter[i]->SetStartLink(); arArcAdapter[i]->SetEndLink(); // 创建链接 CFilroadConnect *pConnect = NULL; if (pAdapter1->ToLineAdapter() != NULL && pAdapter2->ToLineAdapter() != NULL) { if (CFilroadConnect::CreateConnectFilted(pAdapter1->ToLineAdapter(), bStartLink1, pAdapter2->ToLineAdapter(), bStartLink2, pConnect, arArcAdapter[i])) arConnect.append(pConnect); } else if (pAdapter1->ToLineAdapter() != NULL && pAdapter2->ToArcAdapter() != NULL) { if (CFilroadConnect::CreateConnectFilted(pAdapter1->ToLineAdapter(), bStartLink1, pAdapter2->ToArcAdapter(), bStartLink2, pConnect, arArcAdapter[i])) arConnect.append(pConnect); } else if (pAdapter1->ToArcAdapter() != NULL && pAdapter2->ToLineAdapter() != NULL) { if (CFilroadConnect::CreateConnectFilted(pAdapter2->ToLineAdapter(), bStartLink2, pAdapter1->ToArcAdapter(), bStartLink1, pConnect, arArcAdapter[i])) arConnect.append(pConnect); } else if (pAdapter1->ToArcAdapter() != NULL && pAdapter2->ToArcAdapter() != NULL) { if (CFilroadConnect::CreateConnectFilted(pAdapter1->ToArcAdapter(), bStartLink1, pAdapter2->ToArcAdapter(), bStartLink2, pConnect, arArcAdapter[i])) arConnect.append(pConnect); } } } } // 检测道路的链接关系。 void CRoadFillterMgr::MakeFilroadConnect() { CFilroadConnect::SetInterTol(); // 先识别已经倒角的道路边线,两两成对 IdentifyOldFilterConnect(m_arEdgeLineAdapter, m_arEdgeArcAdapter, m_arFilroadEdgeConnect); IdentifyOldFilterConnect(m_arMidLineAdapter, m_arMidArcAdapter, m_arFilroadMidConnect); // 在识别普通的道路边线,两两成对 MakeFilroadConnect(m_arEdgeLineAdapter, m_arEdgeArcAdapter, m_arFilroadEdgeConnect); MakeFilroadConnect(m_arMidLineAdapter, m_arMidArcAdapter, m_arFilroadMidConnect); } // 根据距离检测分组。 void CRoadFillterMgr::GroupConnect() { ASSERT(m_bSameCenter); CFilroadConnectGroup::SetSameCenterLimit(SameCenterTol()); // 只选了两组连接线,则直接分为一组(分组仅仅考虑了距离) if (m_arFilroadEdgeConnect.length() == 2) { CFilroadConnectGroup *pGroup = new CFilroadConnectGroup(); pGroup->AddConnect(m_arFilroadEdgeConnect[0]); pGroup->AddConnect(m_arFilroadEdgeConnect[1]); m_arFilroadGroup.append(pGroup); } else { // 选择了多个线段,则匹配分组 int i = 0, j = 0; for (i = (int)m_arFilroadEdgeConnect.length() - 1; i > -1; i--) { CFilroadConnect *pConnect = m_arFilroadEdgeConnect[i]; CFilroadConnectGroup *pGroup = NULL; for ( j = (int)m_arFilroadGroup.length() - 1; j > -1; j--) { if (m_arFilroadGroup[j]->CheckAConnect(pConnect)) { if (pGroup != NULL) { pGroup->AddGroup(*(m_arFilroadGroup[j])); m_arFilroadGroup.removeAt(j); } else { pGroup = m_arFilroadGroup[j]; } pGroup->AddConnect(pConnect); } } if (pGroup == NULL) m_arFilroadGroup.append(new CFilroadConnectGroup(pConnect, FALSE)); } } // 处理中线: for (int i = (int)m_arFilroadMidConnect.length() - 1; i > -1; i--) { CFilroadConnect *pConnectMid = m_arFilroadMidConnect[i]; for (int j = (int)m_arFilroadGroup.length() - 1; j > -1; j--) { // 当然,只有道路拐角处的中线才会被添加进来。 if (m_arFilroadGroup[j]->CheckInsideMidConnect(pConnectMid)) { m_arFilroadGroup[j]->AddMidConnect(pConnectMid); break; } } if (j == -1) m_arFilroadGroupMid.append(new CFilroadConnectGroup(pConnectMid, TRUE)); } } BOOL CRoadFillterMgr::FilltRoad() { BOOL bRet = TRUE; if (m_bSameCenter) { // 同圆心 AcAryCircArc2d arEdgeArcDump, arMidArcDump; // ArFilroadGroupPointer arGroupDump; arGroupDump.append(m_arFilroadGroupMid); arGroupDump.append(m_arFilroadGroup); for (int i = 0; i < (int)arGroupDump.length(); i++) { ClearAcaryAll(arEdgeArcDump); ClearAcaryAll(arMidArcDump); if (!arGroupDump[i]->Draw(m_dRadius, arEdgeArcDump, arMidArcDump)) bRet = FALSE; m_arEdgeInterCircle.append(arEdgeArcDump); m_arMidInterCircle.append(arMidArcDump); } } else { // 同半径 AcGeCircArc2d arcEdge, arcMid; ArFilroadConnectPointer arConnectDump; for (int i = 0; i < (int)m_arFilroadEdgeConnect.length(); i++) { if (m_arFilroadEdgeConnect[i]->Filroad(m_dRadius, arcEdge)) m_arEdgeInterCircle.append(arcEdge); else bRet = FALSE; } for (i = 0; i < (int)m_arFilroadMidConnect.length(); i++) { if (m_arFilroadMidConnect[i]->Filroad(m_dRadius, arcMid)) m_arMidInterCircle.append(arcMid); else bRet = FALSE; } } return bRet; } void CRoadFillterMgr::Draw() { // 重现绘制原来的线 int index = 0, iLen = 0; for (index = 0, iLen = (int)m_arEdgeLineAdapter.length(); index < iLen; index++) { m_arEdgeLineAdapter[index]->Redraw(eRoadEdgeType); } for (index = 0, iLen = (int)m_arEdgeArcAdapter.length(); index < iLen; index++) { m_arEdgeArcAdapter[index]->Redraw(eRoadEdgeType); } for (index = 0, iLen = (int)m_arMidLineAdapter.length(); index < iLen; index++) { m_arMidLineAdapter[index]->Redraw(eRoadMidType); } for (index = 0, iLen = (int)m_arMidArcAdapter.length(); index < iLen; index++) { m_arMidArcAdapter[index]->Redraw(eRoadMidType); } // 绘制新添加的倒角线 for (index = 0, iLen = (int)m_arEdgeInterCircle.length(); index < iLen; index++) { AcDbArc *pArc = new AcDbArc; GeArcToDbSys(m_arEdgeInterCircle[index], *pArc); SetLayer(pArc, eRoadEdgeType); AddToModelSpace(pArc); } for (index = 0, iLen = (int)m_arMidInterCircle.length(); index < iLen; index++) { AcDbArc *pArc = new AcDbArc; GeArcToDbSys(m_arMidInterCircle[index], *pArc); SetLayer(pArc, eRoadMidType); AddToModelSpace(pArc); } } void CRoadFillterMgr::ReleaseMem() { ClearAndDeleteAry(m_arEdgeLine); ClearAndDeleteAry(m_arEdgeArc); ClearAndDeleteAry(m_arMidLine); ClearAndDeleteAry(m_arMidArc); ClearAndDeleteAry(m_arEdgeLineAdapter); ClearAndDeleteAry(m_arEdgeArcAdapter); ClearAndDeleteAry(m_arMidLineAdapter); ClearAndDeleteAry(m_arMidArcAdapter); ClearAndDeleteAry(m_arFilroadEdgeConnect); ClearAndDeleteAry(m_arFilroadMidConnect); ClearAndDeleteAry(m_arFilroadGroup); ClearAndDeleteAry(m_arFilroadGroupMid); ClearAcaryAll(m_arEdgeInterCircle); ClearAcaryAll(m_arMidInterCircle); }