PosApi.cs 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  1. using DPP_YH_Core.Extensions;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Runtime.CompilerServices;
  6. using System.Runtime.InteropServices;
  7. using System.Security.Policy;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using XdCxRhDW.Entity;
  11. using XdCxRhDW.Framework;
  12. namespace XdCxRhDW.Api
  13. {
  14. /// <summary>
  15. ///TODO 定位算法接口.在这里调用罗博士的算法库
  16. /// </summary>
  17. public static class PosApi
  18. {
  19. //置信度统计次数
  20. private static int confidenceCount = 1000;
  21. //置信度有效距离(m)
  22. private static int confidenceDistance = 10000;
  23. #region cpp dll Interop
  24. //两星一地和三星解析定位算法(精度差、速度快,适用于置信度等统计时的多次调用)
  25. private const string gzPos = @"AddIns\定位\DLL_GZDW.dll";
  26. //一星一地测向带参定位
  27. private const string XDCX = @"AddIns\定位\DLL_DTO_DOA_DW.dll";
  28. //三星双时差带参、三星双时差无参、三星双频差带参、双星时频差带参、两星一地无参定位及时差线、一星两地
  29. private const string OtherPos = @"AddIns\定位\Position-New.dll";//DLL_11J_DW
  30. [DllImport(gzPos, EntryPoint = "DW_Analysis", CallingConvention = CallingConvention.Cdecl)]//两星一地和三星的解析定位算法(精度差、速度快)
  31. 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);
  32. [DllImport(XDCX, EntryPoint = "XD_CX_DW", CallingConvention = CallingConvention.Cdecl)]//一星一地测向带参
  33. 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);
  34. [DllImport(OtherPos, EntryPoint = "SC_2X1D_DW", CallingConvention = CallingConvention.Cdecl)]//两星一地带参
  35. private extern static void X2D1_Pos20240305_Core(double[] mainSat, double[] adjaSat, double[] cdbStation, double[] satStation1, double[] satStation2, double[] satStation3, double[] satStation4,
  36. double[] satStation5, double[] refStation, double[] zone, double tarSxDto, double tarXdDto, double samp_main_dto, double samp_neigh_dto, double[] res);
  37. [DllImport(OtherPos, EntryPoint = "XingDi_2X1D_DW_NoRef", CallingConvention = CallingConvention.Cdecl)]//两星一地无参
  38. private extern static void X2D1_PosNoRef20240305_Core(double[] mainSat, double[] adjaSat, double[] cdbStation, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  39. , double[] zone, double tarSxDto, double tarXdDto, double[] res);
  40. [DllImport(OtherPos, EntryPoint = "SanXing_DW", CallingConvention = CallingConvention.Cdecl)]//三星双时差带参
  41. private extern static void X3_Pos20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  42. , double[] mainSatRefStation, double[] adjaSat1RefStation, double[] adjaSat2RefStation, double[] refStation, double[] zone, double tarDto1, double tarDto2, double refDto1, double refDto2, double[] res);
  43. [DllImport(OtherPos, EntryPoint = "SanXing_DW_NoRef", CallingConvention = CallingConvention.Cdecl)]//三星双时差无参
  44. private extern static void X3_PosNoRef20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  45. , double[] zone, double tarDto1, double tarDto2, double[] res);
  46. [DllImport(OtherPos, EntryPoint = "TriStar_2DFO_DW", CallingConvention = CallingConvention.Cdecl)]//三星双频差带参
  47. private extern static void X3_PosTwoDfo20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  48. , double[] refStation, double[] zone, double tarDfo1, double tarDfo2, double refDfo1, double refDfo2, double fu1, double fd1, double fu2, double fd2, double[] res);
  49. [DllImport(OtherPos, EntryPoint = "TwoStar_DTFO_DW", CallingConvention = CallingConvention.Cdecl)]//双星时频差带参
  50. private extern static void X2_Pos20240305_Core(double[] mainSat, double[] adjaSat, double[] mainSatTarStation, double[] adjaSatTarStation, double[] refStation, double[] zone
  51. , double tarDto, double tarDfo, double refDto, double refDfo, double fu1, double fd1, double fu2, double fd2, double[] res);
  52. #endregion
  53. /// <summary>
  54. /// 一星一地带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  55. /// </summary>
  56. /// <param name="cgRes">参估结果</param>
  57. /// <param name="sRes">站点信息</param>
  58. /// <param name="cxRes">测向结果</param>
  59. /// <param name="CalcConfidence">是否计算置信度</param>
  60. /// <returns></returns>
  61. public static double[] X1D1_Pos(CgRes cgRes, StationRes sRes, CxRes cxRes, bool CalcConfidence = false)
  62. {
  63. if (cgRes.DtoCdb.Value == 0) return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  64. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  65. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  66. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  67. double[] cxStation = new double[3] { sRes.CxLon.Value, sRes.CxLat.Value, 0 };
  68. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  69. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  70. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  71. double theta = cxRes.Fx;//单位°
  72. double[] res = new double[6];
  73. var ybDto1 = cgRes.YbMainDto.Value / 1e6;
  74. X1D1_Pos20240305_Core(mainSat, satStation, cdbStation, cxStation, refStation, zone, theta, dtoCdb, ybDto1, res);
  75. var posRes = ConvertToGeoPoint(res);
  76. if (CalcConfidence && IsGeoPoint2(posRes))
  77. {
  78. int succeedCount = 0;
  79. for (int i = 0; i < confidenceCount; i++)
  80. {
  81. var mainSatNew = new double[3]
  82. {
  83. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  84. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  85. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  86. };
  87. var dtoCdbNew = (dtoCdb * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  88. var ybDtoNew = (ybDto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  89. var thetaNew = theta + RandomHelper.Normal(0, 0.4);//单位°
  90. X1D1_Pos20240305_Core(mainSatNew, satStation, cdbStation, cxStation, refStation, zone, thetaNew, dtoCdbNew, ybDtoNew, res);
  91. var posResNew = ConvertToGeoPoint(res);
  92. if (IsGeoPoint2(posResNew))
  93. {
  94. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  95. if (distance <= confidenceDistance)
  96. {
  97. succeedCount++;
  98. }
  99. }
  100. }
  101. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  102. }
  103. return posRes;
  104. }
  105. /// <summary>
  106. /// 两星一地带参解析定位(精度差速度快,主要用于置信度分析等需要多次调用的情况)
  107. /// </summary>
  108. /// <param name="cgRes"></param>
  109. /// <param name="sRes"></param>
  110. /// <returns></returns>
  111. public static double[] X2D1_GzPos(CgRes cgRes, StationRes sRes)
  112. {
  113. if (cgRes.Dto1.Value == 0 || cgRes.DtoCdb.Value == 0)
  114. {
  115. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  116. }
  117. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  118. double[] adjaSat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  119. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  120. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  121. double dto1 = cgRes.Dto1.Value / 1e6;
  122. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  123. double ybDto1 = cgRes.YbMainDto.Value / 1e6;
  124. double ybDto2 = cgRes.YbAdja1Dto.Value / 1e6;
  125. double ybDto = ybDto1 - ybDto2;
  126. double[] posRes = new double[3];
  127. DW_Analysis(mainSat, adjaSat, cdbStation, refStation, dto1, -dtoCdb, ybDto, -ybDto1, posRes, 1);
  128. return posRes;
  129. }
  130. /// <summary>
  131. /// 三星双时差带参解析定位(精度差速度快,主要用于置信度分析等需要多次调用的情况)
  132. /// </summary>
  133. /// <param name="cgRes"></param>
  134. /// <param name="sRes"></param>
  135. /// <returns></returns>
  136. public static double[] X3Dto_GzPos(CgRes cgRes, StationRes sRes)
  137. {
  138. if (cgRes.Dto1.Value == 0 || cgRes.Dto2.Value == 0)
  139. {
  140. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  141. }
  142. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  143. double[] adja1Sat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  144. double[] adja2Sat = new double[3] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value };
  145. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  146. double dto1 = cgRes.Dto1.Value / 1e6;
  147. double dto2 = cgRes.Dto2.Value / 1e6;
  148. double ybDto1 = cgRes.YbMainDto.Value / 1e6;
  149. double ybDto2 = cgRes.YbAdja1Dto.Value / 1e6;
  150. double ybDto3 = cgRes.YbAdja2Dto.Value / 1e6;
  151. double refDto1 = ybDto1 - ybDto2;
  152. double refDto2 = ybDto1 - ybDto3;
  153. double[] posRes = new double[3];
  154. DW_Analysis(mainSat, adja1Sat, adja2Sat, refStation, dto1, dto2, refDto1, refDto2, posRes, 0);
  155. return posRes;
  156. }
  157. /// <summary>
  158. /// 两星一地带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  159. /// </summary>
  160. /// <param name="cgRes">参估结果</param>
  161. /// <param name="sRes">站点信息</param>
  162. /// <param name="CalcConfidence">是否计算置信度</param>
  163. /// <returns></returns>
  164. public static double[] X2D1_Pos(CgRes cgRes, StationRes sRes, double[] zone, bool CalcConfidence = false)
  165. {
  166. if (cgRes.Dto1.Value == 0 || cgRes.DtoCdb.Value == 0)
  167. {
  168. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  169. }
  170. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  171. double[] adjaSat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  172. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  173. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  174. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  175. double dto1 = cgRes.Dto1.Value / 1e6;
  176. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  177. double ybDto1 = cgRes.YbMainDto.Value / 1e6;
  178. double ybDto2 = cgRes.YbAdja1Dto.Value / 1e6;
  179. if (zone == null)
  180. zone = new double[] { -85, 85, -180, 180 }; //定位区域
  181. double[] res = new double[6];
  182. X2D1_Pos20240305_Core(mainSat, adjaSat, cdbStation, satStation, satStation, satStation, satStation, satStation, refStation, zone, dto1, dtoCdb, ybDto1, ybDto2, res);
  183. ConvertToGeoPoint(res);
  184. var posRes = ConvertToGeoPoint(res);//精确搜索值
  185. if (CalcConfidence && IsGeoPoint2(posRes))
  186. {
  187. var posResGz = X2D1_GzPos(cgRes, sRes);
  188. if (IsGeoPoint2(posResGz))
  189. {
  190. int succeedCount = 0;
  191. var cgResNew = cgRes.Clone();
  192. for (int i = 0; i < confidenceCount; i++)
  193. {
  194. cgResNew.MainX = cgRes.MainX + RandomHelper.Normal(0, 200);
  195. cgResNew.MainY = cgRes.MainY + RandomHelper.Normal(0, 200);
  196. cgResNew.MainZ = cgRes.MainZ + RandomHelper.Normal(0, 200);
  197. cgResNew.Adja1X = cgRes.Adja1X + RandomHelper.Normal(0, 200);
  198. cgResNew.Adja1Y = cgRes.Adja1Y + RandomHelper.Normal(0, 200);
  199. cgResNew.Adja1Z = cgRes.Adja1Z + RandomHelper.Normal(0, 200);
  200. cgResNew.Dto1 = (cgRes.Dto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  201. cgResNew.DtoCdb = (cgRes.DtoCdb * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  202. cgResNew.YbMainDto = (cgRes.YbMainDto * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  203. cgResNew.YbAdja1Dto = (cgRes.YbAdja1Dto * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  204. res = X2D1_GzPos(cgResNew, sRes);
  205. var posResNew = ConvertToGeoPoint(res);
  206. if (IsGeoPoint2(posResNew))
  207. {
  208. var distance = PhysicsHelper.DistanceGeo((posResGz[0], posResGz[1], 0), (posResNew[0], posResNew[1], 0));
  209. if (distance <= confidenceDistance)
  210. {
  211. succeedCount++;
  212. }
  213. }
  214. }
  215. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  216. }
  217. else
  218. {
  219. posRes[6] = 0;
  220. }
  221. }
  222. return posRes;
  223. }
  224. /// <summary>
  225. /// 两星一地无参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  226. /// </summary>
  227. /// <param name="cgRes">参估结果</param>
  228. /// <param name="sRes">站点信息</param>
  229. /// <param name="CalcConfidence">是否计算置信度</param>
  230. /// <returns></returns>
  231. public static double[] X2D1_PosNoRef(CgRes cgRes, StationRes sRes, double[] zone, bool CalcConfidence = false)
  232. {
  233. if (cgRes.Dto1.Value == 0 || cgRes.DtoCdb.Value == 0)
  234. {
  235. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  236. }
  237. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  238. double[] adjaSat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  239. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  240. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  241. double dto1 = cgRes.Dto1.Value / 1e6;
  242. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  243. if (zone == null)
  244. zone = new double[] { -85, 85, -180, 180 }; //定位区域
  245. double[] res = new double[6];
  246. X2D1_PosNoRef20240305_Core(mainSat, adjaSat, cdbStation, satStation, satStation, satStation, zone, dto1, dtoCdb, res);
  247. var posRes = ConvertToGeoPoint(res);
  248. if (CalcConfidence && IsGeoPoint2(posRes))
  249. {
  250. int succeedCount = 0;
  251. for (int i = 0; i < confidenceCount; i++)
  252. {
  253. var mainSatNew = new double[3]
  254. {
  255. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  256. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  257. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  258. };
  259. var adjaSatNew = new double[3]
  260. {
  261. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  262. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  263. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  264. };
  265. var dto1New = (dto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  266. var dtoCdbNew = (dtoCdb * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  267. X2D1_PosNoRef20240305_Core(mainSatNew, adjaSatNew, cdbStation, satStation, satStation, satStation, zone, dto1New, dtoCdbNew, res);
  268. var posResNew = ConvertToGeoPoint(res);
  269. if (IsGeoPoint2(posResNew))
  270. {
  271. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  272. if (distance <= confidenceDistance)
  273. {
  274. succeedCount++;
  275. }
  276. }
  277. }
  278. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  279. }
  280. return posRes;
  281. }
  282. public static double[] X2D1_PosNoRef_ZL(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  283. {
  284. if (cgRes.Dto1.Value == 0 || cgRes.DtoCdb.Value == 0)
  285. {
  286. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  287. }
  288. var cdbStation = new double[2] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value };
  289. var satStation = new double[2] { sRes.SatTxLon, sRes.SatTxLat };
  290. var mainXYZ = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  291. var adjaXYZ = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  292. var dtoSxus = cgRes.Dto1.Value;
  293. var dtoXdus = cgRes.DtoCdb.Value;
  294. var posRes = X2D1_PosNoRefCore_Zl(cdbStation, satStation, mainXYZ, adjaXYZ, dtoSxus, dtoXdus);
  295. posRes = ConvertToGeoPoint(posRes);
  296. if (CalcConfidence && IsGeoPoint2(posRes))
  297. {
  298. int succeedCount = 0;
  299. int totalCount = 100;
  300. for (int i = 0; i < totalCount; i++)
  301. {
  302. var mainSatNew = new double[3]
  303. {
  304. cgRes.MainX.Value+RandomHelper.Normal(0,500),
  305. cgRes.MainY.Value+RandomHelper.Normal(0,500),
  306. cgRes.MainZ.Value+RandomHelper.Normal(0,500)
  307. };
  308. var adjaSatNew = new double[3]
  309. {
  310. cgRes.Adja1X.Value+RandomHelper.Normal(0,500),
  311. cgRes.Adja1Y.Value+RandomHelper.Normal(0,500),
  312. cgRes.Adja1Z.Value+RandomHelper.Normal(0,500)
  313. };
  314. var dtoSxusNew = dtoSxus + RandomHelper.Normal(0, 1);
  315. var dtoXdusNew = dtoXdus + RandomHelper.Normal(0, 1);
  316. var posResNew = X2D1_PosNoRefCore_Zl(cdbStation, satStation, mainSatNew, adjaSatNew, dtoSxusNew, dtoXdusNew);
  317. posResNew = ConvertToGeoPoint(posResNew);
  318. if (IsGeoPoint2(posResNew))
  319. {
  320. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  321. if (distance <= confidenceDistance)
  322. {
  323. succeedCount++;
  324. }
  325. }
  326. }
  327. var confidence = (int)(succeedCount / (double)totalCount * 100);
  328. if (confidence == 0)
  329. confidence = 1;
  330. if (confidence == 100)
  331. confidence = 99;
  332. posRes[6] = confidence;
  333. }
  334. return posRes;
  335. }
  336. private static double[] X2D1_PosNoRefCore_Zl(double[] cdbStation, double[] satStation, double[] mainXYZ, double[] adjaXYZ, double dtoSxus, double dtoXdus)
  337. {
  338. double startLon = (int)cdbStation[0] - 10;
  339. double endLon = (int)cdbStation[0] + 10;
  340. double startLat = (int)cdbStation[1] - 10;
  341. double endLat = (int)cdbStation[1] + 10;
  342. List<(double, double, double, double)> list = new List<(double, double, double, double)>();
  343. var recXYZ = PhysicsHelper.GeoToEcef((satStation[0], satStation[1], 0));
  344. var cdbXYZ = PhysicsHelper.GeoToEcef((cdbStation[0], cdbStation[1], 0));
  345. for (double lon = startLon; lon < endLon; lon += 0.0001)
  346. {
  347. int flag = 0;
  348. for (double lat = startLat; lat < endLat; lat += 0.0001)
  349. {
  350. var posXYZ = PhysicsHelper.GeoToEcef((lon, lat, 0));
  351. //目标-主星-接收站的时间(us)
  352. var dt1 = PhysicsHelper.Dto(posXYZ, (mainXYZ[0], mainXYZ[1], mainXYZ[2]), recXYZ) * 1e6;
  353. //目标-超短站的时间(us)
  354. var dt3 = PhysicsHelper.Dto(posXYZ, cdbXYZ) * 1e6;
  355. var dto2 = Math.Abs(dt1 - dt3 - dtoXdus);
  356. if (dto2 > 400)
  357. {
  358. lat += 1;
  359. if (flag < 1)
  360. flag = 1;
  361. continue;
  362. }
  363. else if (dto2 > 200)
  364. {
  365. lat += 0.5;
  366. if (flag < 2)
  367. flag = 2;
  368. continue;
  369. }
  370. else if (dto2 > 100)
  371. {
  372. lat += 0.2;
  373. if (flag < 3)
  374. flag = 3;
  375. continue;
  376. }
  377. else if (dto2 > 10)
  378. {
  379. lat += 0.01;
  380. if (flag < 4)
  381. flag = 4;
  382. continue;
  383. }
  384. //else if (dto2 > 2)
  385. //{
  386. // lat += 0.001;
  387. // if (flag < 5)
  388. // flag = 5;
  389. // continue;
  390. //}
  391. //目标-邻星-接收站的时间(us)
  392. var dt2 = PhysicsHelper.Dto(posXYZ, (adjaXYZ[0], adjaXYZ[1], adjaXYZ[2]), recXYZ) * 1e6;
  393. var dto1 = Math.Abs(dt1 - dt2 - dtoSxus);
  394. if (dto1 > 400)
  395. {
  396. lat += 1;
  397. if (flag < 1)
  398. flag = 1;
  399. continue;
  400. }
  401. if (dto1 > 200)
  402. {
  403. lat += 0.5;
  404. if (flag < 2)
  405. flag = 2;
  406. continue;
  407. }
  408. else if (dto1 > 100)
  409. {
  410. lat += 0.2;
  411. if (flag < 3)
  412. flag = 3;
  413. continue;
  414. }
  415. else if (dto1 > 10)
  416. {
  417. lat += 0.01;
  418. if (flag < 4)
  419. flag = 4;
  420. continue;
  421. }
  422. //else if (dto1 > 2)
  423. //{
  424. // lat += 0.001;
  425. // if (flag < 5)
  426. // flag = 5;
  427. // continue;
  428. //}
  429. list.Add((lon, lat, dto1, dto2));
  430. }
  431. if (flag == 1)
  432. lon += 1;
  433. else if (flag == 2)
  434. lon += 0.5;
  435. else if (flag == 3)
  436. lon += 0.2;
  437. else if (flag == 4)
  438. lon += 0.01;
  439. else if (flag == 5)
  440. lon += 0.001;
  441. }
  442. double[] posRes;
  443. var p1 = list.OrderBy(p => p.Item4 * p.Item4 + p.Item3 * p.Item3).FirstOrDefault();
  444. if (p1 == default)
  445. {
  446. posRes = new double[6] { 999, 999, 0, 999, 999, 0 };
  447. return posRes;
  448. }
  449. var p2 = list.Where(p => PhysicsHelper.DistanceGeo((p1.Item1, p1.Item2, 0), (p.Item1, p.Item2, 0)) > 10000).OrderBy(p => p.Item4 * p.Item4 + p.Item3 * p.Item3).FirstOrDefault();
  450. if (p2 == default)
  451. posRes = new double[6] { p1.Item1, p1.Item2, 0, 999, 999, 0 };
  452. else
  453. posRes = new double[6] { p1.Item1, p1.Item2, 0, p2.Item1, p2.Item2, 0 };
  454. if (posRes[3] != 999)
  455. {
  456. var dis1 = PhysicsHelper.DistanceArcGeo((posRes[3], posRes[4]), (cdbStation[0], cdbStation[1]));
  457. var dis2 = PhysicsHelper.DistanceArcGeo((posRes[0], posRes[1]), (cdbStation[0], cdbStation[1]));
  458. if (dis1 < dis2)
  459. {
  460. var tmp1 = posRes[3];
  461. var tmp2 = posRes[4];
  462. posRes[3] = posRes[0];
  463. posRes[4] = posRes[1];
  464. posRes[0] = tmp1;
  465. posRes[1] = tmp2;
  466. }
  467. }
  468. return posRes;
  469. }
  470. /// <summary>
  471. /// 融合定位带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  472. /// </summary>
  473. /// <param name="cgRes">参估结果</param>
  474. /// <param name="sRes">站点信息</param>
  475. /// <param name="cxRes">测向结果</param>
  476. /// <param name="CalcConfidence">是否计算置信度</param>
  477. /// <returns></returns>
  478. public static double[] RH_Pos(CgRes cgRes, StationRes sRes, CxRes cxRes, bool CalcConfidence = false)
  479. {
  480. var res1 = X1D1_Pos(cgRes, sRes, cxRes, CalcConfidence);
  481. var res2 = X2D1_Pos(cgRes, sRes, null,CalcConfidence);
  482. double[] res = new double[] { 999, 999, 0, 999, 999, 0, 100 };
  483. var p1 = res1.Take(3).ToArray();
  484. var p2 = res1.Skip(3).ToArray();
  485. var p3 = res2.Take(3).ToArray();
  486. var p4 = res2.Skip(3).ToArray();
  487. if (IsGeoPoint(p1) && IsGeoPoint(p2) && IsGeoPoint(p3) && IsGeoPoint(p4))
  488. {
  489. res = new double[7] {
  490. (p1[0] + p3[0]) / 2 + 0.003,
  491. (p1[1] + p3[1]) / 2 - 0.002,
  492. 0,
  493. (p2[0] + p4[0]) / 2 + 0.003,
  494. (p2[1] + p4[1]) / 2 - 0.002,
  495. 0,
  496. (res1[6]+res2[6])/2
  497. };
  498. }
  499. else if (IsGeoPoint(p1) && IsGeoPoint(p3))
  500. {
  501. res = new double[7] {
  502. (p1[0] + p3[0]) / 2 + 0.003,
  503. (p1[1] + p3[1]) / 2 - 0.002,
  504. 0,
  505. 999,
  506. 999,
  507. 0,
  508. (res1[6]+res2[6])/2
  509. };
  510. }
  511. else if (IsGeoPoint(p1) && IsGeoPoint(p2))
  512. {
  513. res = new double[7]
  514. {
  515. p1[0] + 0.003,
  516. p1[1] - 0.002,
  517. 0,
  518. p2[0] + 0.003,
  519. p2[1] - 0.002,
  520. 0,
  521. (res1[6]+res2[6])/2
  522. };
  523. }
  524. else if (IsGeoPoint(p3) && IsGeoPoint(p4))
  525. {
  526. res = new double[7]
  527. {
  528. p3[0] + 0.003,
  529. p3[1] - 0.002,
  530. 0,
  531. p4[0] + 0.003,
  532. p4[1] - 0.002,
  533. 0,
  534. (res1[6]+res2[6])/2
  535. };
  536. }
  537. return res;
  538. }
  539. /// <summary>
  540. /// 三星双时差带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  541. /// </summary>
  542. /// <param name="cgRes">参估结果</param>
  543. /// <param name="sRes">站点信息</param>
  544. /// <param name="CalcConfidence">是否计算置信度</param>
  545. /// <returns></returns>
  546. public static double[] X3_Pos(CgRes cgRes, StationRes sRes, double[] zone, bool CalcConfidence = false)
  547. {
  548. if (cgRes.Dto1.Value == 0 || cgRes.Dto2.Value == 0)
  549. {
  550. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  551. }
  552. if (cgRes.Dto1.Value == 0 || cgRes.Dto2.Value == 0) return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  553. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  554. double[] adjaSat1 = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  555. double[] adjaSat2 = new double[3] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value };
  556. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  557. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  558. if (zone == null)
  559. zone = new double[] { -85, 85, -180, 180 }; //定位区域
  560. var tarDto1 = cgRes.Dto1.Value / 1e6;
  561. var tarDto2 = cgRes.Dto2.Value / 1e6;
  562. var refDto1 = (cgRes.YbMainDto.Value - cgRes.YbAdja1Dto.Value) / 1e6;
  563. var refDto2 = (cgRes.YbMainDto.Value - cgRes.YbAdja2Dto.Value) / 1e6;
  564. double[] res = new double[6];
  565. X3_Pos20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation, satStation,
  566. satStation, satStation, refStation, zone, tarDto1, tarDto2, refDto1, refDto2, res);
  567. var posRes = ConvertToGeoPoint(res);//精确搜索值
  568. if (CalcConfidence && IsGeoPoint2(posRes))
  569. {
  570. var posResGz = X3Dto_GzPos(cgRes, sRes);
  571. if (IsGeoPoint2(posResGz))
  572. {
  573. int succeedCount = 0;
  574. var cgResNew = cgRes.Clone();
  575. for (int i = 0; i < confidenceCount; i++)
  576. {
  577. cgResNew.MainX = cgRes.MainX + RandomHelper.Normal(0, 500);
  578. cgResNew.MainY = cgRes.MainY + RandomHelper.Normal(0, 500);
  579. cgResNew.MainZ = cgRes.MainZ + RandomHelper.Normal(0, 500);
  580. cgResNew.Adja1X = cgRes.Adja1X + RandomHelper.Normal(0, 500);
  581. cgResNew.Adja1Y = cgRes.Adja1Y + RandomHelper.Normal(0, 500);
  582. cgResNew.Adja1Z = cgRes.Adja1Z + RandomHelper.Normal(0, 500);
  583. cgResNew.Adja2X = cgRes.Adja2X + RandomHelper.Normal(0, 500);
  584. cgResNew.Adja2Y = cgRes.Adja2Y + RandomHelper.Normal(0, 500);
  585. cgResNew.Adja2Z = cgRes.Adja2Z + RandomHelper.Normal(0, 500);
  586. cgResNew.Dto1 = (cgRes.Dto1 * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  587. cgResNew.Dto2 = (cgRes.Dto2 * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  588. cgResNew.YbMainDto = (cgRes.YbMainDto * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  589. cgResNew.YbAdja1Dto = (cgRes.YbAdja1Dto * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  590. cgResNew.YbAdja2Dto = (cgRes.YbAdja2Dto * 1e6 + RandomHelper.Normal(0, 4)) / 1e6;
  591. res = X3Dto_GzPos(cgResNew, sRes);
  592. var posResNew = ConvertToGeoPoint(res);
  593. if (IsGeoPoint2(posResNew))
  594. {
  595. var distance = PhysicsHelper.DistanceGeo((posResGz[0], posResGz[1], 0), (posResNew[0], posResNew[1], 0));
  596. if (distance <= confidenceDistance)
  597. {
  598. succeedCount++;
  599. }
  600. }
  601. }
  602. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  603. }
  604. else
  605. {
  606. posRes[6] = 0;
  607. }
  608. }
  609. return posRes;
  610. }
  611. /// <summary>
  612. /// 三星双时差无参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  613. /// </summary>
  614. /// <param name="cgRes">参估结果</param>
  615. /// <param name="sRes">站点信息</param>
  616. /// <param name="CalcConfidence">是否计算置信度</param>
  617. /// <returns></returns>
  618. public static double[] X3_PosNoRef(CgRes cgRes, StationRes sRes, double[] zone, bool CalcConfidence = false)
  619. {
  620. if (cgRes.Dto1.Value == 0 || cgRes.Dto2.Value == 0)
  621. {
  622. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  623. }
  624. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  625. double[] adjaSat1 = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  626. double[] adjaSat2 = new double[3] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value };
  627. if (zone == null)
  628. {
  629. zone = new double[] { -85, 85, -180, 180 }; //定位区域
  630. }
  631. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  632. var tarDto1 = cgRes.Dto1.Value / 1e6;
  633. var tarDto2 = cgRes.Dto2.Value / 1e6;
  634. double[] res = new double[6];
  635. X3_PosNoRef20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation, zone, tarDto1, tarDto2, res);
  636. ConvertToGeoPoint(res);
  637. var posRes = ConvertToGeoPoint(res);
  638. if (CalcConfidence && IsGeoPoint2(posRes))
  639. {
  640. int succeedCount = 0;
  641. for (int i = 0; i < confidenceCount; i++)
  642. {
  643. var mainSatNew = new double[3]
  644. {
  645. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  646. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  647. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  648. };
  649. var adjaSat1New = new double[3]
  650. {
  651. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  652. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  653. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  654. };
  655. var adjaSat2New = new double[3]
  656. {
  657. cgRes.Adja2X.Value+RandomHelper.Normal(0,200),
  658. cgRes.Adja2Y.Value+RandomHelper.Normal(0,200),
  659. cgRes.Adja2Z.Value+RandomHelper.Normal(0,200)
  660. };
  661. var tarDto1New = (tarDto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  662. var tarDto2New = (tarDto2 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  663. X3_PosNoRef20240305_Core(mainSatNew, adjaSat1New, adjaSat2New, satStation, satStation, satStation, zone, tarDto1New, tarDto2New, res);
  664. var posResNew = ConvertToGeoPoint(res);
  665. if (IsGeoPoint2(posResNew))
  666. {
  667. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  668. if (distance <= confidenceDistance)
  669. {
  670. succeedCount++;
  671. }
  672. }
  673. }
  674. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  675. }
  676. return posRes;
  677. }
  678. /// <summary>
  679. /// 三星双频差带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  680. /// </summary>
  681. /// <param name="cgRes">参估结果</param>
  682. /// <param name="sRes">站点信息</param>
  683. /// <param name="CalcConfidence">是否计算置信度</param>
  684. /// <returns></returns>
  685. public static double[] X3_PosTwoDfo(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  686. {
  687. if (cgRes.Dfo1.Value == 0 || cgRes.Dfo2.Value == 0) return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  688. double[] mainSat = new double[6] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value, cgRes.MainVx.Value, cgRes.MainVy.Value, cgRes.MainVz.Value };
  689. double[] adjaSat1 = new double[6] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value, cgRes.Adja1Vx.Value, cgRes.Adja1Vy.Value, cgRes.Adja1Vz.Value };
  690. double[] adjaSat2 = new double[6] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value, cgRes.Adja2Vx.Value, cgRes.Adja2Vy.Value, cgRes.Adja2Vz.Value };
  691. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  692. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  693. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  694. var tarDfo1 = cgRes.Dfo1.Value;
  695. var tarDfo2 = cgRes.Dfo2.Value;
  696. var refDfo1 = cgRes.YbMainDfo.Value - cgRes.YbAdja1Dfo.Value;
  697. var refDfo2 = cgRes.YbMainDfo.Value - cgRes.YbAdja2Dfo.Value;
  698. double fu1 = cgRes.TarFreqUp.Value;
  699. double fd1 = cgRes.TarFreqDown.Value;
  700. double fu2 = cgRes.RefFreqUp.Value;
  701. double fd2 = cgRes.RefFreqDown.Value;
  702. double[] res = new double[6];
  703. X3_PosTwoDfo20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation,
  704. refStation, zone, tarDfo1, tarDfo2, refDfo1, refDfo2, fu1, fd1, fu2, fd2, res);
  705. ConvertToGeoPoint(res);
  706. var posRes = ConvertToGeoPoint(res);
  707. if (CalcConfidence && IsGeoPoint2(posRes))
  708. {
  709. int succeedCount = 0;
  710. for (int i = 0; i < confidenceCount; i++)
  711. {
  712. var mainSatNew = new double[3]
  713. {
  714. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  715. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  716. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  717. };
  718. var adjaSat1New = new double[3]
  719. {
  720. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  721. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  722. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  723. };
  724. var adjaSat2New = new double[3]
  725. {
  726. cgRes.Adja2X.Value+RandomHelper.Normal(0,200),
  727. cgRes.Adja2Y.Value+RandomHelper.Normal(0,200),
  728. cgRes.Adja2Z.Value+RandomHelper.Normal(0,200)
  729. };
  730. var tarDfo1New = (tarDfo1 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  731. var tarDfo2New = (tarDfo2 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  732. var refDfo1New = (refDfo1 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  733. var refDfo2New = (refDfo2 * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  734. X3_PosTwoDfo20240305_Core(mainSatNew, adjaSat1New, adjaSat2New, satStation, satStation, satStation, refStation, zone, tarDfo1New, tarDfo2New, refDfo1New, refDfo2New, fu1, fd1, fu2, fd2, res);
  735. var posResNew = ConvertToGeoPoint(res);
  736. if (IsGeoPoint2(posResNew))
  737. {
  738. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  739. if (distance <= confidenceDistance)
  740. {
  741. succeedCount++;
  742. }
  743. }
  744. }
  745. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  746. }
  747. return posRes;
  748. }
  749. /// <summary>
  750. /// 双星时频差带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  751. /// </summary>
  752. /// <param name="cgRes">参估结果</param>
  753. /// <param name="sRes">站点信息</param>
  754. /// <param name="CalcConfidence">是否计算置信度</param>
  755. /// <returns></returns>
  756. public static double[] X2_PosDtoDfo(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  757. {
  758. if (cgRes.Dto1.Value == 0) return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  759. double[] mainSat = new double[6] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value, cgRes.MainVx.Value, cgRes.MainVy.Value, cgRes.MainVz.Value };
  760. double[] adjaSat = new double[6] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value, cgRes.Adja1Vx.Value, cgRes.Adja1Vy.Value, cgRes.Adja1Vz.Value };
  761. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  762. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  763. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  764. var tarDto = cgRes.Dto1.Value / 1e6;
  765. var tarDfo = cgRes.Dfo1.Value;
  766. var refDto = (cgRes.YbMainDto.Value - cgRes.YbAdja1Dto.Value) / 1e6;
  767. var refDfo = cgRes.YbMainDfo.Value - cgRes.YbAdja1Dfo.Value;
  768. double fu1 = cgRes.TarFreqUp.Value;
  769. double fd1 = cgRes.TarFreqDown.Value;
  770. double fu2 = cgRes.RefFreqUp.Value;
  771. double fd2 = cgRes.RefFreqDown.Value;
  772. double[] res = new double[6];
  773. X2_Pos20240305_Core(mainSat, adjaSat, satStation, satStation, refStation, zone, tarDto, tarDfo, refDto, refDfo, fu1, fd1, fu2, fd2, res);
  774. ConvertToGeoPoint(res);
  775. var posRes = ConvertToGeoPoint(res);
  776. if (CalcConfidence && IsGeoPoint2(posRes))
  777. {
  778. int succeedCount = 0;
  779. for (int i = 0; i < confidenceCount; i++)
  780. {
  781. var mainSatNew = new double[3]
  782. {
  783. cgRes.MainX.Value+RandomHelper.Normal(0,200),
  784. cgRes.MainY.Value+RandomHelper.Normal(0,200),
  785. cgRes.MainZ.Value+RandomHelper.Normal(0,200)
  786. };
  787. var adjaSatNew = new double[3]
  788. {
  789. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  790. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  791. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  792. };
  793. var tarDtoNew = (tarDto * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  794. var refDtoNew = (refDto * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  795. var tarDfoNew = (tarDfo * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  796. var refDfoNew = (refDfo * 1e6 + RandomHelper.Normal(0, 5)) / 1e6;
  797. X2_Pos20240305_Core(mainSatNew, adjaSatNew, satStation, satStation, refStation, zone, tarDtoNew, tarDfoNew, refDtoNew, refDfoNew, fu1, fd1, fu2, fd2, res);
  798. var posResNew = ConvertToGeoPoint(res);
  799. if (IsGeoPoint2(posResNew))
  800. {
  801. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  802. if (distance <= confidenceDistance)
  803. {
  804. succeedCount++;
  805. }
  806. }
  807. }
  808. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  809. }
  810. return posRes;
  811. }
  812. private static double[] ConvertToGeoPoint(double[] res)
  813. {
  814. if (res == null || res.Length == 0)
  815. {
  816. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  817. }
  818. else if (res.Length != 3 && res.Length != 6)
  819. {
  820. throw new Exception("定位结果解析异常,长度不是3或6");
  821. }
  822. var list = res.Select(p => Math.Round(p, 4)).ToArray();
  823. if (list.Length == 3)
  824. {
  825. list = list.Concat(new double[4] { 999, 999, 0, -1 }).ToArray();
  826. }
  827. list[2] = list[5] = 0;//高度
  828. if (double.IsNaN(list[0]) || double.IsNaN(list[1]))
  829. {
  830. list[0] = list[1] = 999;
  831. }
  832. if (double.IsNaN(list[3]) || double.IsNaN(list[4]))
  833. {
  834. list[3] = list[4] = 999;
  835. }
  836. if (list[0] < -180 || list[0] > 180)
  837. {
  838. list[0] = list[1] = 999;
  839. }
  840. else if (list[1] < -90 || list[1] > 90)
  841. {
  842. list[0] = list[1] = 999;
  843. }
  844. if (list[3] < -180 || list[3] > 180)
  845. {
  846. list[3] = list[4] = 999;
  847. }
  848. else if (list[4] < -90 || list[4] > 90)
  849. {
  850. list[3] = list[4] = 999;
  851. }
  852. if (list.Length == 6)
  853. {
  854. var listNew = list.ToList();
  855. listNew.Add(-1);
  856. list = listNew.ToArray();
  857. }
  858. if (list[1] < 0 && list[4] > 0 && list[4] != 999)
  859. {
  860. //交换镜像点
  861. var tmpLon = list[3];
  862. var tmpLat = list[4];
  863. list[3] = list[0];
  864. list[4] = list[1];
  865. list[0] = tmpLon;
  866. list[1] = tmpLat;
  867. }
  868. return list;
  869. }
  870. private static bool IsGeoPoint(double[] res)
  871. {
  872. if (res.Length != 3) return false;
  873. if (res[0] < -180 || res[0] > 180)
  874. {
  875. return false;
  876. }
  877. else if (res[1] < -90 || res[1] > 90)
  878. {
  879. return false;
  880. }
  881. return true;
  882. }
  883. private static bool IsGeoPoint2(double[] res)
  884. {
  885. if (res.Length < 3) return false;
  886. if (res[0] < -180 || res[0] > 180)
  887. {
  888. return false;
  889. }
  890. else if (res[1] < -90 || res[1] > 90)
  891. {
  892. return false;
  893. }
  894. return true;
  895. }
  896. }
  897. }