using Casic.Birmm.RbFreqStandMeasure.Properties; using Casic.Birmm.RbFreqStandMeasure.tools; using Casic.Birmm.RbFreqStandMeasure.Tools; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.IO.Ports; using System.Reflection; using System.Text; using System.Threading; using System.Windows.Forms; namespace Casic.Birmm.RbFreqStandMeasure { public partial class StatusCtrlForm : UserControl { public static StatusCtrlForm statusCtrlForm; public static Coordinate coo ; private readonly object obj = new object(); public static Graphics gp; private static bool created = false; public static SerialPort portSatellite = new SerialPort(); public static string receiverStatus = ""; public static string date = ""; public static string time = ""; public static string mjd = ""; public static string lat = ""; public static string lng = ""; public static string x = ""; public static string y = ""; public static string z = ""; public static List<string> gpList = new List<string>(); public static List<string> bdList = new List<string>(); public static int totalGP = 0; public static int totalBD = 0; public static int gpCount = 0; public StatusCtrlForm() { InitializeComponent(); statusCtrlForm = this; this.DoubleBuffered = true; // SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true); //label_date.Text = DateTime.Now.ToString("yyyy-MM-dd"); //label_time.Text = DateTime.Now.ToString("HH:mm:ss"); ////if (!created) //{ // gp = coo.CreateGraphics(); // created = true; //} coo = new Coordinate(); panelSite.Controls.Add(coo); coo.Show(); //if (!FreshStatus.isStarted) //{ // // 开始获取原子钟状态的timer // // FreshStatus.startClockFresh(); //} new Thread(() => { Thread.Sleep(500); lock (obj) { label_clockStatus.Text = FreshStatus.clockStatus; label_receiverStatus.Text = receiverStatus; label_date.Text = date; label_time.Text = time; label_mjd.Text = mjd; label_lat.Text = lat; label_lng.Text = lng; label_x.Text = x; label_y.Text = y; label_z.Text = z; refreshDraw(); //LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "界面初始化。。。。。。"); //draw(FreshStatus.bdList, FreshStatus.gpList); } }).Start(); } public void draw(List<string> bdList, List<string> gpList) { try { if (bdList.Count > 0 || gpList.Count>0) { Invoke(new MethodInvoker(delegate () { //Graphics gp = panelSite.CreateGraphics(); //gp.Clear(panelSite.BackColor); //gp.Dispose(); panelSite.Controls.Clear(); coo = new Coordinate(); panelSite.Controls.Add(coo); coo.Show(); //drawFunc(bdList); //drawFunc(gpList); } )); } } catch (Exception ex) { LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "draw error:" + ex.Message); } } private void PaintImage(Graphics gp) { try { Invoke(new MethodInvoker(delegate () { //if(receiverStatus.Equals("警告")) //{ return; } if (bdList.Count > 0) { int bdCount = 0; foreach (string gsv in bdList) { string[] arr = gsv.Split(','); int length = arr.Length; for (int i = 4; i < arr.Length; i = i + 3) { if ((i + 3) < arr.Length && !arr[i + 1].Equals("") && !arr[i + 2].Equals("") && !arr[i + 3].Equals("")) { int Elevation = Convert.ToInt32(arr[i + 1]); int azimuth = Convert.ToInt32(arr[i + 2]); double cosLen = Math.Cos(Elevation * Math.PI / 180) * (575 / 2); double xCor = Math.Cos(azimuth * Math.PI / 180) * cosLen; double yCor = Math.Sin(azimuth * Math.PI / 180) * cosLen; int x = (int)Math.Floor(600 / 2 + xCor); int y = (int)Math.Floor(610 / 2 - yCor); string type = "CHN"; gp.DrawImage((Bitmap)Resources.ResourceManager.GetObject(type), x, y); bdCount++; } } } if (bdCount > 0) label_chnTotal.Text = bdCount + ""; } if (gpList.Count > 0) { gpCount = 0; foreach (string gsv in gpList) { string[] arr = gsv.Split(','); int length = arr.Length; for (int i = 4; i < arr.Length; i = i + 3) { if ((i + 3) < arr.Length && !arr[i + 1].Equals("") && !arr[i + 2].Equals("") && !arr[i + 3].Equals("")) { int Elevation = Convert.ToInt32(arr[i + 1]); int azimuth = Convert.ToInt32(arr[i + 2]); double cosLen = Math.Cos(Elevation * Math.PI / 180) * (575 / 2); double xCor = Math.Cos(azimuth * Math.PI / 180) * cosLen; double yCor = Math.Sin(azimuth * Math.PI / 180) * cosLen; int x = (int)Math.Floor(600 / 2 + xCor); int y = (int)Math.Floor(610 / 2 - yCor); string type = "USA"; gp.DrawImage((Bitmap)Resources.ResourceManager.GetObject(type), x, y); gpCount++; } } } if (gpCount > 0) label_usaTotal.Text = gpCount + ""; } } )); } catch (Exception e) { LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "drawFunc错误:" + e.Message); } } private void panelSite_Paint(object sender, PaintEventArgs e) { try { if (receiverStatus.Equals("警告")) { } if ( bdList.Count > 0 ||gpList.Count > 0) { Invoke(new MethodInvoker(delegate () { Rectangle rect = e.ClipRectangle; BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current; BufferedGraphics myBuffer = currentContext.Allocate(e.Graphics, e.ClipRectangle); Graphics g = myBuffer.Graphics; g.SmoothingMode = SmoothingMode.HighQuality; g.PixelOffsetMode = PixelOffsetMode.HighSpeed; g.Clear(panelSite.BackColor); PaintImage(g); myBuffer.Render(e.Graphics); g.Dispose(); myBuffer.Dispose();//释放资源 } )); } } catch (Exception ex) { LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "error error:" + ex.Message); } } private void timer1_Tick(object sender, EventArgs e) { refreshDraw(); } private void refreshDraw() { try { if (!portSatellite.IsOpen) { string portName = ConfigHelper.GetAppConfig("satellite").Split(' ')[0]; int bandRate = Convert.ToInt32(ConfigHelper.GetAppConfig("satellite").Split(' ')[1]); portSatellite.PortName = portName; portSatellite.BaudRate = bandRate; portSatellite.Parity = Parity.None; portSatellite.DataBits = 8; portSatellite.StopBits = StopBits.One; portSatellite.Handshake = Handshake.None; portSatellite.ReadTimeout = -1; portSatellite.WriteTimeout = 3000; // 打开串口 if (!portSatellite.IsOpen) portSatellite.Open(); if (portSatellite.IsOpen) { LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "打开卫星状态串口成功!" + portName); } else { MessageBox.Show("无法打开串口" + portName + ",卫星状态更新失败!"); return; } } int bdMessCount = 0; int gpMessCount = 0; int count = 0; lock (obj) { gpList.Clear(); bdList.Clear(); totalGP = 0; totalBD = 0; } while (count < 1000) { Thread.Sleep(100); int Readlen = portSatellite.BytesToRead; if (Readlen > 0) { byte[] buffer = new byte[Readlen]; portSatellite.Read(buffer, 0, Readlen);// 接收数据到buffer里面 string data = Encoding.ASCII.GetString(buffer); string[] dataArray = data.Split('$'); if (dataArray.Length > 0) { lock (obj) { } int index = -1; bool drawed = false; bool gga = false; bool rmc = false; foreach (string sss in dataArray) { index++; if ((sss.Contains("GPGGA") || sss.Contains("GNGGA")) && sss.Contains("*")) { string[] resultArray = sss.Split(','); if (resultArray.Length > 5) { gga = true; try { lat = resultArray[2].Replace(".", "").Insert(2, ".") + resultArray[3]; lng = resultArray[4].Replace(".", "").Insert(3, ".") + resultArray[5]; x = parseGGA(sss).Split(',')[0]; y = parseGGA(sss).Split(',')[1]; z = parseGGA(sss).Split(',')[2]; lock (obj) { statusCtrlForm.label_lat.Text = lat; statusCtrlForm.label_lng.Text = lng; statusCtrlForm.label_x.Text = x; statusCtrlForm.label_y.Text = y; statusCtrlForm.label_z.Text = z; } } catch (Exception ex) { LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "GGA error:" + ex.Message); } } } else if (sss.Contains("GNRMC") && sss.Contains("*")) { string[] resultArray = sss.Split(','); if (resultArray.Length > 9) { rmc = true; date = resultArray[9]; mjd = ""; if (date.Length > 5) { mjd = getMJD("20" + date.Substring(4, 2), date.Substring(2, 2), date.Substring(0, 2)); date = "20" + date.Substring(4, 2) + "-" + date.Substring(2, 2) + "-" + date.Substring(0, 2); } time = resultArray[1]; if (time.Length > 5) { int hour = Convert.ToInt32(time.Substring(0, 2)); if ((hour + 8) > 23) hour = hour + 8 - 24; else hour = hour + 8; time = hour + ":" + time.Substring(2, 2) + ":" + time.Substring(4); } if (resultArray[2] == "A") receiverStatus = "定位有效"; else if (resultArray[2] == "V") receiverStatus = "警告"; try { lock (obj) { statusCtrlForm.label_date.Text = date; statusCtrlForm.label_time.Text = time; statusCtrlForm.label_mjd.Text = mjd; statusCtrlForm.label_receiverStatus.Text = receiverStatus; HomeCtrlForm.homeCtrlForm.label_receiverStatus.Text = receiverStatus; } } catch (Exception ex) { LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "RMC error:" + ex.Message); } } } else if ((sss.Contains("GPGSV") || sss.Contains("BDGSV") || sss.Contains("GBGSV")) && sss.Contains("*")) { if (sss.Split(',').Length > 8) { if (sss.Contains("GPGSV")) { gpMessCount = Convert.ToInt32(sss.Split(',')[1]); if (gpList.Count < gpMessCount) { gpList.Add(sss); totalGP = Convert.ToInt32(sss.Split(',')[3]); } } else { bdMessCount = Convert.ToInt32(sss.Split(',')[1]); if (bdList.Count < bdMessCount) { bdList.Add(sss); totalBD = Convert.ToInt32(sss.Split(',')[3]); } } if ((gpList.Count > 0 && gpList.Count == gpMessCount) && (bdList.Count > 0) && bdList.Count == bdMessCount) { if (!drawed) { drawed = true; try { lock (obj) { panelSite.Refresh(); } } catch (Exception ex) { LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "draw gsv error:" + ex.Message); } } } } } if (drawed && gga && rmc) { break; } } break; } } count++; } } catch (Exception ex) { LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "exeSatellite error:" + ex.Message); } } private static string getMJD(string ys, string ms, string ds) { try { int y = Convert.ToInt32(ys) - 1900; int m = Convert.ToInt32(ms); int d = Convert.ToInt32(ds); int L = 0; if (m == 1 || m == 2) L = 1; int njdINT = 14956 + d + (int)((y - L) * 365.25) + (int)((m + 1 + L * 12) * 30.6001); return njdINT + ""; } catch (Exception ex) { LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "getMJD error:" + ex.Message); return ""; } } private string parseGGA(string ggaStr) { try { double f = 1 / 298.257223563; /*基准椭球体的极扁率*/ double a = 6378137.0; /*基准椭球体的长半径*/ double b = 6356752.314; /*基准椭球体的短半径*/ double e2 = f * (2 - f); /*基准椭球体的偏心率*/ double pi_180 = Math.PI / 180; //$GPGGA,081918.00,3954.7889938,N,11615.5667600,E,1,28,0.68,78.6748,M,-9.7970,M,02,*7D var arr = ggaStr.Split(','); string m_pBs = parseCoord(arr[2], arr[3]); string m_pLs = parseCoord(arr[4], arr[5]); string m_pHs = ""; if (!arr[9].Equals("") && !arr[11].Equals("")) m_pHs = Convert.ToDouble(arr[9]) + Convert.ToDouble(arr[11]) + "";// add 大地水准面高度 纠正误差 // objBLH.b = util.parseCoord(arr[2],arr[3]); // objBLH.l = util.parseCoord(arr[4],arr[5]); // objBLH.h = parseFloat(arr[9]); string X = "", Y = "", Z = ""; if (!m_pBs.Equals("") && !m_pLs.Equals("") && !m_pHs.Equals("")) { double m_pB = Convert.ToDouble(m_pBs); double m_pL = Convert.ToDouble(m_pLs); double m_pH = Convert.ToDouble(m_pHs); double N = a / Math.Sqrt(1 - e2 * Math.Sin(m_pB * pi_180) * Math.Sin(m_pB * Math.PI)); X = (N + m_pH) * Math.Cos(m_pB * pi_180) * Math.Cos(m_pL * Math.PI) + ""; Y = (N + m_pH) * Math.Cos(m_pB * pi_180) * Math.Sin(m_pL * Math.PI) + ""; Z = (N * (1 - e2) + m_pH) * Math.Sin(m_pB * pi_180) + ""; } return X + "," + Y + "," + Z; } catch (Exception ex) { LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "parseGGA error:" + ex.Message); return " , , "; } } private string parseCoord(string coord, string dir) { //$GPGGA,081918.00,3954.7889938,N,11615.5667600,E,1,28,0.68,78.6748,M,-9.7970,M,02,*7D if (coord.Equals("")) return null; int n = 1, sgn = 1; switch (dir) { case "S": sgn = -1; break; case "N": n = 2; break; case "W": sgn = -1; break; case "E": n = 3; break; default: break; } return sgn * (Convert.ToDouble(coord.Substring(0, n)) + Convert.ToDouble(coord.Substring(n)) / 60) + ""; } private string BLH2XYX(string objectBLH) { // var objectBLH ={l:116.259446,b:39.91314989666667,h:78.6748};//for test // var N = a / Math.sqrt(1 - e2 * Math.sin(objectBLH.b * pi_180) * Math.sin(objectBLH.b * pi_180)); // var X = (N + objectBLH.h) * Math.cos(objectBLH.b * pi_180) * Math.cos(objectBLH.l * pi_180); // var Y = (N + objectBLH.h) * Math.cos(objectBLH.b * pi_180) * Math.sin(objectBLH.l * pi_180); // var Z = [N * (1 - e2 ) + objectBLH.h] * Math.sin(objectBLH.b * pi_180); // var objectXYZ = {}; // objectXYZ.X = X; // objectXYZ.Y = Y; // objectXYZ.Z = Z; string X = "", Y = "", Z = ""; double m_pB = Convert.ToDouble(objectBLH.Split(',')[0]); double m_pL = Convert.ToDouble(objectBLH.Split(',')[1]); double m_pH = Convert.ToDouble(objectBLH.Split(',')[2]); //double N = a / Math.Sqrt(1 - e2 * Math.Sin(m_pB * pi_180) * Math.Sin(m_pB * Math.PI)); //X = (N + m_pH) * Math.Cos(m_pB * pi_180) * Math.Cos(m_pL * Math.PI); //Y = (N + m_pH) * Math.Cos(m_pB * pi_180) * Math.Sin(m_pL * Math.PI); //Z = [N * (1 - e2) + m_pH] * Math.Sin(m_pB * pi_180); return X + "," + Y + "," + Z; } } }