DrawDtoLineHelper.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. 
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using XdCxRhDW.Entity;
  10. namespace XdCxRhDW.Api
  11. {
  12. public class DrawDtoLineHelper
  13. {
  14. private const string XdtsDll = @"AddIns\时差线\Positioning.dll";
  15. //三星双时差带参、三星双时差无参、三星双频差带参、双星时频差带参、两星一地无参定位及时差线
  16. private const string xddtodll = @"AddIns\时差线\Position-New.dll";
  17. [DllImport(xddtodll, EntryPoint = "XingDi_SCX_NoRef", CallingConvention = CallingConvention.Cdecl)]//高轨双星有参时差线
  18. public extern static void XingDi_SCX_NoRef(double[] main_sat_pos, double[] mbwx_rec_pos, double[] cdb_rec_pos,
  19. double[] Zone, double target_dto, out IntPtr LOP_Value, ref int LOP_Len);
  20. [DllImport(XdtsDll, EntryPoint = "CurveByTwoTDOA", CallingConvention = CallingConvention.Cdecl)]//高轨双星有参时差线
  21. public extern static void CurveByTwoTDOA(double[] main_sat_pos, double[] neigh_sat_pos, double[] rec1_pos, double[] rec2_pos, double[] ref_pos, double[] Zone,
  22. double target_dto, double ref_dto, out IntPtr LOP_Value, ref int LOP_Len);
  23. /*
  24. 双星时差线-无参
  25. LOP_Value 返回值 结构参考DTO_Plot
  26. LOP_Len*3为LOP_Value的长度
  27. */
  28. [DllImport(XdtsDll, EntryPoint = "CurveByTwoTDOAWithNoRef", CallingConvention = CallingConvention.Cdecl)]//高轨双星无参时差线
  29. public extern static void CurveByTwoTDOAWithNoRef(double[] main_sat_pos, double[] neigh_sat_pos, double[] rec1_pos, double[] rec2_pos,
  30. double[] Zone, double target_dto, out IntPtr LOP_Value, ref int LOP_Len);
  31. [DllImport(XdtsDll, CallingConvention = CallingConvention.Cdecl)]
  32. public static extern void Destory(IntPtr val);
  33. private const string exeName = "XingDiSCX.exe";//星地时差线
  34. // private static double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  35. /// <summary>
  36. /// 星地有参时差线
  37. /// </summary>
  38. /// <param name="opt"></param>
  39. /// <returns></returns>
  40. /// <exception cref="Exception"></exception>
  41. public static IEnumerable<(double lon, double lat)> DtoLineXd(DtoLineXdOption opt)
  42. {
  43. List<DtoLinePoint> list = new List<DtoLinePoint>();
  44. string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AddIns\\时差线\\DtoLine.dat");
  45. string exePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AddIns\\时差线");
  46. if (string.IsNullOrWhiteSpace(exePath))
  47. throw new Exception($"请先调用SetExePath指定{exeName}进程所在路径,支持相对路径");
  48. if (!Directory.Exists(exePath))
  49. throw new Exception($"路径[{exePath}]不存在");
  50. var exeFile = Path.Combine(exePath, exeName);
  51. if (!File.Exists(exeFile))
  52. throw new Exception($"文件[{exeFile}]不存在");
  53. List<string> arguments = new List<string>
  54. {
  55. file,
  56. $"{opt.MsEph[0]}",
  57. $"{opt.MsEph[1]}",
  58. $"{opt.MsEph[2]}",
  59. $"{opt.MsAnt[0]}",
  60. $"{opt.MsAnt[1]}",
  61. $"{opt.CDBAnt[0]}",
  62. $"{opt.CDBAnt[1]}",
  63. $"{opt.RefGeod[0]}",
  64. $"{opt.RefGeod[1]}",
  65. $"{opt.xdDto}",
  66. $"{opt.RefDto}",
  67. $"{opt.PosLon}",
  68. $"{opt.PosLat}"
  69. };
  70. Process p = new Process();
  71. p.StartInfo.WorkingDirectory = exePath;
  72. p.StartInfo.FileName = exeFile;
  73. p.StartInfo.Arguments = string.Join(" ", arguments);
  74. p.StartInfo.CreateNoWindow = true;
  75. p.StartInfo.RedirectStandardError = true;
  76. p.StartInfo.RedirectStandardOutput = true;
  77. p.StartInfo.UseShellExecute = false;
  78. p.Start();
  79. var succeed = p.WaitForExit(10000);
  80. if (!succeed)
  81. {
  82. throw new Exception($"进程[{exeName}]超时未完成!");
  83. }
  84. string result = p.StandardOutput.ReadToEnd();
  85. if (string.IsNullOrWhiteSpace(result))
  86. {
  87. throw new Exception("计算时差线出现未知错误!");
  88. }
  89. var array = result.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
  90. if (array[0] == "1")
  91. {
  92. throw new Exception(array[1]);
  93. }
  94. if (File.Exists(file))
  95. {
  96. var dtostr = File.ReadAllText(file);
  97. list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<DtoLinePoint>>(dtostr);
  98. }
  99. var Lines = list.Select(s => (s.Lon, s.Lat));
  100. return Lines;
  101. }
  102. /// <summary>
  103. /// 星地无参时差线
  104. /// </summary>
  105. /// <param name="opt"></param>
  106. /// <returns></returns>
  107. /// <exception cref="Exception"></exception>
  108. public static IEnumerable<(double lon, double lat)> DtoLineXdNoRef(DtoLineXdOption opt)
  109. {
  110. List<DtoLinePoint> list = new List<DtoLinePoint>();
  111. IntPtr LOP_ValuePtr;
  112. int LOP_Len = 0;
  113. XingDi_SCX_NoRef(opt.MsEph, opt.MsAnt, opt.CDBAnt,
  114. new double[] { -85, 85, -180, 180 }, opt.xdDto * 1e-6, out LOP_ValuePtr, ref LOP_Len);
  115. double[] LOP_Value = new double[LOP_Len * 3];
  116. if (LOP_Len > 0)
  117. {
  118. Marshal.Copy(LOP_ValuePtr, LOP_Value, 0, LOP_Value.Length);
  119. list = OutputHelper.WriteDtoLine(LOP_Value, LOP_Len);
  120. }
  121. var Lines = list.Select(p => (p.Lon, p.Lat));
  122. return Lines;
  123. }
  124. /// <summary>
  125. /// 星地有参时差线
  126. /// </summary>
  127. /// <param name="opt"></param>
  128. /// <returns></returns>
  129. /// <exception cref="Exception"></exception>
  130. public static IEnumerable<(double lon, double lat)> DtoLineXdEx(DtoLineXdOption opt)
  131. {
  132. List<DtoLinePoint> list = new List<DtoLinePoint>();
  133. IntPtr LOP_ValuePtr;
  134. int LOP_Len = 0;
  135. GDOPApi.SCX_XD(opt.MsEph, opt.MsAnt, opt.MsAnt, opt.CDBAnt, opt.RefGeod, opt.xdDto * 1e-6, opt.RefDto * 1e-6, ref LOP_Len, out LOP_ValuePtr);
  136. double[] LOP_Value = new double[LOP_Len];
  137. if (LOP_Len > 0)
  138. {
  139. Marshal.Copy(LOP_ValuePtr, LOP_Value, 0, LOP_Value.Length);
  140. }
  141. GDOPApi.FreeGDOPBuf(LOP_ValuePtr);
  142. var points = ParseResult(LOP_Value);
  143. var mapDots = points.Select(p => p).Select(p => (p.Lon, p.Lat));
  144. return mapDots;
  145. }
  146. private static List<MapDot> ParseResult(double[] ponits)
  147. {
  148. List<MapDot> mapDots = new List<MapDot>();
  149. int count = 2;
  150. for (int i = 0; i < ponits.Length / count; i++)
  151. {
  152. MapDot mapDot = new MapDot();
  153. mapDot.Lon = ponits[count * i];
  154. mapDot.Lat = ponits[count * i + 1];//0 1 2 3 4 5 6 7
  155. mapDots.Add(mapDot);
  156. }
  157. return mapDots;
  158. }
  159. /// <summary>
  160. /// 星地无参时差线
  161. /// </summary>
  162. /// <param name="opt"></param>
  163. /// <returns></returns>
  164. /// <exception cref="Exception"></exception>
  165. public static IEnumerable<(double lon, double lat)> DtoLineXdNoRefEx(DtoLineXdOption opt)
  166. {
  167. List<DtoLinePoint> list = new List<DtoLinePoint>();
  168. IntPtr LOP_ValuePtr;
  169. int LOP_Len = 0;
  170. GDOPApi.SCX_XD_NoRef(opt.MsEph, opt.MsAnt, opt.CDBAnt, opt.xdDto * 1e-6, ref LOP_Len, out LOP_ValuePtr);
  171. double[] LOP_Value = new double[LOP_Len];
  172. if (LOP_Len > 0)
  173. {
  174. Marshal.Copy(LOP_ValuePtr, LOP_Value, 0, LOP_Value.Length);
  175. }
  176. GDOPApi.FreeGDOPBuf(LOP_ValuePtr);
  177. var points = ParseResult(LOP_Value);
  178. var mapDots = points.Select(p => p).Select(p => (p.Lon, p.Lat));
  179. return mapDots;
  180. }
  181. public static IEnumerable<(double lon, double lat)> DtoLineXdNoRefZl(DtoLineXdOption opt)
  182. {
  183. double startLon = (int)opt.CDBAnt[0] - 30;
  184. double endLon = (int)opt.CDBAnt[0] + 30;
  185. double startLat = (int)opt.CDBAnt[1] - 30;
  186. double endLat = (int)opt.CDBAnt[1] + 30;
  187. List<(double, double, double)> list2 = new List<(double, double, double)>();
  188. var recXYZ = PhysicsHelper.GeoToEcef((opt.MsAnt[0], opt.MsAnt[1], opt.MsAnt[2]));
  189. var cdbXYZ = PhysicsHelper.GeoToEcef((opt.CDBAnt[0], opt.CDBAnt[1], opt.CDBAnt[2]));
  190. for (double lon = startLon; lon < endLon; lon += 0.01)
  191. {
  192. List<(double, double, double)> list = new List<(double, double, double)>();
  193. int flag = 0;
  194. for (double lat = startLat; lat < endLat; lat += 0.01)
  195. {
  196. var posXYZ = PhysicsHelper.GeoToEcef((lon, lat, 0));
  197. //目标-主星-接收站的时间(us)
  198. var dt1 = PhysicsHelper.Dto(posXYZ, (opt.MsEph[0], opt.MsEph[1], opt.MsEph[2]), recXYZ) * 1e6;
  199. //目标-超短站的时间(us)
  200. var dt2 = PhysicsHelper.Dto(posXYZ, cdbXYZ) * 1e6;
  201. var dto = Math.Abs(dt1 - dt2 - opt.xdDto);
  202. if (dto > 100)
  203. {
  204. lat += 1;
  205. if (flag < 1)
  206. flag = 1;
  207. continue;
  208. }
  209. else if (dto > 50)
  210. {
  211. lat += 0.5;
  212. if (flag < 2)
  213. flag = 2;
  214. continue;
  215. }
  216. else if (dto > 20)
  217. {
  218. lat += 0.2;
  219. if (flag < 3)
  220. flag = 3;
  221. continue;
  222. }
  223. else if (dto > 5)
  224. {
  225. lat += 0.1;
  226. if (flag < 4)
  227. flag = 4;
  228. continue;
  229. }
  230. else if (dto > 2)
  231. {
  232. lat += 0.05;
  233. if (flag < 5)
  234. flag = 5;
  235. continue;
  236. }
  237. flag = 10;
  238. list.Add((lon, lat, dto));
  239. }
  240. if (list.Any())
  241. {
  242. var p1 = list.OrderBy(p => p.Item3).FirstOrDefault();
  243. list2.Add(p1);
  244. var p2 = list.Where(p => p.Item3 < 0.01 && PhysicsHelper.DistanceGeo((p.Item1, p.Item2, 0), p1) > 5000).OrderBy(p => p.Item3).FirstOrDefault();
  245. if (p2 != default)
  246. list2.Add(p2);
  247. }
  248. else
  249. {
  250. if (flag == 1)
  251. lon += 1;
  252. else if (flag == 2)
  253. lon += 0.5;
  254. else if (flag == 3)
  255. lon += 0.2;
  256. else if (flag == 4)
  257. lon += 0.1;
  258. else if (flag == 5)
  259. lon += 0.05;
  260. }
  261. list.Clear();
  262. }
  263. return list2.Select(p => (p.Item1, p.Item2)).OrderBy(p => p.Item1).OrderBy(p => p.Item2);
  264. }
  265. /// <summary>
  266. /// 高轨双星时差线
  267. /// </summary>
  268. /// <param name="opt"></param>
  269. /// <returns></returns>
  270. public static IEnumerable<(double lon, double lat)> DtoLine2XStart(DtoLineTwoStartOption opt)
  271. {
  272. List<DtoLinePoint> list = new List<DtoLinePoint>();
  273. IntPtr LOP_ValuePtr;
  274. int LOP_Len = 0;
  275. CurveByTwoTDOA(
  276. opt.MsEph,
  277. opt.NsEph,
  278. opt.MsAnt,
  279. opt.NsAnt,
  280. opt.RefGeod,
  281. new double[] { -85, 85, -180, 180 },
  282. opt.TargetDto * 1e-6,
  283. opt.RefDto * 1e-6, out LOP_ValuePtr, ref LOP_Len);
  284. double[] LOP_Value = new double[LOP_Len * 3];
  285. if (LOP_Len > 0)
  286. {
  287. Marshal.Copy(LOP_ValuePtr, LOP_Value, 0, LOP_Value.Length);
  288. list = OutputHelper.WriteDtoLine(LOP_Value, LOP_Len);
  289. }
  290. Destory(LOP_ValuePtr);
  291. var Lines = list.Select(p => (p.Lon, p.Lat));
  292. return Lines;
  293. }
  294. public static IEnumerable<(double lon, double lat)> DtoLine2XNoRefStart(DtoLineTwoStartOption opt)
  295. {
  296. List<DtoLinePoint> list = new List<DtoLinePoint>();
  297. IntPtr LOP_ValuePtr;
  298. int LOP_Len = 0;
  299. CurveByTwoTDOAWithNoRef(
  300. opt.MsEph,
  301. opt.NsEph,
  302. opt.MsAnt,
  303. opt.NsAnt,
  304. new double[] { -85, 85, -180, 180 },
  305. opt.TargetDto * 1e-6, out LOP_ValuePtr, ref LOP_Len);
  306. double[] LOP_Value = new double[LOP_Len * 3];
  307. if (LOP_Len > 0)
  308. {
  309. Marshal.Copy(LOP_ValuePtr, LOP_Value, 0, LOP_Value.Length);
  310. list = OutputHelper.WriteDtoLine(LOP_Value, LOP_Len);
  311. }
  312. Destory(LOP_ValuePtr);
  313. var Lines = list.Select(p => (p.Lon, p.Lat));
  314. return Lines;
  315. }
  316. public static IEnumerable<(double lon, double lat)> DtoLine2XNoRefStartZl(DtoLineTwoStartOption opt)
  317. {
  318. double startLon = -180;
  319. double endLon = 180;
  320. double startLat = -80;
  321. double endLat = 80;
  322. List<(double, double, double)> list2 = new List<(double, double, double)>();
  323. var recXYZ = PhysicsHelper.GeoToEcef((opt.MsAnt[0], opt.MsAnt[1], opt.MsAnt[2]));
  324. for (double lon = startLon; lon < endLon; lon += 0.01)
  325. {
  326. List<(double, double, double)> list = new List<(double, double, double)>();
  327. int flag = 0;
  328. for (double lat = startLat; lat < endLat; lat += 0.01)
  329. {
  330. var posXYZ = PhysicsHelper.GeoToEcef((lon, lat, 0));
  331. //目标-主星-接收站的时间(us)
  332. var dt1 = PhysicsHelper.Dto(posXYZ, (opt.MsEph[0], opt.MsEph[1], opt.MsEph[2]), recXYZ) * 1e6;
  333. //目标-邻星-接收站的时间(us)
  334. var dt2 = PhysicsHelper.Dto(posXYZ, (opt.NsEph[0], opt.NsEph[1], opt.NsEph[2]), recXYZ) * 1e6;
  335. var dto = Math.Abs(dt1 - dt2 - opt.TargetDto);
  336. if (dto > 100)
  337. {
  338. lat += 1;
  339. if (flag < 1)
  340. flag = 1;
  341. continue;
  342. }
  343. else if (dto > 50)
  344. {
  345. lat += 0.5;
  346. if (flag < 2)
  347. flag = 2;
  348. continue;
  349. }
  350. else if (dto > 20)
  351. {
  352. lat += 0.2;
  353. if (flag < 3)
  354. flag = 3;
  355. continue;
  356. }
  357. else if (dto > 5)
  358. {
  359. lat += 0.1;
  360. if (flag < 4)
  361. flag = 4;
  362. continue;
  363. }
  364. else if (dto > 2)
  365. {
  366. lat += 0.05;
  367. if (flag < 5)
  368. flag = 5;
  369. continue;
  370. }
  371. flag = 10;
  372. list.Add((lon, lat, dto));
  373. }
  374. if (list.Any())
  375. {
  376. var p1 = list.OrderBy(p => p.Item3).FirstOrDefault();
  377. list2.Add(p1);
  378. //var p2 = list.Where(p => p.Item3 < 0.01 && PhysicsHelper.DistanceGeo((p.Item1, p.Item2, 0), p1) > 5000).OrderBy(p => p.Item3).FirstOrDefault();
  379. //if (p2 != default)
  380. // list2.Add(p2);
  381. }
  382. else
  383. {
  384. if (flag == 1)
  385. lon += 1;
  386. else if (flag == 2)
  387. lon += 0.5;
  388. else if (flag == 3)
  389. lon += 0.2;
  390. else if (flag == 4)
  391. lon += 0.1;
  392. else if (flag == 5)
  393. lon += 0.05;
  394. }
  395. list.Clear();
  396. }
  397. return list2.Select(p => (p.Item1, p.Item2)).OrderBy(p=>PhysicsHelper.DistanceGeo((1,1,0),(1,1,9)));
  398. }
  399. }
  400. }