#include "stdafx.h" #include "commonRoad.h" //#include #include "TDbObjectPointer.h" #include "RoadDataCenterNew.h" void CRoadDataCenterNew::SelectEntInCAD(const AcGePoint2d &ptLeftDown, const AcGePoint2d &ptRightUp, AcAryLineEntEdgeAdapterPtr &lineEdges, AcAryArcEntEdgeAdapterPtr &arcEdges, AcAryLineEntEdgeAdapterPtr &lineMids, AcAryArcEntEdgeAdapterPtr &arcMids) { //add tyj 20161020:解决在UCS坐标系下,道路无法正常倒角 /*-----------------begin-------------------*/ TADSGePoint3d ptSave1(ptLeftDown.x, ptLeftDown.y, 0.0); TADSGePoint3d ptSave2(ptRightUp.x, ptRightUp.y, 0.0); ptSave1 = Wcs2Ucs(ptSave1); ptSave2 = Wcs2Ucs(ptSave2); ads_point pt1 = {ptSave1.x, ptSave1.y, 0.0}; ads_point pt2 = {ptSave2.x, ptSave2.y, 0.0}; //ads_point pt1 = {ptLeftDown.x, ptLeftDown.y, 0.0}; //ads_point pt2 = {ptRightUp.x, ptRightUp.y, 0.0}; /*------------------end--------------------*/ CString strRoadLay = LAY_ROAD; CString strMidRoadLay = LAY_ROADDOTE; ads_name ssName; // 差选! acedSSGet(_T("C"), pt1, pt2, NULL, ssName); Adesk::Int32 len = 0; acedSSLength(ssName, &len); ads_name ent; AcDbObjectId id; for (long i = 0; i < len; i++) { if (acedSSName(ssName, i, ent) == RTNORM) if (acdbGetObjectId(id, ent) == Acad::eOk) { AcDbObjectPointer pEnt; if (pEnt.open(id, AcDb::kForRead) == Acad::eOk) { TCHAR* lay = pEnt->layer(); if (strRoadLay.CompareNoCase(pEnt->layer()) == 0) { if (pEnt->isKindOf(AcDbLine::desc())) { pEnt.close(); // CLineCADEntEdgeAdapter line(id); lineEdges.append(new CLineCADEntEdgeAdapter(id)); } else if (pEnt->isKindOf(AcDbArc::desc())) { pEnt.close(); // CArcCADEntEdgeAdapter arc(id); arcEdges.append(new CArcCADEntEdgeAdapter(id)); } } else if (strMidRoadLay.CompareNoCase(pEnt->layer()) == 0) { if (pEnt->isKindOf(AcDbLine::desc())) { pEnt.close(); // CLineCADEntEdgeAdapter line(id); lineMids.append(new CLineCADEntEdgeAdapter(id)); } else if (pEnt->isKindOf(AcDbArc::desc())) { pEnt.close(); // CArcCADEntEdgeAdapter arc(id); arcMids.append(new CArcCADEntEdgeAdapter(id)); } } } } } ads_ssfree(ssName); } template void EdgeSplitFunTem(const TRoad &road, ROAD_EDGE_STRUCT &res, const TEdge &edge, TEdgeEnt &edgeEnt) { AcAryInterStructPointer arLeftInterDump, arRightInterDump, arIntersAll; road.SplitEdge(edge, arLeftInterDump, arRightInterDump, edgeEnt, arIntersAll); res.leftIntersAll.append(arLeftInterDump); res.rightIntersAll.append(arRightInterDump); res.intersOriginAll.append(arIntersAll); } // #define MidSplitFunTem(road, leftInters, rightInters, edge, edgeEnt, ArType)\ // {\ // ArType arLeftInterDump, arRightInterDump; \ // road.SplitMid(edge, arLeftInterDump, arRightInterDump, edgeEnt); \ // leftInters.append(arLeftInterDump); \ // rightInters.append(arRightInterDump); \ // } template void MidSplitFunTem(const TRoad &road, ROAD_MID_STRUCT &rms, const TEdge &edge, TEdgeEnt &edgeEnt) { AcAryInterStructPointer arLeftInterDump, arRightInterDump; road.SplitMid(edge, arLeftInterDump, arRightInterDump, edgeEnt); rms.leftInterMid.append(arLeftInterDump); rms.rightInterMid.append(arRightInterDump); } //把单线实体处理为道路左边的(interStruct),和道路右边的interStruct, void CRoadDataCenterNew::DealLeftAndRightEnt(const CLineRoad &lineRoad, ROAD_MID_STRUCT &rms, ROAD_EDGE_STRUCT &res) { int i = 0; for (i = 0; i < (int)res.lineEdges.length(); i++) { AcGeLineSeg2d line = res.lineEdges[i]->Line();// EdgeSplitFunTem(lineRoad, res, line, *res.lineEdges[i]); } for (i = 0; i < (int)res.arcEdges.length(); i++) { AcGeCircArc2d arc = res.arcEdges[i]->Arc(); EdgeSplitFunTem(lineRoad, res, arc, *res.arcEdges[i]); } for (i = 0; i < (int)rms.lineMids.length(); i++) { AcGeLineSeg2d line = rms.lineMids[i]->Line(); MidSplitFunTem(lineRoad, rms, line, *rms.lineMids[i]); } for (i = 0; i < (int)rms.arcMids.length(); i++) { AcGeCircArc2d arc = rms.arcMids[i]->Arc(); MidSplitFunTem(lineRoad, rms, arc, *rms.arcMids[i]); } SaveMidInterStruct(rms); } //把单线实体处理为道路左边的(interStruct),和道路右边的interStruct, void CRoadDataCenterNew::DealLeftAndRightEnt(const CArcRoad &arcRoad, ROAD_MID_STRUCT &rms, ROAD_EDGE_STRUCT &res) { int i = 0; for (i = 0; i < (int)res.lineEdges.length(); i++) { AcGeLineSeg2d line = res.lineEdges[i]->Line();// EdgeSplitFunTem(arcRoad, res, line, *res.lineEdges[i]); } for (i = 0; i < (int)res.arcEdges.length(); i++) { AcGeCircArc2d arc = res.arcEdges[i]->Arc(); EdgeSplitFunTem(arcRoad, res, arc, *res.arcEdges[i]); } for ( i = 0; i < (int)rms.lineMids.length(); i++) { AcGeLineSeg2d line = rms.lineMids[i]->Line(); MidSplitFunTem(arcRoad, rms, line, *rms.lineMids[i]); } for (i = 0; i < (int)rms.arcMids.length(); i++) { AcGeCircArc2d arc = rms.arcMids[i]->Arc(); MidSplitFunTem(arcRoad, rms, arc, *rms.arcMids[i]); } SaveMidInterStruct(rms); } struct __InterSortStruct { CInterStruct* pInter; double dLen;// 带方向的长度 }; int CompareLineSortStruct(const void *p1, const void *p2) { const __InterSortStruct *ps1 = (__InterSortStruct*)(p1); const __InterSortStruct *ps2 = (__InterSortStruct*)(p2); ASSERT(ps1 != NULL); ASSERT(ps2 != NULL); // 不设置0返回。 return ps1->dLen < ps2->dLen ? -1 : 1; } // 对道路的相交结构体排序(包括的可能有直线的,弧线的) // 问题描述,这些点分布在道路上边线上,根据道路的方向对这些点,执行排序。 void CRoadDataCenterNew::SortInterStructsSimp(const AcGeLineSeg2d &lineDir, bool bSequence, AcAryInterStructPointer &arInterPointer) { ASSERT(bSequence == true); if (arInterPointer.length() < 2) return; // 只有一个也不排序 AcGePoint2d ptStart = lineDir.startPoint(); AcGeVector2d vecDir = lineDir.direction(); __InterSortStruct *pSortStruct = new __InterSortStruct[arInterPointer.length()]; int i; for (i = 0;i < (int)arInterPointer.length(); i++) { AcGeVector2d vecDump = arInterPointer[i]->InterPoint() - ptStart; pSortStruct[i].pInter = arInterPointer[i]; pSortStruct[i].dLen = vecDump.dotProduct(vecDir); } qsort(pSortStruct, (int)arInterPointer.length(), sizeof(__InterSortStruct), CompareLineSortStruct); for (i = 0; i < (int)arInterPointer.length(); i++) { arInterPointer[i] = pSortStruct[i].pInter; } delete [] pSortStruct; } // 方法: // 想象圆弧是一个两端有限延伸的曲线,该排序建立在这个曲线上。从起点到终点。 void CRoadDataCenterNew::SortInterStructsSimp(const AcGeCircArc2d &arcDir, bool bSequence, AcAryInterStructPointer &arInterPointer) { ASSERT(bSequence == true); if (arInterPointer.length() < 2) return; AcGePoint2d ptStart = arcDir.startPoint(); AcGePoint2d ptEnd = arcDir.endPoint(); AcGePoint2d ptCenter = arcDir.center(); double dStartAngle = AcGeVector2d(ptStart - ptCenter).angle(); double dEndAngle = AcGeVector2d(ptEnd - ptCenter).angle(); double dArcAngle = AngleInClock(arcDir.isClockWise() == Adesk::kTrue, dStartAngle, dEndAngle); // 计算每个点与这个角度的夹角 double dAccurateStartAngle = AntiAngle(AddAngleInClock(arcDir.isClockWise() == Adesk::kTrue, dStartAngle, dArcAngle*0.5)); __InterSortStruct *pSortStruct = new __InterSortStruct[arInterPointer.length()]; int i; for (i = 0; i < (int)arInterPointer.length(); i++) { AcGeVector2d vecDump = arInterPointer[i]->InterPoint() - ptCenter; pSortStruct[i].pInter = arInterPointer[i]; pSortStruct[i].dLen = AngleInClock(arcDir.isClockWise() == Adesk::kTrue, dAccurateStartAngle, vecDump.angle()); } qsort(pSortStruct, (int)arInterPointer.length(), sizeof(__InterSortStruct), CompareLineSortStruct); for (i = 0; i < (int)arInterPointer.length(); i++) { arInterPointer[i] = pSortStruct[i].pInter; } delete [] pSortStruct; } bool GetInIndex(const AcAryInterStructPointer &aryInterPointer, int &nFirstIn, int &nLastIn) { nFirstIn = -1; nLastIn = -1; for (int i = 0; i < (int)aryInterPointer.length(); i++) { if (aryInterPointer[i]->Position() == eInEdge) { if (nFirstIn == -1) nFirstIn = i; nLastIn = i; } } return nFirstIn != -1 && nLastIn != -1; } // 判断道路的过滤方式,目前的方式有:保留第一个,不保留第一个(间隔取路),可能还会增加其他的过滤方式。 CFilterMode CRoadDataCenterNew::FindFilterMode(const AcGeLineSeg2d &lineDir, bool bSequence, const AcAryInterStructPointer &aryInterPointer) { ASSERT(bSequence == true); CFilterMode filterMode; //此处aryInterPointer是经过排序的。 // 去总长度,然后计算平均长度 double dFirsrtLen = 0.0, dSecondLen = 0.0; int nFirstNum = 0, nSecondNum = 0; int nFirstIn = -1, nLastIn = -1; GetInIndex(aryInterPointer, nFirstIn, nLastIn); if (nFirstIn == -1 && nLastIn == -1) filterMode.KeepFirst(TRUE);// 留下这段 else if (nFirstIn == nLastIn) { // 只有一个线在里边,比较两侧那边更长 AcGePoint2d ptCurrent = aryInterPointer[nFirstIn]->InterPoint(); filterMode.KeepFirst(lineDir.startPoint().distanceTo(ptCurrent) > lineDir.endPoint().distanceTo(ptCurrent)); } else { // 有多个内点: for (int i = nFirstIn; i <= nLastIn; i++) { if (i == nFirstIn) { nFirstNum = 1; dFirsrtLen += lineDir.startPoint().distanceTo(aryInterPointer[i]->InterPoint()); continue; } else { if (EvenNum(nFirstNum+nSecondNum)) { nFirstNum += 1; dFirsrtLen += aryInterPointer[i-1]->InterPoint().distanceTo(aryInterPointer[i]->InterPoint()); } else { nSecondNum += 1; dSecondLen += aryInterPointer[i-1]->InterPoint().distanceTo(aryInterPointer[i]->InterPoint()); } } if (i == nLastIn) { if (EvenNum(nFirstNum+nSecondNum)) { nFirstNum += 1; dFirsrtLen += aryInterPointer[i]->InterPoint().distanceTo(lineDir.endPoint()); } else { nSecondNum += 1; dSecondLen += aryInterPointer[i]->InterPoint().distanceTo(lineDir.endPoint()); } } } filterMode.KeepFirst(dFirsrtLen/nFirstNum > dSecondLen/nSecondNum); } return filterMode; } CFilterMode CRoadDataCenterNew::FindFilterMode(const AcGeCircArc2d &arcDir, bool bSequence, const AcAryInterStructPointer &aryInterPointer) { #define INTERPOINT(n) (aryInterPointer[n]->InterPoint()) ASSERT(bSequence == true); CFilterMode filterMode; //此处aryInterPointer是经过排序的。 // 取总长度,然后计算平均长度,比较大小。长的保留 double dFirsrtLen = 0.0, dSecondLen = 0.0; int nFirstNum = 0, nSecondNum = 0; int nFirstIn = -1, nLastIn = -1; GetInIndex(aryInterPointer, nFirstIn, nLastIn); if (nFirstIn == -1 && nLastIn == -1) filterMode.KeepFirst(TRUE);// 留下这段 else if (nFirstIn == nLastIn) { // 只有一个线在里边,比较两侧那边更长 AcGePoint2d ptCurrent = INTERPOINT(nFirstIn); filterMode.KeepFirst(LenOfArc(ConNewArc(arcDir, arcDir.startPoint(), ptCurrent)) > LenOfArc(ConNewArc(arcDir, ptCurrent, arcDir.endPoint()))); } else { // 有多个内点: for (int i = nFirstIn; i <= nLastIn; i++) { if (i == nFirstIn) { nFirstNum = 1; dFirsrtLen += LenOfArc(ConNewArc(arcDir, arcDir.startPoint(), INTERPOINT(i))); continue; } else { if (EvenNum(nFirstNum+nSecondNum)) { nFirstNum += 1; dFirsrtLen += LenOfArc(ConNewArc(arcDir, INTERPOINT(i-1), INTERPOINT(i))); } else { nSecondNum += 1; dSecondLen += LenOfArc(ConNewArc(arcDir, INTERPOINT(i-1), INTERPOINT(i))); } } if (i == nLastIn) { if (EvenNum(nFirstNum+nSecondNum)) { nFirstNum += 1; dFirsrtLen += LenOfArc(ConNewArc(arcDir, INTERPOINT(i), arcDir.endPoint())); } else { nSecondNum += 1; dSecondLen += LenOfArc(ConNewArc(arcDir, INTERPOINT(i), arcDir.endPoint())); } } } filterMode.KeepFirst(dFirsrtLen/nFirstNum > dSecondLen/nSecondNum); } #undef INTERPOINT return filterMode; } int CRoadDataCenterNew::InterStuctRealIn(const AcAryInterStructPointer &aryAll, AcAryInterStructPointer &aryRealIn) { for (int i = 0; i < (int)aryAll.length(); i++) { if (aryAll[i]->IsInEdge() && (aryAll[i]->Position() == eInEdge) && (!aryAll[i]->IsPara())) aryRealIn.append(aryAll[i]); } return (int)aryRealIn.length(); } // 把相交结构体合并了。 void CRoadDataCenterNew::CombinInterStruct(const AcAryLineInterStruct &lineInters, const AcAryArcInterStruct &arcInters, AcAryInterStructPointer &arInterPointer) { ASSERT(arInterPointer.isEmpty()); int i = 0; for (i = 0; i < (int)lineInters.length(); i++) { const CLineInterStruct *pLineInter = lineInters[i]; arInterPointer.append(const_cast(pLineInter)); } for (i = 0; i < (int)arcInters.length(); i++) { const CArcInterStruct *pArcInter = arcInters[i]; arInterPointer.append(const_cast(pArcInter)); } } void CRoadDataCenterNew::RemoveShortInterStruct(AcAryInterStructPointer &aryInterStruct, double dTolLen) { for (int i = (int)aryInterStruct.length() - 1; i > -1; i--) { if (aryInterStruct[i]->Lenth() < dTolLen) { // delete aryInterStruct[i]; aryInterStruct[i]->SetCreateFlag(); // 因为他删除了,所以其他没有删除的需要创建。 aryInterStruct[i]->SetShortFlag(true); aryInterStruct.removeAt(i); } } } void CRoadDataCenterNew::RemoveShortInterStruct(ROAD_EDGE_STRUCT &res, double dTolLen) { RemoveShortInterStruct(res.leftIntersAll, dTolLen); RemoveShortInterStruct(res.rightIntersAll, dTolLen); } void CRoadDataCenterNew::ReTestInterStruct(AcAryInterStructPointer &aryInterStruct, TGGeCurveSegment &curveSeg, double dTolLen, bool bOldClock) { // 判断两端的,从前往后判断 int i=0; for (i = 0; i < (int)aryInterStruct.length(); ++i) { if (aryInterStruct[i]->Position() == eInEdge) { // 在道路内 double dDist = curveSeg.PathDistance(aryInterStruct[i]->InterPoint(), bOldClock ? 0 : 1); if (dDist < dTolLen) aryInterStruct[i]->SetPostion(eRoadStartOut); else break; } } for (i = (aryInterStruct.length() - 1); i > -1; --i) { if (aryInterStruct[i]->Position() == eInEdge) { // 在道路内 double dDist = curveSeg.PathDistance(aryInterStruct[i]->InterPoint(), bOldClock ? 1 : 0); if (dDist < dTolLen) aryInterStruct[i]->SetPostion(eRoadEndOut); else break; } } } void CRoadDataCenterNew::ReTestInterStruct(ROAD_EDGE_STRUCT &res, const CRoad *pRoad, double dTolLen, bool bOldClock) { TGGeCurveSegment c1(pRoad->ToCurveSeg(1)), c2(pRoad->ToCurveSeg(2)); ReTestInterStruct(res.leftIntersAll, c1, dTolLen, bOldClock); ReTestInterStruct(res.rightIntersAll, c2, dTolLen, bOldClock); } void CRoadDataCenterNew::CreateRoadEdgeStruct(ROAD_EDGE_STRUCT &res) { int index = 0, ilen = (int)res.lineEdges.length(); for (index = 0; index < ilen; index++) res.lineEdges[index]->ReCreate(); ilen = (int)res.arcEdges.length(); for (index = 0; index < ilen; index++) res.arcEdges[index]->ReCreate(); } void CRoadDataCenterNew::Clear(ROAD_EDGE_STRUCT &res, ROAD_MID_STRUCT &rms) { ClearAndDeleteAry(res.lineEdges); ClearAndDeleteAry(res.arcEdges); ClearAndDeleteAry(res.intersOriginAll); ClearAndDeleteAry(rms.lineMids); ClearAndDeleteAry(rms.arcMids); ClearAndDeleteAry(rms.intersOriginAll); } void CRoadDataCenterNew::SaveMidInterStruct(ROAD_MID_STRUCT &rms) { rms.intersOriginAll.append(rms.leftInterMid); rms.intersOriginAll.append(rms.rightInterMid); }