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.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XdCxRhDW.App.DTO;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;
namespace XzXdDw.App.Api.低轨GDOP误差椭圆
{
///
/// 误差椭圆计算帮助类.该类调用了GdopCore.exe进程
/// 每种误差椭圆算法提供了两个接口,这两种接口是完全等价的,一种传入双行根,一种直接传入卫星状态x、y、z等
///
public static class ErrEllipseHelper
{
private static string exePath = "Api\\低轨GDOP误差椭圆\\GDOP";
private const string exeName = "GdopCore.exe";
///
/// 三星双时差误差椭圆带参
///
/// 主星双行根数
/// 邻1星双行根数
/// 邻2星双行根数
/// 采集时刻
/// 定位点经纬度,数组长度=2
/// 参考站经纬度,数组长度=2
/// 输出参数:椭圆长轴(km)
/// 输出参数:椭圆短轴(km)
/// 时差误差(单位us)
/// 星历位置误差(单位米)
/// 误差概率百分比(0-100,默认50)
///
public static (List, List) ErrEllipse3Sat2DtoRef(string mainSatTle, string adja1SatTle, string adja2SatTle, DateTime time, double[] posLonLat, double[] refLonLat, out double R1, out double R2, double dtousErr = 1, double satLocErr = 10000, double errProb = 50)
{
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 = $"50 \"{mainSatTle}\" \"{adja1SatTle}\" \"{adja2SatTle}\" \"{time:yyyy-MM-dd HH:mm:ss.000000}\" {string.Join(" ", posLonLat)} {string.Join(" ", refLonLat)} {dtousErr} {satLocErr} {errProb}";
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(3, sb.ToString(), out R1, out R2);
}
///
/// 三星双时差误差椭圆带参
///
/// 主星xyz星历,数组长度=3
/// 邻1星xyz星历,数组长度=3
/// 邻2星xyz星历,数组长度=3
/// 定位点经纬度,数组长度=2
/// 参考站经纬度,数组长度=2
/// 输出参数:椭圆长轴(km)
/// 输出参数:椭圆短轴(km)
/// 时差误差(单位us)
/// 星历位置误差(单位米)
/// 误差概率百分比(0-100,默认50)
///
public static (List, List) ErrEllipse3Sat2DtoRef(double[] mainSatEph, double[] adja1SatEph, double[] adja2SatEph, double[] posLonLat, double[] refLonLat, out double R1, out double R2, double dtousErr = 1, double satLocErr = 10000, double errProb = 50)
{
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 = $"51 {string.Join(" ", mainSatEph)} {string.Join(" ", adja1SatEph)} {string.Join(" ", adja2SatEph)} {string.Join(" ", posLonLat)} {string.Join(" ", refLonLat)} {dtousErr} {satLocErr} {errProb}";
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(3, sb.ToString(), out R1, out R2);
}
///
/// 三星双时差误差椭圆无参
///
/// 主星双行根数
/// 邻1星双行根数
/// 邻2星双行根数
/// 采集时刻
/// 定位点经纬度,数组长度=2
/// 接收站经纬度,数组长度=2
/// 输出参数:椭圆长轴(km)
/// 输出参数:椭圆短轴(km)
/// 时差误差(单位us)
/// 星历位置误差(单位米)
/// 误差概率百分比(0-100,默认50)
///
public static (List, List) ErrEllipse3Sat2Dto(string mainSatTle, string adja1SatTle, string adja2SatTle, DateTime time, double[] posLonLat, double[] recLonLat, out double R1, out double R2, double dtousErr = 1, double satLocErr = 10000, double errProb = 50)
{
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 = $"52 \"{mainSatTle}\" \"{adja1SatTle}\" \"{adja2SatTle}\" \"{time:yyyy-MM-dd HH:mm:ss.000000}\" {string.Join(" ", posLonLat)} {string.Join(" ", recLonLat)} {dtousErr} {satLocErr} {errProb}";
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(3, sb.ToString(), out R1, out R2);
}
///
/// 三星双时差误差椭圆无参
///
/// 主星xyz星历,数组长度=3
/// 邻1星xyz星历,数组长度=3
/// 邻2星xyz星历,数组长度=3
/// 定位点经纬度,数组长度=2
/// 接收站经纬度,数组长度=2
/// 输出参数:椭圆长轴(km)
/// 输出参数:椭圆短轴(km)
/// 时差误差(单位us)
/// 星历位置误差(单位米)
/// 误差概率百分比(0-100,默认50)
///
public static (List, List) ErrEllipse3Sat2Dto(double[] mainSatEph, double[] adja1SatEph, double[] adja2SatEph, double[] posLonLat, double[] recLonLat, out double R1, out double R2, double dtousErr = 1, double satLocErr = 10000, double errProb = 50)
{
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 = $"51 {string.Join(" ", mainSatEph)} {string.Join(" ", adja1SatEph)} {string.Join(" ", adja2SatEph)} {string.Join(" ", posLonLat)} {string.Join(" ", recLonLat)} {dtousErr} {satLocErr} {errProb}";
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(3, sb.ToString(), out R1, out R2);
}
///
/// 双星时频差误差椭圆带参
///
/// 主星双行根数
/// 邻星双行根数
/// 采集时刻
/// 目标上行频点MHz
/// 参考上行频点MHz
/// 主星转发器本振MHz
/// 邻星转发器本振MHz
/// 定位点经纬度,数组长度=2
/// 参考站经纬度,数组长度=2
/// 输出参数:椭圆长轴(km)
/// 输出参数:椭圆短轴(km)
///
public static (List, List) ErrEllipse2SatDtoDfoRef(string mainTle, string adjaTle, DateTime time, double tarFreqUpMHz, double refFreqUpMHz, double mainSatTransMHz, double adjaSatTransMHz, double[] posLonLat, double[] refLonLat, out double R1, out double R2)
{
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 = $"54 \"{mainTle}\" \"{adjaTle}\" \"{time:yyyy-MM-dd HH:mm:ss.000000}\" {tarFreqUpMHz} {refFreqUpMHz} {mainSatTransMHz} {adjaSatTransMHz} {string.Join(" ", posLonLat)} {string.Join(" ", refLonLat)} ";
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(), out R1, out R2);
}
///
/// 双星时频差误差椭圆带参
///
/// 主星星历xyz vx vy vz,数组长度=6
/// 邻星星历xyz vx vy vz,数组长度=6
/// 目标上行频点MHz
/// 参考上行频点MHz
/// 主星转发器本振MHz
/// 邻星转发器本振MHz
/// 定位点经纬度,数组长度=2
/// 参考站经纬度,数组长度=2
/// 输出参数:椭圆长轴(km)
/// 输出参数:椭圆短轴(km)
///
public static (List, List) ErrEllipse2SatDtoDfoRef(double[] mainSatEph, double[] adjaSatEph, double tarFreqUpMHz, double refFreqUpMHz, double mainSatTransMHz, double adjaSatTransMHz, double[] posLonLat, double[] refLonLat, out double R1, out double R2)
{
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 = $"55 {string.Join(" ", mainSatEph)} {string.Join(" ", adjaSatEph)} {tarFreqUpMHz} {refFreqUpMHz} {mainSatTransMHz} {adjaSatTransMHz} {string.Join(" ", posLonLat)} {string.Join(" ", refLonLat)}";
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(), out R1, out R2);
}
///
/// 双星时频差误差椭圆无参
///
/// 主星双行根数
/// 邻星双行根数
/// 采集时刻
/// 目标上行频点MHz
/// 主星转发器本振MHz
/// 邻星转发器本振MHz
/// 定位点经纬度,数组长度=2
/// 接收站经纬度,数组长度=2
/// 输出参数:椭圆长轴(km)
/// 输出参数:椭圆短轴(km)
///
public static (List, List) ErrEllipse2SatDtoDfo(string mainTle, string adjaTle, DateTime time, double tarFreqUpMHz, double mainSatTransMHz, double adjaSatTransMHz, double[] posLonLat, double[] recLonLat, out double R1, out double R2)
{
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 = $"56 \"{mainTle}\" \"{adjaTle}\" \"{time:yyyy-MM-dd HH:mm:ss.000000}\" {tarFreqUpMHz} {mainSatTransMHz} {adjaSatTransMHz} {string.Join(" ", posLonLat)} {string.Join(" ", recLonLat)}";
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(), out R1, out R2);
}
///
/// 双星时频差误差椭圆无参
///
/// 主星星历xyz vx vy vz,数组长度=6
/// 邻星星历xyz vx vy vz,数组长度=6
/// 目标上行频点MHz
/// 主星转发器本振MHz
/// 邻星转发器本振MHz
/// 定位点经纬度,数组长度=2
/// 接收站经纬度,数组长度=2
/// 输出参数:椭圆长轴(km)
/// 输出参数:椭圆短轴(km)
///
public static (List, List) ErrEllipse2SatDtoDfo(double[] mainSatEph, double[] adjaSatEph, double tarFreqUpMHz, double mainSatTransMHz, double adjaSatTransMHz, double[] posLonLat, double[] recLonLat, out double R1, out double R2)
{
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 = $"57 {string.Join(" ", mainSatEph)} {string.Join(" ", adjaSatEph)} {tarFreqUpMHz} {mainSatTransMHz} {adjaSatTransMHz} {string.Join(" ", posLonLat)} {string.Join(" ", recLonLat)}";
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(), out R1, out R2);
}
private static (List, List) ParseResult(int satCount, string txt, out double errR1, out double errR2)
{
if (string.IsNullOrWhiteSpace(txt))
{
throw new Exception("误差椭圆计算出现未知错误!");
}
if (txt.StartsWith("1 "))
{
throw new Exception(txt.Remove(0, 2));
}
var arr = txt.Split(' ');
List list = new List();
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);
}
errR1 = Convert.ToDouble(arr[1 + satCount * 3]);//椭圆长轴
errR2 = Convert.ToDouble(arr[2 + satCount * 3]);//椭圆短轴
var jsonStr = arr[3 + satCount * 3];
var res = JsonConvert.DeserializeObject>(jsonStr);
return (list, res);
}
}
}