EphHelper.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. using DevExpress.Charts.Native;
  2. using DevExpress.XtraPrinting;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace PosResAnalysis
  11. {
  12. /// <summary>
  13. /// 星历推算帮助类.该类调用了Tle2XYZ.exe进程
  14. /// </summary>
  15. public static class EphHelper
  16. {
  17. private static readonly DateTime dtZero = new DateTime(1970, 1, 1, 0, 0, 0, 0);
  18. private static string exePath= "星历推算";
  19. private const string exeName = "Tle2XYZ.exe";
  20. /// <summary>
  21. /// 设置【Tle2XYZ.exe】文件所在路径,支持相对路径
  22. /// </summary>
  23. public static void SetExePath(string path)
  24. {
  25. if (string.IsNullOrWhiteSpace(path)) return;
  26. if (path.StartsWith("\\"))//相对路径要么开头不带\,要么是 .\
  27. path = path.Remove(0, 1);
  28. exePath = path;
  29. }
  30. /// <summary>
  31. /// 推算双行星历
  32. /// </summary>
  33. /// <param name="tleStr">双行根数</param>
  34. /// <param name="dt">指定时刻(北京时间)</param>
  35. /// <returns></returns>
  36. public static SatEphDto Calc(string tleStr, DateTime dt)
  37. {
  38. if (string.IsNullOrWhiteSpace(exePath))
  39. throw new Exception($"请先调用SetExePath指定{exeName}进程所在路径,支持相对路径");
  40. if (!Directory.Exists(exePath))
  41. throw new Exception($"路径[{exePath}]不存在");
  42. var exeFile = Path.Combine(exePath, exeName);
  43. if (!File.Exists(exeFile))
  44. throw new Exception($"文件[{exeFile}]不存在");
  45. tleStr = tleStr.Replace(";", ";");
  46. if (tleStr.EndsWith(";"))
  47. tleStr = tleStr.Substring(0, tleStr.Length - 1);
  48. tleStr = tleStr.Replace(";", ";");
  49. var line1 = tleStr.Split(';')[0];
  50. var line2 = tleStr.Split(';')[1];
  51. var dtUtc = dt.AddHours(-8);
  52. var timeSpan = (long)(dtUtc - dtZero).TotalSeconds;
  53. Process p = new Process();
  54. p.StartInfo.WorkingDirectory = exePath;
  55. p.StartInfo.FileName = exeFile;
  56. p.StartInfo.Arguments = $"-a \"{line1}\" -b \"{line2}\" -t {timeSpan} -p 1 -c 1";
  57. p.StartInfo.CreateNoWindow = true;
  58. p.StartInfo.RedirectStandardError = true;
  59. p.StartInfo.RedirectStandardOutput = true;
  60. p.StartInfo.UseShellExecute = false;
  61. p.Start();
  62. var succeed = p.WaitForExit(10000);
  63. if (!succeed)
  64. {
  65. throw new Exception($"进程[{exeName}]超时未完成!");
  66. }
  67. return ParseOneResult(p.StandardOutput.ReadToEnd());
  68. }
  69. /// <summary>
  70. /// 批量推算双行星历
  71. /// </summary>
  72. /// <param name="tleStr">双行根数</param>
  73. /// <param name="start">起始时刻(北京)</param>
  74. /// <param name="end">结束(北京)</param>
  75. /// <param name="spanSeconds">推算间隔(秒)</param>
  76. /// <returns></returns>
  77. public static List<SatEphDto> CalcMult(string tleStr, DateTime start, DateTime end, int spanSeconds)
  78. {
  79. if (string.IsNullOrWhiteSpace(exePath))
  80. throw new Exception($"请先调用SetExePath指定{exeName}进程所在路径,支持相对路径");
  81. if (!Directory.Exists(exePath))
  82. throw new Exception($"路径[{exePath}]不存在");
  83. var exeFile = Path.Combine(exePath, exeName);
  84. if (!File.Exists(exeFile))
  85. throw new Exception($"文件[{exeFile}]不存在");
  86. tleStr = tleStr.Replace(";", ";");
  87. if (tleStr.EndsWith(";"))
  88. tleStr = tleStr.Substring(0, tleStr.Length - 1);
  89. tleStr = tleStr.Replace(";", ";");
  90. var line1 = tleStr.Split(';')[0];
  91. var line2 = tleStr.Split(';')[1];
  92. var dtUtc = start.AddHours(-8);
  93. var timeSpan = (long)(dtUtc - dtZero).TotalSeconds;
  94. var c = (end - start).TotalSeconds / spanSeconds;
  95. Process p = new Process();
  96. var binPath = AppDomain.CurrentDomain.BaseDirectory;
  97. p.StartInfo.WorkingDirectory = exePath;
  98. p.StartInfo.FileName = exeFile;
  99. p.StartInfo.Arguments = $"-a \"{line1}\" -b \"{line2}\" -t {timeSpan} -p {spanSeconds} -c {c + 1}";
  100. p.StartInfo.CreateNoWindow = true;
  101. p.StartInfo.RedirectStandardError = true;
  102. p.StartInfo.RedirectStandardOutput = true;
  103. p.StartInfo.UseShellExecute = false;
  104. StringBuilder sb = new StringBuilder();
  105. p.OutputDataReceived += (sender, e) => sb.Append(e.Data);
  106. p.Start();
  107. p.BeginOutputReadLine();
  108. p.WaitForExit();//WaitForExit加了超时时间的话进程退出后不能保证异步流已经读取完成,这是.NET框架的BUG
  109. return ParseResult(sb.ToString());
  110. }
  111. static List<SatEphDto> ParseResult(string result)
  112. {
  113. if (string.IsNullOrWhiteSpace(result))
  114. {
  115. throw new Exception("星历推算出现未知错误!");
  116. }
  117. var array = result.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
  118. List<SatEphDto> list = new List<SatEphDto>();
  119. foreach (var item in array)
  120. {
  121. var arrayItem = item.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
  122. for (int i = 0; i < arrayItem.Length; i++)
  123. {
  124. var dto = new SatEphDto
  125. {
  126. SatId = Convert.ToInt32(arrayItem[i++]),
  127. TleTime = dtZero.AddSeconds(Convert.ToInt64(arrayItem[i++])).AddHours(16),//内部有BUG需要多加8h
  128. SatTime = dtZero.AddSeconds(Convert.ToInt64(arrayItem[i++])).AddHours(8),//utc to beijing
  129. X = Math.Round(Convert.ToDouble(arrayItem[i++]), 3),
  130. Y = Math.Round(Convert.ToDouble(arrayItem[i++]), 3),
  131. Z = Math.Round(Convert.ToDouble(arrayItem[i++]), 3),
  132. VX = Math.Round(Convert.ToDouble(arrayItem[i++]), 3),
  133. VY = Math.Round(Convert.ToDouble(arrayItem[i++]), 3),
  134. VZ = Math.Round(Convert.ToDouble(arrayItem[i]), 3)
  135. };
  136. list.Add(dto);
  137. }
  138. }
  139. return list;
  140. }
  141. static SatEphDto ParseOneResult(string result)
  142. {
  143. if (string.IsNullOrWhiteSpace(result))
  144. {
  145. throw new Exception("星历推算出现未知错误!");
  146. }
  147. result = result.Replace(";", "");
  148. var array = result.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
  149. int i = 0;
  150. var dto = new SatEphDto
  151. {
  152. SatId = Convert.ToInt32(array[i++]),
  153. TleTime = dtZero.AddSeconds(Convert.ToInt64(array[i++])).AddHours(16),//内部有BUG需要多加8h
  154. SatTime = dtZero.AddSeconds(Convert.ToInt64(array[i++])).AddHours(8),//utc to beijing
  155. X = Math.Round(Convert.ToDouble(array[i++]), 3),
  156. Y = Math.Round(Convert.ToDouble(array[i++]), 3),
  157. Z = Math.Round(Convert.ToDouble(array[i++]), 3),
  158. VX = Math.Round(Convert.ToDouble(array[i++]), 3),
  159. VY = Math.Round(Convert.ToDouble(array[i++]), 3),
  160. VZ = Math.Round(Convert.ToDouble(array[i++]), 3)
  161. };
  162. return dto;
  163. }
  164. }
  165. public class SatEphDto
  166. {
  167. public int SatId { get; set; }
  168. public DateTime SatTime { get; set; }
  169. public DateTime TleTime { get; set; }
  170. public double X { get; set; }
  171. public double Y { get; set; }
  172. public double Z { get; set; }
  173. public double VX { get; set; }
  174. public double VY { get; set; }
  175. public double VZ { get; set; }
  176. public override string ToString()
  177. {
  178. return $"{X},{Y},{Z},{VX},{VY},{VZ}";
  179. }
  180. }
  181. }