EphHelper.cs 9.1 KB

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