PosApi.cs 46 KB

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