PosApi.cs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  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 = 10000;
  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, -1};
  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, -1};
  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. /// 三星双时差带参解析定位(精度差速度快,主要用于置信度分析等需要多次调用的情况)
  129. /// </summary>
  130. /// <param name="cgRes"></param>
  131. /// <param name="sRes"></param>
  132. /// <returns></returns>
  133. public static double[] X3Dto_GzPos(CgRes cgRes, StationRes sRes)
  134. {
  135. if (cgRes.Dto1.Value == 0 || cgRes.Dto2.Value == 0)
  136. {
  137. return new double[7] { 999, 999, 0, 999, 999, 0, -1};
  138. }
  139. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  140. double[] adja1Sat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  141. double[] adja2Sat = new double[3] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value };
  142. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  143. double dto1 = cgRes.Dto1.Value / 1e6;
  144. double dto2 = cgRes.Dto2.Value / 1e6;
  145. double ybDto1 = cgRes.YbMainDto.Value / 1e6;
  146. double ybDto2 = cgRes.YbAdja1Dto.Value / 1e6;
  147. double ybDto3 = cgRes.YbAdja2Dto.Value / 1e6;
  148. double refDto1 = ybDto1 - ybDto2;
  149. double refDto2 = ybDto1 - ybDto3;
  150. double[] posRes = new double[3];
  151. DW_Analysis(mainSat, adja1Sat, adja2Sat, refStation, dto1, dto2, refDto1, refDto2, posRes, 0);
  152. return posRes;
  153. }
  154. /// <summary>
  155. /// 两星一地带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  156. /// </summary>
  157. /// <param name="cgRes">参估结果</param>
  158. /// <param name="sRes">站点信息</param>
  159. /// <param name="CalcConfidence">是否计算置信度</param>
  160. /// <returns></returns>
  161. public static double[] X2D1_Pos(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  162. {
  163. if (cgRes.Dto1.Value == 0 || cgRes.DtoCdb.Value == 0)
  164. {
  165. return new double[7] { 999, 999, 0, 999, 999, 0, -1};
  166. }
  167. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  168. double[] adjaSat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  169. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  170. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  171. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  172. double dto1 = cgRes.Dto1.Value / 1e6;
  173. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  174. double ybDto1 = cgRes.YbMainDto.Value / 1e6;
  175. double ybDto2 = cgRes.YbAdja1Dto.Value / 1e6;
  176. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  177. double[] res = new double[6];
  178. X2D1_Pos20240305_Core(mainSat, adjaSat, cdbStation, satStation, satStation, satStation, satStation, satStation, refStation, zone, dto1, dtoCdb, ybDto1, ybDto2, res);
  179. ConvertToGeoPoint(res);
  180. var posRes = ConvertToGeoPoint(res);//精确搜索值
  181. if (CalcConfidence&& IsGeoPoint2(posRes))
  182. {
  183. var posResGz = X2D1_GzPos(cgRes, sRes);
  184. if (IsGeoPoint2(posResGz))
  185. {
  186. int succeedCount = 0;
  187. var cgResNew = cgRes.Clone();
  188. for (int i = 0; i < confidenceCount; i++)
  189. {
  190. cgResNew.MainX = cgRes.MainX + RandomHelper.Normal(0, 500);
  191. cgResNew.MainY = cgRes.MainY + RandomHelper.Normal(0, 500);
  192. cgResNew.MainZ = cgRes.MainZ + RandomHelper.Normal(0, 500);
  193. cgResNew.Adja1X = cgRes.Adja1X + RandomHelper.Normal(0, 500);
  194. cgResNew.Adja1Y = cgRes.Adja1Y + RandomHelper.Normal(0, 500);
  195. cgResNew.Adja1Z = cgRes.Adja1Z + RandomHelper.Normal(0, 500);
  196. cgResNew.Dto1 = (cgRes.Dto1 * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  197. cgResNew.DtoCdb = (cgRes.DtoCdb * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  198. cgResNew.YbMainDto = (cgRes.YbMainDto * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  199. cgResNew.YbAdja1Dto = (cgRes.YbAdja1Dto * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  200. res = X2D1_GzPos(cgResNew, sRes);
  201. var posResNew = ConvertToGeoPoint(res);
  202. if (IsGeoPoint2(posResNew))
  203. {
  204. var distance = PhysicsHelper.DistanceGeo((posResGz[0], posResGz[1], 0), (posResNew[0], posResNew[1], 0));
  205. if (distance <= confidenceDistance)
  206. {
  207. succeedCount++;
  208. }
  209. }
  210. }
  211. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  212. }
  213. else
  214. {
  215. posRes[6] = 0;
  216. }
  217. }
  218. return posRes;
  219. }
  220. /// <summary>
  221. /// 两星一地无参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  222. /// </summary>
  223. /// <param name="cgRes">参估结果</param>
  224. /// <param name="sRes">站点信息</param>
  225. /// <param name="CalcConfidence">是否计算置信度</param>
  226. /// <returns></returns>
  227. public static double[] X2D1_PosNoRef(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  228. {
  229. if (cgRes.Dto1.Value == 0 || cgRes.DtoCdb.Value == 0)
  230. {
  231. return new double[7] { 999, 999, 0, 999, 999, 0, -1};
  232. }
  233. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  234. double[] adjaSat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  235. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  236. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  237. double dto1 = cgRes.Dto1.Value / 1e6;
  238. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  239. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  240. double[] res = new double[6];
  241. X2D1_PosNoRef20240305_Core(mainSat, adjaSat, cdbStation, satStation, satStation, satStation, zone, dto1, dtoCdb, res);
  242. ConvertToGeoPoint(res);
  243. var posRes = ConvertToGeoPoint(res);
  244. if (CalcConfidence && IsGeoPoint2(posRes))
  245. {
  246. int succeedCount = 0;
  247. for (int i = 0; i < confidenceCount; i++)
  248. {
  249. var mainSatNew = new double[3]
  250. {
  251. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  252. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  253. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  254. };
  255. var adjaSatNew = new double[3]
  256. {
  257. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  258. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  259. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  260. };
  261. var dto1New = (dto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  262. var dtoCdbNew = (dtoCdb * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  263. X2D1_PosNoRef20240305_Core(mainSatNew, adjaSatNew, cdbStation, satStation, satStation, satStation, zone, dto1New, dtoCdbNew, res);
  264. var posResNew = ConvertToGeoPoint(res);
  265. if (IsGeoPoint2(posResNew))
  266. {
  267. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  268. if (distance <= confidenceDistance)
  269. {
  270. succeedCount++;
  271. }
  272. }
  273. }
  274. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  275. }
  276. return posRes;
  277. }
  278. /// <summary>
  279. /// 融合定位带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  280. /// </summary>
  281. /// <param name="cgRes">参估结果</param>
  282. /// <param name="sRes">站点信息</param>
  283. /// <param name="cxRes">测向结果</param>
  284. /// <param name="CalcConfidence">是否计算置信度</param>
  285. /// <returns></returns>
  286. public static double[] RH_Pos(CgRes cgRes, StationRes sRes, CxRes cxRes, bool CalcConfidence = false)
  287. {
  288. var res1 = X1D1_Pos(cgRes, sRes, cxRes, CalcConfidence);
  289. var res2 = X2D1_Pos(cgRes, sRes, CalcConfidence);
  290. double[] res = new double[] { 999, 999, 0, 999, 999, 0, 100 };
  291. var p1 = res1.Take(3).ToArray();
  292. var p2 = res1.Skip(3).ToArray();
  293. var p3 = res2.Take(3).ToArray();
  294. var p4 = res2.Skip(3).ToArray();
  295. if (IsGeoPoint(p1) && IsGeoPoint(p2) && IsGeoPoint(p3) && IsGeoPoint(p4))
  296. {
  297. res = new double[7] {
  298. (p1[0] + p3[0]) / 2 + 0.003,
  299. (p1[1] + p3[1]) / 2 - 0.002,
  300. 0,
  301. (p2[0] + p4[0]) / 2 + 0.003,
  302. (p2[1] + p4[1]) / 2 - 0.002,
  303. 0,
  304. (res1[6]+res2[6])/2
  305. };
  306. }
  307. else if (IsGeoPoint(p1) && IsGeoPoint(p3))
  308. {
  309. res = new double[7] {
  310. (p1[0] + p3[0]) / 2 + 0.003,
  311. (p1[1] + p3[1]) / 2 - 0.002,
  312. 0,
  313. 999,
  314. 999,
  315. 0,
  316. (res1[6]+res2[6])/2
  317. };
  318. }
  319. else if (IsGeoPoint(p1) && IsGeoPoint(p2))
  320. {
  321. res = new double[7]
  322. {
  323. p1[0] + 0.003,
  324. p1[1] - 0.002,
  325. 0,
  326. p2[0] + 0.003,
  327. p2[1] - 0.002,
  328. 0,
  329. (res1[6]+res2[6])/2
  330. };
  331. }
  332. else if (IsGeoPoint(p3) && IsGeoPoint(p4))
  333. {
  334. res = new double[7]
  335. {
  336. p3[0] + 0.003,
  337. p3[1] - 0.002,
  338. 0,
  339. p4[0] + 0.003,
  340. p4[1] - 0.002,
  341. 0,
  342. (res1[6]+res2[6])/2
  343. };
  344. }
  345. return res;
  346. }
  347. /// <summary>
  348. /// 三星双时差带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  349. /// </summary>
  350. /// <param name="cgRes">参估结果</param>
  351. /// <param name="sRes">站点信息</param>
  352. /// <param name="CalcConfidence">是否计算置信度</param>
  353. /// <returns></returns>
  354. public static double[] X3_Pos(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  355. {
  356. if (cgRes.Dto1.Value == 0 || cgRes.Dto2.Value == 0)
  357. {
  358. return new double[7] { 999, 999, 0, 999, 999, 0, -1};
  359. }
  360. if (cgRes.Dto1.Value == 0 || cgRes.Dto2.Value == 0) return new double[7] { 999, 999, 0, 999, 999, 0, -1};
  361. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  362. double[] adjaSat1 = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  363. double[] adjaSat2 = new double[3] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value };
  364. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  365. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  366. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  367. var tarDto1 = cgRes.Dto1.Value / 1e6;
  368. var tarDto2 = cgRes.Dto2.Value / 1e6;
  369. var refDto1 = (cgRes.YbMainDto.Value - cgRes.YbAdja1Dto.Value) / 1e6;
  370. var refDto2 = (cgRes.YbMainDto.Value - cgRes.YbAdja2Dto.Value) / 1e6;
  371. double[] res = new double[6];
  372. X3_Pos20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation, satStation,
  373. satStation, satStation, refStation, zone, tarDto1, tarDto2, refDto1, refDto2, res);
  374. var posRes = ConvertToGeoPoint(res);//精确搜索值
  375. if (CalcConfidence && IsGeoPoint2(posRes))
  376. {
  377. var posResGz = X3Dto_GzPos(cgRes, sRes);
  378. if (IsGeoPoint2(posResGz))
  379. {
  380. int succeedCount = 0;
  381. var cgResNew = cgRes.Clone();
  382. for (int i = 0; i < confidenceCount; i++)
  383. {
  384. cgResNew.MainX = cgRes.MainX + RandomHelper.Normal(0, 500);
  385. cgResNew.MainY = cgRes.MainY + RandomHelper.Normal(0, 500);
  386. cgResNew.MainZ = cgRes.MainZ + RandomHelper.Normal(0, 500);
  387. cgResNew.Adja1X = cgRes.Adja1X + RandomHelper.Normal(0, 500);
  388. cgResNew.Adja1Y = cgRes.Adja1Y + RandomHelper.Normal(0, 500);
  389. cgResNew.Adja1Z = cgRes.Adja1Z + RandomHelper.Normal(0, 500);
  390. cgResNew.Adja2X = cgRes.Adja2X + RandomHelper.Normal(0, 500);
  391. cgResNew.Adja2Y = cgRes.Adja2Y + RandomHelper.Normal(0, 500);
  392. cgResNew.Adja2Z = cgRes.Adja2Z + RandomHelper.Normal(0, 500);
  393. cgResNew.Dto1 = (cgRes.Dto1 * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  394. cgResNew.Dto2 = (cgRes.Dto2 * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  395. cgResNew.YbMainDto = (cgRes.YbMainDto * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  396. cgResNew.YbAdja1Dto = (cgRes.YbAdja1Dto * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  397. cgResNew.YbAdja2Dto = (cgRes.YbAdja2Dto * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  398. res = X3Dto_GzPos(cgResNew, sRes);
  399. var posResNew = ConvertToGeoPoint(res);
  400. if (IsGeoPoint2(posResNew))
  401. {
  402. var distance = PhysicsHelper.DistanceGeo((posResGz[0], posResGz[1], 0), (posResNew[0], posResNew[1], 0));
  403. if (distance <= confidenceDistance)
  404. {
  405. succeedCount++;
  406. }
  407. }
  408. }
  409. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  410. }
  411. else
  412. {
  413. posRes[6] = 0;
  414. }
  415. }
  416. return posRes;
  417. }
  418. /// <summary>
  419. /// 三星双时差无参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  420. /// </summary>
  421. /// <param name="cgRes">参估结果</param>
  422. /// <param name="sRes">站点信息</param>
  423. /// <param name="CalcConfidence">是否计算置信度</param>
  424. /// <returns></returns>
  425. public static double[] X3_PosNoRef(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  426. {
  427. if (cgRes.Dto1.Value == 0 || cgRes.Dto2.Value == 0)
  428. {
  429. return new double[7] { 999, 999, 0, 999, 999, 0, -1};
  430. }
  431. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  432. double[] adjaSat1 = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  433. double[] adjaSat2 = new double[3] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value };
  434. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  435. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  436. var tarDto1 = cgRes.Dto1.Value / 1e6;
  437. var tarDto2 = cgRes.Dto2.Value / 1e6;
  438. double[] res = new double[6];
  439. X3_PosNoRef20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation, zone, tarDto1, tarDto2, res);
  440. ConvertToGeoPoint(res);
  441. var posRes = ConvertToGeoPoint(res);
  442. if (CalcConfidence && IsGeoPoint2(posRes))
  443. {
  444. int succeedCount = 0;
  445. for (int i = 0; i < confidenceCount; i++)
  446. {
  447. var mainSatNew = new double[3]
  448. {
  449. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  450. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  451. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  452. };
  453. var adjaSat1New = new double[3]
  454. {
  455. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  456. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  457. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  458. };
  459. var adjaSat2New = new double[3]
  460. {
  461. cgRes.Adja2X.Value+RandomHelper.Normal(0,200),
  462. cgRes.Adja2Y.Value+RandomHelper.Normal(0,200),
  463. cgRes.Adja2Z.Value+RandomHelper.Normal(0,200)
  464. };
  465. var tarDto1New = (tarDto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  466. var tarDto2New = (tarDto2 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  467. X3_PosNoRef20240305_Core(mainSatNew, adjaSat1New, adjaSat2New, satStation, satStation, satStation, zone, tarDto1New, tarDto2New, res);
  468. var posResNew = ConvertToGeoPoint(res);
  469. if (IsGeoPoint2(posResNew))
  470. {
  471. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  472. if (distance <= confidenceDistance)
  473. {
  474. succeedCount++;
  475. }
  476. }
  477. }
  478. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  479. }
  480. return posRes;
  481. }
  482. /// <summary>
  483. /// 三星双频差带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  484. /// </summary>
  485. /// <param name="cgRes">参估结果</param>
  486. /// <param name="sRes">站点信息</param>
  487. /// <param name="CalcConfidence">是否计算置信度</param>
  488. /// <returns></returns>
  489. public static double[] X3_PosTwoDfo(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  490. {
  491. if (cgRes.Dfo1.Value == 0 || cgRes.Dfo2.Value == 0) return new double[7] { 999, 999, 0, 999, 999, 0, -1};
  492. double[] mainSat = new double[6] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value, cgRes.MainVx.Value, cgRes.MainVy.Value, cgRes.MainVz.Value };
  493. double[] adjaSat1 = new double[6] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value, cgRes.Adja1Vx.Value, cgRes.Adja1Vy.Value, cgRes.Adja1Vz.Value };
  494. double[] adjaSat2 = new double[6] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value, cgRes.Adja2Vx.Value, cgRes.Adja2Vy.Value, cgRes.Adja2Vz.Value };
  495. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  496. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  497. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  498. var tarDfo1 = cgRes.Dfo1.Value;
  499. var tarDfo2 = cgRes.Dfo2.Value;
  500. var refDfo1 = cgRes.YbMainDfo.Value - cgRes.YbAdja1Dfo.Value;
  501. var refDfo2 = cgRes.YbMainDfo.Value - cgRes.YbAdja2Dfo.Value;
  502. double fu1 = cgRes.TarFreqUp.Value;
  503. double fd1 = cgRes.TarFreqDown.Value;
  504. double fu2 = cgRes.RefFreqUp.Value;
  505. double fd2 = cgRes.RefFreqDown.Value;
  506. double[] res = new double[6];
  507. X3_PosTwoDfo20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation,
  508. refStation, zone, tarDfo1, tarDfo2, refDfo1, refDfo2, fu1, fd1, fu2, fd2, res);
  509. ConvertToGeoPoint(res);
  510. var posRes = ConvertToGeoPoint(res);
  511. if (CalcConfidence && IsGeoPoint2(posRes))
  512. {
  513. int succeedCount = 0;
  514. for (int i = 0; i < confidenceCount; i++)
  515. {
  516. var mainSatNew = new double[3]
  517. {
  518. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  519. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  520. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  521. };
  522. var adjaSat1New = new double[3]
  523. {
  524. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  525. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  526. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  527. };
  528. var adjaSat2New = new double[3]
  529. {
  530. cgRes.Adja2X.Value+RandomHelper.Normal(0,200),
  531. cgRes.Adja2Y.Value+RandomHelper.Normal(0,200),
  532. cgRes.Adja2Z.Value+RandomHelper.Normal(0,200)
  533. };
  534. var tarDfo1New = (tarDfo1 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  535. var tarDfo2New = (tarDfo2 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  536. var refDfo1New = (refDfo1 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  537. var refDfo2New = (refDfo2 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  538. X3_PosTwoDfo20240305_Core(mainSatNew, adjaSat1New, adjaSat2New, satStation, satStation, satStation, refStation, zone, tarDfo1New, tarDfo2New, refDfo1New, refDfo2New, fu1, fd1, fu2, fd2, res);
  539. var posResNew = ConvertToGeoPoint(res);
  540. if (IsGeoPoint2(posResNew))
  541. {
  542. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  543. if (distance <= confidenceDistance)
  544. {
  545. succeedCount++;
  546. }
  547. }
  548. }
  549. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  550. }
  551. return posRes;
  552. }
  553. /// <summary>
  554. /// 双星时频差带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  555. /// </summary>
  556. /// <param name="cgRes">参估结果</param>
  557. /// <param name="sRes">站点信息</param>
  558. /// <param name="CalcConfidence">是否计算置信度</param>
  559. /// <returns></returns>
  560. public static double[] X2_PosDtoDfo(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  561. {
  562. if (cgRes.Dto1.Value == 0) return new double[7] { 999, 999, 0, 999, 999, 0, -1};
  563. double[] mainSat = new double[6] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value, cgRes.MainVx.Value, cgRes.MainVy.Value, cgRes.MainVz.Value };
  564. double[] adjaSat = new double[6] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value, cgRes.Adja1Vx.Value, cgRes.Adja1Vy.Value, cgRes.Adja1Vz.Value };
  565. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  566. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  567. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  568. var tarDto = cgRes.Dto1.Value / 1e6;
  569. var tarDfo = cgRes.Dfo1.Value;
  570. var refDto = (cgRes.YbMainDto.Value - cgRes.YbAdja1Dto.Value) / 1e6;
  571. var refDfo = cgRes.YbMainDfo.Value - cgRes.YbAdja1Dfo.Value;
  572. double fu1 = cgRes.TarFreqUp.Value;
  573. double fd1 = cgRes.TarFreqDown.Value;
  574. double fu2 = cgRes.RefFreqUp.Value;
  575. double fd2 = cgRes.RefFreqDown.Value;
  576. double[] res = new double[6];
  577. X2_Pos20240305_Core(mainSat, adjaSat, satStation, satStation, refStation, zone, tarDto, tarDfo, refDto, refDfo, fu1, fd1, fu2, fd2, res);
  578. ConvertToGeoPoint(res);
  579. var posRes = ConvertToGeoPoint(res);
  580. if (CalcConfidence && IsGeoPoint2(posRes))
  581. {
  582. int succeedCount = 0;
  583. for (int i = 0; i < confidenceCount; i++)
  584. {
  585. var mainSatNew = new double[3]
  586. {
  587. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  588. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  589. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  590. };
  591. var adjaSatNew = new double[3]
  592. {
  593. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  594. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  595. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  596. };
  597. var tarDtoNew = (tarDto * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  598. var refDtoNew = (refDto * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  599. var tarDfoNew = (tarDfo * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  600. var refDfoNew = (refDfo * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  601. X2_Pos20240305_Core(mainSatNew, adjaSatNew, satStation, satStation, refStation, zone, tarDtoNew, tarDfoNew, refDtoNew, refDfoNew, fu1, fd1, fu2, fd2, res);
  602. var posResNew = ConvertToGeoPoint(res);
  603. if (IsGeoPoint2(posResNew))
  604. {
  605. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  606. if (distance <= confidenceDistance)
  607. {
  608. succeedCount++;
  609. }
  610. }
  611. }
  612. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  613. }
  614. return posRes;
  615. }
  616. private static double[] ConvertToGeoPoint(double[] res)
  617. {
  618. if (res == null || res.Length == 0)
  619. {
  620. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  621. }
  622. else if (res.Length != 3 && res.Length != 6)
  623. {
  624. throw new Exception("定位结果解析异常,长度不是3或6");
  625. }
  626. var list = res.Select(p => Math.Round(p, 4)).ToArray();
  627. if (list.Length == 3)
  628. {
  629. list = list.Concat(new double[4] { 999, 999, 0, -1 }).ToArray();
  630. }
  631. list[2] = list[5] = 0;//高度
  632. if (double.IsNaN(list[0]) || double.IsNaN(list[1]))
  633. {
  634. list[0] = list[1] = 999;
  635. }
  636. if (double.IsNaN(list[3]) || double.IsNaN(list[4]))
  637. {
  638. list[3] = list[4] = 999;
  639. }
  640. if (list[0] < -180 || list[0] > 180)
  641. {
  642. list[0] = list[1] = 999;
  643. }
  644. else if (list[1] < -90 || list[1] > 90)
  645. {
  646. list[0] = list[1] = 999;
  647. }
  648. if (list[3] < -180 || list[3] > 180)
  649. {
  650. list[3] = list[4] = 999;
  651. }
  652. else if (list[4] < -90 || list[4] > 90)
  653. {
  654. list[3] = list[4] = 999;
  655. }
  656. if (list.Length == 6)
  657. {
  658. var listNew = list.ToList();
  659. listNew.Add(-1);
  660. list = listNew.ToArray();
  661. }
  662. return list;
  663. }
  664. private static bool IsGeoPoint(double[] res)
  665. {
  666. if (res.Length != 3) return false;
  667. if (res[0] < -180 || res[0] > 180)
  668. {
  669. return false;
  670. }
  671. else if (res[1] < -90 || res[1] > 90)
  672. {
  673. return false;
  674. }
  675. return true;
  676. }
  677. private static bool IsGeoPoint2(double[] res)
  678. {
  679. if (res.Length < 3) return false;
  680. if (res[0] < -180 || res[0] > 180)
  681. {
  682. return false;
  683. }
  684. else if (res[1] < -90 || res[1] > 90)
  685. {
  686. return false;
  687. }
  688. return true;
  689. }
  690. }
  691. }