用来获取指定图层中在封闭多段线内的文字信息。
一、主要步骤如下:
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方法是用来判断一个点是否在一个多段线内部的方法。该方法通过遍历多段线的每个边,计算边和点的位置关系,最终判断点是否在多段线内部。
该代码的功能是获取指定图层中在指定的封闭多段线内的文字信息,并输出文字内容。