uBIMEarthTools/地质建模/DWGDataExport.cs
2018-10-22 19:28:56 +08:00

278 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace uBIM_EarthTools
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class DwgDataExport : IExternalCommand
{
public Result Execute(Autodesk.Revit.UI.ExternalCommandData CommandData, ref string Message, ElementSet elementset)
{
#region
Autodesk.Revit.ApplicationServices.Application Revit = CommandData.Application.Application;
Autodesk.Revit.UI.UIDocument uidoc = CommandData.Application.ActiveUIDocument;
Autodesk.Revit.DB.Document doc = CommandData.Application.ActiveUIDocument.Document;
// ICollection<ElementId> currentselectid = uidoc.Selection.GetElementIds();
Autodesk.Revit.DB.View curview = doc.ActiveView;
List<TextNote> textnoteList = (new FilteredElementCollector(doc, curview.Id)).
WherePasses(new ElementClassFilter(typeof(TextNote))).
ToElements().Select(x => x as TextNote).ToList();//所有文字
XYZ pointFirstTable_L = new XYZ();
XYZ pointFirstTable_R = new XYZ();
XYZ pointSecTable = new XYZ();
XYZ pointLayer_L = new XYZ();//地层编号左侧x坐标
XYZ pointLayer_R = new XYZ();//地层编号右侧x坐标
XYZ pointButtom_L = new XYZ();//层底高程左侧x坐标
XYZ pointButtom_R = new XYZ();//层底高程右侧x坐标
XYZ pointStart = new XYZ();//此坐标以下为地层数据
XYZ pointNum = new XYZ();//钻孔编号
XYZ pointLevel = new XYZ();//孔口标高
XYZ pointX = new XYZ();//孔口X
XYZ pointY = new XYZ();//孔口Y
List<Borehole> boreholes = new List<Borehole>();
#endregion
#region
try
{
pointFirstTable_L = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击第一个图框左上角……");
pointFirstTable_R = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击第一个图框右下角……");
pointSecTable = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击第二个图框左上角……");
pointLayer_L = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击地层编号列左侧……");
pointLayer_R = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击地层编号列右侧……");
pointButtom_L = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击层底高程列左侧……");
pointButtom_R = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击层底高程列右侧……");
pointStart = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击地层数据上方横线……");
pointNum = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击钻孔编号数字左下角……");
pointLevel = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击孔口标高数字左下角……");
pointX = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击孔口X数字左下角……");
pointY = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击地孔口Y数字左下角……");
}
catch
{
return Result.Succeeded;
}
#endregion
#region
string localFilePath = String.Empty;
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Excel files|*.xlsx";
saveFileDialog.FileName = doc.Title.Replace(".rvt", "") + "-" + DateTime.Now.ToString("yyyyMMdd");
saveFileDialog.FilterIndex = 1;
saveFileDialog.RestoreDirectory = true;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
localFilePath = saveFileDialog.FileName.ToString();
}
else
return Result.Cancelled;
#endregion
#region
TransactionStatus status = TransactionStatus.Uninitialized;
TransactionGroup transGroup = new TransactionGroup(doc, "地质建模");
if (transGroup.Start() == TransactionStatus.Started)
{
Transaction transaction = new Transaction(doc, "uBIM");
int k = 0;
while (true)
{
#region
XYZ origin_k = pointFirstTable_L + new XYZ(k * (pointSecTable.X - pointFirstTable_L.X), 0, 0);//当前图框左上角坐标
List<TextNote> textnoteKList = new List<TextNote>(); //当前图框里的textnote
List<TextNote> dcbhList = new List<TextNote>(); //地层编号
List<TextNote> dcgcList = new List<TextNote>(); //地层高程
List<TextNote> delTextnoteList = new List<TextNote>(); //被归并的textnote后面被排除
#endregion
#region textnote
foreach (TextNote tntmp in textnoteList)
{
if (tntmp.Coord.X > origin_k.X && tntmp.Coord.X < origin_k.X + (pointFirstTable_R.X - pointFirstTable_L.X) &&
tntmp.Coord.Y > origin_k.Y - (pointFirstTable_L.Y - pointFirstTable_R.Y) && tntmp.Coord.Y < origin_k.Y)
{
//消重
//当前条件:距离相差1cm且文字相等
Boolean dub = false;
for (int i = 0; i <= textnoteKList.Count - 1; i++)
{
TextNote tntmp1 = textnoteKList[i];
if (tntmp.Coord.DistanceTo(tntmp1.Coord) < 1 / 304.8 && tntmp.Text == tntmp1.Text)
{
dub = true;
break;
}
}
if (dub == false)
textnoteKList.Add(tntmp);
}
}
if (textnoteKList.Count == 0) //获取不到时,跳出
break;
#endregion
#region ,,X,Y
TextNote zkbhTn = Common.Textnote_At_Point(new XYZ(origin_k.X + pointNum.X - pointFirstTable_L.X, pointNum.Y, pointNum.Z), textnoteKList, 4); //钻孔编号
TextNote kkbgTn = Common.Textnote_At_Point(new XYZ(origin_k.X + pointLevel.X - pointFirstTable_L.X, pointLevel.Y, pointLevel.Z), textnoteKList, 4); //孔口标高
TextNote xTn = Common.Textnote_At_Point(new XYZ(origin_k.X + pointX.X - pointFirstTable_L.X, pointX.Y, pointX.Z), textnoteKList, 4); //孔口X
TextNote yTn = Common.Textnote_At_Point(new XYZ(origin_k.X + pointY.X - pointFirstTable_L.X, pointY.Y, pointY.Z), textnoteKList, 4); //孔口Y
//钻孔编号跟孔口标高不对应时,跳至下个图框
if (zkbhTn == null || kkbgTn == null)
{
k++;
continue;
}
#endregion
#region 3-1(:X公差:4mm;Y公差:2mm;:null)
foreach (TextNote tntmp1 in textnoteKList)
{
if (tntmp1.Coord.X > origin_k.X + pointLayer_R.X - pointFirstTable_L.X)//排除超出范围的
continue;
if (delTextnoteList.Contains(tntmp1))//排除已剔除的
continue;
if (tntmp1.Text.Contains("."))//排除包含"."的
continue;
foreach (TextNote tntmp2 in textnoteKList)
{
if (delTextnoteList.Contains(tntmp2))//排除已剔除的
continue;
if (tntmp2.Coord.X > origin_k.X + pointLayer_R.X - pointFirstTable_L.X)//排除超出范围的
continue;
if (tntmp2.Text.Contains("."))//排除包含"."的
continue;
if (tntmp1.Id == tntmp2.Id)//排除与当前比较的同一TextNote
continue;
//三重过滤X相近、Y相近、字高不一
if (Math.Abs(tntmp1.Coord.X - tntmp2.Coord.X) < 4 / 304.8 &&
Math.Abs(tntmp1.Coord.Y - tntmp2.Coord.Y) < 2 / 304.8)// &&Math.Abs(tntmp1.Height - tntmp2.Height) > 0.00001 / 304.8)
{
transaction.Start();
if (tntmp1.Coord.X < tntmp2.Coord.X)
{
tntmp1.Text = tntmp1.Text + "-" + tntmp2.Text;
delTextnoteList.Add(tntmp2);
}
else
{
tntmp2.Text = tntmp2.Text + "-" + tntmp1.Text;
delTextnoteList.Add(tntmp1);
}
transaction.Commit();
}
}
}
textnoteKList = textnoteKList.Except(delTextnoteList).ToList<TextNote>();
#endregion
#region ,
foreach (var tntmp in textnoteKList)
{
if (tntmp.Coord.Y > pointStart.Y)
continue;
else if (tntmp.Coord.X > origin_k.X + pointLayer_L.X - pointFirstTable_L.X && tntmp.Coord.X < origin_k.X + pointLayer_R.X - pointFirstTable_L.X)
{
dcbhList.Add(tntmp);
}
else if (tntmp.Coord.X > origin_k.X + pointButtom_L.X - pointFirstTable_L.X && tntmp.Coord.X < origin_k.X + pointButtom_R.X - pointFirstTable_L.X)
{
dcgcList.Add(tntmp);
}
}
dcbhList = dcbhList.OrderByDescending(x => x.Coord.Y).ToList();
dcgcList = dcgcList.OrderByDescending(x => x.Coord.Y).ToList();
#endregion
#region ,
Borehole bh;
if (boreholes.Count != 0 && boreholes.Select(x => x.Name).ToList().Contains(zkbhTn.Text))
{
bh = boreholes.ElementAt(boreholes.Select(x => x.Name).ToList().IndexOf(zkbhTn.Text));
}
else
{
bh = new Borehole { Name = zkbhTn.Text };
bh.ValueList.Add(new GeologyLayer(dcbhList.First().Text, new XYZ(System.Convert.ToDouble(xTn.Text), System.Convert.ToDouble(yTn.Text), System.Convert.ToDouble(kkbgTn.Text))));
boreholes.Add(bh);
}
#endregion
#region
for (int i = 0; i < (dcbhList.Count < dcgcList.Count ? dcbhList.Count : dcgcList.Count); i++)
{
string dcbh_i = dcbhList[i].Text;
string dcmc_i = dcgcList[i].Text;
double x = System.Convert.ToDouble(xTn.Text);
double y = System.Convert.ToDouble(yTn.Text);
double z = System.Convert.ToDouble(dcmc_i);
GeologyLayer geologyLayer = new GeologyLayer(dcbh_i, new XYZ(x, y, z));
bh.ValueList.Add(geologyLayer);
}
#endregion
k++;
}
}
status = transGroup.RollBack();
#endregion
#region
if (boreholes.Count == 0)
{
MessageBox.Show("当前界面无法读取到钻孔数据", "uBIM");
return Result.Succeeded;
}
using (ExcelPackage excelPackage = new ExcelPackage())
{
using (FileStream fs = new FileStream(localFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
excelPackage.Load(fs);
ExcelWorksheet excelWorksheet = excelPackage.Workbook.Worksheets["Data"];
if (excelWorksheet == null)
{
excelWorksheet = excelPackage.Workbook.Worksheets.Add("Data");
}
excelWorksheet.Cells.Clear();
excelWorksheet.Cells.Style.Numberformat.Format = "@";
for (int i = 0; i < boreholes.Count; i++)
{
Borehole borehole = boreholes[i];
if (borehole.ValueList.Count != 0)
{
excelWorksheet.Cells[2 * i + 1, 1].Value = borehole.Name;
excelWorksheet.Cells[2 * i + 1, 2].Value = borehole.ValueList[0].Point.X;
excelWorksheet.Cells[2 * i + 1, 3].Value = borehole.ValueList[0].Point.Y;
excelWorksheet.Cells[2 * i + 2, 1].Value = borehole.Name;
excelWorksheet.Cells[2 * i + 2, 2].Value = borehole.ValueList[0].Point.X;
excelWorksheet.Cells[2 * i + 2, 3].Value = borehole.ValueList[0].Point.Y;
for (int j = 0; j < borehole.ValueList.Count; j++)
{
excelWorksheet.Cells[2 * i + 1, j + 4].Value = borehole.ValueList[j].Type;
excelWorksheet.Cells[2 * i + 2, j + 4].Value = borehole.ValueList[j].Point.Z;
}
}
}
}
File.WriteAllBytes(localFilePath, excelPackage.GetAsByteArray());
}
#endregion
return Result.Succeeded;
}
}
}