using DataEntity;
using DataEntity.Share;
using DataRWDAL;
using HxSocket;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml;
using XCommon.Image;
using XCommon.Log;
using XHandler.Class;
using XHandler.Class.DataEx;
using XHandler.Controls.DrawCanvas;
using XHandler.View.ManualPick;
using XHandler.View.MethodProperty;
using XImagingXhandler.XDAL;
using System.Windows.Media.Media3D;
namespace XHandler.View.ElectroCutGum
{
///
/// ManualPickGum.xaml 的交互逻辑
///
public partial class ManualPickGum : Window
{
#region 变量
private string srcImageFile;
private string jsonFile;
private double startZoom;
private string bacteriaTypeID; // 菌名称ID
private ObservableCollection bacteriaCoordinatesSource;
private ObservableCollection dgBacteriaCoordinates = new ObservableCollection();
public ExperimentRunChoiceBacteraModel expRunChoiceBactera = new ExperimentRunChoiceBacteraModel();
public event EventHandler stopEvent;
public event EventHandler nextEvent;
public HxSocketClient socketTcpListener = null;
public bool isSimulator = false;
public RunWnd launchView; // 运行窗体
public XmlNode methodNode; // 当前拍照的节点
public DataTable dtChoiceParams; // 当前成像参数
public bool cancelFlg = false;
public bool isRemotingOper = false; // 是否是远程整合运行
private bool isDrawViewerInited = false; // 画图控件是否已初始化
private int countOfAutoanalysis = 0;//成像识别菌落数量
private int countOfManualchoice = 0;//人工挑选菌落数量
private int countOfManualdelete = 0;//人工删除菌落数量
private int countOfoating = 0;//涂布菌落总数
#endregion
public ManualPickGum()
{
InitializeComponent();
}
#region 构造函数
///
/// 构造函数
///
/// 拍照原图路径
/// 识别图路径
/// 识别结果json文件
/// 是否虚拟运行
public ManualPickGum(string originalImageFilePath, string imagePath, string jsonPath, bool isSimulator)
{
try
{
InitializeComponent();
srcImageFile = originalImageFilePath;
jsonFile = jsonPath;
this.Owner = (Window)Shared.Main;
}
catch (Exception ex)
{
LoggerHelper.ErrorLog("ERROR:", ex);
}
}
#endregion
#region 页面加载完成
private void Window_Load(object sender, RoutedEventArgs e)
{
try
{
// 获取获取挑菌参数
GetBacteriasParamInfo();
// 获取拍照json文件里的数据
bacteriaCoordinatesSource = DataModule.getInstance().GetBacteriaCoordinateList(jsonFile);
LoggerHelper.InfoLog(string.Format("[ManualPickBacteria]拍照挑菌个数:{0}", bacteriaCoordinatesSource.Count()));
countOfAutoanalysis = bacteriaCoordinatesSource.Count();
dgPickData.ItemsSource = dgBacteriaCoordinates;
drawViewer.BackgroundImage = BitmapFrame.Create(new Uri(srcImageFile), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
catch (Exception ex)
{
LoggerHelper.ErrorLog("ERROR:", ex);
}
}
#endregion
#region 获取获取挑菌参数
///
/// 获取获取挑菌参数
///
private void GetBacteriasParamInfo()
{
string filePath = ConfigurationManager.AppSettings["choiceFilePath"];
if (!File.Exists(filePath))
{
return;
}
// 获取挑菌参数
DataTable dtParam = ExcelAndCsvHelper.GetDataTableFromExcelFile(filePath, true);
// 获取细菌信息
ObservableCollection listBacteria = DataModule.getInstance().GetBacterias();
Bacteria bacteria = listBacteria.Where(s => s.bacteria_name == this.textblockBacteriaName.Text).FirstOrDefault();
if (bacteria != null)
{
bacteriaTypeID = bacteria.bacteria_id;
}
#region 控件赋值
this.textblockTestID.Text = dtParam.Rows[0][2].ToString(); // 实验ID
this.textblockBacteriaName.Text = dtParam.Rows[2][2].ToString(); // 菌名称
#endregion
}
#endregion
private void btnClose_Click(object sender, RoutedEventArgs e)
{
if (EventResponseController.Instance.CanExecute() == false)
return;
ConfirmClose confirmClose = new ConfirmClose();
confirmClose.closeEvent += Confirm_closeEvent;
confirmClose.stopEvent += ConfirmClose_stopEvent;
confirmClose.skipEvent += ConfirmClose_skipEvent;
Window wnd = Application.Current.MainWindow;
Grid parent = Utilities.FindVisualChild(wnd);
parent.Children.Add(confirmClose);
}
///
/// 关闭页面:控件隐藏了
///
///
///
private void ConfirmClose_skipEvent(object sender, EventArgs e)
{
string strDateTime = DateTime.Now.ToString("yyyyMMddTHHmmssms");
// 跳过此步,执行下一命令
SaveBacteriaResultImage(strDateTime);
SaveJsonResult(strDateTime);
Confirm_closeEvent(sender, EventArgs.Empty);
nextEvent?.Invoke(this, EventArgs.Empty);
}
///
/// 保存挑菌图片
///
///
///
private string SaveBacteriaResultImage(string fileName)
{
string imageFilePath = string.Empty;
// 保存成图片
var backgroundImage = this.drawViewer.BackgroundImage;
var frame = this.drawCanvas.ToBitmapFrame(backgroundImage.PixelWidth, backgroundImage.PixelHeight, DpiHelper.GetDpiFromVisual(this.drawCanvas), backgroundImage);
if (frame == null)
return imageFilePath;
var pickResultPath = ConfigurationManager.AppSettings["PickResultPath"];
if (!Directory.Exists(pickResultPath))
{
Directory.CreateDirectory(pickResultPath);
}
imageFilePath = pickResultPath + fileName + ".jpg";
ImageHelper.Save(imageFilePath, frame);
return imageFilePath;
}
///
/// 保存挑菌数据成json格式文件
///
///
///
private string SaveJsonResult(string fileName)
{
string jsonFilePath = string.Empty;
string jsonData = File.ReadAllText(jsonFile);
jsonData = jsonData.Replace("#!HxSEP!#", "");
JObject job = JObject.Parse(jsonData);
job["count"] = dgBacteriaCoordinates.Count;
JArray jArray = (JArray)job["germlist"];
jArray.Clear();
foreach (BacteriaCoordinateEx item in dgBacteriaCoordinates)
{
if (!item.canEdit)
continue;
JObject newObj = new JObject();
newObj.Add("index", item.bacteriacoordinate_id);
newObj.Add("orgType", bacteriaTypeID);
newObj.Add("diameterSize", item.diameter);
newObj.Add("manualPick", item.isManualPick.ToString().ToLower());
JObject pixelObj = new JObject();
pixelObj.Add("x", item.pixelPoint.X);
pixelObj.Add("y", item.pixelPoint.Y);
newObj.Add("coordinatePixel", pixelObj);
JObject coorObj = new JObject();
coorObj.Add("x", item.coordinate_machine.Split(',')[0]);
coorObj.Add("y", item.coordinate_machine.Split(',')[1]);
coorObj.Add("z", item.coordinate_machine.Split(',')[2]);
newObj.Add("coordinate3D", coorObj);
jArray.Add(newObj);
}
countOfoating = dgBacteriaCoordinates.Count;
if (!isRemotingOper)
{
var pickResultPath = ConfigurationManager.AppSettings["PickResultPath"];
if (!Directory.Exists(pickResultPath))
{
Directory.CreateDirectory(pickResultPath);
}
jsonFilePath = pickResultPath + fileName + ".json";
using (System.IO.StreamWriter file = new System.IO.StreamWriter(jsonFilePath))
{
string data = job.ToString() + "#!HxSEP!#";
file.Write(data);
}
}
else
{
var folder = System.IO.Path.Combine(Environment.CurrentDirectory, "UploadFolder");
if (!Directory.Exists(folder))
{
Directory.CreateDirectory("UploadFolder");
}
jsonFilePath = folder + "\\" + fileName + ".json";
using (System.IO.StreamWriter file = new System.IO.StreamWriter(jsonFilePath))
{
string data = job.ToString();// + "#!HxSEP!#";
file.Write(data);
}
}
return jsonFilePath;
}
///
/// 取消继续
///
///
///
private void ConfirmClose_stopEvent(object sender, EventArgs e)
{
// 停止当前流程
Confirm_closeEvent(sender, EventArgs.Empty);
stopEvent?.Invoke(this, EventArgs.Empty);
}
private void Confirm_closeEvent(object sender, EventArgs e)
{
Window wnd = Application.Current.MainWindow;
Grid grid = Utilities.FindVisualChild(wnd);
UIElement element = sender as UIElement;
grid.Children.Remove(element);
}
private void drawViewer_Loaded(object sender, RoutedEventArgs e)
{
try
{
startZoom = drawViewer.Zoom;
drawCanvas.ID = 1;
Point point;
LoggerHelper.DebugLog(string.Format("[drawViewer_Loaded]: start draw, bacteriaCnt = {0}", bacteriaCoordinatesSource.Count()));
foreach (BacteriaCoordinateEx item in bacteriaCoordinatesSource)
{
string[] pixels = item.coordinate_pixel.Split(',');
//point = new Point((Convert.ToDouble(pixels[0]) / 1.254), (Convert.ToDouble(pixels[1]) / 1.254));
point = new Point((Convert.ToDouble(pixels[0])), (Convert.ToDouble(pixels[1])));
drawCanvas.MouseLeftButtonDown(point);
// 机械坐标
string coordinateMachine = string.Format("{0},{1},{2}", item.machinePoint.X, item.machinePoint.Y, item.machinePoint.Z);
drawCanvas.MouseLeftButtonUp(point, coordinateMachine);
}
LoggerHelper.DebugLog(string.Format("[drawViewer_Loaded]: end draw"));
// 自动挑菌时,自动点击确认按钮
string choicemode = dtChoiceParams==null?"1":dtChoiceParams.Rows[9]["属性值"].ToString();
if (choicemode.Equals("0")) // 0:成像系统自动挑选菌落
{
btnConfirm_Click(null, null);
}
}
catch (Exception ex)
{
LoggerHelper.ErrorLog("ERROR:", ex);
}
finally
{
// 画图控件已初始化
isDrawViewerInited = true;
LoggerHelper.DebugLog(string.Format("[drawViewer_Loaded]: call finished"));
}
}
private void drawCanvas_AddPointEvent(object sender, Class.CustomRoutedEventArgs e)
{
try
{
PointData data = e.param as PointData;
BacteriaCoordinateEx ex = new BacteriaCoordinateEx();
ex.bacteriacoordinate_id = data.id.ToString();
//ex.coordinate_pixel = Convert.ToInt32(Convert.ToDouble((data.point.X * 1.254).ToString("F2"))).ToString() + "," + Convert.ToInt32(Convert.ToDouble((data.point.Y * 1.254).ToString("F2"))).ToString();
ex.coordinate_pixel = Convert.ToInt32(Convert.ToDouble((data.point.X).ToString("F2"))).ToString() + "," + Convert.ToInt32(Convert.ToDouble((data.point.Y).ToString("F2"))).ToString();
ex.coordinate_machine = "0,0,0";
ex.diameter = data.diameter.ToString("F2");
ex.pixelPoint = data.point;
//pixelPoint=====>machinePoint
ex.machinePoint = new Point3D(0, 0, 0);
ex.isManualPick = false;
// 用户自己在画图上增加的,需要调用成像系统计算坐标
if (isDrawViewerInited)
{
Mouse.OverrideCursor = Cursors.Wait;
List ret = ExecuteCalculate(ex, isSimulator); // 像素坐标转机械坐标
if (ret.Count == 2)
{
string dataSrc = ret[1];
string dataChg = dataSrc.Replace("#!HxSEP!#", "");
JObject job = JObject.Parse(dataChg);
int iType = Convert.ToInt32(job["message_type"].ToString());
if (iType == 5)
{
JArray jArray = (JArray)job["data"]["result"];
ex.coordinate_machine = jArray[0]["x"].ToString() + "," + jArray[0]["y"].ToString() + "," + jArray[0]["z"].ToString();
}
}
Mouse.OverrideCursor = null;
ex.isManualPick = true;
LoggerRunHelper.InfoLog(string.Format("[ManualPickBacteria][drawCanvas_AddPointEvent]人工增加坐标: 像素坐标:{0}, 机械坐标:{1}",
ex.coordinate_pixel, ex.coordinate_machine));
}
else
{
ex.coordinate_machine = data.coordinate_machine;
}
dgBacteriaCoordinates.Add(ex);
countOfManualchoice++;
tbxCountOfSelected.Text = dgBacteriaCoordinates.Count.ToString();
}
catch (Exception ex)
{
LoggerHelper.ErrorLog("ERROR:", ex);
}
}
#region 像素坐标转成机械坐标
///
/// 像素坐标转成机械坐标
///
/// 像素坐标对象
///
/// 结果实体对象
private List ExecuteCalculate(BacteriaCoordinateEx bacteriaCoordinateEx, bool isSimulator = false)
{
// 像素坐标转成机械坐标
List strResult = socketTcpListener.SendMessage(GenerateCommand(bacteriaCoordinateEx), true);
return strResult;
}
///
/// 像素坐标转换成机械坐标
///
///
///
private string GenerateCommand(BacteriaCoordinateEx bacteriaCoordinateEx)
{
string strCommand = string.Empty;
try
{
if (bacteriaCoordinateEx != null)
{
string pixelGroup = bacteriaCoordinateEx.coordinate_pixel;
string[] pixels = pixelGroup.Split(',');
string pixelx = pixels[0];
string pixely = pixels[1];
string experimentid = "Unknown";
strCommand = "{" + "\"message_id\":\"" + Guid.NewGuid().ToString() +
"\",\"message_type\":1" +
",\"method\":\"Calculate\"" +
",\"equipment_id\":\"ID2023\"" +
",\"workflow_id\":\"\"" +
",\"experiment_id\":\"" + experimentid +
"\",\"parameters\":" +
"{" +
"\"data\":[{" + "\"x\":" + pixelx +
",\"y\":" + pixely +
"}]" +
"}" +
",\"process_info\":{}" +
",\"estimate_time\":5" +
",\"timeout\":60" +
",\"description\":\"NO DESC\"" +
",\"timestamp\":\"" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\"}";
}
}
catch (Exception ex)
{
LoggerHelper.ErrorLog("ERROR:", ex);
}
return strCommand;
}
#endregion
private void btnClear_Click(object sender, RoutedEventArgs e)
{
PlsToolTipWin plsToolTipWin = new PlsToolTipWin("确定要全部删除吗?");
plsToolTipWin.ShowDialog();
if (plsToolTipWin.DialogResult != true)
{
return;
}
if (dgBacteriaCoordinates != null && dgBacteriaCoordinates.Count > 0)
{
foreach (BacteriaCoordinateEx bacteriaItem in dgBacteriaCoordinates)
{
// 删除菌落坐标
DeleteBacteriaItem(bacteriaItem);
}
dgBacteriaCoordinates.Clear();
tbxCountOfSelected.Text = dgBacteriaCoordinates.Count.ToString();
}
}
private void btnConfirm_Click(object sender, RoutedEventArgs e)
{
try
{
// 进入到手工设置板位数据
string fileName = $"{Shared.Exp.ExperimentId}_{DateTime.Now.ToString("yyyyMMddTHHmmssms")}";
string imageFilePath = SaveBacteriaResultImage(fileName); // 手工挑选之后的图
string jsonFilePath = SaveJsonResult(fileName); // 手工挑选之后的json
if (launchView != null)
{
expRunChoiceBactera.CountAutoAnalysis = countOfAutoanalysis;
expRunChoiceBactera.CountManualChoice = countOfManualchoice;
expRunChoiceBactera.CountManualDelete = countOfManualdelete;
expRunChoiceBactera.CountCoating = countOfoating;
expRunChoiceBactera.SourceImagePath = srcImageFile;
expRunChoiceBactera.UpdateImagePath = imageFilePath;
expRunChoiceBactera.UpdateJsonPath = jsonFilePath;
string filePath = ConfigurationManager.AppSettings["choiceFilePath"];// 挑菌下发参数.xls
dtChoiceParams = ExcelAndCsvHelper.GetDataTableFromExcelFile(filePath, true);
expRunChoiceBactera.BacteriaName = dtChoiceParams == null ? "" : dtChoiceParams.Rows[2]["属性值"].ToString();
expRunChoiceBactera.BacteriaColor = dtChoiceParams == null ? "" : dtChoiceParams.Rows[5]["属性值"].ToString();
expRunChoiceBactera.BacteriaEdge = dtChoiceParams == null ? "" : dtChoiceParams.Rows[4]["属性值"].ToString();
expRunChoiceBactera.BacteriaShape = dtChoiceParams == null ? "" : dtChoiceParams.Rows[3]["属性值"].ToString();
expRunChoiceBactera.BacteriaMinSize = dtChoiceParams == null ? 0 : Convert.ToDouble(dtChoiceParams.Rows[6]["属性值"].ToString());
expRunChoiceBactera.BacteriaMaxSize = dtChoiceParams == null ? 0 : Convert.ToDouble(dtChoiceParams.Rows[7]["属性值"].ToString());
expRunChoiceBactera.BacteraProx = dtChoiceParams == null ? 0 : Convert.ToDouble(dtChoiceParams.Rows[8]["属性值"].ToString());
ExperimentRunChoiceBacteraDB.Add(expRunChoiceBactera);
}
ChoiceConfirmNext confirmNext = new ChoiceConfirmNext();
if (isRemotingOper) // 远程整合调用中,发送挑菌结构给中控
{
return;
}
else
{
this.Visibility = Visibility.Hidden;
confirmNext.Height = this.ActualHeight;
confirmNext.Width = this.ActualWidth;
confirmNext.manualPickGum = this;
confirmNext.launchView = launchView;
confirmNext.methodNode = methodNode;
confirmNext.dtChoiceParams = dtChoiceParams;
SolidColorBrush mybtn1_Brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0, 0, 0, 0));
confirmNext.Background = (System.Windows.Media.Brush)mybtn1_Brush;
confirmNext.dgBacteriaCoordinates = dgBacteriaCoordinates;
confirmNext.ShowDialog();
}
cancelFlg = confirmNext.cancelFlg;
}
catch (Exception ex)
{
LoggerHelper.ErrorLog("ERROR:", ex);
}
}
private void delete_Button_Click(object sender, RoutedEventArgs e)
{
try
{
Button btn = (Button)sender;
if (btn != null)
{
string id = btn.Tag as string;
BacteriaCoordinateEx bacteriaItem = dgBacteriaCoordinates.Where(s => s.bacteriacoordinate_id == id).FirstOrDefault();
// 删除菌落坐标
if (DeleteBacteriaItem(bacteriaItem))
{
dgBacteriaCoordinates.Remove(bacteriaItem);
tbxCountOfSelected.Text = dgBacteriaCoordinates.Count.ToString();
}
}
}
catch (Exception ex)
{
LoggerHelper.ErrorLog("ERROR:", ex);
}
}
///
/// 删除菌落坐标
///
///
///
private bool DeleteBacteriaItem(BacteriaCoordinateEx bacteriaItem)
{
if (bacteriaItem != null)
{
Visual dv = drawCanvas.GetVisual(Convert.ToInt32(bacteriaItem.bacteriacoordinate_id));
if (dv != null)
{
// 删除Visual
drawCanvas.DeleteVisual(dv);
// 删除DataGridItem
countOfManualdelete++;
LoggerRunHelper.InfoLog(string.Format("[ManualPickBacteria][DeleteBacteriaItem]: 删除坐标成功: 像素坐标:{0}, 机械坐标:{1}",
bacteriaItem.coordinate_pixel, bacteriaItem.coordinate_machine));
return true;
}
else
{
LoggerRunHelper.ErrorLog(string.Format("[ManualPickBacteria][DeleteBacteriaItem]: 删除坐标失败: bacteriacoordinate_id:{0}",
bacteriaItem.bacteriacoordinate_id));
return false;
}
}
else
{
LoggerRunHelper.ErrorLog(string.Format("[ManualPickBacteria][DeleteBacteriaItem]: bacteriaItem = null, 删除失败!"));
return false;
}
}
private void btnZoomin_Click(object sender, RoutedEventArgs e)
{
try
{
double zoom = drawViewer.Zoom * 0.8;
drawViewer.Zoom = zoom;
}
catch (Exception ex)
{
LoggerHelper.ErrorLog("ERROR:", ex);
}
}
private void btnZoomout_Click(object sender, RoutedEventArgs e)
{
try
{
double zoom = drawViewer.Zoom * 1.2;
drawViewer.Zoom = zoom;
}
catch (Exception ex)
{
LoggerHelper.ErrorLog("ERROR:", ex);
}
}
private void btnFit_Click(object sender, RoutedEventArgs e)
{
try
{
drawViewer.Zoom = startZoom;
}
catch (Exception ex)
{
LoggerHelper.ErrorLog("ERROR:", ex);
}
}
}
}