/// <summary> 提取断面中对应的边坡对象。在某些断面中,可能根本就不会画出边坡线,此时返回 null </summary> /// <param name="left">true 表示提取左边的边坡, false 表示提取右边的边坡</param> /// <returns></returns> public SlopeLine GetSlopeLine(bool left) { var xdata = XData; var db = DocMdf.acDataBase; if (left) { if (xdata.LeftSlopeExists) { var pl = xdata.LeftSlopeHandle.GetDBObject <Polyline>(db); var retainingWall = xdata.LeftRetainingWallType != RetainingWallType.无 ? xdata.LeftRetainingWallHandle.GetDBObject <Polyline>(db) : null; var slp = new SlopeLine(DocMdf, pl, this, onLeft: true, isFill: xdata.LeftSlopeFill.Value, retainingWallType: xdata.LeftRetainingWallType, retainingWall: retainingWall); return(slp); } } else { if (xdata.RightSlopeExists) { var pl = xdata.RightSlopeHandle.GetDBObject <Polyline>(db); var retainingWall = xdata.RightRetainingWallType != RetainingWallType.无 ? xdata.RightRetainingWallHandle.GetDBObject <Polyline>(db) : null; var slp = new SlopeLine(DocMdf, pl, this, onLeft: false, isFill: xdata.RightSlopeFill.Value, retainingWallType: xdata.RightRetainingWallType, retainingWall: retainingWall); return(slp); } } return(null); }
/// <summary> 搜索边坡线 </summary> /// <param name="leftFill">左边边坡为填方还是挖方</param> /// <param name="rightFill">右边边坡为填方还是挖方</param> private bool FindSlopes(Extents3d extSection, out Polyline leftSlope, out bool leftFill, out Polyline rightSlope, out bool rightFill) { leftSlope = null; rightSlope = null; leftFill = false; rightFill = false; var res = DocMdf.acEditor.SelectCrossingWindow( pt1: extSection.MinPoint, pt2: extSection.MaxPoint, filter: SlopeLine.Filter); if (res.Status == PromptStatus.OK) { var lines = res.Value.GetObjectIds().Select(id => id.GetObject(OpenMode.ForRead)).OfType <Polyline>().ToList(); var lefts = lines.Where(l => SlopeLine.IsSlopeLineLayer(l.Layer, left: true)).ToArray(); if (lefts.Length > 0) { // 从多个边坡线中搜索某个端点距离中轴线中心最近的那一条 var slp = GetClosestPolyLine(lefts, _MiddlePt); // 当界面图形缩得太小时,有可以会把其他断面中的挡墙误加进来, // 此时通过挡墙多段线中的某点是否位于此断面的Extends范围之内来确定它是否真是本断面的挡墙 if (slp != null && extSection.Contains(slp.StartPoint)) { leftSlope = slp as Polyline; leftFill = slp.Layer == Options_LayerNames.LayerName_Slope_Left_Fill; } } var rights = lines.Where(l => SlopeLine.IsSlopeLineLayer(l.Layer, left: false)).ToArray(); if (rights.Length > 0) { // 从多个边坡线中搜索某个端点距离中轴线中心最近的那一条 var slp = GetClosestPolyLine(rights, _MiddlePt); if (slp != null && extSection.Contains(slp.StartPoint)) { rightSlope = slp as Polyline; rightFill = slp.Layer == Options_LayerNames.LayerName_Slope_Right_Fill; } } } // 对于一个横断面而言,可以没有边坡线,即不进行挖填 return(true); }
/// <summary> /// 计算道路横断面的某一侧中,从路面中心到边坡外边缘的范围内,属于填方的区域在 AutoCAD 几何中的 X 范围 /// </summary> /// <param name="sec"></param> /// <param name="left"></param> /// <param name="slp"> 某一侧边坡,其值可能为null,表示此侧没有边坡线 </param> /// <param name="cGround"></param> /// <param name="db"></param> /// <param name="edgeXleft">此侧边坡的填方左边界</param> /// <param name="edgeXright">此侧边坡的填方右边界</param> /// <returns>如果没有填方区域,则返回 false </returns> public bool GetFillSlopeXRange(bool left, SlopeLine slp, CompositeCurve2d cGround, Database db, out double edgeXleft, out double edgeXright) { edgeXleft = 0.0; edgeXright = 0.0; var centerFill = IsCenterFill(); var slopeFill = slp == null || slp.XData.FillCut; if (!centerFill && (slp == null || !slopeFill)) { return(false); } // 确定进行搜索的左右边界:路基边缘(或边坡脚) 到 道路中线 double roadEdge = left ? LeftRoadEdge.X : RightRoadEdge.X; double slopeEdge = roadEdge; // 边坡的坡脚的 X 值 if (slp != null && slp.XData.Slopes.Count > 0) { var data = slp.XData; slopeEdge = data.Slopes[data.Slopes.Count - 1].OuterPoint.X; } if (centerFill && slopeFill) { // 道路中心与边坡均为填方 double edgeX1 = CenterX; edgeXleft = Math.Min(edgeX1, slopeEdge); edgeXright = Math.Max(edgeX1, slopeEdge); } else { // 说明 坡脚与道路中心这二者中有一个为挖方,另一个为填方 var roadSurfHandle = left ? LeftRoadSurfaceHandle : RightRoadSurfaceHandle; var roadSurf = roadSurfHandle.GetDBObject <Polyline>(db); var cRoad = roadSurf.Get2dLinearCurve(); var inters = new CurveCurveIntersector2d(cRoad, cGround); double iX; if (inters.NumberOfIntersectionPoints > 0) { iX = inters.GetIntersectionPoint(0).X; } else { // 这种情况极少会出现,但测试中确实会有,即自然地面线与挖方坡底边沟相交,而不与路面相交 iX = roadEdge; } // 自然地面与路面的交点 var roadWidth = Math.Abs((roadEdge - CenterX)); var innerRatio = Math.Abs((iX - CenterX) / roadWidth); if ((centerFill && innerRatio > 0.5)) { // 靠道路中心为填方,边坡为挖方 if (left) { edgeXleft = iX; edgeXright = CenterX; } else { edgeXleft = CenterX; edgeXright = iX; } } else if (!centerFill && innerRatio <= 0.5) { // 靠道路中心为挖方,边坡为填方 if (left) { edgeXleft = slopeEdge; edgeXright = iX; } else { edgeXleft = iX; edgeXright = slopeEdge; } } else { // 填方区域太小 return(false); } } return(true); }