| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493 |
- /**
- *
- * @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
- {
- /// <summary>
- /// 名称:入口类
- /// 用途:dxf文件信息加载
- /// </summary>
- [Serializable]
- public partial class GasDxfDocument
- {
- //原始图形
- public List<GasLine> Lines = null;
- public List<GasCircle> Circles = null;
- public List<GasFunnel> Funnels = null;
- public List<GasText> Texts = null;
- public List<GasPolyLine> PolyLines = null;
- public List<GasAITValve> Valves = null;
- public List<GasButton> Buttons = null;
- public List<GasAnalogControl4Jet> Analogs = null;
- //事件属性
- public Dictionary<int, string> BoolConditions { get; set; } = null;
- public Dictionary<int, string> StringConditions { get; set; } = null;
- public Dictionary<int, string> 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<Brush, Pen> 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<string>() { "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);
- }
- /// <summary>
- /// 读取dxf文件数据 转化为页面元素 加载元素事件
- /// </summary>
- /// <param name="filename"></param>
- 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<string> hText = new List<string>();
- 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; }
- }
- }
|