278 lines
15 KiB
C#
278 lines
15 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|