GdopHelper.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. using DevExpress.Charts.Native;
  2. using DevExpress.Internal.WinApi.Windows.UI.Notifications;
  3. using DevExpress.XtraPrinting;
  4. using Newtonsoft.Json;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Data.Entity.Core.Common.EntitySql;
  8. using System.Diagnostics;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Runtime.InteropServices;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using XdCxRhDW.App.DTO;
  15. using static DevExpress.XtraCharts.GLGraphics.Platform.EGL;
  16. using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;
  17. namespace XzXdDw.App.Api.星地GDOP误差椭圆
  18. {
  19. /// <summary>
  20. /// Gdop误差分布计算帮助类.该类调用了GdopCore.exe进程
  21. /// 每种GDOP算法提供了两个接口,这两种接口是完全等价的,一种传入双行根,一种直接传入卫星状态x、y、z等
  22. /// </summary>
  23. public static class GdopHelper
  24. {
  25. private static string exePath = "Api\\星地GDOP误差椭圆\\GDOP";
  26. private const string exeName = "GdopCore.exe";
  27. private const string GDOPDll = @"Api\星地GDOP误差椭圆\GDOP\GDOP_Draw.dll";
  28. static readonly DateTime dtZero = new DateTime(1970, 1, 1, 8, 0, 0, 0);
  29. /// <returns></returns>
  30. [DllImport(GDOPDll, CallingConvention = CallingConvention.Cdecl)]
  31. public static extern int GdopLeoTowSatDRef(string mainLines, string adajLines, Int64 captime, double[] refPos
  32. , double fuHz1, double fuHz2, double dtousErr, double dfoHzErr, double ephLocErr, double ephVLocErr
  33. , double[] level, int levlen, int[] resCount, out IntPtr res, double[] satllh);
  34. [DllImport(GDOPDll, CallingConvention = CallingConvention.Cdecl)]
  35. public static extern void FreeGDOPBuf(IntPtr val);
  36. /// <summary>
  37. /// 低轨双星GDOP
  38. /// </summary>
  39. /// <param name="mainLines">主星星历</param>
  40. /// <param name="adajLines">邻星星历</param>
  41. /// <param name="captime">采集时间</param>
  42. /// <param name="refPos">参考站位置 长度3</param>
  43. /// <param name="fuHz1">目标上行频点 Hz</param>
  44. /// <param name="fuHz2">参考上行频点 Hz</param>
  45. /// <param name="dtousErr">时差误差</param>
  46. /// <param name="dfoHzErr">频差误差</param>
  47. /// <param name="ephLocErr">星历位置误差</param>
  48. /// <param name="ephVLocErr">星历速度误差</param>
  49. /// <param name="level"></param>
  50. /// <param name="satllh"></param>
  51. /// <param name="points"></param>
  52. public static (List<SatInfo>, List<ErrDistanceMapPoints>) GdopLeoTowSatDRef(string mainLines, string adajLines, DateTime captime, double[] refPos
  53. , double fuHz1, double fuHz2, double dtousErr, double dfoHzErr, double ephLocErr, double ephVLocErr)
  54. {
  55. int satCount = 2;
  56. //该值和points 一一对应
  57. double[] level = GdopParam.误差配置.小误差距离m;
  58. double[] satllh = new double[satCount*3];
  59. var timeSpan = (long)(captime - dtZero).TotalSeconds;
  60. IntPtr res = IntPtr.Zero;
  61. int[] resCount = new int[level.Length];
  62. GdopLeoTowSatDRef(mainLines, adajLines, timeSpan, refPos
  63. , fuHz1, fuHz2, dtousErr, dfoHzErr, ephLocErr, ephVLocErr, level, level.Length, resCount, out res, satllh);
  64. IntPtr tmp = res;
  65. //用于绘制的数据
  66. List<double[]> points = new List<double[]>();
  67. for (int idx = 0; idx < level.Length; ++idx)
  68. {
  69. double[] levelval = new double[resCount[idx]];
  70. Marshal.Copy(tmp, levelval, 0, resCount[idx]);
  71. tmp += (resCount[idx] * sizeof(double));
  72. points.Add(levelval);
  73. }
  74. FreeGDOPBuf(res);
  75. List<SatInfo> satInfos = ParseResult(satCount, satllh, mainLines, adajLines);
  76. List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
  77. for (int i = 0; i < points.Count; i++)
  78. {
  79. ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
  80. errDistanceMap.ErrDistance = level[i];
  81. errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
  82. errs.Add(errDistanceMap);
  83. }
  84. return (satInfos, errs);
  85. }
  86. /// <summary>
  87. /// 低轨两星GDOP
  88. /// </summary>
  89. /// <param name="refLonLat">参考站位置 长度2</param>
  90. /// <param name="mainTle">主星星历双行根</param>
  91. /// <param name="adjaTle">邻星星历双行根</param>
  92. /// <param name="time">采集时刻</param>
  93. /// <param name="dtousErr">时差误差(us)</param>
  94. /// <param name="dfoHzErr">频差误差(Hz)</param>
  95. /// <param name="ephLocErr">星历位置误差(m)</param>
  96. /// <param name="ephVLocErr">星历速度误差(m/s)</param>
  97. /// <param name="fu1">主星上行频点</param>
  98. /// <param name="fu2">邻星上行频点</param>
  99. /// <returns></returns>
  100. /// <exception cref="Exception"></exception>
  101. public static (List<SatInfo>, List<ErrDistanceMapLines>) GdopLeoTowSatDRef(double[] refLonLat, string mainTle, string adjaTle, DateTime time, double dtousErr, double dfoHzErr, double ephLocErr, double ephVLocErr, double fuHz1, double fuHz2)
  102. {
  103. if (string.IsNullOrWhiteSpace(exePath))
  104. throw new Exception($"请先调用SetExePath指定{exeName}进程所在路径,支持相对路径");
  105. if (!Directory.Exists(exePath))
  106. throw new Exception($"路径[{exePath}]不存在");
  107. var exeFile = Path.Combine(exePath, exeName);
  108. if (!File.Exists(exeFile))
  109. throw new Exception($"文件[{exeFile}]不存在");
  110. Process p = new Process();
  111. p.StartInfo.WorkingDirectory = exePath;
  112. p.StartInfo.FileName = exeFile;
  113. p.StartInfo.Arguments = $"73 \"{mainTle}\" \"{adjaTle}\" \"{time:yyyy-MM-dd HH:mm:ss.000000}\" {string.Join(" ", refLonLat)} {dtousErr} {dfoHzErr} {ephLocErr} {ephVLocErr} {fuHz1} {fuHz2}";
  114. p.StartInfo.CreateNoWindow = true;
  115. p.StartInfo.RedirectStandardError = true;
  116. p.StartInfo.RedirectStandardOutput = true;
  117. p.StartInfo.UseShellExecute = false;
  118. StringBuilder sb = new StringBuilder();
  119. p.OutputDataReceived += (sender, e) => sb.Append(e.Data);
  120. p.Start();
  121. p.BeginOutputReadLine();
  122. p.WaitForExit();//WaitForExit加了超时时间的话进程退出后不能保证异步流已经读取完成,这是.NET框架的BUG
  123. return ParseResult(2, sb.ToString());
  124. }
  125. /// <summary>
  126. /// 单星GDOP
  127. /// </summary>
  128. /// <param name="mainTle">第一刻时刻星历双行根</param>
  129. /// <param name="adjaTle1">第二刻时刻星历双行根</param>
  130. /// <param name="adjaTle2">第三刻时刻星历双行根></param>
  131. /// <param name="time">采集时刻</param>
  132. /// <param name="dfoHzErr">频差误差(Hz)</param>
  133. /// <param name="ephLocErr">星历位置误差(m</param>
  134. /// <param name="ephVLocErr">星历速度误差(m/s)</param>
  135. /// <param name="fuHz">卫星上行频点(Hz)</param>
  136. /// <returns></returns>
  137. /// <exception cref="Exception"></exception>
  138. public static (List<SatInfo>, List<ErrDistanceMapLines>) GdopSingleSatDRef(string mainTle, DateTime time1, DateTime time2, DateTime time3, double dfoHzErr, double ephLocErr, double ephVLocErr, double fuHz)
  139. {
  140. if (string.IsNullOrWhiteSpace(exePath))
  141. throw new Exception($"请先调用SetExePath指定{exeName}进程所在路径,支持相对路径");
  142. if (!Directory.Exists(exePath))
  143. throw new Exception($"路径[{exePath}]不存在");
  144. var exeFile = Path.Combine(exePath, exeName);
  145. if (!File.Exists(exeFile))
  146. throw new Exception($"文件[{exeFile}]不存在");
  147. Process p = new Process();
  148. p.StartInfo.WorkingDirectory = exePath;
  149. p.StartInfo.FileName = exeFile;
  150. p.StartInfo.Arguments = $"74 \"{mainTle}\" \"{time1:yyyy-MM-dd HH:mm:ss.000000}\" \"{time2:yyyy-MM-dd HH:mm:ss.000000}\" \"{time3:yyyy-MM-dd HH:mm:ss.000000}\" {dfoHzErr} {ephLocErr} {ephVLocErr} {fuHz}";
  151. p.StartInfo.CreateNoWindow = true;
  152. p.StartInfo.RedirectStandardError = true;
  153. p.StartInfo.RedirectStandardOutput = true;
  154. p.StartInfo.UseShellExecute = false;
  155. StringBuilder sb = new StringBuilder();
  156. p.OutputDataReceived += (sender, e) => sb.Append(e.Data);
  157. p.Start();
  158. p.BeginOutputReadLine();
  159. p.WaitForExit();//WaitForExit加了超时时间的话进程退出后不能保证异步流已经读取完成,这是.NET框架的BUG
  160. return ParseResult(1, sb.ToString());
  161. }
  162. private static List<MapDot> ParseResult(double[] ponits)
  163. {
  164. List<MapDot> mapDots = new List<MapDot>();
  165. int count = 2;
  166. for (int i = 0; i < ponits.Length / count; i++)
  167. {
  168. MapDot mapDot = new MapDot();
  169. mapDot.Lat = ponits[count * i + 1];
  170. mapDot.Lon = ponits[count * i];
  171. mapDots.Add(mapDot);
  172. }
  173. return mapDots;
  174. }
  175. private static List<SatInfo> ParseResult(int satCount, double[] satllh, params string[] ephLine)
  176. {
  177. List<SatInfo> list = new List<SatInfo>();
  178. int len = 3;
  179. for (int i = 0; i < satCount; i++)
  180. {
  181. SatInfo satInfo = new SatInfo();
  182. var ephstrs = ephLine[i].Split(new string[] { " ", "U" }, StringSplitOptions.RemoveEmptyEntries);
  183. if (ephstrs.Length == 16)
  184. {
  185. satInfo.SatCode = Convert.ToInt32(ephstrs[1]);
  186. }
  187. satInfo.SatLon = Convert.ToDouble(satllh[len * i]);
  188. satInfo.SatLat = Convert.ToDouble(satllh[len * i + 1]);
  189. list.Add(satInfo);
  190. }
  191. return list;
  192. }
  193. private static (List<SatInfo>, List<ErrDistanceMapLines>) ParseResult(int satCount, string txt)
  194. {
  195. if (string.IsNullOrWhiteSpace(txt))
  196. {
  197. throw new Exception("GDOP计算出现未知错误!");
  198. }
  199. if (txt.StartsWith("1 "))
  200. {
  201. throw new Exception(txt.Remove(0, 2));
  202. }
  203. var arr = txt.Split(' ');
  204. List<SatInfo> list = new List<SatInfo>();
  205. for (int i = 0; i < satCount; i++)
  206. {
  207. SatInfo satInfo = new SatInfo();
  208. var satCode = Convert.ToInt32(arr[3 * i + 1]);
  209. if (satCode > 0)
  210. satInfo.SatCode = satCode;
  211. satInfo.SatLon = Convert.ToDouble(arr[3 * i + 2]);
  212. satInfo.SatLat = Convert.ToDouble(arr[3 * i + 3]);
  213. list.Add(satInfo);
  214. }
  215. var jsonStr = arr[1 + satCount * 3];
  216. var res = JsonConvert.DeserializeObject<List<ErrDistanceMapLines>>(jsonStr);
  217. return (list, res);
  218. }
  219. }
  220. }