/** * * @author seagle * @date 2024-7-22 * @Description 管路图处理主对象封装 */ using Aitex.Common.Util; using Aitex.Core.RT.DataCenter; using MECF.Framework.Common.DataCenter; using netDxf; using netDxf.Entities; using System; using System.Collections.Generic; using System.Configuration; using System.Globalization; using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Xml; using Point = System.Windows.Point; namespace MECF.Framework.UI.Core.DxfScript { /// /// 名称:入口类 /// 用途:dxf文件信息加载 /// [Serializable] public partial class GasDxfDocument { //原始图形 public List Lines = null; public List Circles = null; public List Funnels = null; public List Texts = null; public List PolyLines = null; public List Valves = null; public List Buttons = null; public List Analogs = null; //事件属性 public Dictionary BoolConditions { get; set; } = null; public Dictionary StringConditions { get; set; } = null; public Dictionary ClickConditions { get; set; } = null; public string InitScriptContent { get; set; } = null; public Script InitScriptExpress { get; set; } = null; public double DxfWidth { get; set; } = 0; public double DxfHeight { get; set; } = 0; public double MinX { get; set; } = 100000; public double MinY { get; set; } = 100000; public double MaxX { get; set; } = 0; public double MaxY { get; set; } = 0; //编辑属性 public string GasFilename { get; set; } = null; public bool IsGasFileModified { get; set; } = false; public GasBaseShape SelectedShape = null; public bool IsExecuted { get; set; } = false; public DrawingCanvas draw { get; set; } = null; public Brush NormalBrush = new SolidColorBrush(Colors.Black); public Brush SelectedBrush = new SolidColorBrush(Colors.Red); public Brush WithConditionBrush = new SolidColorBrush(Colors.LightBlue); public Brush ReturnTrueBrush = new SolidColorBrush(Colors.Green); public Brush WithErrorBrush = new SolidColorBrush(Colors.Yellow); public Brush TransparentBrush = new SolidColorBrush(Colors.Transparent); public Brush DisabledBrush = new SolidColorBrush(Colors.Gray); public Pen NormalPen, SelectedPen, WithConditionPen, ReturnTruePen, WithErrorPen, TransparentPen, DisabledPen;//,BackgroundPen; public static Dictionary BrushPenMapping; public DrawingContext dc = null; public double LineWidth = 1; private static TextBlock computeSizeTextBlock = null; public static double PixelsPerDip; public GasDxfDocument(DrawingCanvas canvas, bool isExecute, string fileName) { ClearAll(); var path = QueryDataClient.Instance.Service.PollData(new List() { "GasUIConfigHome" }).FirstOrDefault().Value.ToString(); if (path == null) { MessageBox.Show($"\"{path} is not set!"); return; } GasFilename = path + fileName; draw = canvas; NormalBrush.Freeze(); SelectedBrush.Freeze(); WithConditionBrush.Freeze(); ReturnTrueBrush.Freeze(); WithErrorBrush.Freeze(); TransparentBrush.Freeze(); DisabledBrush.Freeze(); IsExecuted = isExecute; NormalPen = new Pen(NormalBrush, LineWidth); NormalPen.Freeze();//可以提高性能 SelectedPen = new Pen(SelectedBrush, LineWidth); SelectedPen.Freeze();//可以提高性能 WithConditionPen = new Pen(WithConditionBrush, LineWidth); WithConditionPen.Freeze();//可以提高性能 ReturnTruePen = new Pen(ReturnTrueBrush, LineWidth); ReturnTruePen.Freeze();//可以提高性能 WithErrorPen = new Pen(WithErrorBrush, LineWidth); WithErrorPen.Freeze();//可以提高性能 TransparentPen = new Pen(TransparentBrush, LineWidth); TransparentPen.Freeze();//可以提高性能 DisabledPen = new Pen(DisabledBrush, LineWidth); DisabledPen.Freeze();//可以提高性能 //BackgroundPen = new Pen(BackgroundBrush, LineWidth); } /// /// 读取dxf文件数据 转化为页面元素 加载元素事件 /// /// public void LoadDxf(string filename) { #region 清除页面组件元素 准备重新加载dxf ClearDxf(); #endregion #region 文件流方式进行识别dxf信息 并转化为自定义元素组件 StreamReader reader = new StreamReader(filename); DxfRecord record = new DxfRecord(); while (ReadOneRecord(reader, ref record)) { if (record.Code == 0 && record.Value.Equals("EOF")) { break; } if (record.Code == 100 && record.Value.Equals("AcDbLine")) ReadOneAcDbLine(reader); else if (record.Code == 100 && record.Value.Equals("AcDbCircle")) ReadOneAcDbCircle(reader); else if (record.Code == 100 && record.Value.Equals("AcDbText_Nouse")) ReadOneAcDbTextNouse(reader); else if (record.Code == 100 && record.Value.Equals("AcDbMText")) ReadOneAcDbMText(reader); else if (record.Code == 100 && record.Value.Equals("AcDbPolyline")) ReadOneAcDbPolyline(reader); } RecognizeShape(); #endregion #region netDxf 方式识别dxf信息 并转化为自定义元素组件 NetDxfDocument(filename); #endregion reader.Close(); IsGasFileModified = true; //不再对dxf做坐标变换,只是取第一象限 DxfWidth = MaxX; DxfHeight = MaxY; } #region 文件流读取dxf格式信息 /*从文件流中读取一条记录*/ private bool ReadOneRecord(StreamReader reader, ref DxfRecord record) { string line = reader.ReadLine(); if (line == null) return false; /* if (line.Equals("") || !line.Substring(0, 1).Equals(" ")) { MessageBox.Show("Line must begin with a space["+line+"]", "Notice", MessageBoxButton.OK); Clear(); return false; } */ line = line.Trim(); record.Code = int.Parse(line); record.Value = reader.ReadLine(); if (record.Value == null) return false; return true; } private void ReadOneAcDbPolyline(StreamReader reader) { List<(double, double)> points = new List<(double, double)>(); DxfRecord recordDetail = new DxfRecord(); double x, y; x = y = 0; bool failed = false; while (ReadOneRecord(reader, ref recordDetail)) { if (recordDetail.Code == 10) { x = double.Parse(recordDetail.Value); } if (recordDetail.Code == 20) { y = double.Parse(recordDetail.Value); if (x <= GasBaseShape.E || y <= GasBaseShape.E) { failed = true; break; } if (x > MaxX) { MaxX = x; } if (x < MinX) { MinX = x; } if (y > MaxY) { MaxY = y; } if (y < MinY) { MinY = y; } points.Add((x, y)); } if (recordDetail.Code == 0) break; } if (failed) return; GasPolyLine polyLine = new GasPolyLine(); for (int i = 0; i < points.Count; i++) { polyLine.InnerLines.Add(new GasLine(points[i].Item1, points[i].Item2, points[(i + 1) % points.Count].Item1, points[(i + 1) % points.Count].Item2)); } PolyLines.Add(polyLine); polyLine.Id = polyLine.CreateId(); } private void ReadOneAcDbMText(StreamReader reader) { double x, y; string text; x = y = 0; double x2, y2; x2 = y2 = 0; text = ""; DxfRecord recordDetail = new DxfRecord(); int align71 = 0;//1 = 左上;2 = 中上;3 = 右上 4 = 左中;5 = 正中;6 = 右中 7 = 左下;8 = 中下;9 = 右下 double space44 = 0.6; double fontSize = 0; double rectWidth = 0; double rectHeight = 0; double textHeight = 0; while (ReadOneRecord(reader, ref recordDetail)) { if (recordDetail.Code == 10) x = double.Parse(recordDetail.Value); if (recordDetail.Code == 20) y = double.Parse(recordDetail.Value); if (recordDetail.Code == 11) x2 = double.Parse(recordDetail.Value); if (recordDetail.Code == 21) y2 = double.Parse(recordDetail.Value); if (recordDetail.Code == 1) text = recordDetail.Value; if (recordDetail.Code == 71) align71 = int.Parse(recordDetail.Value); if (recordDetail.Code == 40) fontSize = double.Parse(recordDetail.Value); if (recordDetail.Code == 41) rectWidth = double.Parse(recordDetail.Value); if (recordDetail.Code == 44) space44 = double.Parse(recordDetail.Value); if (recordDetail.Code == 46) rectHeight = double.Parse(recordDetail.Value); if (recordDetail.Code == 0) break; } if (x <= GasBaseShape.E || y <= GasBaseShape.E) return; if (text != null) { string[] fields = text.Split(';'); if (fields.Length > 0) text = fields[fields.Length - 1]; if (fields.Length > 1) { for (int fieldId = 0; fieldId < fields.Length - 1; fieldId++) { string wstr = fields[fieldId]; if (wstr.Contains("\\W")) { double fontRate = double.Parse(wstr.Substring(2, wstr.Length - 2)); fontSize *= fontRate; break; } } List hText = new List(); foreach (var wstr in fields) { if (wstr.Contains("\\H")) { var content = wstr.Split('\\').FirstOrDefault(); if (string.IsNullOrEmpty(content)) continue; hText.Add(content); } } hText.Add(text); text = string.Join("", hText.ToArray()); } if (text != null && text.Length > 0) { text = text.Substring(0, text.Length - 1); Texts.Add(new GasText(x, y, text)); //SET:fontSize-字符尺寸 //SET:align71-对齐方式 //SET:space44-行间距 //SET:rectWidth-矩形宽度 //SET:rectHeight-矩形高度 string[] textLines = Regex.Split(text, "\\\\P"); if (textLines.Length > 0) { //SET:textHeight-文本高度 textHeight = fontSize * textLines.Length - space44 * rectHeight; } //根据对齐调整位置 GasText obj = Texts[Texts.Count - 1]; obj.RectWidth = rectWidth; obj.RectHeight = rectHeight; obj.LineSpace = space44; obj.FontSize = fontSize; obj.Alignment = align71; if (obj.X < MinX) MinX = obj.X; if (obj.Y < MinY) MinY = obj.Y; if (obj.X + obj.RectWidth > MaxX) MaxX = obj.X + obj.RectWidth; if (obj.Y + obj.RectHeight > MaxY) MaxY = obj.Y + obj.RectHeight; } } } private void ReadOneAcDbTextNouse(StreamReader reader) { double x, y; string text; x = y = 0; text = ""; DxfRecord recordDetail = new DxfRecord(); while (ReadOneRecord(reader, ref recordDetail)) { if (recordDetail.Code == 10) x = double.Parse(recordDetail.Value); if (recordDetail.Code == 20) y = double.Parse(recordDetail.Value); if (recordDetail.Code == 1) text = recordDetail.Value; if (recordDetail.Code == 0) break; } if (x < 0 || y < 0) return; Texts.Add(new GasText(x, y, text)); } private void ReadOneAcDbCircle(StreamReader reader) { double x, y, r, startAngle, endAngle; x = y = r = startAngle = endAngle = 0; DxfRecord recordDetail = new DxfRecord(); while (ReadOneRecord(reader, ref recordDetail)) { if (recordDetail.Code == 10) x = double.Parse(recordDetail.Value); if (recordDetail.Code == 20) y = double.Parse(recordDetail.Value); if (recordDetail.Code == 40) r = double.Parse(recordDetail.Value); if (recordDetail.Code == 50) startAngle = double.Parse(recordDetail.Value); if (recordDetail.Code == 51) endAngle = double.Parse(recordDetail.Value); if (recordDetail.Code == 0) break; } if (x <= GasBaseShape.E || y <= GasBaseShape.E) return; Circles.Add(new GasCircle(x, y, r, startAngle, endAngle)); if (x + r > MaxX) { MaxX = x + r; } if (x - r < MinX) { MinX = x - r; } if (y + r > MaxY) { MaxY = y + r; } if (y - r < MinY) { MinY = y - r; } } private void ReadOneAcDbLine(StreamReader reader) { double x1, y1, x2, y2; x1 = x2 = y1 = y2 = 0; DxfRecord recordDetail = new DxfRecord(); string sx1, sy1, sx2, sy2; sx1 = sx2 = sy1 = sy2 = ""; while (ReadOneRecord(reader, ref recordDetail)) { if (recordDetail.Code == 10) { x1 = double.Parse(recordDetail.Value); sx1 = recordDetail.Value; } if (recordDetail.Code == 20) { y1 = double.Parse(recordDetail.Value); sy1 = recordDetail.Value; } if (recordDetail.Code == 11) { x2 = double.Parse(recordDetail.Value); sx2 = recordDetail.Value; } if (recordDetail.Code == 21) { y2 = double.Parse(recordDetail.Value); sy2 = recordDetail.Value; } if (recordDetail.Code == 0) break; } if (x1 <= GasBaseShape.E || x2 <= GasBaseShape.E || y1 <= GasBaseShape.E || y2 <= GasBaseShape.E) return; GasLine gasLine = new GasLine(x1, y1, x2, y2); Lines.Add(gasLine); gasLine.Tag = sx1 + "," + sy1 + "," + sx2 + "," + sy2; if (x1 > MaxX) { MaxX = x1; } if (x1 < MinX) { MinX = x1; } if (x2 > MaxX) { MaxX = x2; } if (x2 < MinX) { MinX = x2; } if (y1 > MaxY) { MaxY = y1; } if (y1 < MinY) { MinY = y1; } if (y2 > MaxY) { MaxY = y2; } if (y2 < MinY) { MinY = y2; } } #endregion #region netDxf 读取dxf格式信息 private void NetDxfDocument(string filename) { using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) { // 使用 Stream 参数加载 DXF 文件 DxfDocument dxf = DxfDocument.Load(filename); if (dxf != null) { RecognizeGasFunnel(dxf); } } } #endregion } class DxfRecord { public int Code { get; set; } public string Value { get; set; } } }