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

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

一、主要步骤如下:

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

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

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

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

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

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

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

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

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

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

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

 9、事务处理

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

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

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

 11、判断多段线是否闭合

if (polyline.Closed)
{

}

 12、创建过滤器

TypedValue[] tvs = new TypedValue[]
             {
         new TypedValue((int)DxfCode.Operator, "<and"),
         new TypedValue((int)DxfCode.Start, "TEXT"),
         new TypedValue((int)DxfCode.LayerName, layerName),
         new TypedValue((int)DxfCode.Operator, "and>")
             };

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

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

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

if (psr.Status == PromptStatus.OK)
             {
                 SelectionSet ss = psr.Value;
                 foreach (SelectedObject so in ss)
                 {
                     DBText text = tr.GetObject(so.ObjectId, OpenMode.ForRead) as DBText;
                     if (IsPointInside(polyline,text.Position))
                     {
                         ed.WriteMessage("\n文字内容:{0}", text.TextString+ text.Position.X+ text.Position.Y);
                     }
                 }
             }

 

 二、以下完整代码

 //获取封闭多段线指定图层文本信息
 [CommandMethod("getybh")]
 public void getybh()
 {
     string layerName = "预编号";
     Document doc = Application.DocumentManager.MdiActiveDocument;
     Database db = doc.Database;
     Editor ed = doc.Editor;

     PromptEntityOptions peo = new PromptEntityOptions("\n选择封闭多段线:");
     peo.SetRejectMessage("\n请选择封闭多段线。");
     peo.AddAllowedClass(typeof(Polyline), true);
     PromptEntityResult per = ed.GetEntity(peo);
     if (per.Status != PromptStatus.OK)
         return;

     using (Transaction tr = db.TransactionManager.StartTransaction())
     {
         Polyline polyline = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Polyline;
         if (polyline.Closed)
         {
             TypedValue[] tvs = new TypedValue[]
             {
         new TypedValue((int)DxfCode.Operator, "<and"),
         new TypedValue((int)DxfCode.Start, "TEXT"),
         new TypedValue((int)DxfCode.LayerName, layerName),
         new TypedValue((int)DxfCode.Operator, "and>")
             };

             SelectionFilter sf = new SelectionFilter(tvs);
             PromptSelectionResult psr = ed.SelectAll(sf);
             if (psr.Status == PromptStatus.OK)
             {
                 SelectionSet ss = psr.Value;
                 foreach (SelectedObject so in ss)
                 {
                     DBText text = tr.GetObject(so.ObjectId, OpenMode.ForRead) as DBText;
                     if (IsPointInside(polyline,text.Position))
                     {
                         ed.WriteMessage("\n文字内容:{0}", text.TextString+ text.Position.X+ text.Position.Y);
                     }
                 }
             }
         }
         else
         {
             ed.WriteMessage("\n所选实体不是封闭多段线。");
         }

         tr.Commit();
     }
 }



 public bool IsPointInside(Polyline polyline, Point3d point)
 {
     int crossings = 0;

     for (int i = 0; i < polyline.NumberOfVertices; i++)
     {
         Point3d start = polyline.GetPoint3dAt(i);
         Point3d end = polyline.GetPoint3dAt((i + 1) % polyline.NumberOfVertices);

         if (start.Y > point.Y && end.Y > point.Y)
         {
             continue;
         }

         if (start.Y <= point.Y && end.Y <= point.Y)
         {
             continue;
         }

         if (point.X < Math.Min(start.X, end.X))
         {
             continue;
         }

         double slope = (end.Y - start.Y) / (end.X - start.X);
         double intersectX = start.X + (point.Y - start.Y) / slope;

         if (point.X >= intersectX)
         {
             crossings++;
         }
     }

     return (crossings % 2) == 1;
 }

 三、总结 

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

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

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

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

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

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

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

最后,代码提交事务。

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

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

 

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用region对象分割多段线C#代码示例: ```csharp using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; public void SplitPolylineByRegion(Polyline polyline, Region region) { Database db = HostApplicationServices.WorkingDatabase; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); bool isInsideRegion = false; Point3dCollection points = new Point3dCollection(); for (int i = 0; i < polyline.NumberOfVertices; i++) { Point3d point = polyline.GetPoint3dAt(i); if (region.IsPointInside(point, Vector3d.ZAxis)) { if (!isInsideRegion) { if (points.Count > 1) { Polyline newPolyline = new Polyline(points.Count); for (int j = 0; j < points.Count; j++) { newPolyline.AddVertexAt(j, points[j], 0, 0, 0); } btr.AppendEntity(newPolyline); tr.AddNewlyCreatedDBObject(newPolyline, true); } points = new Point3dCollection(); } isInsideRegion = true; } else { if (isInsideRegion) { points.Add(point); } isInsideRegion = false; } } if (points.Count > 1) { Polyline newPolyline = new Polyline(points.Count); for (int j = 0; j < points.Count; j++) { newPolyline.AddVertexAt(j, points[j], 0, 0, 0); } btr.AppendEntity(newPolyline); tr.AddNewlyCreatedDBObject(newPolyline, true); } tr.Commit(); } } ``` 这个方法接受两个参数,一个是多段线对象,另一个是region对象。方法会遍历多段线的所有顶点,判断每个顶点是否在region内部。如果顶点在region内部,就将其添加到新的多段线中;如果顶点不在region内部,就将之前的顶点组成的多段线添加到图形数据库中,并开始新的多段线。 注意,此代码示例仅供参考,并不保证在所有情况下都能正常工作。您需要根据具体的项目需求进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值