为了作业方便,一般会将某个区域按照某种规则划分成单个的小区域,这样就会形成接合表。对于接合表重要的信息主要有单元名称和单元名称所对应的区域(在CAD中用Polyline2d表示)。作业过程中通常会统计接合表各作业单元的接合表面积。
以下是CAD.Net求算过程,在中间环节使用了NPOI,目的是用Excel表输出对应的接合表面积和单元名称。
首先申明输出Excel里面输出的列标题名称:
public const string strTHField = "图号";
public const string strJHBAreaField = "CAD结合表面积";
public const string strDwgAreaField = "DWG图FQ层面积";
求算接合表面积主要代码:
[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("\n请输入结合表二维线图层名称: ");
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("\n请输入结合表文字图层名称: ");
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("\n正在写入第" + iRowCount.ToString() + "个@@@单元名:" + pText.TextString + "@@@的面积");
}
else
{
pRow = pSheet.GetRow(iRowIndex);
ed.WriteMessage("\n正在写入第" + 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("\n正在写入第" + iRowCount.ToString() + "个@@@单元名:" + theRightDBText.TextString + "@@@的面积");
}
else
{
pRow = pSheet.GetRow(iRowIndex);
ed.WriteMessage("\n正在写入第" + 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("\n正在写入第" + iRowCount.ToString() + "个@@@单元名:" + theRightDBText.TextString + "@@@的面积");
}
else
{
pRow = pSheet.GetRow(iRowIndex);
ed.WriteMessage("\n正在写入第" + 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("\n正在写入第" + iRowCount.ToString() + "个@@@单元名:" + theRightDBText.TextString + "@@@的面积");
}
else
{
pRow = pSheet.GetRow(iRowIndex);
ed.WriteMessage("\n正在写入第" + 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();
}
}
创建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]);
}
}
}
获取某层下的所有实体
/// <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;
}
获取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;
}
/// <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;
}
}
获取某多边形范围内所有的文本集合
/// <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;
}
查找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;
}
返回某个字段所在单元格的列索引,-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;
}