PosApi.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using DevExpress.Drawing.Internal.Fonts.Interop;
  8. using DevExpress.XtraBars.Docking2010.Views.Widget;
  9. using XdCxRhDW.App.Model;
  10. using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;
  11. namespace XdCxRhDW.App.Api
  12. {
  13. /// <summary>
  14. ///TODO 定位算法接口.在这里调用罗博士的算法库
  15. /// </summary>
  16. public static class PosApi
  17. {
  18. #region cpp dll Interop
  19. //一星一地测向带参定位
  20. private const string XDCX = @"AddIns\DLL_DTO_DOA_DW.dll";
  21. //两星一地带参定位
  22. private const string X2D1 = @"AddIns\DLL_SC_2X1D_DW.dll";
  23. //三星双时差带参、三星双时差无参、三星双频差带参、双星时频差带参、两星一地无参
  24. private const string OtherPos = @"AddIns\DLL_11J.dll";
  25. [DllImport(XDCX, EntryPoint = "XD_CX_DW", CallingConvention = CallingConvention.Cdecl)]//一星一地测向带参
  26. 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);
  27. [DllImport(X2D1, EntryPoint = "SC_2X1D_DW", CallingConvention = CallingConvention.Cdecl)]//两星一地带参
  28. private extern static void X2D1_Pos20240305_Core(double[] mainSat, double[] adjaSat, double[] cdbStation, double[] satStation1, double[] satStation2, double[] satStation3, double[] satStation4,
  29. double[] satStation5, double[] refStation, double[] zone, double tarSxDto, double tarXdDto, double samp_main_dto, double samp_neigh_dto, double[] res);
  30. [DllImport(OtherPos, EntryPoint = "XingDi_2X1D_DW_NoRef", CallingConvention = CallingConvention.Cdecl)]//两星一地无参
  31. private extern static void X2D1_PosNoRef20240305_Core(double[] mainSat, double[] adjaSat, double[] cdbStation, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  32. , double[] zone, double tarSxDto, double tarXdDto, double[] res);
  33. [DllImport(OtherPos, EntryPoint = "SanXing_DW", CallingConvention = CallingConvention.Cdecl)]//三星双时差带参
  34. private extern static void X3_Pos20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  35. , double[] mainSatRefStation, double[] adjaSat1RefStation, double[] adjaSat2RefStation, double[] refStation, double[] zone, double tarDto1, double tarDto2, double refDto1, double refDto2, double[] res);
  36. [DllImport(OtherPos, EntryPoint = "SanXing_DW_NoRef", CallingConvention = CallingConvention.Cdecl)]//三星双时差无参
  37. private extern static void X3_PosNoRef20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  38. , double[] zone, double tarDto1, double tarDto2, double[] res);
  39. [DllImport(OtherPos, EntryPoint = "TriStar_2DFO_DW", CallingConvention = CallingConvention.Cdecl)]//三星双频差带参
  40. private extern static void X3_PosTwoDfo20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  41. , double[] refStation, double[] zone, double tarDfo1, double tarDfo2, double refDfo1, double refDfo2, double fu1, double fd1, double fu2, double fd2, double[] res);
  42. [DllImport(OtherPos, EntryPoint = "TwoStar_DTFO_DW", CallingConvention = CallingConvention.Cdecl)]//双星时频差带参
  43. private extern static void X2_Pos20240305_Core(double[] mainSat, double[] adjaSat, double[] mainSatTarStation, double[] adjaSatTarStation, double[] refStation, double[] zone
  44. , double tarDto, double tarDfo, double refDto, double refDfo, double fu1, double fd1, double fu2, double fd2, double[] res);
  45. private const string XdtsDll = @"Api\时差线\Positioning.dll";
  46. [DllImport(XdtsDll, EntryPoint = "CurveByTwoTDOA", CallingConvention = CallingConvention.Cdecl)]//星地时差线
  47. public extern static void CurveByTwoTDOA(double[] main_sat_pos, double[] neigh_sat_pos, double[] rec1_pos, double[] rec2_pos, double[] ref_pos, double[] Zone,
  48. double target_dto, double ref_dto, out IntPtr LOP_Value, ref int LOP_Len);
  49. #endregion
  50. /// <summary>
  51. /// 一星一地带参,返返回经度纬度高度及镜像点,数组长度为6
  52. /// </summary>
  53. /// <param name="cgRes">参估结果</param>
  54. /// <param name="sRes">站点信息</param>
  55. /// <param name="cxRes">测向结果</param>
  56. /// <returns></returns>
  57. public static double[] X1D1_Pos(CgRes cgRes, StationRes sRes, CxRes cxRes)
  58. {
  59. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  60. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  61. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  62. double[] cxStation = new double[3] { sRes.CxLon.Value, sRes.CxLat.Value, 0 };
  63. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  64. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  65. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  66. double theta = cxRes.Fx;//单位°
  67. double[] res = new double[6];
  68. var ybDto1 = cgRes.YbMainDto.Value / 1e6;
  69. X1D1_Pos20240305_Core(mainSat, satStation, cdbStation, cxStation, refStation, zone, theta, dtoCdb, ybDto1, res);
  70. return ConvertToGeoPoint(res);
  71. }
  72. /// <summary>
  73. /// 两星一地带参,返回经度纬度高度及镜像点,数组长度为6
  74. /// </summary>
  75. /// <param name="cgRes">参估结果</param>
  76. /// <param name="sRes">站点信息</param>
  77. /// <returns></returns>
  78. public static double[] X2D1_Pos(CgRes cgRes, StationRes sRes)
  79. {
  80. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  81. double[] adjaSat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  82. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  83. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  84. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  85. double dto1 = cgRes.Dto1.Value / 1e6;
  86. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  87. double ybDto1 = cgRes.YbMainDto.Value / 1e6;
  88. double ybDto2 = cgRes.YbAdja1Dto.Value / 1e6;
  89. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  90. double[] res = new double[6];
  91. X2D1_Pos20240305_Core(mainSat, adjaSat, cdbStation, satStation, satStation, satStation, satStation, satStation, refStation, zone, dto1, dtoCdb, ybDto1, ybDto2, res);
  92. return ConvertToGeoPoint(res);
  93. }
  94. /// <summary>
  95. /// 两星一地无参,返回经度纬度高度及镜像点,数组长度为6
  96. /// </summary>
  97. /// <param name="cgRes">参估结果</param>
  98. /// <param name="sRes">站点信息</param>
  99. /// <returns></returns>
  100. public static double[] X2D1_PosNoRef(CgRes cgRes, StationRes sRes)
  101. {
  102. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  103. double[] adjaSat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  104. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  105. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  106. double dto1 = cgRes.Dto1.Value / 1e6;
  107. double dtoCdb = cgRes.DtoCdb.Value / 1e6;
  108. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  109. double[] res = new double[6];
  110. X2D1_PosNoRef20240305_Core(mainSat, adjaSat, cdbStation, satStation, satStation, satStation, zone, dto1, dtoCdb, res);
  111. return ConvertToGeoPoint(res);
  112. }
  113. /// <summary>
  114. /// 融合定位带参,返回经度纬度高度及镜像点,数组长度为6
  115. /// </summary>
  116. /// <param name="cgRes">参估结果</param>
  117. /// <param name="sRes">站点信息</param>
  118. /// <param name="cxRes">测向结果</param>
  119. /// <returns></returns>
  120. public static double[] RH_Pos(CgRes cgRes, StationRes sRes, CxRes cxRes)
  121. {
  122. var res1 = X1D1_Pos(cgRes, sRes, cxRes);
  123. var res2 = X2D1_Pos(cgRes, sRes);
  124. double[] res = new double[] { 999, 999, 0, 999, 999, 0 };
  125. var p1 = res1.Take(3).ToArray();
  126. var p2 = res1.Skip(3).ToArray();
  127. var p3 = res2.Take(3).ToArray();
  128. var p4 = res2.Skip(3).ToArray();
  129. if (IsGeoPoint(p1) && IsGeoPoint(p2) && IsGeoPoint(p3) && IsGeoPoint(p4))
  130. {
  131. res = new double[6] {
  132. (p1[0] + p3[0]) / 2 + 0.003,
  133. (p1[1] + p3[1]) / 2 - 0.002,
  134. 0,
  135. (p2[0] + p4[0]) / 2 + 0.003,
  136. (p2[1] + p4[1]) / 2 - 0.002,
  137. 0,
  138. };
  139. }
  140. else if (IsGeoPoint(p1) && IsGeoPoint(p3))
  141. {
  142. res = new double[6] {
  143. (p1[0] + p3[0]) / 2 + 0.003,
  144. (p1[1] + p3[1]) / 2 - 0.002,
  145. 0,
  146. 999,
  147. 999,
  148. 0,
  149. };
  150. }
  151. else if (IsGeoPoint(p1) && IsGeoPoint(p2))
  152. {
  153. res = new double[6]
  154. {
  155. p1[0] + 0.003,
  156. p1[1] - 0.002,
  157. 0,
  158. p2[0] + 0.003,
  159. p2[1] - 0.002,
  160. 0,
  161. };
  162. }
  163. else if (IsGeoPoint(p3) && IsGeoPoint(p4))
  164. {
  165. res = new double[6]
  166. {
  167. p3[0] + 0.003,
  168. p3[1] - 0.002,
  169. 0,
  170. p4[0] + 0.003,
  171. p4[1] - 0.002,
  172. 0,
  173. };
  174. }
  175. return res;
  176. }
  177. /// <summary>
  178. /// 三星双时差带参,返回经度纬度高度及镜像点,数组长度为6
  179. /// </summary>
  180. /// <param name="cgRes">参估结果</param>
  181. /// <param name="sRes">站点信息</param>
  182. /// <returns></returns>
  183. public static double[] X3_Pos(CgRes cgRes, StationRes sRes)
  184. {
  185. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  186. double[] adjaSat1 = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  187. double[] adjaSat2 = new double[3] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value };
  188. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  189. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  190. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  191. var tarDto1 = cgRes.Dto1.Value / 1e6;
  192. var tarDto2 = cgRes.Dto2.Value / 1e6;
  193. var refDto1 = (cgRes.YbMainDto.Value - cgRes.YbAdja1Dto.Value) / 1e6;
  194. var refDto2 = (cgRes.YbMainDto.Value - cgRes.YbAdja2Dto.Value) / 1e6;
  195. double[] res = new double[6];
  196. X3_Pos20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation, satStation,
  197. satStation, satStation, refStation, zone, tarDto1, tarDto2, refDto1, refDto2, res);
  198. return ConvertToGeoPoint(res);
  199. }
  200. /// <summary>
  201. /// 三星双时差无参,返回经度纬度高度及镜像点,数组长度为6
  202. /// </summary>
  203. /// <param name="cgRes">参估结果</param>
  204. /// <param name="sRes">站点信息</param>
  205. /// <returns></returns>
  206. public static double[] X3_PosNoRef(CgRes cgRes, StationRes sRes)
  207. {
  208. double[] mainSat = new double[3] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value };
  209. double[] adjaSat1 = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  210. double[] adjaSat2 = new double[3] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value };
  211. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  212. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  213. var tarDto1 = cgRes.Dto1.Value / 1e6;
  214. var tarDto2 = cgRes.Dto2.Value / 1e6;
  215. double[] res = new double[6];
  216. X3_PosNoRef20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation, zone, tarDto1, tarDto2, res);
  217. return ConvertToGeoPoint(res);
  218. }
  219. /// <summary>
  220. /// 三星双频差带参,返回经度纬度高度及镜像点,数组长度为6
  221. /// </summary>
  222. /// <param name="cgRes">参估结果</param>
  223. /// <param name="sRes">站点信息</param>
  224. /// <returns></returns>
  225. public static double[] X3_PosTwoDfo(CgRes cgRes, StationRes sRes)
  226. {
  227. double[] mainSat = new double[6] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value, cgRes.MainVx.Value, cgRes.MainVy.Value, cgRes.MainVz.Value };
  228. double[] adjaSat1 = new double[6] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value, cgRes.Adja1Vx.Value, cgRes.Adja1Vy.Value, cgRes.Adja1Vz.Value };
  229. double[] adjaSat2 = new double[6] { cgRes.Adja2X.Value, cgRes.Adja2Y.Value, cgRes.Adja2Z.Value, cgRes.Adja2Vx.Value, cgRes.Adja2Vy.Value, cgRes.Adja2Vz.Value };
  230. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  231. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  232. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  233. var tarDfo1 = cgRes.Dfo1.Value;
  234. var tarDfo2 = cgRes.Dfo2.Value;
  235. var refDfo1 = cgRes.YbMainDfo.Value - cgRes.YbAdja1Dfo.Value;
  236. var refDfo2 = cgRes.YbMainDfo.Value - cgRes.YbAdja2Dfo.Value;
  237. double fu1 = cgRes.TarFreqUp.Value;
  238. double fd1 = cgRes.TarFreqDown.Value;
  239. double fu2 = cgRes.RefFreqUp.Value;
  240. double fd2 = cgRes.RefFreqDown.Value;
  241. double[] res = new double[6];
  242. X3_PosTwoDfo20240305_Core(mainSat, adjaSat1, adjaSat2, satStation, satStation, satStation,
  243. refStation, zone, tarDfo1, tarDfo2, refDfo1, refDfo2, fu1, fd1, fu2, fd2, res);
  244. return ConvertToGeoPoint(res);
  245. }
  246. /// <summary>
  247. /// 双星时频差带参,返回经度纬度高度及镜像点,数组长度为6
  248. /// </summary>
  249. /// <param name="cgRes">参估结果</param>
  250. /// <param name="sRes">站点信息</param>
  251. /// <returns></returns>
  252. public static double[] X2_PosDtoDfo(CgRes cgRes, StationRes sRes)
  253. {
  254. double[] mainSat = new double[6] { cgRes.MainX.Value, cgRes.MainY.Value, cgRes.MainZ.Value, cgRes.MainVx.Value, cgRes.MainVy.Value, cgRes.MainVz.Value };
  255. double[] adjaSat = new double[6] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value, cgRes.Adja1Vx.Value, cgRes.Adja1Vy.Value, cgRes.Adja1Vz.Value };
  256. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  257. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  258. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  259. var tarDto = cgRes.Dto1.Value / 1e6;
  260. var tarDfo = cgRes.Dfo1.Value;
  261. var refDto = (cgRes.YbMainDto.Value - cgRes.YbAdja1Dto.Value) / 1e6;
  262. var refDfo = cgRes.YbMainDfo.Value - cgRes.YbAdja1Dfo.Value;
  263. double fu1 = cgRes.TarFreqUp.Value;
  264. double fd1 = cgRes.TarFreqDown.Value;
  265. double fu2 = cgRes.RefFreqUp.Value;
  266. double fd2 = cgRes.RefFreqDown.Value;
  267. double[] res = new double[6];
  268. X2_Pos20240305_Core(mainSat, adjaSat, satStation, satStation, refStation, zone, tarDto, tarDfo, refDto, refDfo, fu1, fd1, fu2, fd2, res);
  269. return ConvertToGeoPoint(res);
  270. }
  271. private static double[] ConvertToGeoPoint(double[] res)
  272. {
  273. if (res == null || res.Length == 0)
  274. {
  275. return new double[6] { 999, 999, 0, 999, 999, 0 };
  276. }
  277. else if (res.Length != 3 && res.Length != 6)
  278. {
  279. throw new Exception("定位结果解析异常,长度不是3或6");
  280. }
  281. var list = res.Select(p => Math.Round(p, 4)).ToArray();
  282. if (list.Length == 3)
  283. {
  284. list = list.Concat(new double[3] { 999, 999, 0 }).ToArray();
  285. }
  286. list[2] = list[5] = 0;//高度
  287. if (list[0] < -180 || list[0] > 180)
  288. {
  289. list[0] = list[1] = 999;
  290. }
  291. else if (list[1] < -90 || list[1] > 90)
  292. {
  293. list[0] = list[1] = 999;
  294. }
  295. if (list[3] < -180 || list[3] > 180)
  296. {
  297. list[3] = list[4] = 999;
  298. }
  299. else if (list[4] < -90 || list[4] > 90)
  300. {
  301. list[3] = list[4] = 999;
  302. }
  303. else if (double.IsNaN(list[3]) || double.IsNaN(list[4]))
  304. {
  305. list[3] = list[4] = 999;
  306. }
  307. return list;
  308. }
  309. private static bool IsGeoPoint(double[] res)
  310. {
  311. if (res.Length != 3) return false;
  312. if (res[0] < -180 || res[0] > 180)
  313. {
  314. return false;
  315. }
  316. else if (res[1] < -90 || res[1] > 90)
  317. {
  318. return false;
  319. }
  320. return true;
  321. }
  322. }
  323. }