PosApi.cs 33 KB

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