PosApi.cs 36 KB

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