PosApi.cs 48 KB

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