运行环境Visual Studio 2022 c# cad2016 cass10
根据 “预编号” “权利人”图层对应信息 批量添加到宗地图层
一、主要步骤
-
zdimport
方法:这个方法用于导入宗地信息。首先通过调用 AutoCAD API 获取当前活动文档、数据库和编辑器对象。然后根据CreatePalette.SelectedLayerName
获取用户选择的图层名字,并通过FindJZDLayer
方法找到名为 "JZD" 的图层的 ObjectId。接下来,通过创建一个外部多段线的选择过滤器
outerFilter
来选择用户在指定图层上选择的所有外部多段线。如果选择成功,就开始一个数据库事务tr
,以确保数据的一致性。在每个被选中的外部多段线上进行迭代,首先读取外部多段线的属性,包括是否闭合和顶点的数量。如果多段线是闭合的且顶点数量大于0,则需要进一步处理。
通过调用
GetCenterOfPolyline
方法计算多边形的中心点,并根据一定的比例因子对顶点进行缩放计算,得到缩放后的点scaledPoint
。然后创建一个文本对象
DBText
,设置其文本内容为顶点的索引值,并将其位置设置为缩放后的点。将缩放后的点添加到一个点集合outerPoints
中,以备后续操作使用。接下来,创建一个用于选择内部文本对象的选择过滤器
innerFilter
,其中包含实体类型为 "TEXT"。然后使用
ed.SelectWindowPolygon
方法根据外部多段线的顶点集合和内部选择过滤器选择所有位于多段线内部的文本对象。如果选择成功,则开始处理内部文本对象。在内部文本对象的迭代中,根据文本对象所在的图层名称判断其属性,并将预编号和权利人信息保存到相应的变量中,并使用
ed.WriteMessage
方法输出到编辑器中。最后,通过创建一个新的
ResultBuffer
对象rb
,添加各种扩展数据(包括预编号、权利人等),并将其赋值给外部多段线的XData
属性。还将外部多段线的图层设置为 "JZD" 图层,并提交事务。 -
GetCenterOfPolyline
方法:这个方法用于计算多段线的中心点。它遍历多段线的每个顶点,将顶点的 X、Y、Z 坐标分别累加求和,最后返回坐标的平均值作为中心点的坐标。 -
FindJZDLayer
方法:这个方法用于在图层表中查找名为 "JZD" 的图层。它遍历图层表,比较每个图层记录的名称是否与 "JZD" 相同,如果找到了匹配的图层记录,则返回该图层的 ObjectId。 -
GetOrCreateJZDLayer
方法:这个方法用于获取名为 "JZD" 的图层的 ObjectId。首先检查图层表中是否已经存在名为 "JZD" 的图层,如果存在则直接返回该图层的 ObjectId,如果不存在则创建一个新的图层记录,并添加到图层表中,最后返回新图层的 ObjectId。 -
IsPointInside
方法:这个方法用于判断一个点是否在给定的多段线内部。它使用交叉次数的方法来判断,如果点与多段线相交的次数为奇数,则认为该点在多段线内部,否则认为在外部。 -
CountCharacterOccurrences
方法:这个静态方法用于统计一个字符串中某个子字符串出现的次数。它使用IndexOf
方法查找子字符串在字符串中的位置,并通过迭代进行计数,直到找不到子字符串为止。
二、完整代码
namespace 宗地信息.宗地
{
internal class zd初始化
{
public static void zdimport()
{
// 获取当前AutoCAD应用中的活动文档、数据库和编辑器对象
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
string SelectedLayerName = CreatePalette.SelectedLayerName;
ObjectId jzdLayerId = FindJZDLayer(db); // 使用实例调用 FindJZDLayer 方法
SelectionFilter outerFilter = new SelectionFilter(new TypedValue[] {
new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),
new TypedValue((int)DxfCode.LayerName, SelectedLayerName)
});
PromptSelectionResult outerSelRes = ed.GetSelection(outerFilter);
if (outerSelRes.Status == PromptStatus.OK)
{
using (Transaction tr = db.TransactionManager.StartTransaction())// 开始事务处理以确保数据一致性
{
foreach (ObjectId outerId in outerSelRes.Value.GetObjectIds())// 遍历所有被选中的外部多段线
{
using (Polyline outerPolyline = (Polyline)tr.GetObject(outerId, OpenMode.ForRead))// 读取所选多段线
{
if (outerPolyline.Closed && outerPolyline.NumberOfVertices > 0)
{
Point3dCollection outerPoints = new Point3dCollection();
for (int i = 0; i < outerPolyline.NumberOfVertices; i++)
{
Point3d point = outerPolyline.GetPoint3dAt(i);
Point3d center = GetCenterOfPolyline(outerPolyline);
double scaleFactor = 1.1;
Point3d scaledPoint = new Point3d(
(point.X - center.X) * scaleFactor + center.X,
(point.Y - center.Y) * scaleFactor + center.Y,
(point.Z - center.Z) * scaleFactor + center.Z
);
// 创建并设置文本对象
DBText text = new DBText();
text.TextString = i.ToString();
//text.Height = 1; // 文字高度设为1个单位
text.Position = scaledPoint;
outerPoints.Add(scaledPoint);
}
SelectionFilter innerFilter = new SelectionFilter(new TypedValue[] {
new TypedValue((int)DxfCode.Start, "TEXT"), // 实体类型为TEXT
});
PromptSelectionResult innerSelRes = ed.SelectWindowPolygon(outerPoints, innerFilter);
if (innerSelRes.Status == PromptStatus.OK)
{
string ybh = "";
string qlr = "";
foreach (ObjectId id2 in innerSelRes.Value.GetObjectIds())
{
DBText text = tr.GetObject(id2, OpenMode.ForRead) as DBText;
if (text != null)
{
if (text.Layer == "预编号")
{
ybh = text.TextString;
ed.WriteMessage("预编号:" + ybh + "\n");
}
if (text.Layer == "权利人")
{
qlr = text.TextString;
ed.WriteMessage("权利人:" + qlr + "\n");
}
}
}
ed.WriteMessage("\n 修改XData01。");
// 遍历ResultBuffer以查看数据
using (Transaction transaction = db.TransactionManager.StartTransaction())
{
Entity ent01 = transaction.GetObject(outerId, OpenMode.ForWrite) as Entity;
RegAppTable table = (RegAppTable)transaction.GetObject(doc.Database.RegAppTableId, OpenMode.ForWrite, false);
ResultBuffer rb = new ResultBuffer();
string appName = "YBDJH";
if (!table.Has(appName))
{
RegAppTableRecord regAppRec = new RegAppTableRecord();
regAppRec.Name = appName;
table.Add(regAppRec);
transaction.AddNewlyCreatedDBObject(regAppRec, true);
}
rb.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName));
rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, ybh));
appName = "SOUTH";
if (!table.Has(appName))
{
RegAppTableRecord regAppRec = new RegAppTableRecord();
regAppRec.Name = appName;
table.Add(regAppRec);
transaction.AddNewlyCreatedDBObject(regAppRec, true);
}
rb.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName));
rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, "300000"));
rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, "JC"+ybh));
rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, qlr));
rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, "0710"));
appName = "JZSJMJ";
if (!table.Has(appName))
{
RegAppTableRecord regAppRec = new RegAppTableRecord();
regAppRec.Name = appName;
table.Add(regAppRec);
transaction.AddNewlyCreatedDBObject(regAppRec, true);
}
rb.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName));
rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, ybh));
ent01.XData = rb;
ent01.LayerId = jzdLayerId;
transaction.Commit();
ed.WriteMessage("\n 修改XData。");
}
}
}
}
}
tr.Commit();
}
}
}
// GetCenterOfPolyline 是一个假设存在的方法,用于计算多边形的中心点
private static Point3d GetCenterOfPolyline(Polyline polyline)
{
{
double xSum = 0, ySum = 0, zSum = 0;
for (int i = 0; i < polyline.NumberOfVertices; i++)
{
Point3d vertex = polyline.GetPoint3dAt(i);
xSum += vertex.X;
ySum += vertex.Y;
zSum += vertex.Z;
}
return new Point3d(xSum / polyline.NumberOfVertices, ySum / polyline.NumberOfVertices, zSum / polyline.NumberOfVertices);
}
}
public static ObjectId FindJZDLayer(Database db)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
LayerTable lt = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
if (lt == null)
{
return ObjectId.Null;
}
foreach (ObjectId layerId in lt)
{
LayerTableRecord ltr = tr.GetObject(layerId, OpenMode.ForRead) as LayerTableRecord;
if (ltr.Name.Equals("JZD", StringComparison.OrdinalIgnoreCase))
{
return layerId;
}
}
return ObjectId.Null;
}
}
public ObjectId GetOrCreateJZDLayer(Database db)
{
string layerName = "JZD";
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// 检查图层是否已存在
LayerTable lt = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
if (lt.Has("JZD"))
{
return lt["JZD"];
}
else
{
LayerTableRecord newLayer = new LayerTableRecord();
newLayer.Name = layerName;
ObjectId newLayerId = lt.Add(newLayer);
tr.AddNewlyCreatedDBObject(newLayer, true);
tr.Commit();
return newLayerId;
}
}
}
// 定义一个方法,输入参数为一个多段线对象和一个三维点,返回值为布尔类型,表示该点是否在多段线内部
public bool IsPointInside(Polyline polyline, Point3d point)
{
int crossings = 0;
for (int i = 0; i < polyline.NumberOfVertices; i++)
{
Point3d start = polyline.GetPoint3dAt(i);
int nextIndex = (i + 1) % polyline.NumberOfVertices;
Point3d end = polyline.GetPoint3dAt(nextIndex);
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;
}
//包含字符 出现次数
public static int CountCharacterOccurrences(string str, string substring)
{
if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(substring))
return 0;
int index = 0, count = 0;
while ((index = str.IndexOf(substring, index)) != -1)
{
count++;
index += substring.Length; // 移动到下一个可能的位置
}
return count;
}
}
}
//有需要cad二次开发可以私信进行联系
//感谢大家的点赞,收藏,转发,关注