LINQ还是很方便的

很长时间没有LINQ了,

除了知道LINQ外,

基本上都忘了。

昨天快下班时,

一个项目要统计图中的图块(BlockReference)数量及位置信息,

开始还想自己写排序及分组的代码,

忽然想到可以使用LINQ,

这使得代码简单了很多很多。

//使用LINQ排序、分组
var group = from blk in blks
            orderby blk.Name,blk.Position.X,blk.Position.Y,blk.Position.Z
            group blk by blk.Name;

 完整代码如下:

大部分代码是插入AutoCAD表格的,

如果把信息输出到命令行,

代码会少很多。

表格的列宽,

我是统计每一列文本的长度得出的,

所以代码显得复杂了些。

using System;
using System.Collections.Generic;
using System.Linq;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.Civil.ApplicationServices;

namespace ModelingTools
{
    class BlockStatics
    {
        Document doc;
        Editor ed;
        double textHeigt = 2.5;//文本高度
        double xScale = 1; //文本宽度系数
        double obliquingAngle = 0;//文本倾角
        double nameColumWidth = 15;//用于名称那一列的宽度,第1种列宽
        double lengthColumWidth1 = 10; //第2种列宽
        double lengthColumWidth2 = 10; //第3种列宽

        ObjectId textStyleId;//文本样式Id

        public void Statics()
        {
            doc = Application.DocumentManager.MdiActiveDocument;
            ed = doc.Editor;

            //文本样式相关的
            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                SymbolTable symTable = (SymbolTable)tr.GetObject(
                   doc.Database.TextStyleTableId, OpenMode.ForRead);
                textStyleId = symTable["Standard"];
                var textStyle = textStyleId.GetObject(OpenMode.ForRead)
                    as TextStyleTableRecord;
                xScale = textStyle.XScale;
                obliquingAngle = textStyle.ObliquingAngle;
                tr.Commit();
            }

            //选择要统计的块
            //这里用过设置过滤器,我的图里没有对象,所以给省略了
            PromptSelectionOptions pso = new PromptSelectionOptions();
            pso.MessageForAdding = "
选择块";

            PromptSelectionResult psr = ed.GetSelection(pso);

            if (psr.Status != PromptStatus.OK) return;

            //拾取表格插入点
            //创建表格
            Autodesk.AutoCAD.DatabaseServices.Table table
             = new Autodesk.AutoCAD.DatabaseServices.Table();
            //设置表格样式
            table.SetSize(2, 5);

            table.Cells.TextHeight = textHeigt;
            table.Rows[0].Height = textHeigt * 3;
            table.Rows[0].TextHeight = textHeigt + 1;
            table.Rows[1].Height = textHeigt * 2;
            table.Rows[1].TextHeight = textHeigt + 0.5;
            //表格名称
            table.Cells[0, 0].TextString = "主要乔木统计表";

            table.Rows[0].Borders.Top.IsVisible = false;
            table.Rows[0].Borders.Left.IsVisible = false;
            table.Rows[0].Borders.Right.IsVisible = false;
            //标题行
            table.Cells[1, 0].TextString = "名称";
            table.Cells[1, 1].TextString = "X";
            table.Cells[1, 2].TextString = "Y";
            table.Cells[1, 3].TextString = "Z";
            table.Cells[1, 4].TextString = "数量";
            //拾取表格插入点
            //
            PromptPointResult pr = ed.GetPoint("
点取表格插入点");
            if (pr.Status == PromptStatus.OK)
            {
                table.Position = pr.Value;
            }
            else
            {
                return;
            }
            //获取块对象集合
            List<BlockReference> blks = new List<BlockReference>();
            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                foreach (ObjectId id in psr.Value.GetObjectIds())
                {
                    var block = id.GetObject(OpenMode.ForRead) as BlockReference;
                    if (block != null)
                    {
                        blks.Add(block);
                    }
                }
                tr.Commit();
            }
            //使用LINQ排序、分组
            var group = from blk in blks
                        orderby blk.Name,blk.Position.X,blk.Position.Y,blk.Position.Z
                        group blk by blk.Name;

