#include "stdafx.h" #include "RoadGradeStyle.h" #include "TchGlobalFunc.h" #include "TRoadGradeArrowJig.h" #include "TchAnnotateGlobalFunc.h" #include "RoadGradeDlg.h" #include "acappvar.h" void GetArrowPolyLineByParam(AcGePoint3d &ptCenter, AcGeVector2d &vecDirction, double dArrowLenth, XPoly2D &poly2d) { AcGePoint3d ptGeStart, ptGeEnd; ptGeStart = (vecDirction * dArrowLenth * 0.5 / vecDirction.length()) + ptCenter; ptGeEnd = (-vecDirction * dArrowLenth * 0.5 / vecDirction.length()) + ptCenter; poly2d.AppendNode(ptGeStart); poly2d.AppendNode(ptGeEnd); } double CRoadGradeStyle::m_dAngle = 0; double CRoadGradeStyle::m_dRoadGrade = 0.0; double CRoadGradeStyle::m_dRoadLenth = 10.00; CRoadGradeStyle::CRoadGradeStyle(void) { } CRoadGradeStyle::~CRoadGradeStyle(void) { } //判断选择的道路标高是否满足规定的个数 bool CRoadGradeStyle::JudgeSelectRoadElevation(PickSet &ss) { int len = ss.Length(); if (len < 1) { ads_prompt(_T("\n未选择,请选择!")); return false; } else if (len == 1) { ads_prompt(_T("\n请选取第二个道路标高!")); TRBList rbFilter(acutBuildList(RTDXF0, _T("ATS_ELEVATION"), NULL)); TEntitySet ent; if (RTNORM != SelectEntity(_T("\n请选取第二个道路标高!"),ent, rbFilter)) return false; else { AcDbObjectId id = NULL; acdbGetObjectId(id, ent); ss += id; return true; } } else if (len == 2) { return true; } else if (len > 2 ) { ads_prompt(_T("选择超过两个标高,请重新选择!")); return false; } return false; } //判断选择道路中心线是否连续 //返回true,连续,返回false,不连续 bool CRoadGradeStyle::JudgeRoadCentersIsContinue(const PickSet &ssRoadCenter, XPoly2D &roadCenterLine2d)//判断选择道路中心线是否连续 { int nRoadLen = ssRoadCenter.Length(); if (nRoadLen == 1) { Entity ent = ssRoadCenter[0]; XPoly2D polyTemp(ent); roadCenterLine2d = polyTemp; return true; } int nFirstPoly(0), nSecondPoly(0); int nInterNum = 0; AcGePoint3d ptInter; ////////////////////////////////////////////////////////////////////////// for (int nEndpt = 0; nEndpt < nRoadLen; ++nEndpt) { TGGePoly2D poly2d; Entity ent = ssRoadCenter[nEndpt]; XCurveSegment cvFirst(ent); cvFirst.AsPoly2D(poly2d); AcGePoint3d ptStart,ptEnd; ptStart = poly2d.GetPointListAt(0)->AsAcGePoint3d(); ptEnd = poly2d.GetPointListAt(poly2d.Length() - 1)->AsAcGePoint3d(); for (int n = 0; n < nRoadLen; ++n) { nInterNum = 0; if (n == nEndpt) continue; TGGePoly2D poly2dTemp(ssRoadCenter[n]); if (ptStart.isEqualTo(poly2dTemp.GetPointListAt(0)->AsAcGePoint3d()) || ptStart.isEqualTo(poly2dTemp.GetPointListAt(poly2dTemp.Length() - 1)->AsAcGePoint3d())) { ptInter = ptStart; ++nInterNum; } if (ptEnd.isEqualTo(poly2dTemp.GetPointListAt(0)->AsAcGePoint3d()) || ptEnd.isEqualTo(poly2dTemp.GetPointListAt(poly2dTemp.Length() - 1)->AsAcGePoint3d())) { ptInter = ptEnd; ++nInterNum; } if (nInterNum == 1) { if (ptInter.isEqualTo(poly2d.GetPointListAt(0)->AsAcGePoint3d())) { roadCenterLine2d.AppendSegment(cvFirst, 1, 0); } else { roadCenterLine2d.AppendSegment(cvFirst, 0, 0); } nFirstPoly = nEndpt; nSecondPoly = nFirstPoly; break; } } if (nInterNum == 1) { break; } } if (nInterNum == 2) { TGGePoly2D poly2d; Entity ent = ssRoadCenter[0]; XCurveSegment cvFirst(ent); cvFirst.AsPoly2D(poly2d); nFirstPoly = 0; nSecondPoly = nFirstPoly; roadCenterLine2d.AppendSegment(cvFirst, 0, 0); ptInter = poly2d.GetPointListAt(poly2d.Length() - 1)->AsAcGePoint3d(); } for (int nNum = 0; nNum < nRoadLen - 1; ++nNum) { for (int i = 0; i < nRoadLen; ++i) { if (i == nFirstPoly || i == nSecondPoly) { continue; } TGGePoly2D poly2dTemp; Entity ent = ssRoadCenter[i]; XCurveSegment cv(ent); cv.AsPoly2D(poly2dTemp); if (ptInter.isEqualTo(poly2dTemp.GetPointListAt(0)->AsAcGePoint3d())) { ptInter = poly2dTemp.GetPointListAt(poly2dTemp.Length() - 1)->AsAcGePoint3d(); if (roadCenterLine2d.TotalSegments() == nRoadLen - 2) { roadCenterLine2d.AppendSegment(cv, 0, 1); } else { roadCenterLine2d.AppendSegment(cv, 0, 0); } nSecondPoly = i; break; } else if (ptInter.isEqualTo(poly2dTemp.GetPointListAt(poly2dTemp.Length() - 1)->AsAcGePoint3d())) { ptInter = poly2dTemp.GetPointListAt(0)->AsAcGePoint3d(); if (roadCenterLine2d.TotalSegments() == nRoadLen - 2) { roadCenterLine2d.AppendSegment(cv, 1, 1); } else { roadCenterLine2d.AppendSegment(cv, 1, 0); } nSecondPoly = i; break; } } } if (roadCenterLine2d.TotalSegments() == nRoadLen) { return true; } else { return false; } } //判断标高是否在选择的道路中心线上 bool CRoadGradeStyle::JudgeElevationOnRoadCenter(const XPoly2D &roadCenterLine2d, const PickSet &ssElevation) { XPoint ptStart, ptEnd; int len = ssElevation.Length(); if (len != 2) return false ; for(long i=0;iGetLocation();//返回的是世界坐标的点 } else { ptEnd = pEnt->GetLocation(); } } OPENOBJ_END(); } } len = roadCenterLine2d.Length() - 1; bool bStartOnLine = false, bEndOnLine = false; XPoint ptProjectStart, ptProjectEnd;//投影点 for (int i = 0; i < len; ++i) { TGGeCurveSegment curve; roadCenterLine2d.Nth(i, curve); curve.ProjectToMe(ptStart, ptProjectStart); curve.ProjectToMe(ptEnd, ptProjectEnd); if (ptProjectStart == ptStart && ( 5 == curve.HitTest2d(ptProjectStart) || 4 == curve.HitTest2d(ptProjectStart) || 3 == curve.HitTest2d(ptProjectStart))) bStartOnLine = true; if (ptProjectEnd == ptEnd && ( 5 == curve.HitTest2d(ptProjectEnd) || 3 ==curve.HitTest2d(ptProjectEnd) || 4 ==curve.HitTest2d(ptProjectEnd))) bEndOnLine = true; } if (bStartOnLine && bEndOnLine) return true; else return false; } void CRoadGradeStyle::SetArrowDirection(XPoly2D &roadCenterLine2d, const PickSet &ssElevation) { XPoint ptStart, ptEnd; double dStartElevation(0.0), dEndElevation(0.0); int len = ssElevation.Length(); if (len != 2) return; for(long i=0;iGetLocation();//返回的是世界坐标的点 pEnt->GetElev1(dStartElevation); } else { ptEnd = pEnt->GetLocation(); pEnt->GetElev1(dEndElevation); } } OPENOBJ_END(); } } len = roadCenterLine2d.Length() - 1; bool bStartOnLine = false, bEndOnLine = false; XPoint ptProjectStart, ptProjectEnd;//投影点 for (int i = 0; i < len; ++i) { TGGeDirectionCurve curve; roadCenterLine2d.Nth(i, curve); curve.ProjectToMe(ptStart, ptProjectStart); curve.ProjectToMe(ptEnd, ptProjectEnd); if (ptProjectStart == ptStart) { bStartOnLine = true; } if (ptProjectEnd == ptEnd) { bEndOnLine = true; } } //两个标高在同一条线段上,判断方向了。 if (bStartOnLine && bEndOnLine) { if (roadCenterLine2d.PathDistance2d(ptProjectStart) >= roadCenterLine2d.PathDistance2d(ptProjectEnd)) { bEndOnLine = false; } else bStartOnLine = false; } if ((dStartElevation - dEndElevation) >= 0 ) { //判断起始标高点是否在多段线的前侧,如果不是,则返回 if (!bStartOnLine && bEndOnLine) roadCenterLine2d.Reverse(); } else { if (bStartOnLine && !bEndOnLine) roadCenterLine2d.Reverse(); } } bool CRoadGradeStyle::GetDistanceAndGrade(const XPoly2D &roadCenterLine2d, const PickSet &ssElevation, double &dRoadLenth, double &dRoadGrade) { XPoint ptStart, ptEnd; double dStartElevation(0.0), dEndElevation(0.0); int len = ssElevation.Length(); if (len != 2) return false ; for(long i=0;iGetLocation();//返回的是世界坐标的点 pEnt->GetElev1(dStartElevation); } else { ptEnd = pEnt->GetLocation(); pEnt->GetElev1(dEndElevation); } } OPENOBJ_END(); } } int nLen = roadCenterLine2d.Length(); double d1 = roadCenterLine2d.PathDistance2d(ptStart); double d2 = roadCenterLine2d.PathDistance2d(ptEnd); dRoadLenth = abs(roadCenterLine2d.PathDistance2d(ptStart) - roadCenterLine2d.PathDistance2d(ptEnd))/1000.0;; if (DocGetCurMeterUnitDraw()) dRoadLenth = abs(roadCenterLine2d.PathDistance2d(ptStart) - roadCenterLine2d.PathDistance2d(ptEnd)); dRoadGrade = abs(dStartElevation - dEndElevation) / (dRoadLenth) * 100; return true; } //返回1:成功;返回0,则不选择道路中心线;返回-1,则直接退出命令,框选图层为Road_Dot的实体 int CRoadGradeStyle::SelectRoadCenterLine(PickSet &ssRoadCenter, XPoly2D &pCenterLine) { bool bFirst = true; while (1) { PickSet ssSelect; TRBList rbFilter(acutBuildList(RTDXF0, _T("POLYLINE,LWPOLYLINE,LINE,ARC"), NULL)); //rbFilter.Append(ads_buildlist(8, _T("ROAD_DOTE"), NULL));//图层过滤 int nReturnValue = 0; if (bFirst) { nReturnValue = SelectEnts(_T("\n请选择道路中心线<按直线标注>!"), ssSelect, rbFilter, _T(" ")); bFirst = false; } else nReturnValue = SelectEnts(_T(""), ssSelect, rbFilter, _T(" ")); if (RTNONE == nReturnValue) { break; } if (RTNORM == nReturnValue) { ssRoadCenter += ssSelect; ssRoadCenter.Redraw(3); } else { return 0; } } if (ssRoadCenter.Length() == 0) return 0; if (!JudgeRoadCentersIsContinue(ssRoadCenter, pCenterLine))//判断选择道路中心线是否连续 { ads_prompt(_T("\n所选道路中心线不连续,请检查!")); return -1; } else { return kRetEsc; } } //功能:自动标高,程序把所选的两个标高之间按直线连接,并在其连线中点位置自动生成坡度标注,箭头方向沿两标高的连线方向从标高值高的点指向标高值低的点 bool CRoadGradeStyle::AutoCreateRoadGradeSymble(const PickSet &ssElevation, TDbSymbArrow *pSymbArrowEnt, CRoadGradeDlg* pDlg) { if (!pSymbArrowEnt) return false; XPoint ptStart, ptEnd; double dStartElevation(0.0), dEndElevation(0.0); int len = ssElevation.Length(); if (len != 2) return false ; for(long i=0;iGetLocation();//返回的是世界坐标的点 pEnt->GetElev1(dStartElevation); } else { ptEnd = pEnt->GetLocation(); pEnt->GetElev1(dEndElevation); } } OPENOBJ_END(); } } AcGeVector2d vecDirction; if (dStartElevation > dEndElevation) { vecDirction = ptStart - ptEnd; } else vecDirction = ptEnd - ptStart; XPoint ptCenter; ptCenter.x = (ptStart.x + ptEnd.x)/2.0; ptCenter.y = (ptStart.y + ptEnd.y)/2.0; ptCenter.z = (ptStart.z + ptEnd.z)/2.0; double dDis = abs(ptStart.Distance(ptEnd)); if (dDis <= 0.000001) return false; double dRoadGrade = abs((dStartElevation-dEndElevation) / (dDis/1000)) * 100; if (DocGetCurMeterUnitDraw()) dRoadGrade = abs((dStartElevation-dEndElevation) / (dDis)) * 100; double dArrowLenth = pDlg->GetArrowLineLength(); XPoly2D poly2d; AcGePoint3d ptGeCenter(ptCenter.x ,ptCenter.y, ptCenter.z); GetArrowPolyLineByParam(ptGeCenter, vecDirction, dArrowLenth, poly2d); pSymbArrowEnt->SetPoly2D(poly2d); double dRoadLenth = abs(ptStart.Distance(ptEnd))/1000.0;//mm单位下以米单位为距离 if (DocGetCurMeterUnitDraw()) dRoadLenth= abs(ptStart.Distance(ptEnd)); pDlg->SetDisFormatData(pSymbArrowEnt, dRoadLenth, dRoadGrade); TDbSymbArrow *pSymbArrowEntClone = new TDbSymbArrow(); pSymbArrowEntClone = (TDbSymbArrow*)pSymbArrowEnt->clone(); double dSize = pDlg->GetArrowSize(); if (dSize > 1.0E-3) pSymbArrowEntClone->SetArrowSize(dSize); AddToModelSpace(pSymbArrowEntClone); return true; } //选择标高进行道路坡度标注 int CRoadGradeStyle::SelectStyle(TDbSymbArrow *pSymbArrowEnt, CRoadGradeDlg* pDlg) { PickSet ssElevation(SS_FREE); TRBList rbFilter(acutBuildList(RTDXF0, _T("ATS_ELEVATION"), NULL)); TCHAR chRet; const TCHAR *kword=_T("` D S"); THookMsg hookmsg; int iRetCode = SelectEntities(_T("\n请选取两个道路标高自动标注或[手工绘制(D)/设置(S)]<退出>:"), ssElevation, rbFilter, kword, chRet); int vn = hookmsg.GetValue(); if (iRetCode == RTNORM)//选择标注 { if (!JudgeSelectRoadElevation(ssElevation))//判断选择的道路标高是否满足规定的个数 return kRetContinue; PickSet ssRoadCenter(SS_FREE); XPoly2D roadCenterLine; int nRet = SelectRoadCenterLine(ssRoadCenter, roadCenterLine); if (1 == nRet)//选择道路中心线 { if (!JudgeElevationOnRoadCenter(roadCenterLine, ssElevation)) { ads_prompt(_T("\n有标高点不在所选道路中心线上,请检查!!")); ssRoadCenter.Redraw(4); return kRetEsc;//直接退出命令 } acutPrintf(_T("\n 请点取标注位置<退出>")); //箭头方向沿两标高的连线方向从标高值高的点指向标高值低的点。 SetArrowDirection(roadCenterLine, ssElevation); double dRoadLenth= 0.00, dRoadGrade = 0.00; GetDistanceAndGrade(roadCenterLine, ssElevation, dRoadLenth, dRoadGrade); pDlg->SetDisFormatData(pSymbArrowEnt, dRoadLenth, dRoadGrade); TADSGePoint3d ptCenter = roadCenterLine.GetPoint(0, roadCenterLine.GetLength() * 0.5); TRoadGradeArrowJig jig(roadCenterLine, ptCenter, pSymbArrowEnt, pDlg->GetArrowLineLength(),false); int nRetValue = jig.doIt(); if (nRetValue == RTNORM) { TDbSymbArrow *pSymbArrowEntClone = new TDbSymbArrow(); pSymbArrowEntClone = (TDbSymbArrow*)pSymbArrowEnt->clone(); double dSize = pDlg->GetArrowSize(); if (dSize > 1.0E-3) pSymbArrowEntClone->SetArrowSize(dSize); AddToModelSpace(pSymbArrowEntClone); } ssRoadCenter.Redraw(4); } else if (0 == nRet)//如果没有选择道路中心线,则按选中标高在图上自动生成坡度标注 { if (!AutoCreateRoadGradeSymble(ssElevation, pSymbArrowEnt, pDlg)) { return kRetEsc; } else { ssRoadCenter.Redraw(4); } } else { ssRoadCenter.Redraw(4); return kRetEsc;//返回-1,则直接退出命令 } } else if (iRetCode == RTKWORD) { if (chRet == _T('S'))//打开道路坡度标注对话框 { acutPrintf(_T("S")); return kRetSettingDlg; } else if (chRet == _T('D'))//动态绘制 { acutPrintf(_T("D")); return kRetDynamicStyle; } else return kRetEsc; } else { //当前焦点在CAD上,并且没有选中 if(vn == 0 && GetFocus() == acedGetAcadDwgView()->GetSafeHwnd()) { acutPrintf(_T("\n选择无效,请重新选择!")); return kRetContinue; } else return kRetEsc; } return kRetContinue; } namespace { double Str2Double(const CString& str) { CString sTemp(str); double d; LPTSTR p = sTemp.GetBuffer(10); d = _tstof(p); sTemp.ReleaseBuffer( ); return d; } } namespace { #if ADS <= 17 double _ttof(LPCTSTR psz) { if (!psz) return .0; USES_CONVERSION; return atof(W2A(psz)); } #endif } //动态绘制道路坡度标注 void CRoadGradeStyle::DynamicStyle(TDbSymbArrow *pSymbArrowEnt, CRoadGradeDlg* pDlg) { XPoint ptCenter; int rc (0); if (RTNORM != acedGetPoint(NULL, _T("\n请点取标注道路坡度的位置<自动标注>"), ptCenter)) return; AcGePoint3d ptPos = Ucs2Wcs(ptCenter).AsAcGePoint3d();//add by yyc 20160407 坐标系修正 CString str(_T("")), strTmp(_T("")); XPoly2D roadCenterLine; pSymbArrowEnt->SetText(_T("")); pSymbArrowEnt->SetText2(_T("")); TRoadGradeArrowJig jig(roadCenterLine, ptPos, pSymbArrowEnt, pDlg->GetArrowLineLength(),true,true); CString strPrompt(_T("")); strPrompt.Format(_T("\n请确定标注方向<%.f>:"), m_dAngle); jig.SetPrompt(strPrompt); int nRet = jig.doIt(); if (nRet == RTCAN ) { return; } else if (nRet == RTNONE)//回车或者右键时 { jig.SetAngle(m_dAngle / 180 * PI); } else { m_dAngle = jig.GetAngle() / PI * 180; } strTmp = str = strPrompt = _T(""); do { int nAccuracyGrade = pDlg->GetAccuracyGrade(); if (nAccuracyGrade == 0) strPrompt.Format(_T("\n请输入道路坡度<%0.0f>:"), m_dRoadGrade); else if (nAccuracyGrade == 1) strPrompt.Format(_T("\n请输入道路坡度<%0.1f>:"), m_dRoadGrade); else if (nAccuracyGrade == 2) strPrompt.Format(_T("\n请输入道路坡度<%0.2f>:"), m_dRoadGrade); else if (nAccuracyGrade == 3) strPrompt.Format(_T("\n请输入道路坡度<%0.3f>:"), m_dRoadGrade); rc = acedGetString(FALSE, strPrompt, str.GetBufferSetLength(1000)); if (rc == RTNORM) { str.ReleaseBufferSetLength(1000); if (str == _T("")) { if (nAccuracyGrade == 0) strTmp.Format(_T("%.0f"), m_dRoadGrade); else if (nAccuracyGrade == 1) strTmp.Format(_T("%.1f"), m_dRoadGrade); else if (nAccuracyGrade == 2) strTmp.Format(_T("%.2f"), m_dRoadGrade); else if (nAccuracyGrade == 3) strTmp.Format(_T("%.3f"), m_dRoadGrade); } else { strTmp = str.SpanIncluding(_T(".0123456789")); if (strTmp.IsEmpty()) acutPrintf(_T("\n输入无效,请重新输入数值!")); } } else return; } while (strTmp.IsEmpty()); m_dRoadGrade = _tstof(strTmp); strTmp = str = strPrompt = +_T(""); do { int nAccuracyLength = pDlg->GetAccuracyLength(); if (nAccuracyLength == 0) strPrompt.Format(_T("\n请输入道路坡长(M)<%0.0f>:"), m_dRoadLenth); else if (nAccuracyLength == 1) strPrompt.Format(_T("\n请输入道路坡长(M)<%0.1f>:"), m_dRoadLenth); else if (nAccuracyLength == 2) strPrompt.Format(_T("\n请输入道路坡长(M)<%0.2f>:"), m_dRoadLenth); else if (nAccuracyLength == 3) strPrompt.Format(_T("\n请输入道路坡长(M)<%0.3f>:"), m_dRoadLenth); rc = acedGetString(FALSE, strPrompt, str.GetBufferSetLength(1000)); if (rc == RTNORM) { str.ReleaseBufferSetLength(1000); if (str == _T("")) { if (nAccuracyLength == 0) strTmp.Format(_T("%.0f"), m_dRoadLenth); else if (nAccuracyLength == 1) strTmp.Format(_T("%.1f"), m_dRoadLenth); else if (nAccuracyLength == 2) strTmp.Format(_T("%.2f"), m_dRoadLenth); else if (nAccuracyLength == 3) strTmp.Format(_T("%.3f"), m_dRoadLenth); } else { strTmp = str.SpanIncluding(_T(".0123456789")); if (strTmp.IsEmpty()) acutPrintf(_T("\n输入无效,请重新输入数值!")); } } else return; } while (strTmp.IsEmpty()); m_dRoadLenth = _tstof(strTmp); pDlg->SetDisFormatData(pSymbArrowEnt, m_dRoadLenth, m_dRoadGrade); TDbSymbArrow *pSymbArrowEntClone = new TDbSymbArrow(); pSymbArrowEntClone = (TDbSymbArrow*)pSymbArrowEnt->clone(); double dSize = pDlg->GetArrowSize(); if (dSize > 1.0E-3) pSymbArrowEntClone->SetArrowSize(dSize); AddToModelSpace(pSymbArrowEntClone); }