123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- using GrxCAD.ApplicationServices;
- using GrxCAD.DatabaseServices;
- using GrxCAD.EditorInput;
- using GrxCAD.Geometry;
-
- namespace HCTools
- {
- class SlopeLine
- {
- public static int blc;
- public struct ContourElevation
- {
- public double elevation;
- public double length;
- public ObjectId objID;
- }
- ObjectIdCollection idcoll = new ObjectIdCollection();
-
- public void slopeline()
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- Database db = doc.Database;
- Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
-
- TypedValue[] value = new TypedValue[]
- {
- new TypedValue((int)DxfCode.Start,"LWPOLYLINE"),
- new TypedValue((int)DxfCode.LayerName,"8110,8120")
- };//设置筛选条件
- SelectionFilter filter = new SelectionFilter(value);
- //选择区域中全部对象
- //PromptSelectionResult psr = ed.SelectAll(filter);
- // 要求在图形区域中手动选择对象
- PromptSelectionResult psr = ed.GetSelection(filter);
-
- if (psr.Status == PromptStatus.OK)
- {
- SelectionSet ss = psr.Value;
- ObjectId[] ids = new ObjectId[ss.Count];
- ids = ss.GetObjectIds();
- foreach (ObjectId id in ids)
- {
- DocumentLock doclock = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
- using (Transaction trans = db.TransactionManager.StartTransaction())
- {
- Polyline pll = trans.GetObject(id, OpenMode.ForRead) as Polyline;
-
- if (pll.StartPoint == pll.EndPoint || pll.Closed == true)
- {
- searchslpline(pll,trans);
- }
- trans.Commit();
- }
- doclock.Dispose();
- }
- }
- }
-
- /// <summary>
- /// 搜索闭合等高线并画出示坡线
- /// </summary>
- private void searchslpline(Polyline pll, Transaction trans)
- {
- if (idcoll.Contains(pll.Id))
- return;
-
- Point3dCollection ptcoll = new Point3dCollection();
- Point3dCollection ptcoll2 = new Point3dCollection();
- int windowwidth = 30 * 5 * blc / 1000;//当前可视范围
- int windowheight = 30 * 5 * blc / 1000;
-
- Extents3d extents = pll.GeometricExtents;
- Point3d center = extents.MinPoint + (extents.MaxPoint - extents.MinPoint) / 2.0;//计算几何中心
-
- Matrix3d mt1 = Matrix3d.Scaling(2, center);
- pll = trans.GetObject(pll.Id,OpenMode.ForWrite)as Polyline;
- pll.TransformBy(mt1);
- pll.GetStretchPoints(ptcoll);//将闭合等高线缩放至原来的两倍大并获取其节点用于之后的筛选
- Matrix3d mt2 = Matrix3d.Scaling(0.5, center);
- pll.TransformBy(mt2);//还原闭合等高线
-
-
- //获取闭合等高线的节点并搜索其内是否还有闭合等高线,若有,则选择最里面的闭合等高线画示坡线
- pll.GetStretchPoints(ptcoll2);
-
- Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
-
- TypedValue[] value = new TypedValue[]
- {
- new TypedValue((int)DxfCode.Start,"LWPOLYLINE"),
- new TypedValue((int)DxfCode.LayerName,"8110,8120")
- };//设置筛选条件
- SelectionFilter filter = new SelectionFilter(value);
-
-
- ViewTableRecord currview = ed.GetCurrentView();
- currview.CenterPoint = new Point2d(pll.StartPoint.X, pll.StartPoint.Y);
- currview.ViewDirection = new Vector3d(0, 0, 1);
- currview.Width = windowwidth;
- currview.Height = windowheight;
- ed.SetCurrentView(currview);
-
- PromptSelectionResult psr1 = ed.SelectWindowPolygon(ptcoll2, filter);
- if (psr1.Status == PromptStatus.OK && psr1.Value.Count > 0)
- {
- SelectionSet selects = psr1.Value;
- ObjectId[] idss = selects.GetObjectIds();
-
- List<ContourElevation> Contourcollect = new List<ContourElevation>();
- ContourElevation self = new ContourElevation();
- self.length = pll.Length;
- self.objID = pll.Id;
- Contourcollect.Add(self);
- for (int ii = 0; ii < idss.Length; ii++)
- {
- Polyline pllselected = trans.GetObject(idss[ii], OpenMode.ForRead) as Polyline;
- ContourElevation cl = new ContourElevation();
- cl.length = pllselected.Length;
- cl.objID = pllselected.Id;
- Contourcollect.Add(cl);
- }
- List<ContourElevation> sorted = Contourcollect.OrderBy(s => s.length).ToList();//length 从小到大
- pll = trans.GetObject(sorted[0].objID, OpenMode.ForWrite) as Polyline;
- while (pll.Closed == false && pll.StartPoint != pll.EndPoint)//判断最短的等高线是否闭合
- {
- sorted.RemoveAt(0);
- pll = trans.GetObject(sorted[0].objID, OpenMode.ForWrite) as Polyline;
- }
- if (idcoll.Contains(pll.Id))
- return;
- }
-
-
- //通过之前得到的增大两倍后的闭合等高线节点进行窗交,获取周围等高线,根据此闭合等高线和
- //周围等高线的大小关系决定示坡线的方向
- PromptSelectionResult psr2 = ed.SelectCrossingPolygon(ptcoll, filter);
- if (psr2.Status == PromptStatus.OK)
- {
- SelectionSet ss = psr2.Value;
- ObjectId[] ids = ss.GetObjectIds();
- List<ContourElevation> Contour = new List<ContourElevation>();
- for (int ii = 0; ii < ids.Length; ii++)
- {
- Polyline pllselected = trans.GetObject(ids[ii], OpenMode.ForRead) as Polyline;
- //if (pllselected.Closed == true || pllselected.StartPoint == pllselected.EndPoint &&
- // pllselected.Id != pll.Id)
- // continue;
- ContourElevation ce = new ContourElevation();
- ce.elevation = pllselected.Elevation;
- ce.objID = pllselected.Id;
- Contour.Add(ce);
- }
- List<ContourElevation> sorted = Contour.OrderBy(s => s.elevation).ToList();//elevation 从小到大
- if (sorted[Contour.Count - 1].elevation == pll.Elevation)
- {
- int j = 1;
- drawslpline(pll, j, trans);
- idcoll.Add(pll.Id);
- }
- if (sorted[0].elevation == pll.Elevation)
- {
- int j = -1;
- drawslpline(pll, j, trans);
- idcoll.Add(pll.Id);
- }
- }
- }
-
- /// <summary>
- /// 画示坡线
- /// </summary>
- private void drawslpline(Polyline pll, double i, Transaction trans)
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- Database db = doc.Database;
- BlockTable blocktable = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
- BlockTableRecord blocktablerecord = trans.GetObject(blocktable[BlockTableRecord.ModelSpace],
- OpenMode.ForWrite) as BlockTableRecord;
-
- //创建标注相交点符号的图层
- LayerControl layerscontrol = new LayerControl();
- string layname = "8200";
- if (!layerscontrol.haslayername(layname))
- {
- colorgb col = new colorgb(0, 255, 0);
- layerscontrol.creatlayer(layname, col);
- layerscontrol.movelayertofront(layname);
- }
- else
- layerscontrol.movelayertofront(layname);
-
-
- //此等高线高程最高
- if (i == 1)
- {
- //由于IntersectWith()函数在离原点太远的位置会有误差,所以将需要判断的闭合等高线移动到原点附近
- Point3d tagpt = pll.StartPoint;//移动目标点
- Point3dCollection ptss = new Point3dCollection();
- pll.GetStretchPoints(ptss);
- Vector3d acVec3d = pll.StartPoint.GetVectorTo(new Point3d(0, 0, 0));
- pll.TransformBy(Matrix3d.Displacement(acVec3d));
-
- //获取几何中心
- Extents3d extents = pll.GeometricExtents;
- Point3d center = extents.MinPoint + (extents.MaxPoint - extents.MinPoint) / 2.0;
- Point3dCollection ptcoll = new Point3dCollection();
-
-
- //由几何中心到闭合等高线的起点画一条示坡线,将其以几何中心作为基点延长
- Line slpline = new Line(center, pll.StartPoint);
- blocktablerecord.AppendEntity(slpline);
- trans.AddNewlyCreatedDBObject(slpline, true);
- slpline = trans.GetObject(slpline.Id,OpenMode.ForWrite)as Line;
- Matrix3d mt1 = Matrix3d.Scaling(1.5, center);
- slpline.TransformBy(mt1);
-
- //获取示坡线与闭合等高线的交点,将示坡线由此打断,删除闭合等高线内的部分
- slpline.IntersectWith(pll, Intersect.OnBothOperands, ptcoll, IntPtr.Zero, IntPtr.Zero);
- Point3d pt1 = ptcoll[0];
- Point3d pt2 = ptcoll[1];
- DBObjectCollection objcoll= slpline.GetSplitCurves(ptcoll);
- slpline.Erase();
- foreach (Entity ent in objcoll)
- {
- Line plline = ent as Line;
- if (plline.StartPoint != pll.StartPoint)
- {
- blocktablerecord.AppendEntity(plline);
- trans.AddNewlyCreatedDBObject(plline, true);
- objcoll.Remove(plline);
- plline.Erase();
- }
- }
- Line slpline1 = objcoll[0] as Line;
- slpline1.Layer = "8200";
- blocktablerecord.AppendEntity(slpline1);
- trans.AddNewlyCreatedDBObject(slpline1, true);
-
-
-
-
- Point3dCollection pts = new Point3dCollection();
- pll.GetStretchPoints(pts);//获取当前闭合等高线节点
-
- //由闭合等高线的几何中心和中间节点创建另一条示坡线,以几何中心作为基点延长
- Line slpline2 = new Line(center, pts[pts.Count / 2 - 1]);
- blocktablerecord.AppendEntity(slpline2);
- trans.AddNewlyCreatedDBObject(slpline2, true);
- slpline2 = trans.GetObject(slpline2.Id, OpenMode.ForWrite) as Line;
- Matrix3d mt2 = Matrix3d.Scaling(1.5, center);
- slpline2.TransformBy(mt2);
-
- ptcoll.Clear();
- //获取示坡线与闭合等高线的交点,将示坡线由此打断,删除闭合等高线内的部分
- slpline2.IntersectWith(pll, Intersect.OnBothOperands, ptcoll, IntPtr.Zero, IntPtr.Zero);
- DBObjectCollection objcoll1 = slpline2.GetSplitCurves(ptcoll);
- slpline2.Erase();
- foreach (Entity ent in objcoll1)
- {
- Line plline = ent as Line;
- if (plline.StartPoint != pts[pts.Count / 2 - 1])
- {
- blocktablerecord.AppendEntity(plline);
- trans.AddNewlyCreatedDBObject(plline, true);
- objcoll1.Remove(plline);
- plline.Erase();
- }
- }
- Line slpline3 = objcoll1[0] as Line;
- slpline3.Layer = "8200";
- blocktablerecord.AppendEntity(slpline3);
- trans.AddNewlyCreatedDBObject(slpline3, true);
-
- //将闭合等高线和示坡线移回原来的位置
- Vector3d target1 = pll.StartPoint.GetVectorTo(tagpt);
- pll.TransformBy(Matrix3d.Displacement(target1));
-
- slpline1 = trans.GetObject(slpline1.Id, OpenMode.ForWrite) as Line;
- Vector3d target2 = slpline1.StartPoint.GetVectorTo(tagpt);
- slpline1.TransformBy(Matrix3d.Displacement(target2));
-
- slpline3 = trans.GetObject(slpline3.Id, OpenMode.ForWrite) as Line;
- Vector3d target3 = slpline3.StartPoint.GetVectorTo(ptss[ptss.Count / 2 - 1]);
- slpline3.TransformBy(Matrix3d.Displacement(target3));
-
- }
-
-
- //此等高线高程最低
- if (i == -1)
- {
- //获取几何中心
- Extents3d extents = pll.GeometricExtents;
- Point3d center = extents.MinPoint + (extents.MaxPoint - extents.MinPoint) / 2.0;
- Point3dCollection ptcoll = new Point3dCollection();
-
- //由几何中心到闭合等高线的起点画一条示坡线,将其以闭合等高线的起点作为基点缩短
- Line slpline = new Line(center, pll.StartPoint);
- blocktablerecord.AppendEntity(slpline);
- trans.AddNewlyCreatedDBObject(slpline, true);
- slpline = trans.GetObject(slpline.Id, OpenMode.ForWrite) as Line;
- Matrix3d mt1 = Matrix3d.Scaling(0.5, pll.StartPoint);
- slpline.TransformBy(mt1);
- slpline.Layer = "8200";
-
-
- //由闭合等高线的几何中心和中间节点创建另一条示坡线,以中间节点作为基点缩短
- Point3dCollection pts = new Point3dCollection();
- pll.GetStretchPoints(pts);
- Line slpline1 = new Line(center, pts[pts.Count / 2 - 1]);
- blocktablerecord.AppendEntity(slpline1);
- trans.AddNewlyCreatedDBObject(slpline1, true);
- slpline1 = trans.GetObject(slpline1.Id, OpenMode.ForWrite) as Line;
- Matrix3d mt2 = Matrix3d.Scaling(0.5, pts[pts.Count / 2 - 1]);
- slpline1.TransformBy(mt2);
- slpline1.Layer = "8200";
- }
- }
- }
- }
|