            Array.ForEach(group.ToArray(), x =>
            {
                //添加树种的信息:名称,数量
                //ed.WriteMessage("
" + x.Key);
                //ed.WriteMessage("	数量为:" + x.Count());
                table.InsertRows(table.Rows.Count, textHeigt * 2, 1);
                int rn = table.Rows.Count - 1;
                table.Rows[rn].TextHeight = 2.5;
                //单元格内输入名称
                table.Cells[rn, 0].TextString = x.Key;
                table.Cells[rn, 0].Alignment = CellAlignment.MiddleLeft;
                table.Cells[rn, 0].Borders.Horizontal.Margin = 2;
                nameColumWidth = Math.Max(nameColumWidth, GetTextLength(x.Key, textHeigt));
                //单元格内输入数量
                table.Cells[rn, 4].TextString = x.Count().ToString("f0");
                lengthColumWidth2 = Math.Max(lengthColumWidth2,
                    GetTextLength(x.Count().ToString("f0"), textHeigt));
                table.Cells[rn, 4].Alignment = CellAlignment.MiddleRight;
                table.Cells[rn, 4].Borders.Horizontal.Margin = 2;


                Array.ForEach(x.ToArray(), y =>
                {
                    //添加每棵树的位置信息,X,Y,Z
                    //ed.WriteMessage("
	" + y.Position.ToString());
                    table.InsertRows(table.Rows.Count, textHeigt * 2, 1);
                    rn = table.Rows.Count - 1;
                    table.Rows[rn].TextHeight = 2.5;
                    //单元格内输入坐标X
                    string coorX = y.Position.X.ToString("f2");
                    table.Cells[rn, 1].TextString = coorX;
                    lengthColumWidth1 = Math.Max(lengthColumWidth1,
                        GetTextLength(coorX, textHeigt));
                    table.Cells[rn, 1].Alignment = CellAlignment.MiddleRight;
                    table.Cells[rn, 1].Borders.Horizontal.Margin = 2;
                    //单元格内输入坐标Y
                    string coorY =y.Position.Y.ToString("f2");
                    table.Cells[rn, 2].TextString = coorY;
                    lengthColumWidth1 = Math.Max(lengthColumWidth1,
                        GetTextLength(coorY, textHeigt));
                    table.Cells[rn, 2].Alignment = CellAlignment.MiddleRight;
                    table.Cells[rn, 2].Borders.Horizontal.Margin = 2;
                    //单元格内输入坐标Z
                    string coorZ = y.Position.Z.ToString("f2");
                    table.Cells[rn, 3].TextString = coorZ;
                    lengthColumWidth1 = Math.Max(lengthColumWidth1,
                        GetTextLength(coorZ, textHeigt));
                    table.Cells[rn, 3].Alignment = CellAlignment.MiddleRight;
                    table.Cells[rn, 3].Borders.Horizontal.Margin = 2;

                });
            });

            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                ///设置表格文本样式
                table.Cells.TextStyleId = textStyleId;
                ///设置表格列宽
                table.Columns[0].Width = nameColumWidth + 6;
                table.Columns[1].Width = lengthColumWidth1 + 6;
                table.Columns[2].Width = lengthColumWidth1 + 6;
                table.Columns[3].Width = lengthColumWidth1 + 6;
                table.Columns[4].Width = lengthColumWidth2 + 6;


                BlockTable bt = (BlockTable)tr.GetObject(Autodesk.AutoCAD
                   .ApplicationServices.Application.DocumentManager
                   .MdiActiveDocument.Database.BlockTableId, OpenMode.ForRead);
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
                    bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                btr.AppendEntity(table);
                tr.AddNewlyCreatedDBObject(table, true);
                tr.Commit();
            }


        }
        //获取文本长度,用来设置表格列宽
        //对中文貌似不太灵
        double GetTextLength(string str, double height)
        {
            if (str == "" || str == null)
            {
                return 0;
            }
            else
            {
                DBText tmp = new DBText();
                tmp.TextStyleId = textStyleId;
                tmp.WidthFactor = xScale;
                tmp.Oblique = obliquingAngle;
                tmp.TextString = str;
                tmp.Height = height;
                var ext = tmp.GeometricExtents;
                return ext.MaxPoint.X - ext.MinPoint.X;
            }
        }
    }
}

结果如下:

原文地址:https://www.cnblogs.com/myzw/p/13233785.html