CAD环境中求算接合表面积

为了作业方便,一般会将某个区域按照某种规则划分成单个的小区域,这样就会形成接合表。对于接合表重要的信息主要有单元名称和单元名称所对应的区域(在CAD中用Polyline2d表示)。作业过程中通常会统计接合表各作业单元的接合表面积。

以下是CAD.Net求算过程,在中间环节使用了NPOI,目的是用Excel表输出对应的接合表面积和单元名称。

  首先申明输出Excel里面输出的列标题名称:

        public const string strTHField = "图号";
        public const string strJHBAreaField = "CAD结合表面积";
        public const string strDwgAreaField = "DWG图FQ层面积";
View Code

    求算接合表面积主要代码:

        [CommandMethod("cadjhbarea")]
        public void CalCADJHBArea()
        {

            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;
            ArrayList layerArrayList = GetLayerName(acCurDb);
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;


            string strJHBLayerGeometryName = "FQ";
            string strJHBLayerTextName = "MC";

            PromptStringOptions pStrOpts = new PromptStringOptions("
请输入结合表二维线图层名称: ");
            pStrOpts.AllowSpaces = false;
            pStrOpts.UseDefaultValue = true;
            pStrOpts.DefaultValue = strJHBLayerGeometryName;
            PromptResult pStrRes = acDoc.Editor.GetString(pStrOpts);
            if (pStrRes.Status == PromptStatus.OK)
            {
                strJHBLayerGeometryName = pStrRes.StringResult;
                ed.WriteMessage("您输入的结合表二维线图层名称为" + strJHBLayerGeometryName);
                if (!layerArrayList.Contains(strJHBLayerGeometryName))
                {
                    Application.ShowAlertDialog("未找到结合表二维线图层名称" + strJHBLayerGeometryName);
                    return;
                }
            }
            pStrOpts = new PromptStringOptions("
请输入结合表文字图层名称: ");
            pStrOpts.AllowSpaces = false;
            pStrOpts.UseDefaultValue = true;
            pStrOpts.DefaultValue = strJHBLayerTextName;
            pStrRes = acDoc.Editor.GetString(pStrOpts);
            if (pStrRes.Status == PromptStatus.OK)
            {
                strJHBLayerTextName = pStrRes.StringResult;
                ed.WriteMessage("您输入的结合表文字图层名称为" + strJHBLayerTextName);
                if (!layerArrayList.Contains(strJHBLayerTextName))
                {
                    Application.ShowAlertDialog("未找到结合表文字图层名称" + strJHBLayerTextName);
                    return;
                }
            }
            string strAppExcel = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "JHBArea.xls");

            HSSFWorkbook wk = null;
            ISheet pSheet = null;

            if (File.Exists(strAppExcel))
            {
                using (System.IO.FileStream fs = new System.IO.FileStream(strAppExcel, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                {
                    wk = new HSSFWorkbook(fs);
                    pSheet = wk.GetSheet("mysheet");
                    if (pSheet == null)
                    {
                        pSheet = wk.CreateSheet("mysheet");
                    }
                    ///创建列标题
                    CreateHeader(pSheet, wk, new string[] { strTHField, strJHBAreaField });


                }
            }
            else
            {
                using (System.IO.FileStream fs = new System.IO.FileStream(strAppExcel, FileMode.CreateNew, FileAccess.ReadWrite))
                {
                    wk = new HSSFWorkbook();
                    pSheet = wk.GetSheet("mysheet");
                    if (pSheet == null)
                    {
                        pSheet = wk.CreateSheet("mysheet");
                    }
                    CreateHeader(pSheet, wk, new string[] { strTHField, strJHBAreaField });
                }
            }

            //理论上iRowCount最后应该等于objJHBCol.Length
            int iRowCount = 0;
            ObjectIdCollection objJHBNameCol = GetObjectidsAtLayer(strJHBLayerTextName);
            ObjectIdCollection objJHBGeometryCol = GetObjectidsAtLayer(strJHBLayerGeometryName);
            List<DBText> allDBTextList = null;

            using (Transaction trans = acCurDb.TransactionManager.StartTransaction())
            {
                foreach (ObjectId strJHBGeometryID in objJHBGeometryCol)
                {
                    Entity jhbPolyline2dEntity = trans.GetObject(strJHBGeometryID, OpenMode.ForRead) as Entity;
                    Point3dCollection pPoint3DCol = new Point3dCollection();
                    Polyline2d pJHBPolyline2d = jhbPolyline2dEntity as Polyline2d;
                    if (pJHBPolyline2d != null)
                    {
                        foreach (ObjectId verId in pJHBPolyline2d)
                        {
                            Vertex2d ver2d = trans.GetObject(verId, OpenMode.ForRead) as Vertex2d;
                            if (!pPoint3DCol.Contains(ver2d.Position))
                            {
                                pPoint3DCol.Add(ver2d.Position);
                            }
                        }

                        TypedValue[] filList = new TypedValue[1] { new TypedValue((int)DxfCode.LayerName, strJHBLayerTextName) };
                        SelectionFilter pSelectionFilter = new SelectionFilter(filList);
                        PromptSelectionResult pPromptSelectionResult = ed.SelectCrossingPolygon(pPoint3DCol, pSelectionFilter);
                        if (pPromptSelectionResult.Status == PromptStatus.OK)
                        {
                            SelectionSet pSelectionSet = pPromptSelectionResult.Value;
                            ObjectId[] oids = pSelectionSet.GetObjectIds();
                            if (oids.Length == 1)
                            {
                                DBText pText = trans.GetObject(oids[0], OpenMode.ForRead) as DBText;
                                if (pText != null)
                                {
                                    int iRowIndex = GetTHRowIndexFromNOPIExcel(pText.TextString, pSheet);
                                    IRow pRow = null;
                                    if (iRowIndex == -1)
                                    {
                                        pRow = pSheet.CreateRow(++iRowCount);
                                        ed.WriteMessage("
正在写入第" + iRowCount.ToString() + "个@@@单元名:" + pText.TextString + "@@@的面积");
                                    }
                                    else
                                    {
                                        pRow = pSheet.GetRow(iRowIndex);
                                        ed.WriteMessage("
正在写入第" + String.Format("{0}", iRowIndex) + "个@@@单元名:" + pText.TextString + "@@@的面积");
                                    }

                                    ICell pCell = pRow.CreateCell(GetFieldColumnIndexFromNOPIExcel(strTHField, pSheet) > -1 ? GetFieldColumnIndexFromNOPIExcel(strTHField, pSheet) : 0);
                                    pCell.SetCellValue(pText.TextString);
                                    pCell = pRow.CreateCell(GetFieldColumnIndexFromNOPIExcel(strJHBAreaField, pSheet) > -1 ? GetFieldColumnIndexFromNOPIExcel(strJHBAreaField, pSheet) : 0);
                                    pCell.SetCellValue(pJHBPolyline2d.Area.ToString("f4"));


                                }
                            }
                            else
                            {
                                if (allDBTextList == null)
                                {
                                    allDBTextList = new List<DBText>();
                                    foreach (ObjectId objJHBName in objJHBNameCol)
                                    {
                                        Entity jhbNameEntity = trans.GetObject(objJHBName, OpenMode.ForRead) as Entity;
                                        DBText everyDBText = jhbNameEntity as DBText;
                                        if (everyDBText != null)
                                        {
                                            allDBTextList.Add(everyDBText);
                                        }
                                    }
                                }
                                List<DBText> DaYu1DBTextList = GetDBTextInPolyline2D(allDBTextList, pPoint3DCol);
                                if (DaYu1DBTextList.Count == 1)
                                {
                                    foreach (DBText theRightDBText in DaYu1DBTextList)
                                    {
                                        int iRowIndex = GetTHRowIndexFromNOPIExcel(theRightDBText.TextString, pSheet);
                                        IRow pRow = null;
                                        if (iRowIndex == -1)
                                        {
                                            pRow = pSheet.CreateRow(++iRowCount);
                                            ed.WriteMessage("
正在写入第" + iRowCount.ToString() + "个@@@单元名:" + theRightDBText.TextString + "@@@的面积");
                                        }
                                        else
                                        {
                                            pRow = pSheet.GetRow(iRowIndex);
                                            ed.WriteMessage("
正在写入第" + String.Format("{0}", iRowIndex) + "个@@@单元名:" + theRightDBText.TextString + "@@@的面积");
                                        }

                                        ICell pCell = pRow.CreateCell(GetFieldColumnIndexFromNOPIExcel(strTHField, pSheet) > -1 ? GetFieldColumnIndexFromNOPIExcel(strTHField, pSheet) : 0);
                                        pCell.SetCellValue(theRightDBText.TextString);

                                        pCell = pRow.CreateCell(GetFieldColumnIndexFromNOPIExcel(strJHBAreaField, pSheet) > -1 ? GetFieldColumnIndexFromNOPIExcel(strJHBAreaField, pSheet) : 0);
                                        pCell.SetCellValue(pJHBPolyline2d.Area.ToString("f4"));

                                    }

                                }
                                else
                                {
                                    //超过一个在多边形范围内
                                    for (int i = 0; i < DaYu1DBTextList.Count; i++)
                                    {
                                        //如果文本的AlignmentPoint不在多边形范围内,则进行排除
                                        if (!PointInPolygon(DaYu1DBTextList[i].AlignmentPoint, pPoint3DCol))
                                        {
                                            DaYu1DBTextList.Remove(DaYu1DBTextList[i]);
                                            i--;
                                        }
                                    }
                                    if (DaYu1DBTextList.Count == 1)
                                    {
                                        foreach (DBText theRightDBText in DaYu1DBTextList)
                                        {
                                            int iRowIndex = GetTHRowIndexFromNOPIExcel(theRightDBText.TextString, pSheet);
                                            IRow pRow = null;
                                            if (iRowIndex == -1)
                                            {
                                                pRow = pSheet.CreateRow(++iRowCount);
                                                ed.WriteMessage("
正在写入第" + iRowCount.ToString() + "个@@@单元名:" + theRightDBText.TextString + "@@@的面积");
                                            }
                                            else
                                            {
                                                pRow = pSheet.GetRow(iRowIndex);
                                                ed.WriteMessage("
正在写入第" + String.Format("{0}", iRowIndex) + "个@@@单元名:" + theRightDBText.TextString + "@@@的面积");
                                            }

                                            ICell pCell = pRow.CreateCell(GetFieldColumnIndexFromNOPIExcel(strTHField, pSheet) > -1 ? GetFieldColumnIndexFromNOPIExcel(strTHField, pSheet) : 0);
                                            pCell.SetCellValue(theRightDBText.TextString);

                                            pCell = pRow.CreateCell(GetFieldColumnIndexFromNOPIExcel(strJHBAreaField, pSheet) > -1 ? GetFieldColumnIndexFromNOPIExcel(strJHBAreaField, pSheet) : 0);
                                            pCell.SetCellValue(pJHBPolyline2d.Area.ToString("f4"));


                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (allDBTextList == null)
                            {
                                allDBTextList = new List<DBText>();
                                foreach (ObjectId objJHBName in objJHBNameCol)
                                {
                                    Entity jhbNameEntity = trans.GetObject(objJHBName, OpenMode.ForRead) as Entity;
                                    DBText everyDBText = jhbNameEntity as DBText;
                                    if (everyDBText != null)
                                    {
                                        allDBTextList.Add(everyDBText);
                                    }
                                }
                            }
                            List<DBText> reRightDBTextList = GetDBTextInPolyline2D(allDBTextList, pPoint3DCol);

                            if (reRightDBTextList.Count == 1)
                            {
                                foreach (DBText theRightDBText in reRightDBTextList)
                                {
                                    int iRowIndex = GetTHRowIndexFromNOPIExcel(theRightDBText.TextString, pSheet);
                                    IRow pRow = null;
                                    if (iRowIndex == -1)
                                    {
                                        pRow = pSheet.CreateRow(++iRowCount);
                                        ed.WriteMessage("
正在写入第" + iRowCount.ToString() + "个@@@单元名:" + theRightDBText.TextString + "@@@的面积");
                                    }
                                    else
                                    {
                                        pRow = pSheet.GetRow(iRowIndex);

                                        ed.WriteMessage("
正在写入第" + String.Format("{0}", iRowIndex) + "个@@@单元名:" + theRightDBText.TextString + "@@@的面积");
                                    }

                                    ICell pCell = pRow.CreateCell(GetFieldColumnIndexFromNOPIExcel(strTHField, pSheet) > -1 ? GetFieldColumnIndexFromNOPIExcel(strTHField, pSheet) : 0);
                                    pCell.SetCellValue(theRightDBText.TextString);

                                    pCell = pRow.CreateCell(GetFieldColumnIndexFromNOPIExcel(strJHBAreaField, pSheet) > -1 ? GetFieldColumnIndexFromNOPIExcel(strJHBAreaField, pSheet) : 0);
                                    pCell.SetCellValue(pJHBPolyline2d.Area.ToString("f4"));


                                }
                            }

                        }
                    }

                }
                trans.Commit();
                ed.WriteMessage("处理完成:总共处理" + pSheet.PhysicalNumberOfRows.ToString() + "个单元;图号面积存储在" + strAppExcel);
            }
            using (System.IO.FileStream fs = File.OpenWrite(strAppExcel))
            {
                wk.Write(fs);
                fs.Close();
            }
        }
View Code

    创建Excel表格列标题:

        /// <summary>
        /// 创建列标题
        /// </summary>
        /// <param name="pSheet"></param>
        /// <param name="wk"></param>
        public static void CreateHeader(ISheet pSheet, HSSFWorkbook wk, string[] strHeaderTextArray)
        {
            IRow pHeaderRow = null;
            //第一行一定是列标题
            if (pSheet.PhysicalNumberOfRows > 1)
            {
                pHeaderRow = pSheet.GetRow(0);
            }
            else
            {
                pHeaderRow = pSheet.CreateRow(0);
                pHeaderRow.Height = 20 * 20;
            }
            //创建单元样式
            ICellStyle cellStyle = wk.CreateCellStyle();
            IFont font = wk.CreateFont();
            font.FontHeightInPoints = 10;
            font.FontName = "微软雅黑";
            cellStyle.Alignment = HorizontalAlignment.CENTER;
            cellStyle.SetFont(font);

            for (int i = 0; i < strHeaderTextArray.Length; i++)
            {
                //i表示该行第i列,从0开始算起
                int iColumnIndex = GetFieldColumnIndexFromNOPIExcel(strHeaderTextArray[i], pSheet);
                if (iColumnIndex == -1)
                {
                    ICell pHeaderCell = pHeaderRow.CreateCell(pHeaderRow.Cells.Count);
                    pHeaderCell.CellStyle = cellStyle;
                    pHeaderCell.SetCellValue(strHeaderTextArray[i]);
                }

            }

        }
View Code

    获取某层下的所有实体

        /// <summary>
        /// 获取某层下的所有对象ID
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static ObjectIdCollection GetObjectidsAtLayer(string name)
        {
            ObjectIdCollection ids = new ObjectIdCollection();
            TypedValue[] filList = new TypedValue[1] { new TypedValue((int)DxfCode.LayerName, name) };
            SelectionFilter pSelectionFilter = new SelectionFilter(filList);
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

            PromptSelectionResult pPromptSelectionResult = ed.SelectAll(pSelectionFilter);
            if (pPromptSelectionResult.Status == PromptStatus.OK)
            {
                SelectionSet pSelectionSet = pPromptSelectionResult.Value;
                ObjectId[] oids = pSelectionSet.GetObjectIds();
                for (int i = 0; i < oids.Length; i++)
                {
                    ids.Add(oids[i]);
                }
            }
            return ids;
        }
View Code

   获取cad的所有图层

        /// <summary>
        /// 遍历层名
        /// </summary>
        /// <param name="db"></param>
        /// <returns></returns>
        public static ArrayList GetLayerName(Database db)
        {
            ArrayList layers = new ArrayList();
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                using (LayerTable layerTable = (LayerTable)trans.GetObject(db.LayerTableId, OpenMode.ForRead))
                {
                    foreach (ObjectId id in layerTable)
                    {
                        LayerTableRecord lyrTableRecord = (LayerTableRecord)trans.GetObject(id, OpenMode.ForRead);
                        layers.Add(lyrTableRecord.Name);
                    }
                }
                trans.Commit();
            }
            return layers;
        }
View Code

   由于cad算法有限,判断点是否在多边形范围内

        /// <summary>
        /// 判断点是否在点集所构成的多边形范围内
        /// </summary>
        /// <param name="pPoint"></param>
        /// <param name="pPointCol">多边形点集s</param>
        /// <returns></returns>
        public static bool PointInPolygon(Point3d pPoint, Point3dCollection pPointCol)
        {
            try
            {
                List<System.Drawing.PointF> pList = new List<System.Drawing.PointF>();
                foreach (Point3d pPoint3d in pPointCol)
                {
                    pList.Add(new System.Drawing.PointF(float.Parse(pPoint3d.X.ToString()), float.Parse(pPoint3d.Y.ToString())));
                }
                System.Drawing.Drawing2D.GraphicsPath myGraphicsPath = new System.Drawing.Drawing2D.GraphicsPath();
                System.Drawing.Region myRegion = new System.Drawing.Region();
                myGraphicsPath.Reset();
                myGraphicsPath.AddPolygon(pList.ToArray());
                myRegion.MakeEmpty();
                myRegion.Union(myGraphicsPath);

                return myRegion.IsVisible(new System.Drawing.PointF(float.Parse(pPoint.X.ToString()), float.Parse(pPoint.Y.ToString())));

            }
            catch
            {
                return false;
            }
        }
View Code

   获取某多边形范围内所有的文本集合

        /// <summary>
        /// 返回文本图层在点集所对应的多边形范围内的文本集合
        /// </summary>
        /// <param name="allDBTextList">所有的文本集合</param>
        /// <param name="pPointCol">点集所对应的多边形</param>
        /// <returns></returns>
        public static List<DBText> GetDBTextInPolyline2D(List<DBText> allDBTextList, Point3dCollection pPointCol)
        {
            List<DBText> listExistDBText = new List<DBText>();
            foreach (DBText singleDBText in allDBTextList)
            {
                if (PointInPolygon(singleDBText.Position, pPointCol))
                {
                    if (!listExistDBText.Contains(singleDBText))
                    {
                        listExistDBText.Add(singleDBText);
                    }
                }
            }
            return listExistDBText;
        }
View Code

    查找Excel表是否存在图名

        /// <summary>
        /// 判断图号在Excel表中是否存在.-1表示不存在,如果存在则返回行索引
        /// </summary>
        /// <param name="strTH"></param>
        /// <param name="pSheet"></param>
        /// <returns></returns>
        public static int GetTHRowIndexFromNOPIExcel(string strTH, ISheet pSheet)
        {
            int iResult = -1;
            for (int i = 0; i < pSheet.PhysicalNumberOfRows; i++)
            {
                IRow pRow = pSheet.GetRow(i);
                foreach (ICell pCell in pRow.Cells)
                {
                    if (pCell.CellType != NPOI.SS.UserModel.CellType.FORMULA)
                    {
                        if (pCell.StringCellValue.Equals(strTH, StringComparison.CurrentCultureIgnoreCase))
                        {
                            iResult = pRow.RowNum;
                            break;
                        }
                    }
    
                }
                if (iResult != -1)
                {
                    break;
                }
            }
            return iResult;

        }
View Code

    返回某个字段所在单元格的列索引,-1表示未找到,否则则返回索引

        /// <summary>
        /// 返回某个字段所在单元格的列索引,-1表示未找到,否则则返回索引
        /// </summary>
        /// <param name="strField"></param>
        /// <param name="pSheet"></param>
        /// <returns></returns>
        public static int GetFieldColumnIndexFromNOPIExcel(string strHeaderField, ISheet pSheet)
        {
            int iResult = -1;
            if (pSheet.PhysicalNumberOfRows >= 1)
            {
                IRow pRow = pSheet.GetRow(0);
                foreach (ICell pCell in pRow.Cells)
                {
                    if (pCell.StringCellValue.Equals(strHeaderField, StringComparison.CurrentCultureIgnoreCase))
                    {
                        iResult = pCell.ColumnIndex;
                        break;
                    }
                }
            }
            return iResult;
        }
View Code
高调做事,低调做人~!
原文地址:https://www.cnblogs.com/514687800/p/3528057.html