当前位置:   article > 正文

C# Cad2016二次开发获取封闭多段线指定图层文本信息(四)

C# Cad2016二次开发获取封闭多段线指定图层文本信息(四)

 用来获取指定图层中在封闭多段线内的文字信息。

一、主要步骤如下:

1、获取当前活动的文档并赋值给变量'doc'。

2、获取文档的数据库并赋值给变量'db'。

3、获取文档的编辑器并赋值给变量'ed'。

  1. //1获取当前激活的文档(活动文档)并将其赋给doc变量。
  2. Document doc = Application.DocumentManager.MdiActiveDocument;
  3. //2 将doc文档的数据库(Database)赋给db变量。
  4. Database db = doc.Database;
  5. //3 将doc文档的编辑器(Editor)赋给ed变量。
  6. Editor ed = doc.Editor;

4、使用PromptEntityOptions类创建实体选择的选项,提示用户选择实体。

5、调用peo的SetRejectMessage方法,传入一个字符串参数作为拒绝消息。如果用户没有选择一个封闭的多段线,将会显示这个拒绝消息。

6、调用peo的AddAllowedClass方法。这个方法用于指定允许用户选择的实体类型。在这里,我们传入typeof(Polyline)作为参数,表示只允许用户选择封闭的多段线实体。

7、调用ed(Editor对象)的GetEntity方法,传入peo作为参数,来获取用户选择的实体。这个方法将返回PromptEntityResult对象per,包含了用户选择的实体信息。

  1. PromptEntityOptions peo = new PromptEntityOptions("\n选择封闭多段线:");
  2. peo.SetRejectMessage("\n请选择封闭多段线。");
  3. peo.AddAllowedClass(typeof(Polyline), true);
  4. PromptEntityResult per = ed.GetEntity(peo);

 8、检查实体选择结果的状态是否为PromptStatus.OK,如果是则表示用户已经成功选择了一个实体。

  1. if (per.Status != PromptStatus.OK)
  2. return;

 9、事务处理

  1. using (Transaction tr = db.TransactionManager.StartTransaction())
  2. {
  3. }

10、根据给定的ObjectId从数据库中获取Polyline(多段线)对象

 Polyline polyline = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Polyline;

 11、判断多段线是否闭合

  1. if (polyline.Closed)
  2. {
  3. }

 12、创建过滤器

  1. TypedValue[] tvs = new TypedValue[]
  2. {
  3. new TypedValue((int)DxfCode.Operator, "<and"),
  4. new TypedValue((int)DxfCode.Start, "TEXT"),
  5. new TypedValue((int)DxfCode.LayerName, layerName),
  6. new TypedValue((int)DxfCode.Operator, "and>")
  7. };

