PosApi.cs 44 KB

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