C# cass10 面积计算

运行环境Visual Studio 2022 c# cad2016 cass10

通过面积计算得到扩展数据,宗地面积 ,房屋占地面积,房屋使用面积

一、主要步骤

  1. 获取当前AutoCAD应用中的活动文档、数据库和编辑器对象。
  2. 创建一个选择过滤器,限制用户只能选择"宗地"图层上的LWPOLYLINE对象作为外部边界。
  3. 提示用户根据上述规则进行实体选择,并获取选择结果。
  4. 遍历所有被选中的外部多段线,确保所选多段线是闭合的且至少有一个顶点。
  5. 创建并填充一个表示外部多段线边界坐标的点集合。
  6. 使用多边形窗口选择方式让用户选择位于外部多段线内的实体。
  7. 遍历用户在内部区域所选的所有闭合多段线,计算房屋面积和附属面积。
  8. 计算宗地面积和输出结果。

二、完整代码

internal class zdfwmj
{public static List<string> filelist1 = new List<string>();public static List<string> filelist2 = new List<string>();public void fwzymj(){// 获取当前AutoCAD应用中的活动文档、数据库和编辑器对象Document doc = Application.DocumentManager.MdiActiveDocument;Database db = doc.Database;Editor ed = doc.Editor;string SelectedLayerName = CreatePalette.SelectedLayerName;NumberContainer numberContainer = new NumberContainer();//ed.WriteMessage("选择的图层:" + SelectedLayerName + "\n");// 创建一个选择过滤器,限制用户只能选择"宗地"图层上的LWPOLYLINE对象作为外部边界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))// 读取所选多段线{// 确保所选多段线是闭合的且至少有一个顶点double totalArea = 0; // 总面积double totalAreaZdmj = 0; // 总面积double totalAreaSYmj = 0; // 总面积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);// 定义你的扩展因子,比如 1.5 表示扩大1.5倍double scaleFactor = 1.2;// 将顶点向中心点平移,然后按比例缩放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;将文本添加到模型空间//using (Transaction transaction = db.TransactionManager.StartTransaction())//{//    BlockTable bt = transaction.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;//    BlockTableRecord ms = transaction.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;//    ms.AppendEntity(text);//    transaction.AddNewlyCreatedDBObject(text, true);//    transaction.Commit();//}outerPoints.Add(scaledPoint);}// 创建一个窗口选择过滤器,用于选择位于外部多段线内的所有实体SelectionFilter innerFilter = new SelectionFilter(new TypedValue[] {new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),new TypedValue((int)DxfCode.LayerName, "JMD")});// 使用多边形窗口选择方式让用户选择位于外部多段线内的实体PromptSelectionResult innerSelRes = ed.SelectWindowPolygon(outerPoints, innerFilter);// 检查用户是否成功在内部区域进行了实体选择if (innerSelRes.Status == PromptStatus.OK){SelectionSet innerSelectionSet = innerSelRes.Value;// 遍历用户在内部区域所选的所有闭合多段线foreach (ObjectId id2 in innerSelectionSet.GetObjectIds()){using (Polyline polyline2 = (Polyline)tr.GetObject(id2, OpenMode.ForRead)){if (polyline2.Closed && polyline2.NumberOfVertices > 0){Entity ent2 = (Entity)tr.GetObject(id2, OpenMode.ForWrite);//ent2.Color = Color.FromColorIndex(ColorMethod.ByAci, 3); // 示例:将颜色设为黄色//ed.UpdateScreen(); // 确保颜色更改即时生效filelist1.Clear();filelist2.Clear();int filelist1ii = 0;if (ent2 != null && ent2.XData != null){List<int> numbers01 = new List<int> { 141161, 141121, 141151 };//房屋编码List<int> numbers02 = new List<int> { 141800, 140001, 143130, 143111, 143112 };//房屋附属编码ResultBuffer rb = ent2.GetXDataForApplication("SOUTH");string xdata = rb.ToString();foreach (TypedValue tv in rb){filelist1.Add(tv.TypeCode.ToString());//码filelist2.Add(tv.Value.ToString());//值}filelist1ii = filelist1.Count();//房屋面积if (filelist1ii == 3){if (numbers01.Contains(Convert.ToInt32(filelist2[1]))){string fwjg = numberContainer.GetDescription(Convert.ToInt32(filelist2[1]));int fileValue;if (int.TryParse(filelist2[2], out fileValue)){double calculatedUsageArea = polyline2.Area * fileValue;//ed.WriteMessage($"\n房屋面积信息:{fwjg}{fileValue} 占地面积:{polyline2.Area:N2} 使用面积:{calculatedUsageArea:N2}\n");totalAreaZdmj += polyline2.Area;totalAreaSYmj += calculatedUsageArea;using (Transaction transaction = db.TransactionManager.StartTransaction()){RegAppTable table02 = (RegAppTable)transaction.GetObject(doc.Database.RegAppTableId, OpenMode.ForWrite, false);ResultBuffer rb02 = new ResultBuffer();string appName02 = "扩展数据";if (!table02.Has(appName02)){RegAppTableRecord regAppRec = new RegAppTableRecord();regAppRec.Name = appName02;table02.Add(regAppRec);transaction.AddNewlyCreatedDBObject(regAppRec, true);}rb02.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName02));rb02.Add(new TypedValue((int)DxfCode.ExtendedDataReal, polyline2.Area));rb02.Add(new TypedValue((int)DxfCode.ExtendedDataReal, calculatedUsageArea));ent2.XData = rb02;transaction.Commit();}}else{//ed.WriteMessage("\n无法将文件列表中的值转换为整数以计算使用面积!");}}}if (filelist1ii == 2){ed.WriteMessage("\n附属编码:" + filelist2[1]);if (numbers02.Contains(Convert.ToInt32(filelist2[1]))){string fwjg = numberContainer.GetDescription(Convert.ToInt32(filelist2[1]));//double fsmj = FwmjArea(polyline2, db, ed, tr);TypedValue[] tvs = new TypedValue[]{new TypedValue((int)DxfCode.Operator, "<and"),new TypedValue((int)DxfCode.Start, "TEXT"),new TypedValue((int)DxfCode.LayerName, "房屋附属1"),new TypedValue((int)DxfCode.Operator, "and>")};SelectionFilter sf = new SelectionFilter(tvs);PromptSelectionResult psr = ed.SelectAll(sf);SelectionSet ss = psr.Value;foreach (SelectedObject so in ss){DBText text = tr.GetObject(so.ObjectId, OpenMode.ForRead) as DBText;if (IsPointInside(polyline2, text.Position)){string input = text.TextString;//文字分解string[] parts = input.Split(' ');foreach (string part in parts){// 按中文逗号分割键值对string[] keyValue = part.Split(','); // 注意:这里的逗号是中文逗号,不是英文逗号if (keyValue.Length == 2){string key = keyValue[0];string value = keyValue[1];//ed.WriteMessage("键: " + key + ", 值: " + value+ "\n");bool result = key.Contains("Q");if (result){totalArea += polyline2.Area;//ed.WriteMessage($"全:{key}{value} 附属面积:{polyline2.Area:N2}\n");}result = key.Contains("B");if (result){totalArea += polyline2.Area / 2;//ed.WriteMessage($"半:{key}{value} 附属面积:{polyline2.Area:N2}\n");}}else{//ed.WriteMessage("未能分割出键值对:" + part);}}using (Transaction transaction = db.TransactionManager.StartTransaction()){RegAppTable table02 = (RegAppTable)transaction.GetObject(doc.Database.RegAppTableId, OpenMode.ForWrite, false);ResultBuffer rb02 = new ResultBuffer();string appName02 = "扩展数据";if (!table02.Has(appName02)){RegAppTableRecord regAppRec = new RegAppTableRecord();regAppRec.Name = appName02;table02.Add(regAppRec);transaction.AddNewlyCreatedDBObject(regAppRec, true);}rb02.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName02));rb02.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, input));rb02.Add(new TypedValue((int)DxfCode.ExtendedDataReal, totalArea));ent2.XData = rb02;transaction.Commit();}//ed.WriteMessage($"房屋附属:{input} 附属面积:{totalArea:N2}\n");}}   }}}}}}}Entity ent01 = tr.GetObject(outerId, OpenMode.ForWrite) as Entity;RegAppTable table = (RegAppTable)tr.GetObject(doc.Database.RegAppTableId, OpenMode.ForWrite, false);ResultBuffer rb01 = new ResultBuffer();string appName = "扩展数据";if (!table.Has(appName)){RegAppTableRecord regAppRec = new RegAppTableRecord();regAppRec.Name = appName;table.Add(regAppRec);tr.AddNewlyCreatedDBObject(regAppRec, true);}rb01.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName));rb01.Add(new TypedValue((int)DxfCode.ExtendedDataReal, outerPolyline.Area));rb01.Add(new TypedValue((int)DxfCode.ExtendedDataReal, totalAreaZdmj));rb01.Add(new TypedValue((int)DxfCode.ExtendedDataReal, (totalAreaSYmj + totalArea)));ent01.XData = rb01;}//ed.WriteMessage($"\n宗地面积:{outerPolyline.Area:N2} \n\n房屋占地面积:{totalAreaZdmj:N2}\n房屋使用面积:{(totalAreaSYmj + totalArea):N2}\n");}}tr.Commit();}}}/// <summary>FwmjAreapublic double FwmjArea(Polyline polyline, Database db, Editor ed, Transaction tr){Point3dCollection outerPoints = new Point3dCollection(); // 创建并填充一个表示外部多段线边界坐标的点集合double areaFWFS = 0;//房屋附属面积for (int i = 0; i < polyline.NumberOfVertices; i++){Point3d point = polyline.GetPoint3dAt(i);outerPoints.Add(point);}// 创建一个窗口选择过滤器,用于选择位于外部多段线内的所有实体SelectionFilter innerFilter = new SelectionFilter(new TypedValue[] {new TypedValue((int)DxfCode.Operator, "<and"),new TypedValue((int)DxfCode.Start, "TEXT"),new TypedValue((int)DxfCode.LayerName, "房屋附属1"),new TypedValue((int)DxfCode.Operator, "and>")});// 使用多边形窗口选择方式让用户选择位于外部多段线内的实体PromptSelectionResult innerSelRes = ed.SelectAll(innerFilter);if (innerSelRes.Status == PromptStatus.OK){SelectionSet innerSelectionSet = innerSelRes.Value;foreach (SelectedObject so in innerSelectionSet){DBText text = tr.GetObject(so.ObjectId, OpenMode.ForRead) as DBText;if (IsPointInside(polyline, text.Position)){string input = text.TextString;//ed.WriteMessage("\n房屋附属文字2:", input.ToString());//ed.WriteMessage("\n房屋附属文字2:", polyline.Area);}}}return areaFWFS;}/// </summary>/// <param name="polyline"></param>/// <param name="point"></param>/// <returns></returns>// 定义一个方法,输入参数为一个多段线对象和一个三维点,返回值为布尔类型,表示该点是否在多段线内部public bool IsPointInside(Polyline polyline, Point3d point){// 初始化交叉次数变量为0,用于记录点与多段线各线段相交的次数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);// 如果线段两端点都在检测点Y轴上方或下方,则此线段与过检测点的水平线不相交,跳过此次循环if (start.Y > point.Y && end.Y > point.Y)continue;if (start.Y <= point.Y && end.Y <= point.Y)continue;// 如果检测点X坐标小于线段起点和终点的X坐标最小值,则此线段位于检测点左侧,跳过此次循环if (point.X < Math.Min(start.X, end.X))continue;// 计算线段的斜率,并根据直线方程计算线段与过检测点Y坐标水平线的交点横坐标double slope = (end.Y - start.Y) / (end.X - start.X);double intersectX = start.X + (point.Y - start.Y) / slope;// 如果检测点X坐标大于等于交点横坐标,则表示检测点在线段的一侧,增加交叉次数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;}// GetCenterOfPolyline 是一个假设存在的方法,用于计算多边形的中心点private 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);}
}

