using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace 云心电ECG数据解析服务端
{
public class Hl7EcgOptions
{
float[] valueConvert(float[] valueArray)
{
float[] quotients = valueArray.Select(n => n / 9).ToArray();//把数值缩小9倍 这是用标准数据进行标定得到的 缩小倍数系数
return quotients;
}
///
/// 读取HL7文件中的患者信息和心电分析参数
///
///
public analysisParas getAnalysisParas(string xmlFilePath)
{
try
{
FileInfo fi = new FileInfo(xmlFilePath);
XmlDocument xmlDoc = new XmlDocument();
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;//忽略文档里面的注释
XmlReader reader = XmlReader.Create(xmlFilePath, settings);
xmlDoc.Load(reader);
XmlNodeList xnList = xmlDoc.DocumentElement.GetElementsByTagName("annotation");
analysisParas ap = new analysisParas();
//先从hl7 ecg xml文件中读取心电数据
XmlNodeList xnListx1 = xmlDoc.DocumentElement.GetElementsByTagName("digits");
// Dictionary> EcgTable = new Dictionary>();
int leadDataIndex = 0;
for (int i = 0; i < 12; i++)
{
string[] ecgDataArray = new string[xnListx1.Item(leadDataIndex + i).InnerText.Split(' ').Length];
ecgDataArray = xnListx1.Item(leadDataIndex + i).InnerText.Split(' ');
//List ecg_List = valueConvert(Array.ConvertAll(ecgDataArray, float.Parse)).ToList();
List ecg_List = new List();
for (int b = 0; b < ecgDataArray.Length; b++)
if (!string.IsNullOrEmpty(ecgDataArray[b]))
ecg_List.Add(float.Parse(ecgDataArray[b]) / 9);
if (i == 0) ap.LEAD_I = ecg_List;
if (i == 1) ap.LEAD_II = ecg_List;
if (i == 2) ap.LEAD_III = ecg_List;
if (i == 3) ap.LEAD_AVR = ecg_List;
if (i == 4) ap.LEAD_AVL = ecg_List;
if (i == 5) ap.LEAD_AVF = ecg_List;
if (i == 6) ap.LEAD_V1 = ecg_List;
if (i == 7) ap.LEAD_V2 = ecg_List;
if (i == 8) ap.LEAD_V3 = ecg_List;
if (i == 9) ap.LEAD_V4 = ecg_List;
if (i == 10) ap.LEAD_V5 = ecg_List;
if (i == 11) ap.LEAD_V6 = ecg_List;
// EcgTable.Add(i, ecg_List);
}
XmlNodeList xnList1 = xmlDoc.DocumentElement.GetElementsByTagName("family");
ap.patientName = xnList1[0].InnerText;//姓名
XmlNodeList xnList2 = xmlDoc.DocumentElement.GetElementsByTagName("administrativeGenderCode");
string valStr = xnList2[0].OuterXml;
string sexStr = valStr.Substring(valStr.IndexOf("code="), valStr.IndexOf("codeSystem=") - valStr.IndexOf("code=")).Replace("code=", "").Replace("\"", "").Trim();//性别
if (sexStr.Trim() == "M")
ap.gender = "男";
if (sexStr.Trim() == "F")
ap.gender = "女";
XmlNodeList xnList4 = xmlDoc.DocumentElement.GetElementsByTagName("birthTime");
string birthday = xnList4[0].OuterXml;//出生日期
birthday = birthday.Substring(birthday.IndexOf("value="), birthday.IndexOf("xmlns=") - birthday.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
if (birthday.Length > 0)
{
ap.birthDay = birthday;
int year = int.Parse(ap.birthDay.Substring(0, 4));
ap.age = (DateTime.Now.Year - year).ToString();
}
XmlNodeList xnList5 = xmlDoc.DocumentElement.GetElementsByTagName("patientid");
string patientId = xnList5[0].OuterXml;//患者id
patientId = patientId.Substring(patientId.IndexOf("extension="), patientId.IndexOf("xmlns=") - patientId.IndexOf("extension=")).Replace("extension=", "").Replace("\"", "").Trim();
ap.patientid = patientId;
//获取日期和时间
XmlNodeList xnList3 = xmlDoc.DocumentElement.GetElementsByTagName("effectiveTime");
string collStr = xnList3[0].FirstChild.OuterXml;
string collectTime = collStr.Substring(collStr.IndexOf("value="), collStr.IndexOf("xmlns=") - collStr.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();//采集时间
if (collectTime.Length > 0)
{
ap.collectTime = collectTime.Insert(4, "-").Insert(7, "-").Insert(10, " ").Insert(13, ":").Insert(16, ":");//转换成日期时间格式
}
foreach (XmlNode xnx in xnList)
{
// string sss = xnx.FirstChild.Name;
string OuterXml1 = xnx.FirstChild.OuterXml;
// string xxx = xnx.LastChild.Name;
string OuterXml2 = xnx.LastChild.OuterXml;
if (OuterXml1.Contains("MDC_ECG_HEART_RATE"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.heartRate = valueStr;
}
if (OuterXml1.Contains("MDC_ECG_TIME_PD_P") && !OuterXml1.Contains("MDC_ECG_TIME_PD_PR") && !OuterXml1.Contains("MDC_ECG_TIME_PD_PQ"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.P = valueStr;
}
if (OuterXml1.Contains("MDC_ECG_TIME_PD_QRS"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.QRS = valueStr;
}
if (OuterXml1.Contains("MDC_ECG_TIME_PD_RR"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.RR = valueStr;
}
if (OuterXml1.Contains("MDC_ECG_TIME_PD_PR"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.PR = valueStr;
}
if (OuterXml1.Contains("MDC_ECG_TIME_PD_PQ"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.PQ = valueStr;
}
if (OuterXml1.Contains("MDC_ECG_TIME_PD_QT") && !OuterXml1.Contains("MDC_ECG_TIME_PD_QTc"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.QT = valueStr;
}
if (OuterXml1.Contains("MDC_ECG_TIME_PD_QTc"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.QTc = valueStr;
}
if (OuterXml1.Contains("MDC_ECG_ANGLE_P_FRONT"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.P_degrees = valueStr;
}
if (OuterXml1.Contains("MDC_ECG_ANGLE_QRS_FRONT"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.QRS_degrees = valueStr;
}
if (OuterXml1.Contains("MDC_ECG_ANGLE_T_FRONT"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.T_degrees = valueStr;
}
if (OuterXml1.Contains("Biocare_RV5") && !OuterXml1.Contains("Biocare_RV5_PLUS_SV1"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.RV5 = valueStr;
}
if (OuterXml1.Contains("Biocare_SV1"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.SV1 = valueStr;
}
if (OuterXml1.Contains("Biocare_RV5_PLUS_SV1"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.RV5PLUSSV1 = valueStr;
}
if (OuterXml1.Contains("Biocare_PAPER_SPEED"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.paperSpeed = valueStr + "mm/s";
}
if (OuterXml1.Contains("Biocare_GAIN"))
{
string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();
ap.Gain = valueStr + "mm/mV";
}
}
reader.Close();
return ap;
}
catch (Exception ex) { }
return null;
}
///
/// 根据HL7-ECG XML文件 生成心电图
///
/// HL7-ECG XML 文件的路径
/// 心电图报告标题
///
public string createEcgBmpByHL7XMLFile(string path, string reportInfo)
{
analysisParas ap = getAnalysisParas(path);
FileInfo fi = new FileInfo(path);
XmlDocument xmlDoc = new XmlDocument();
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;//忽略文档里面的注释
XmlReader reader = XmlReader.Create(path, settings);
xmlDoc.Load(reader);
XmlNodeList xn = xmlDoc.ChildNodes;
XmlNodeList xnList = xmlDoc.DocumentElement.GetElementsByTagName("digits");
Dictionary> EcgTable = new Dictionary>();
int leadDataIndex = 0;
for (int i = 0; i < 12; i++)
{
string[] ecgDataArray = new string[xnList.Item(leadDataIndex + i).InnerText.Split(' ').Length];
ecgDataArray = xnList.Item(leadDataIndex + i).InnerText.Split(' ');
List ecg_List = new List();
for (int b = 0; b < ecgDataArray.Length; b++)
if (!string.IsNullOrEmpty(ecgDataArray[b]))
ecg_List.Add(float.Parse(ecgDataArray[b]) / 9);
EcgTable.Add(i, ecg_List);
}
EcgDataDraw_New EDDN = new EcgDataDraw_New();
var btmp = new Bitmap(3319, 2357);
Graphics Ecg_Graphics = Graphics.FromImage(btmp);
List leadInfo = new List();
for (int i = 0; i < 12; i++)
leadInfo.Add(i);
EDDN.InitEcgParameter(btmp, 12, EcgTable, 300, leadInfo);//初始化
EDDN.Draw_EcgBackGroundGrid(500);//画背景网格
EDDN.Draw_EcgWave(500, 0, 0);//画波形
EDDN.Draw_analysisParas(ap);//画患者信息和分析参数
EDDN.Draw_CalibrationVoltage_And_LeadName();//画定标电压和导联名称
EDDN.Draw_ReportHeadInfo(reportInfo, "", "");
//string bmpPath = fi.DirectoryName + @"\EcgDataFiles\" + reportInfo + ".jpg";
// string RotateEcgDataFilesPath = fi.DirectoryName + @"\RotateEcgDataFiles\" + reportInfo+ ".jpg";
//string xmlPath = fi.DirectoryName + @"\XmlDataFiles\" + reportInfo + ".xml";
string ecgBmpPath = fi.DirectoryName + @"\" + ap.patientName + "[" + Guid.NewGuid().ToString() + "].jpg";
btmp.Save(ecgBmpPath, ImageFormat.Jpeg);
//btmp.RotateFlip(RotateFlipType.Rotate90FlipNone);//顺时针旋转90°
//btmp.Save(RotateEcgDataFilesPath, ImageFormat.Jpeg);
btmp.Dispose();
reader.Close();
// fi.CopyTo(xmlPath, true);
//string returnStr = FtpHelper.FileUpLoad(bmpPath, ConfigurationManager.AppSettings["path1"], reportInfo + ".jpg");//上传 png文件
// textBox2.AppendText(bmpPath + "\r\n" + reportInfo + ".jpg" + "\r\n FTP:" + returnStr + "\r\n"); // FtpHelper.FileUpLoad(xmlPath, ConfigurationManager.AppSettings["path1"], reportInfo.Split('_')[0] + ".xml");//上传 xml文件
//dataSubmit(reportInfo);//提交数据
//SqliteOptions_sql.CreateInstance().SqliteAdd("INSERT INTO [dbo].[tb_Pecg] ([ID],[medicalSN],[patientName],[sex],[birthday],[createDate],[ecgFilePath]) VALUES ('" + Guid.NewGuid().ToString() + "','" + reportInfo.Split('_')[0] + "','" + reportInfo.Split('_')[1] + "','" + reportInfo.Split('_')[2] + "','" + birthday + "','" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + (reportInfo.Split('_')[0] + ".jpg") + "')");
//fi.Delete();
//textBox2.AppendText(label1.Text + "\r\n");
//label1.Text = string.Empty;
return ecgBmpPath;
}
}
}