/**
*
* @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; }
}
}