PosApi.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using XdCxRhDW.Entity;
  8. using XdCxRhDW.Framework;
  9. namespace XdCxRhDW.Api
  10. {
  11. /// <summary>
  12. ///TODO 定位算法接口.在这里调用罗博士的算法库
  13. /// </summary>
  14. public static class PosApi
  15. {
  16. //置信度统计次数
  17. private static int confidenceCount = 100;
  18. //置信度有效距离(m)
  19. private static int confidenceDistance = 10000;
  20. #region cpp dll Interop
  21. //一星一地测向带参定位
  22. private const string XDCX = @"AddIns\定位\DLL_DTO_DOA_DW.dll";
  23. //三星双时差带参、三星双时差无参、三星双频差带参、双星时频差带参、两星一地无参定位及时差线、一星两地
  24. private const string OtherPos = @"AddIns\定位\Position-New.dll";//DLL_11J_DW
  25. [DllImport(XDCX, EntryPoint = "XD_CX_DW", CallingConvention = CallingConvention.Cdecl)]//一星一地测向带参
  26. private extern static void X1D1_Pos20240305_Core(double[] mainSat, double[] satStation, double[] cdbStation, double[] cxStation, double[] refStation, double[] zone, double theta, double tarDto, double refDto, double[] res);
  27. [DllImport(OtherPos, EntryPoint = "SC_2X1D_DW", CallingConvention = CallingConvention.Cdecl)]//两星一地带参
  28. private extern static void X2D1_Pos20240305_Core(double[] mainSat, double[] adjaSat, double[] cdbStation, double[] satStation1, double[] satStation2, double[] satStation3, double[] satStation4,
  29. double[] satStation5, double[] refStation, double[] zone, double tarSxDto, double tarXdDto, double samp_main_dto, double samp_neigh_dto, double[] res);
  30. [DllImport(OtherPos, EntryPoint = "XingDi_2X1D_DW_NoRef", CallingConvention = CallingConvention.Cdecl)]//两星一地无参
  31. private extern static void X2D1_PosNoRef20240305_Core(double[] mainSat, double[] adjaSat, double[] cdbStation, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  32. , double[] zone, double tarSxDto, double tarXdDto, double[] res);
  33. [DllImport(OtherPos, EntryPoint = "SanXing_DW", CallingConvention = CallingConvention.Cdecl)]//三星双时差带参
  34. private extern static void X3_Pos20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  35. , double[] mainSatRefStation, double[] adjaSat1RefStation, double[] adjaSat2RefStation, double[] refStation, double[] zone, double tarDto1, double tarDto2, double refDto1, double refDto2, double[] res);
  36. [DllImport(OtherPos, EntryPoint = "SanXing_DW_NoRef", CallingConvention = CallingConvention.Cdecl)]//三星双时差无参
  37. private extern static void X3_PosNoRef20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  38. , double[] zone, double tarDto1, double tarDto2, double[] res);
  39. [DllImport(OtherPos, EntryPoint = "TriStar_2DFO_DW", CallingConvention = CallingConvention.Cdecl)]//三星双频差带参
  40. private extern static void X3_PosTwoDfo20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  41. , double[] refStation, double[] zone, double tarDfo1, double tarDfo2, double refDfo1, double refDfo2, double fu1, double fd1, double fu2, double fd2, double[] res);
  42. [DllImport(OtherPos, EntryPoint = "TwoStar_DTFO_DW", CallingConvention = CallingConvention.Cdecl)]//双星时频差带参
  43. private extern static void X2_Pos20240305_Core(double[] mainSat, double[] adjaSat, double[] mainSatTarStation, double[] adjaSatTarStation, double[] refStation, double[] zone
  44. , double tarDto, double tarDfo, double refDto, double refDfo, double fu1, double fd1, double fu2, double fd2, double[] res);
  45. #endregion
  46. /// <summary>
  47. /// 一星一地带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  48. /// </summary>
  49. /// <param name="cgRes">参估结果</param>
  50. /// <param name="sRes">站点信息</param>
  51. /// <param name="cxRes">测向结果</param>
  52. /// <param name="CalcConfidence">是否计算置信度</param>
  53. /// <returns></returns>
  54. public static double[] X1D1_Pos(CgRes cgRes, StationRes sRes, CxRes cxRes, bool CalcConfidence = false)
  55. {
  56. if (cgRes.DtoCdb.Value == 0) return new double[7] { 999, 999, 0, 999, 999, 0, 100 };
  57. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  58. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  59. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  60. double[] cxStation = new double[3] { sRes.CxLon.Value, sRes.CxLat.Value, 0 };
  61. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  62. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  63. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  64. double theta = cxRes.Fx;//单位°
  65. double[] res = new double[6];
  66. var ybDto1 = cgRes.YbMainDto.Value / 1e6;
  67. X1D1_Pos20240305_Core(mainSat, satStation, cdbStation, cxStation, refStation, zone, theta, dtoCdb, ybDto1, res);
  68. var posRes = ConvertToGeoPoint(res);
  69. if (CalcConfidence && IsGeoPoint2(posRes))
  70. {
  71. int succeedCount = 0;
  72. for (int i = 0; i < confidenceCount; i++)
  73. {
  74. var mainSatNew = new double[3]
  75. {
  76. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  77. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  78. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  79. };
  80. var dtoCdbNew = (dtoCdb * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  81. var ybDtoNew = (ybDto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  82. var thetaNew = theta + RandomHelper.Normal(0, 0.4);//单位°
  83. X1D1_Pos20240305_Core(mainSatNew, satStation, cdbStation, cxStation, refStation, zone, thetaNew, dtoCdbNew, ybDtoNew, res);
  84. var posResNew = ConvertToGeoPoint(res);
  85. if (IsGeoPoint2(posResNew))
  86. {
  87. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  88. if (distance <= confidenceDistance)
  89. {
  90. succeedCount++;
  91. }
  92. }
  93. }
  94. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  95. }
  96. return posRes;
  97. }
  98. /// <summary>
  99. /// 两星一地带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  100. /// </summary>
  101. /// <param name="cgRes">参估结果</param>
  102. /// <param name="sRes">站点信息</param>
  103. /// <param name="CalcConfidence">是否计算置信度</param>
  104. /// <returns></returns>
  105. public static double[] X2D1_Pos(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  106. {
  107. if (cgRes.Dto1.Value == 0 || cgRes.DtoCdb.Value == 0)
  108. {
  109. return new double[7] { 999, 999, 0, 999, 999, 0, 100 };
  110. }
  111. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  112. double[] adjaSat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  113. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  114. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  115. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  116. double dto1 = cgRes.Dto1.Value / 1e6;
  117. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  118. double ybDto1 = cgRes.YbMainDto.Value / 1e6;
  119. double ybDto2 = cgRes.YbAdja1Dto.Value / 1e6;
  120. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  121. double[] res = new double[6];
  122. X2D1_Pos20240305_Core(mainSat, adjaSat, cdbStation, satStation, satStation, satStation, satStation, satStation, refStation, zone, dto1, dtoCdb, ybDto1, ybDto2, res);
  123. ConvertToGeoPoint(res);
  124. var posRes = ConvertToGeoPoint(res);
  125. if (CalcConfidence && IsGeoPoint2(posRes))
  126. {
  127. int succeedCount = 0;
  128. for (int i = 0; i < confidenceCount; i++)
  129. {
  130. var mainSatNew = new double[3]
  131. {
  132. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  133. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  134. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  135. };
  136. var adjaSatNew = new double[3]
  137. {
  138. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  139. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  140. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  141. };
  142. var dto1New = (dto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  143. var dtoCdbNew = (dtoCdb * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  144. var ybDto1New = (ybDto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  145. var ybDto2New = (ybDto2 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  146. X2D1_Pos20240305_Core(mainSatNew, adjaSatNew, cdbStation, satStation, satStation, satStation, satStation, satStation, refStation, zone, dto1New, dtoCdbNew, ybDto1New, ybDto2New, res);
  147. var posResNew = ConvertToGeoPoint(res);
  148. if (IsGeoPoint2(posResNew))
  149. {
  150. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  151. if (distance <= confidenceDistance)
  152. {
  153. succeedCount++;
  154. }
  155. }
  156. }
  157. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  158. }
  159. return posRes;
  160. }
  161. /// <summary>
  162. /// 两星一地无参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  163. /// </summary>
  164. /// <param name="cgRes">参估结果</param>
  165. /// <param name="sRes">站点信息</param>
  166. /// <param name="CalcConfidence">是否计算置信度</param>
  167. /// <returns></returns>
  168. public static double[] X2D1_PosNoRef(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  169. {
  170. if (cgRes.Dto1.Value == 0 || cgRes.DtoCdb.Value == 0)
  171. {
  172. return new double[7] { 999, 999, 0, 999, 999, 0, 100 };
  173. }
  174. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  175. double[] adjaSat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  176. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  177. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  178. double dto1 = cgRes.Dto1.Value / 1e6;
  179. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  180. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  181. double[] res = new double[6];
  182. X2D1_PosNoRef20240305_Core(mainSat, adjaSat, cdbStation, satStation, satStation, satStation, zone, dto1, dtoCdb, res);
  183. ConvertToGeoPoint(res);
  184. var posRes = ConvertToGeoPoint(res);
  185. if (CalcConfidence && IsGeoPoint2(posRes))
  186. {
  187. int succeedCount = 0;
  188. for (int i = 0; i < confidenceCount; i++)
  189. {
  190. var mainSatNew = new double[3]
  191. {
  192. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  193. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  194. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  195. };
  196. var adjaSatNew = new double[3]
  197. {
  198. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  199. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  200. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  201. };
  202. var dto1New = (dto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  203. var dtoCdbNew = (dtoCdb * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  204. X2D1_PosNoRef20240305_Core(mainSatNew, adjaSatNew, cdbStation, satStation, satStation, satStation, zone, dto1New, dtoCdbNew, res);
  205. var posResNew = ConvertToGeoPoint(res);
  206. if (IsGeoPoint2(posResNew))
  207. {
  208. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  209. if (distance <= confidenceDistance)
  210. {
  211. succeedCount++;
  212. }
  213. }
  214. }
  215. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  216. }
  217. return posRes;
  218. }
  219. /// <summary>
  220. /// 融合定位带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  221. /// </summary>
  222. /// <param name="cgRes">参估结果</param>
  223. /// <param name="sRes">站点信息</param>
  224. /// <param name="cxRes">测向结果</param>
  225. /// <param name="CalcConfidence">是否计算置信度</param>
  226. /// <returns></returns>
  227. public static double[] RH_Pos(CgRes cgRes, StationRes sRes, CxRes cxRes, bool CalcConfidence = false)
  228. {
  229. var res1 = X1D1_Pos(cgRes, sRes, cxRes, CalcConfidence);
  230. var res2 = X2D1_Pos(cgRes, sRes, CalcConfidence);
  231. double[] res = new double[] { 999, 999, 0, 999, 999, 0, 100 };
  232. var p1 = res1.Take(3).ToArray();
  233. var p2 = res1.Skip(3).ToArray();
  234. var p3 = res2.Take(3).ToArray();
  235. var p4 = res2.Skip(3).ToArray();
  236. if (IsGeoPoint(p1) && IsGeoPoint(p2) && IsGeoPoint(p3) && IsGeoPoint(p4))
  237. {
  238. res = new double[7] {
  239. (p1[0] + p3[0]) / 2 + 0.003,
  240. (p1[1] + p3[1]) / 2 - 0.002,
  241. 0,
  242. (p2[0] + p4[0]) / 2 + 0.003,
  243. (p2[1] + p4[1]) / 2 - 0.002,
  244. 0,
  245. (res1[6]+res2[6])/2
  246. };
  247. }
  248. else if (IsGeoPoint(p1) && IsGeoPoint(p3))
  249. {
  250. res = new double[7] {
  251. (p1[0] + p3[0]) / 2 + 0.003,
  252. (p1[1] + p3[1]) / 2 - 0.002,
  253. 0,
  254. 999,
  255. 999,
  256. 0,
  257. (res1[6]+res2[6])/2
  258. };
  259. }
  260. else if (IsGeoPoint(p1) && IsGeoPoint(p2))
  261. {
  262. res = new double[7]
  263. {
  264. p1[0] + 0.003,
  265. p1[1] - 0.002,
  266. 0,
  267. p2[0] + 0.003,
  268. p2[1] - 0.002,
  269. 0,
  270. (res1[6]+res2[6])/2
  271. };
  272. }
  273. else if (IsGeoPoint(p3) && IsGeoPoint(p4))
  274. {
  275. res = new double[7]
  276. {
  277. p3[0] + 0.003,
  278. p3[1] - 0.002,
  279. 0,
  280. p4[0] + 0.003,
  281. p4[1] - 0.002,
  282. 0,
  283. (res1[6]+res2[6])/2
  284. };
  285. }
  286. return res;
  287. }
  288. /// <summary>
  289. /// 三星双时差带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  290. /// </summary>
  291. /// <param name="cgRes">参估结果</param>
  292. /// <param name="sRes">站点信息</param>
  293. /// <param name="CalcConfidence">是否计算置信度</param>
  294. /// <returns></returns>
  295. public static double[] X3_Pos(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  296. {
  297. if (cgRes.Dto1.Value == 0 || cgRes.Dto2.Value == 0)
  298. {
  299. return new double[7] { 999, 999, 0, 999, 999, 0, 100 };
  300. }
  301. if (cgRes.Snr1.Value == 0 || cgRes.Snr2.Value == 0) return new double[7] { 999, 999, 0, 999, 999, 0, 100 };
  302. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  303. double[] adjaSat1 = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  304. double[] adjaSat2 = new double[3] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value };
  305. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  306. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  307. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  308. var tarDto1 = cgRes.Dto1.Value / 1e6;
  309. var tarDto2 = cgRes.Dto2.Value / 1e6;
  310. var refDto1 = (cgRes.YbMainDto.Value - cgRes.YbAdja1Dto.Value) / 1e6;
  311. var refDto2 = (cgRes.YbMainDto.Value - cgRes.YbAdja2Dto.Value) / 1e6;
  312. double[] res = new double[6];
  313. X3_Pos20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation, satStation,
  314. satStation, satStation, refStation, zone, tarDto1, tarDto2, refDto1, refDto2, res);
  315. ConvertToGeoPoint(res);
  316. var posRes = ConvertToGeoPoint(res);
  317. if (CalcConfidence && IsGeoPoint2(posRes))
  318. {
  319. int succeedCount = 0;
  320. for (int i = 0; i < confidenceCount; i++)
  321. {
  322. var mainSatNew = new double[3]
  323. {
  324. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  325. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  326. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  327. };
  328. var adjaSat1New = new double[3]
  329. {
  330. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  331. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  332. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  333. };
  334. var adjaSat2New = new double[3]
  335. {
  336. cgRes.Adja2X.Value+RandomHelper.Normal(0,200),
  337. cgRes.Adja2Y.Value+RandomHelper.Normal(0,200),
  338. cgRes.Adja2Z.Value+RandomHelper.Normal(0,200)
  339. };
  340. var tarDto1New = (tarDto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  341. var tarDto2New = (tarDto2 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  342. var refDto1New = (refDto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  343. var refDto2New = (refDto2 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  344. X3_Pos20240305_Core(mainSatNew, adjaSat1New, adjaSat2New, satStation, satStation, satStation, satStation, satStation, satStation, refStation, zone, tarDto1New, tarDto2New, refDto1New, refDto2New, res);
  345. var posResNew = ConvertToGeoPoint(res);
  346. if (IsGeoPoint2(posResNew))
  347. {
  348. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  349. if (distance <= confidenceDistance)
  350. {
  351. succeedCount++;
  352. }
  353. }
  354. }
  355. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  356. }
  357. return posRes;
  358. }
  359. /// <summary>
  360. /// 三星双时差无参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  361. /// </summary>
  362. /// <param name="cgRes">参估结果</param>
  363. /// <param name="sRes">站点信息</param>
  364. /// <param name="CalcConfidence">是否计算置信度</param>
  365. /// <returns></returns>
  366. public static double[] X3_PosNoRef(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  367. {
  368. if (cgRes.Dto1.Value == 0 || cgRes.Dto2.Value == 0)
  369. {
  370. return new double[7] { 999, 999, 0, 999, 999, 0, 100 };
  371. }
  372. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  373. double[] adjaSat1 = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  374. double[] adjaSat2 = new double[3] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value };
  375. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  376. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  377. var tarDto1 = cgRes.Dto1.Value / 1e6;
  378. var tarDto2 = cgRes.Dto2.Value / 1e6;
  379. double[] res = new double[6];
  380. X3_PosNoRef20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation, zone, tarDto1, tarDto2, res);
  381. ConvertToGeoPoint(res);
  382. var posRes = ConvertToGeoPoint(res);
  383. if (CalcConfidence && IsGeoPoint2(posRes))
  384. {
  385. int succeedCount = 0;
  386. for (int i = 0; i < confidenceCount; i++)
  387. {
  388. var mainSatNew = new double[3]
  389. {
  390. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  391. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  392. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  393. };
  394. var adjaSat1New = new double[3]
  395. {
  396. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  397. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  398. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  399. };
  400. var adjaSat2New = new double[3]
  401. {
  402. cgRes.Adja2X.Value+RandomHelper.Normal(0,200),
  403. cgRes.Adja2Y.Value+RandomHelper.Normal(0,200),
  404. cgRes.Adja2Z.Value+RandomHelper.Normal(0,200)
  405. };
  406. var tarDto1New = (tarDto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  407. var tarDto2New = (tarDto2 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  408. X3_PosNoRef20240305_Core(mainSatNew, adjaSat1New, adjaSat2New, satStation, satStation, satStation, zone, tarDto1New, tarDto2New, res);
  409. var posResNew = ConvertToGeoPoint(res);
  410. if (IsGeoPoint2(posResNew))
  411. {
  412. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  413. if (distance <= confidenceDistance)
  414. {
  415. succeedCount++;
  416. }
  417. }
  418. }
  419. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  420. }
  421. return posRes;
  422. }
  423. /// <summary>
  424. /// 三星双频差带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  425. /// </summary>
  426. /// <param name="cgRes">参估结果</param>
  427. /// <param name="sRes">站点信息</param>
  428. /// <param name="CalcConfidence">是否计算置信度</param>
  429. /// <returns></returns>
  430. public static double[] X3_PosTwoDfo(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  431. {
  432. if (cgRes.Dfo1.Value == 0 || cgRes.Dfo2.Value == 0) return new double[7] { 999, 999, 0, 999, 999, 0, 100 };
  433. double[] mainSat = new double[6] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value, cgRes.MainVx.Value, cgRes.MainVy.Value, cgRes.MainVz.Value };
  434. double[] adjaSat1 = new double[6] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value, cgRes.Adja1Vx.Value, cgRes.Adja1Vy.Value, cgRes.Adja1Vz.Value };
  435. double[] adjaSat2 = new double[6] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value, cgRes.Adja2Vx.Value, cgRes.Adja2Vy.Value, cgRes.Adja2Vz.Value };
  436. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  437. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  438. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  439. var tarDfo1 = cgRes.Dfo1.Value;
  440. var tarDfo2 = cgRes.Dfo2.Value;
  441. var refDfo1 = cgRes.YbMainDfo.Value - cgRes.YbAdja1Dfo.Value;
  442. var refDfo2 = cgRes.YbMainDfo.Value - cgRes.YbAdja2Dfo.Value;
  443. double fu1 = cgRes.TarFreqUp.Value;
  444. double fd1 = cgRes.TarFreqDown.Value;
  445. double fu2 = cgRes.RefFreqUp.Value;
  446. double fd2 = cgRes.RefFreqDown.Value;
  447. double[] res = new double[6];
  448. X3_PosTwoDfo20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation,
  449. refStation, zone, tarDfo1, tarDfo2, refDfo1, refDfo2, fu1, fd1, fu2, fd2, res);
  450. ConvertToGeoPoint(res);
  451. var posRes = ConvertToGeoPoint(res);
  452. if (CalcConfidence && IsGeoPoint2(posRes))
  453. {
  454. int succeedCount = 0;
  455. for (int i = 0; i < confidenceCount; i++)
  456. {
  457. var mainSatNew = new double[3]
  458. {
  459. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  460. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  461. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  462. };
  463. var adjaSat1New = new double[3]
  464. {
  465. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  466. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  467. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  468. };
  469. var adjaSat2New = new double[3]
  470. {
  471. cgRes.Adja2X.Value+RandomHelper.Normal(0,200),
  472. cgRes.Adja2Y.Value+RandomHelper.Normal(0,200),
  473. cgRes.Adja2Z.Value+RandomHelper.Normal(0,200)
  474. };
  475. var tarDfo1New = (tarDfo1 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  476. var tarDfo2New = (tarDfo2 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  477. var refDfo1New = (refDfo1 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  478. var refDfo2New = (refDfo2 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  479. X3_PosTwoDfo20240305_Core(mainSatNew, adjaSat1New, adjaSat2New, satStation, satStation, satStation, refStation, zone, tarDfo1New, tarDfo2New, refDfo1New, refDfo2New, fu1, fd1, fu2, fd2, res);
  480. var posResNew = ConvertToGeoPoint(res);
  481. if (IsGeoPoint2(posResNew))
  482. {
  483. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  484. if (distance <= confidenceDistance)
  485. {
  486. succeedCount++;
  487. }
  488. }
  489. }
  490. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  491. }
  492. return posRes;
  493. }
  494. /// <summary>
  495. /// 双星时频差带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  496. /// </summary>
  497. /// <param name="cgRes">参估结果</param>
  498. /// <param name="sRes">站点信息</param>
  499. /// <param name="CalcConfidence">是否计算置信度</param>
  500. /// <returns></returns>
  501. public static double[] X2_PosDtoDfo(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  502. {
  503. if (cgRes.Dto1.Value == 0) return new double[7] { 999, 999, 0, 999, 999, 0, 100 };
  504. double[] mainSat = new double[6] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value, cgRes.MainVx.Value, cgRes.MainVy.Value, cgRes.MainVz.Value };
  505. double[] adjaSat = new double[6] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value, cgRes.Adja1Vx.Value, cgRes.Adja1Vy.Value, cgRes.Adja1Vz.Value };
  506. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  507. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  508. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  509. var tarDto = cgRes.Dto1.Value / 1e6;
  510. var tarDfo = cgRes.Dfo1.Value;
  511. var refDto = (cgRes.YbMainDto.Value - cgRes.YbAdja1Dto.Value) / 1e6;
  512. var refDfo = cgRes.YbMainDfo.Value - cgRes.YbAdja1Dfo.Value;
  513. double fu1 = cgRes.TarFreqUp.Value;
  514. double fd1 = cgRes.TarFreqDown.Value;
  515. double fu2 = cgRes.RefFreqUp.Value;
  516. double fd2 = cgRes.RefFreqDown.Value;
  517. double[] res = new double[6];
  518. X2_Pos20240305_Core(mainSat, adjaSat, satStation, satStation, refStation, zone, tarDto, tarDfo, refDto, refDfo, fu1, fd1, fu2, fd2, res);
  519. ConvertToGeoPoint(res);
  520. var posRes = ConvertToGeoPoint(res);
  521. if (CalcConfidence && IsGeoPoint2(posRes))
  522. {
  523. int succeedCount = 0;
  524. for (int i = 0; i < confidenceCount; i++)
  525. {
  526. var mainSatNew = new double[3]
  527. {
  528. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  529. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  530. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  531. };
  532. var adjaSatNew = new double[3]
  533. {
  534. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  535. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  536. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  537. };
  538. var tarDtoNew = (tarDto * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  539. var refDtoNew = (refDto * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  540. var tarDfoNew = (tarDfo * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  541. var refDfoNew = (refDfo * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  542. X2_Pos20240305_Core(mainSatNew, adjaSatNew, satStation, satStation, refStation, zone, tarDtoNew, tarDfoNew, refDtoNew, refDfoNew, fu1, fd1, fu2, fd2, res);
  543. var posResNew = ConvertToGeoPoint(res);
  544. if (IsGeoPoint2(posResNew))
  545. {
  546. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  547. if (distance <= confidenceDistance)
  548. {
  549. succeedCount++;
  550. }
  551. }
  552. }
  553. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  554. }
  555. return posRes;
  556. }
  557. private static double[] ConvertToGeoPoint(double[] res)
  558. {
  559. if (res == null || res.Length == 0)
  560. {
  561. return new double[7] { 999, 999, 0, 999, 999, 0, 100 };
  562. }
  563. else if (res.Length != 3 && res.Length != 6)
  564. {
  565. throw new Exception("定位结果解析异常,长度不是3或6");
  566. }
  567. var list = res.Select(p => Math.Round(p, 4)).ToArray();
  568. if (list.Length == 3)
  569. {
  570. list = list.Concat(new double[4] { 999, 999, 0, 100 }).ToArray();
  571. }
  572. list[2] = list[5] = 0;//高度
  573. if (double.IsNaN(list[0]) || double.IsNaN(list[1]))
  574. {
  575. list[0] = list[1] = 999;
  576. }
  577. if (double.IsNaN(list[3]) || double.IsNaN(list[4]))
  578. {
  579. list[3] = list[4] = 999;
  580. }
  581. if (list[0] < -180 || list[0] > 180)
  582. {
  583. list[0] = list[1] = 999;
  584. }
  585. else if (list[1] < -90 || list[1] > 90)
  586. {
  587. list[0] = list[1] = 999;
  588. }
  589. if (list[3] < -180 || list[3] > 180)
  590. {
  591. list[3] = list[4] = 999;
  592. }
  593. else if (list[4] < -90 || list[4] > 90)
  594. {
  595. list[3] = list[4] = 999;
  596. }
  597. if (list.Length == 6)
  598. {
  599. var listNew = list.ToList();
  600. listNew.Add(100);
  601. list = listNew.ToArray();
  602. }
  603. return list;
  604. }
  605. private static bool IsGeoPoint(double[] res)
  606. {
  607. if (res.Length != 3) return false;
  608. if (res[0] < -180 || res[0] > 180)
  609. {
  610. return false;
  611. }
  612. else if (res[1] < -90 || res[1] > 90)
  613. {
  614. return false;
  615. }
  616. return true;
  617. }
  618. private static bool IsGeoPoint2(double[] res)
  619. {
  620. if (res.Length < 3) return false;
  621. if (res[0] < -180 || res[0] > 180)
  622. {
  623. return false;
  624. }
  625. else if (res[1] < -90 || res[1] > 90)
  626. {
  627. return false;
  628. }
  629. return true;
  630. }
  631. }
  632. }