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>FwmjArea
    public 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二次开发可以私信进行联系
//感谢大家的点赞,收藏,转发,关注

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值