PosApi.cs 18 KB

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