123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- using DevExpress.Charts.Native;
- using DevExpress.Internal.WinApi.Windows.UI.Notifications;
- using DevExpress.XtraPrinting;
- using Newtonsoft.Json;
- using System;
- using System.Collections.Generic;
- using System.Data.Entity.Core.Common.EntitySql;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading.Tasks;
- using XdCxRhDW.App.DTO;
- using static DevExpress.XtraCharts.GLGraphics.Platform.EGL;
- using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;
- namespace XzXdDw.App.Api.星地GDOP误差椭圆
- {
- /// <summary>
- /// Gdop误差分布计算帮助类.该类调用了GdopCore.exe进程
- /// 每种GDOP算法提供了两个接口,这两种接口是完全等价的,一种传入双行根,一种直接传入卫星状态x、y、z等
- /// </summary>
- public static class GdopHelper
- {
- private static string exePath = "Api\\星地GDOP误差椭圆\\GDOP";
- private const string exeName = "GdopCore.exe";
- private const string GDOPDll = @"Api\星地GDOP误差椭圆\GDOP\GDOP_Draw.dll";
- static readonly DateTime dtZero = new DateTime(1970, 1, 1, 8, 0, 0, 0);
- /// <returns></returns>
- [DllImport(GDOPDll, CallingConvention = CallingConvention.Cdecl)]
- public static extern int GdopLeoTowSatDRef(string mainLines, string adajLines, Int64 captime, double[] refPos
- , double fuHz1, double fuHz2, double dtousErr, double dfoHzErr, double ephLocErr, double ephVLocErr
- , double[] level, int levlen, int[] resCount, out IntPtr res, double[] satllh);
- [DllImport(GDOPDll, CallingConvention = CallingConvention.Cdecl)]
- public static extern void FreeGDOPBuf(IntPtr val);
- /// <summary>
- /// 低轨双星GDOP
- /// </summary>
- /// <param name="mainLines">主星星历</param>
- /// <param name="adajLines">邻星星历</param>
- /// <param name="captime">采集时间</param>
- /// <param name="refPos">参考站位置 长度3</param>
- /// <param name="fuHz1">目标上行频点 Hz</param>
- /// <param name="fuHz2">参考上行频点 Hz</param>
- /// <param name="dtousErr">时差误差</param>
- /// <param name="dfoHzErr">频差误差</param>
- /// <param name="ephLocErr">星历位置误差</param>
- /// <param name="ephVLocErr">星历速度误差</param>
- /// <param name="level"></param>
- /// <param name="satllh"></param>
- /// <param name="points"></param>
- public static (List<SatInfo>, List<ErrDistanceMapPoints>) GdopLeoTowSatDRef(string mainLines, string adajLines, DateTime captime, double[] refPos
- , double fuHz1, double fuHz2, double dtousErr, double dfoHzErr, double ephLocErr, double ephVLocErr)
- {
- int satCount = 2;
- //该值和points 一一对应
- double[] level = GdopParam.误差配置.小误差距离m;
- double[] satllh = new double[satCount*3];
- var timeSpan = (long)(captime - dtZero).TotalSeconds;
- IntPtr res = IntPtr.Zero;
- int[] resCount = new int[level.Length];
- GdopLeoTowSatDRef(mainLines, adajLines, timeSpan, refPos
- , fuHz1, fuHz2, dtousErr, dfoHzErr, ephLocErr, ephVLocErr, level, level.Length, resCount, out res, satllh);
- IntPtr tmp = res;
- //用于绘制的数据
- List<double[]> points = new List<double[]>();
- for (int idx = 0; idx < level.Length; ++idx)
- {
- double[] levelval = new double[resCount[idx]];
- Marshal.Copy(tmp, levelval, 0, resCount[idx]);
- tmp += (resCount[idx] * sizeof(double));
- points.Add(levelval);
- }
- FreeGDOPBuf(res);
- List<SatInfo> satInfos = ParseResult(satCount, satllh, mainLines, adajLines);
- List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
- for (int i = 0; i < points.Count; i++)
- {
- ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
- errDistanceMap.ErrDistance = level[i];
- errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
- errs.Add(errDistanceMap);
- }
- return (satInfos, errs);
- }
- /// <summary>
- /// 低轨两星GDOP
- /// </summary>
- /// <param name="refLonLat">参考站位置 长度2</param>
- /// <param name="mainTle">主星星历双行根</param>
- /// <param name="adjaTle">邻星星历双行根</param>
- /// <param name="time">采集时刻</param>
- /// <param name="dtousErr">时差误差(us)</param>
- /// <param name="dfoHzErr">频差误差(Hz)</param>
- /// <param name="ephLocErr">星历位置误差(m)</param>
- /// <param name="ephVLocErr">星历速度误差(m/s)</param>
- /// <param name="fu1">主星上行频点</param>
- /// <param name="fu2">邻星上行频点</param>
- /// <returns></returns>
- /// <exception cref="Exception"></exception>
- 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)
- {
- if (string.IsNullOrWhiteSpace(exePath))
- throw new Exception($"请先调用SetExePath指定{exeName}进程所在路径,支持相对路径");
- if (!Directory.Exists(exePath))
- throw new Exception($"路径[{exePath}]不存在");
- var exeFile = Path.Combine(exePath, exeName);
- if (!File.Exists(exeFile))
- throw new Exception($"文件[{exeFile}]不存在");
- Process p = new Process();
- p.StartInfo.WorkingDirectory = exePath;
- p.StartInfo.FileName = exeFile;
- p.StartInfo.Arguments = $"73 \"{mainTle}\" \"{adjaTle}\" \"{time:yyyy-MM-dd HH:mm:ss.000000}\" {string.Join(" ", refLonLat)} {dtousErr} {dfoHzErr} {ephLocErr} {ephVLocErr} {fuHz1} {fuHz2}";
- p.StartInfo.CreateNoWindow = true;
- p.StartInfo.RedirectStandardError = true;
- p.StartInfo.RedirectStandardOutput = true;
- p.StartInfo.UseShellExecute = false;
- StringBuilder sb = new StringBuilder();
- p.OutputDataReceived += (sender, e) => sb.Append(e.Data);
- p.Start();
- p.BeginOutputReadLine();
- p.WaitForExit();//WaitForExit加了超时时间的话进程退出后不能保证异步流已经读取完成,这是.NET框架的BUG
- return ParseResult(2, sb.ToString());
- }
- /// <summary>
- /// 单星GDOP
- /// </summary>
- /// <param name="mainTle">第一刻时刻星历双行根</param>
- /// <param name="adjaTle1">第二刻时刻星历双行根</param>
- /// <param name="adjaTle2">第三刻时刻星历双行根></param>
- /// <param name="time">采集时刻</param>
- /// <param name="dfoHzErr">频差误差(Hz)</param>
- /// <param name="ephLocErr">星历位置误差(m</param>
- /// <param name="ephVLocErr">星历速度误差(m/s)</param>
- /// <param name="fuHz">卫星上行频点(Hz)</param>
- /// <returns></returns>
- /// <exception cref="Exception"></exception>
- public static (List<SatInfo>, List<ErrDistanceMapLines>) GdopSingleSatDRef(string mainTle, DateTime time1, DateTime time2, DateTime time3, double dfoHzErr, double ephLocErr, double ephVLocErr, double fuHz)
- {
- if (string.IsNullOrWhiteSpace(exePath))
- throw new Exception($"请先调用SetExePath指定{exeName}进程所在路径,支持相对路径");
- if (!Directory.Exists(exePath))
- throw new Exception($"路径[{exePath}]不存在");
- var exeFile = Path.Combine(exePath, exeName);
- if (!File.Exists(exeFile))
- throw new Exception($"文件[{exeFile}]不存在");
- Process p = new Process();
- p.StartInfo.WorkingDirectory = exePath;
- p.StartInfo.FileName = exeFile;
- 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}";
- p.StartInfo.CreateNoWindow = true;
- p.StartInfo.RedirectStandardError = true;
- p.StartInfo.RedirectStandardOutput = true;
- p.StartInfo.UseShellExecute = false;
- StringBuilder sb = new StringBuilder();
- p.OutputDataReceived += (sender, e) => sb.Append(e.Data);
- p.Start();
- p.BeginOutputReadLine();
- p.WaitForExit();//WaitForExit加了超时时间的话进程退出后不能保证异步流已经读取完成,这是.NET框架的BUG
- return ParseResult(1, sb.ToString());
- }
- private static List<MapDot> ParseResult(double[] ponits)
- {
- List<MapDot> mapDots = new List<MapDot>();
- int count = 2;
- for (int i = 0; i < ponits.Length / count; i++)
- {
- MapDot mapDot = new MapDot();
- mapDot.Lat = ponits[count * i + 1];
- mapDot.Lon = ponits[count * i];
- mapDots.Add(mapDot);
-
- }
- return mapDots;
- }
- private static List<SatInfo> ParseResult(int satCount, double[] satllh, params string[] ephLine)
- {
- List<SatInfo> list = new List<SatInfo>();
- int len = 3;
- for (int i = 0; i < satCount; i++)
- {
- SatInfo satInfo = new SatInfo();
- var ephstrs = ephLine[i].Split(new string[] { " ", "U" }, StringSplitOptions.RemoveEmptyEntries);
- if (ephstrs.Length == 16)
- {
- satInfo.SatCode = Convert.ToInt32(ephstrs[1]);
- }
- satInfo.SatLon = Convert.ToDouble(satllh[len * i]);
- satInfo.SatLat = Convert.ToDouble(satllh[len * i + 1]);
- list.Add(satInfo);
- }
- return list;
- }
- private static (List<SatInfo>, List<ErrDistanceMapLines>) ParseResult(int satCount, string txt)
- {
- if (string.IsNullOrWhiteSpace(txt))
- {
- throw new Exception("GDOP计算出现未知错误!");
- }
- if (txt.StartsWith("1 "))
- {
- throw new Exception(txt.Remove(0, 2));
- }
- var arr = txt.Split(' ');
- List<SatInfo> list = new List<SatInfo>();
- for (int i = 0; i < satCount; i++)
- {
- SatInfo satInfo = new SatInfo();
- var satCode = Convert.ToInt32(arr[3 * i + 1]);
- if (satCode > 0)
- satInfo.SatCode = satCode;
- satInfo.SatLon = Convert.ToDouble(arr[3 * i + 2]);
- satInfo.SatLat = Convert.ToDouble(arr[3 * i + 3]);
- list.Add(satInfo);
- }
- var jsonStr = arr[1 + satCount * 3];
- var res = JsonConvert.DeserializeObject<List<ErrDistanceMapLines>>(jsonStr);
- return (list, res);
- }
- }
- }
|