13、通过SelectionFilter和ed.SelectAll方法根据条件筛选出符合条件的文字实体。

  1. SelectionFilter sf = new SelectionFilter(tvs);
  2. PromptSelectionResult psr = ed.SelectAll(sf);

 14、然后通过循环遍历选择集中的文字实体对象,使用IsPointInside方法判断文字实体的位置是否在封闭多段线内,如果是,则输出文字内容。

  1. if (psr.Status == PromptStatus.OK)
  2. {
  3. SelectionSet ss = psr.Value;
  4. foreach (SelectedObject so in ss)
  5. {
  6. DBText text = tr.GetObject(so.ObjectId, OpenMode.ForRead) as DBText;
  7. if (IsPointInside(polyline,text.Position))
  8. {
  9. ed.WriteMessage("\n文字内容:{0}", text.TextString+ text.Position.X+ text.Position.Y);
  10. }
  11. }
  12. }

 

 二、以下完整代码

  1. //获取封闭多段线指定图层文本信息
  2. [CommandMethod("getybh")]
  3. public void getybh()
  4. {
  5. string layerName = "预编号";
  6. Document doc = Application.DocumentManager.MdiActiveDocument;
  7. Database db = doc.Database;
  8. Editor ed = doc.Editor;
  9. PromptEntityOptions peo = new PromptEntityOptions("\n选择封闭多段线:");
  10. peo.SetRejectMessage("\n请选择封闭多段线。");
  11. peo.AddAllowedClass(typeof(Polyline), true);
  12. PromptEntityResult per = ed.GetEntity(peo);
  13. if (per.Status != PromptStatus.OK)
  14. return;
  15. using (Transaction tr = db.TransactionManager.StartTransaction())
  16. {
  17. Polyline polyline = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Polyline;
  18. if (polyline.Closed)
  19. {
  20. TypedValue[] tvs = new TypedValue[]
  21. {
  22. new TypedValue((int)DxfCode.Operator, "<and"),
  23. new TypedValue((int)DxfCode.Start, "TEXT"),
  24. new TypedValue((int)DxfCode.LayerName, layerName),
  25. new TypedValue((int)DxfCode.Operator, "and>")
  26. };
  27. SelectionFilter sf = new SelectionFilter(tvs);
  28. PromptSelectionResult psr = ed.SelectAll(sf);
  29. if (psr.Status == PromptStatus.OK)
  30. {
  31. SelectionSet ss = psr.Value;
  32. foreach (SelectedObject so in ss)
  33. {
  34. DBText text = tr.GetObject(so.ObjectId, OpenMode.ForRead) as DBText;
  35. if (IsPointInside(polyline,text.Position))
  36. {
  37. ed.WriteMessage("\n文字内容:{0}", text.TextString+ text.Position.X+ text.Position.Y);
  38. }
  39. }
  40. }
  41. }
  42. else
  43. {
  44. ed.WriteMessage("\n所选实体不是封闭多段线。");
  45. }
  46. tr.Commit();
  47. }
  48. }
  49. public bool IsPointInside(Polyline polyline, Point3d point)
  50. {
  51. int crossings = 0;
  52. for (int i = 0; i < polyline.NumberOfVertices; i++)
  53. {
  54. Point3d start = polyline.GetPoint3dAt(i);
  55. Point3d end = polyline.GetPoint3dAt((i + 1) % polyline.NumberOfVertices);
  56. if (start.Y > point.Y && end.Y > point.Y)
  57. {
  58. continue;
  59. }
  60. if (start.Y <= point.Y && end.Y <= point.Y)
  61. {
  62. continue;
  63. }
  64. if (point.X < Math.Min(start.X, end.X))
  65. {
  66. continue;
  67. }
  68. double slope = (end.Y - start.Y) / (end.X - start.X);
  69. double intersectX = start.X + (point.Y - start.Y) / slope;
  70. if (point.X >= intersectX)
  71. {
  72. crossings++;
  73. }
  74. }
  75. return (crossings % 2) == 1;
  76. }

 三、总结 

这段代码是用来获取指定图层中在封闭多段线内的文字信息。

代码首先获取活动文档、数据库和编辑器对象。

然后通过PromptEntityOptions指定选择封闭多段线的选项,并通过ed.GetEntity方法获取用户选择的实体。

接下来,代码开启一个事务,并通过事务获取选择的封闭多段线对象。

如果封闭多段线是闭合的,代码创建一个TypedValue数组,指定筛选文字实体的条件。然后通过SelectionFilter和ed.SelectAll方法根据条件筛选出符合条件的文字实体。

然后通过循环遍历选择集中的文字实体对象,使用IsPointInside方法判断文字实体的位置是否在封闭多段线内,如果是,则输出文字内容。

如果选择的实体不是封闭多段线,代码显示错误信息。

最后,代码提交事务。

IsPointInside方法是用来判断一个点是否在一个多段线内部的方法。该方法通过遍历多段线的每个边,计算边和点的位置关系,最终判断点是否在多段线内部。

该代码的功能是获取指定图层中在指定的封闭多段线内的文字信息,并输出文字内容。

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/111764
推荐阅读
相关标签
  

闽ICP备14008679号