 //有需要cad二次开发可以私信进行联系
//感谢大家的点赞,收藏,转发,关注

   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/485533.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第3.6章:StarRocks数据导入——DataX StarRocksWriter

一、Datax 1.1 DataX 3.0概述 DataX3.0是一个异构数据源离线同步工具&#xff0c;可以方便的对各种异构数据源进行高效的数据同步。 其github地址为&#xff1a; https://github.com/alibaba/DataX/blob/master/introduction.mdhttps://github.com/alibaba/DataX/blob/mast…

了解红帽认证,看这篇就够了!

红帽公司成立于1993年&#xff0c;是全球首家收入超10亿美元的开源公司&#xff0c;总部位于美国&#xff0c;分支机构遍布全球。 红帽公司作为全球领先的开源和Linux系统提供商&#xff0c;其产品已被业界广泛认可并使用&#xff0c;尤其是RHEL系统在业内拥有超高的Linux系统…

体验LobeChat搭建私人聊天应用

LobeChat是什么 LobeChat 是开源的高性能聊天机器人框架&#xff0c;支持语音合成、多模态、可扩展的&#xff08;Function Call&#xff09;插件系统。支持一键免费部署私人 ChatGPT/LLM 网页应用程序。 地址&#xff1a;https://github.com/lobehub/lobe-chat 为什么要用Lobe…

【rust】vscode下rust-analyzer和Rust Test Lens的Lens

背景 一个粉丝问&#xff1a; 我编辑的launch.json为什么只在按F5的时候工作 按这个debug按钮就不工作&#xff1f; 那在哪改这个插件的配置文档&#xff1f;我一直用的F5 今天上午才注意到这个问题&#xff0c;比如怎么改程序的命令行参数&#xff0c;我意思是如果我非要用…

pikachu靶场-CSRF

CSRF: 介绍&#xff1a; Cross-site request forgery简称为"CSRF”。 在CSF的攻击场景中攻击者会伪造一个请求&#xff08;这个请求一般是一个链接&#xff09; 然后欺骗目标用户进行点击&#xff0c;用户一旦点击了这个请求&#xff0c;整个攻击也就完成了&#xff0…

虹科方案 | 冷链物流温度监测解决方案

来源&#xff1a;虹科环境监测技术 虹科方案 | 冷链物流温度监测解决方案 原文链接&#xff1a;https://mp.weixin.qq.com/s/LojawqCT1Rh266A8z3BM-Q 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; #温度监测 #制药供应链 #冷链物流 全球制药、医疗保健、生命科学和…

【Linux进程】冯·诺依曼体系结构以及操作系统的深入理解

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1.冯诺依曼体系结构特…

Python和Jupyter简介

在本notebook中&#xff0c;你将&#xff1a; 1、学习如何使用一个Jupyter notebook 2、快速学习Python语法和科学库 3、学习一些IPython特性&#xff0c;我们将在之后教程中使用。 这是什么&#xff1f; 这是只为你运行在一个个人"容器"中的一个Jupyter noteboo…

适合中国人体质的低成本创业项目,抖音小店抓住小钱到大钱的之路

大家好&#xff0c;我是电商花花。 人啊&#xff0c;这一辈子想要赚钱&#xff0c;想要脱贫致富&#xff0c;小钱靠勤&#xff0c;中财靠运&#xff0c;大富靠命。 我还依稀记得母亲说的一句话&#xff0c;小钱不勤不聚&#xff0c;还谈何赚大钱&#xff0c;所有的大钱也都是…

软件常见设计模式

设计模式 设计模式是为了解决在软件开发过程中遇到的某些问题而形成的思想。同一场景有多种设计模式可以应用&#xff0c;不同的模式有各自的优缺点&#xff0c;开发者可以基于自身需求选择合适的设计模式&#xff0c;去解决相应的工程难题。 良好的软件设计和架构&#xff0…

OpenCV运行gstreamer管道获取相机数据,处理以后,再交给gstreamer显示(QT实现)

效果: 前言 无意中发现,OpenCV也可以运行gstreamer的命令管道,然后使用appsink来与OpenCV连接起来进行处理,在不断测试之下,先后实现了以下功能: 1. OpenCV运行gstreamer命令,通过appsink传递给OpenCV显示 2. OpenCV运行gstreamer命令,然后再把Mat图像数据通过appsrc传…

ProtoBuf认识与Windows下的安装

protobuf简介 Protobuf 是 Protocol Buffers 的简称&#xff0c;它是 Google 公司开发的一种数据描述语言&#xff0c;是一种轻便高效的结 构化数据存储格式&#xff0c;可以用于结构化数据&#xff0c;或者说序列化。它很适合做数据存储 或 RPC 数据交换格 式 。可用于通讯…