PosApi.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.CompilerServices;
  5. using System.Runtime.InteropServices;
  6. using System.Security.Policy;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using DW5S.Entity;
  10. namespace DW5S.KxcApi
  11. {
  12. /// <summary>
  13. ///TODO 定位算法接口.在这里调用罗博士的算法库
  14. /// </summary>
  15. public static class PosApi
  16. {
  17. //置信度统计次数
  18. private static int confidenceCount = 1000;
  19. //置信度有效距离(m)
  20. private static int confidenceDistance = 10000;
  21. #region cpp dll Interop
  22. //两星一地和三星解析定位算法(精度差、速度快,适用于置信度等统计时的多次调用)
  23. private const string gzPos = @"AddIns\定位\DLL_GZDW.dll";
  24. //一星一地测向带参定位
  25. private const string XDCX = @"AddIns\定位\DLL_DTO_DOA_DW.dll";
  26. //三星双时差带参、三星双时差无参、三星双频差带参、双星时频差带参、两星一地无参定位及时差线、一星两地
  27. private const string OtherPos = @"AddIns\定位\Position-New.dll";//DLL_11J_DW
  28. [DllImport(gzPos, EntryPoint = "DW_Analysis", CallingConvention = CallingConvention.Cdecl)]//两星一地和三星的解析定位算法(精度差、速度快)
  29. private extern static void DW_Analysis(double[] mainSatXYZ, double[] adja1XYZ, double[] adja2XYZ, double[] refStation, double tarDto1, double tarDto2, double refDto1, double refDto2, double[] posRes, int flag);
  30. [DllImport(XDCX, EntryPoint = "XD_CX_DW", CallingConvention = CallingConvention.Cdecl)]//一星一地测向带参
  31. private extern static void X1D1_Pos20240305_Core(double[] mainSat, double[] satStation, double[] cdbStation, double[] cxStation, double[] refStation, double[] zone, double theta, double tarDto, double refDto, double[] res);
  32. [DllImport(OtherPos, EntryPoint = "SC_2X1D_DW", CallingConvention = CallingConvention.Cdecl)]//两星一地带参
  33. private extern static void X2D1_Pos20240305_Core(double[] mainSat, double[] adjaSat, double[] cdbStation, double[] satStation1, double[] satStation2, double[] satStation3, double[] satStation4,
  34. double[] satStation5, double[] refStation, double[] zone, double tarSxDto, double tarXdDto, double samp_main_dto, double samp_neigh_dto, double[] res);
  35. [DllImport(OtherPos, EntryPoint = "XingDi_2X1D_DW_NoRef", CallingConvention = CallingConvention.Cdecl)]//两星一地无参
  36. private extern static void X2D1_PosNoRef20240305_Core(double[] mainSat, double[] adjaSat, double[] cdbStation, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  37. , double[] zone, double tarSxDto, double tarXdDto, double[] res);
  38. [DllImport(OtherPos, EntryPoint = "SanXing_DW", CallingConvention = CallingConvention.Cdecl)]//三星双时差带参
  39. private extern static void X3_Pos20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  40. , double[] mainSatRefStation, double[] adjaSat1RefStation, double[] adjaSat2RefStation, double[] refStation, double[] zone, double tarDto1, double tarDto2, double refDto1, double refDto2, double[] res);
  41. [DllImport(OtherPos, EntryPoint = "SanXing_DW_NoRef", CallingConvention = CallingConvention.Cdecl)]//三星双时差无参
  42. private extern static void X3_PosNoRef20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  43. , double[] zone, double tarDto1, double tarDto2, double[] res);
  44. [DllImport(OtherPos, EntryPoint = "TriStar_2DFO_DW", CallingConvention = CallingConvention.Cdecl)]//三星双频差带参
  45. private extern static void X3_PosTwoDfo20240305_Core(double[] mainSat, double[] adjaSat1, double[] adjaSat2, double[] mainSatTarStation, double[] adjaSat1TarStation, double[] adjaSat2TarStation
  46. , double[] refStation, double[] zone, double tarDfo1, double tarDfo2, double refDfo1, double refDfo2, double fu1, double fd1, double fu2, double fd2, double[] res);
  47. [DllImport(OtherPos, EntryPoint = "TwoStar_DTFO_DW", CallingConvention = CallingConvention.Cdecl)]//双星时频差带参
  48. private extern static void X2_Pos20240305_Core(double[] mainSat, double[] adjaSat, double[] mainSatTarStation, double[] adjaSatTarStation, double[] refStation, double[] zone
  49. , double tarDto, double tarDfo, double refDto, double refDfo, double fu1, double fd1, double fu2, double fd2, double[] res);
  50. #endregion
  51. /// <summary>
  52. /// 一星一地带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  53. /// </summary>
  54. /// <param name="cgRes">参估结果</param>
  55. /// <param name="sRes">站点信息</param>
  56. /// <param name="cxRes">测向结果</param>
  57. /// <param name="CalcConfidence">是否计算置信度</param>
  58. /// <returns></returns>
  59. public static double[] X1D1_Pos(CgRes cgRes, StationRes sRes, CxRes cxRes, bool CalcConfidence = false)
  60. {
  61. if (cgRes.Snr1 == 0) return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  62. if (cgRes.RefYbDto1 == null) return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  63. double[] mainSat = new double[3] { cgRes.MainX, cgRes.MainY, cgRes.MainZ };
  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.Dto1 / 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.RefYbDto1.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+RandomHelper.Normal(0,200),
  83. cgRes.MainY+RandomHelper.Normal(0,200),
  84. cgRes.MainZ+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.Snr1 == 0 || cgRes.Snr2 == 0)
  113. {
  114. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  115. }
  116. double[] mainSat = new double[3] { cgRes.MainX, cgRes.MainY, cgRes.MainZ };
  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 / 1e6;
  121. double dtoCdb = cgRes.Dto2.Value / 1e6;
  122. double ybDto1 = cgRes.RefYbDto1.Value / 1e6;
  123. double ybDto2 = cgRes.RefYbDto2.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. /// 两星一地带参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  131. /// </summary>
  132. /// <param name="cgRes">参估结果</param>
  133. /// <param name="sRes">站点信息</param>
  134. /// <param name="CalcConfidence">是否计算置信度</param>
  135. /// <returns></returns>
  136. public static double[] X2D1_Pos(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  137. {
  138. if (cgRes.Snr1 == 0 || cgRes.Snr2 == 0)
  139. {
  140. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  141. }
  142. if (cgRes.RefYbDto1 == null || cgRes.RefYbDto2 == null)
  143. {
  144. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  145. }
  146. double[] mainSat = new double[3] { cgRes.MainX, cgRes.MainY, cgRes.MainZ };
  147. double[] adjaSat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  148. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  149. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  150. double[] refStation = new double[3] { sRes.RefLon.Value, sRes.RefLat.Value, 0 };
  151. double dto1 = cgRes.Dto1 / 1e6;
  152. double dtoCdb = cgRes.Dto2.Value / 1e6;
  153. double ybDto1 = cgRes.RefYbDto1.Value / 1e6;
  154. double ybDto2 = cgRes.RefYbDto2.Value / 1e6;
  155. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  156. double[] res = new double[6];
  157. X2D1_Pos20240305_Core(mainSat, adjaSat, cdbStation, satStation, satStation, satStation, satStation, satStation, refStation, zone, dto1, dtoCdb, ybDto1, ybDto2, res);
  158. ConvertToGeoPoint(res);
  159. var posRes = ConvertToGeoPoint(res);//精确搜索值
  160. if (CalcConfidence && IsGeoPoint2(posRes))
  161. {
  162. var posResGz = X2D1_GzPos(cgRes, sRes);
  163. if (IsGeoPoint2(posResGz))
  164. {
  165. int succeedCount = 0;
  166. var cgResNew = cgRes.Clone();
  167. for (int i = 0; i < confidenceCount; i++)
  168. {
  169. cgResNew.MainX = cgRes.MainX + RandomHelper.Normal(0, 200);
  170. cgResNew.MainY = cgRes.MainY + RandomHelper.Normal(0, 200);
  171. cgResNew.MainZ = cgRes.MainZ + RandomHelper.Normal(0, 200);
  172. cgResNew.Adja1X = cgRes.Adja1X + RandomHelper.Normal(0, 200);
  173. cgResNew.Adja1Y = cgRes.Adja1Y + RandomHelper.Normal(0, 200);
  174. cgResNew.Adja1Z = cgRes.Adja1Z + RandomHelper.Normal(0, 200);
  175. cgResNew.Dto1 = (cgRes.Dto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  176. cgResNew.Dto2 = (cgRes.Dto2 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  177. cgResNew.RefYbDto1 = (cgRes.RefYbDto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  178. cgResNew.RefYbDto2 = (cgRes.RefYbDto2 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  179. res = X2D1_GzPos(cgResNew, sRes);
  180. var posResNew = ConvertToGeoPoint(res);
  181. if (IsGeoPoint2(posResNew))
  182. {
  183. var distance = PhysicsHelper.DistanceGeo((posResGz[0], posResGz[1], 0), (posResNew[0], posResNew[1], 0));
  184. if (distance <= confidenceDistance)
  185. {
  186. succeedCount++;
  187. }
  188. }
  189. }
  190. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  191. }
  192. else
  193. {
  194. posRes[6] = 0;
  195. }
  196. }
  197. return posRes;
  198. }
  199. /// <summary>
  200. /// 两星一地无参,返回经度、纬度、高度、镜像点、置信度,数组长度为7
  201. /// </summary>
  202. /// <param name="cgRes">参估结果</param>
  203. /// <param name="sRes">站点信息</param>
  204. /// <param name="CalcConfidence">是否计算置信度</param>
  205. /// <returns></returns>
  206. public static double[] X2D1_PosNoRef(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  207. {
  208. if (cgRes.Snr1 == 0 || cgRes.Snr2 == 0)
  209. {
  210. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  211. }
  212. double[] mainSat = new double[3] { cgRes.MainX, cgRes.MainY, cgRes.MainZ };
  213. double[] adjaSat = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  214. double[] satStation = new double[3] { sRes.SatTxLon, sRes.SatTxLat, 0 };
  215. double[] cdbStation = new double[3] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value, 0 };
  216. double dto1 = cgRes.Dto1 / 1e6;
  217. double dtoCdb = cgRes.Dto2.Value / 1e6;
  218. double[] zone = new double[] { -85, 85, -180, 180 }; //定位区域
  219. double[] res = new double[6];
  220. X2D1_PosNoRef20240305_Core(mainSat, adjaSat, cdbStation, satStation, satStation, satStation, zone, dto1, dtoCdb, res);
  221. var posRes = ConvertToGeoPoint(res);
  222. if (CalcConfidence && IsGeoPoint2(posRes))
  223. {
  224. int succeedCount = 0;
  225. for (int i = 0; i < confidenceCount; i++)
  226. {
  227. var mainSatNew = new double[3]
  228. {
  229. cgRes.MainX+RandomHelper.Normal(0,200),
  230. cgRes.MainY+RandomHelper.Normal(0,200),
  231. cgRes.MainZ+RandomHelper.Normal(0,200)
  232. };
  233. var adjaSatNew = new double[3]
  234. {
  235. cgRes.Adja1X.Value+RandomHelper.Normal(0,200),
  236. cgRes.Adja1Y.Value+RandomHelper.Normal(0,200),
  237. cgRes.Adja1Z.Value+RandomHelper.Normal(0,200)
  238. };
  239. var dto1New = (dto1 * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  240. var dtoCdbNew = (dtoCdb * 1e6 + RandomHelper.Normal(0, 1)) / 1e6;
  241. X2D1_PosNoRef20240305_Core(mainSatNew, adjaSatNew, cdbStation, satStation, satStation, satStation, zone, dto1New, dtoCdbNew, res);
  242. var posResNew = ConvertToGeoPoint(res);
  243. if (IsGeoPoint2(posResNew))
  244. {
  245. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  246. if (distance <= confidenceDistance)
  247. {
  248. succeedCount++;
  249. }
  250. }
  251. }
  252. posRes[6] = (int)(succeedCount / (double)confidenceCount * 100);
  253. }
  254. return posRes;
  255. }
  256. public static double[] X2D1_PosNoRef_ZL(CgRes cgRes, StationRes sRes, bool CalcConfidence = false)
  257. {
  258. if (cgRes.Snr1 == 0 || cgRes.Snr2 == 0)
  259. {
  260. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  261. }
  262. var cdbStation = new double[2] { sRes.CdbTxLon.Value, sRes.CdbTxLat.Value };
  263. var satStation = new double[2] { sRes.SatTxLon, sRes.SatTxLat };
  264. var mainXYZ = new double[3] { cgRes.MainX, cgRes.MainY, cgRes.MainZ };
  265. var adjaXYZ = new double[3] { cgRes.Adja1X.Value, cgRes.Adja1Y.Value, cgRes.Adja1Z.Value };
  266. var dtoSxus = cgRes.Dto1;
  267. var dtoXdus = cgRes.Dto2.Value;
  268. var posRes = X2D1_PosNoRefCore_Zl(cdbStation, satStation, mainXYZ, adjaXYZ, dtoSxus, dtoXdus);
  269. posRes = ConvertToGeoPoint(posRes);
  270. if (CalcConfidence && IsGeoPoint2(posRes))
  271. {
  272. int succeedCount = 0;
  273. int totalCount = 100;
  274. for (int i = 0; i < totalCount; i++)
  275. {
  276. var mainSatNew = new double[3]
  277. {
  278. cgRes.MainX+RandomHelper.Normal(0,500),
  279. cgRes.MainY+RandomHelper.Normal(0,500),
  280. cgRes.MainZ+RandomHelper.Normal(0,500)
  281. };
  282. var adjaSatNew = new double[3]
  283. {
  284. cgRes.Adja1X.Value+RandomHelper.Normal(0,500),
  285. cgRes.Adja1Y.Value+RandomHelper.Normal(0,500),
  286. cgRes.Adja1Z.Value+RandomHelper.Normal(0,500)
  287. };
  288. var dtoSxusNew = dtoSxus + RandomHelper.Normal(0, 1);
  289. var dtoXdusNew = dtoXdus + RandomHelper.Normal(0, 1);
  290. var posResNew = X2D1_PosNoRefCore_Zl(cdbStation, satStation, mainSatNew, adjaSatNew, dtoSxusNew, dtoXdusNew);
  291. posResNew = ConvertToGeoPoint(posResNew);
  292. if (IsGeoPoint2(posResNew))
  293. {
  294. var distance = PhysicsHelper.DistanceGeo((posRes[0], posRes[1], 0), (posResNew[0], posResNew[1], 0));
  295. if (distance <= confidenceDistance)
  296. {
  297. succeedCount++;
  298. }
  299. }
  300. }
  301. var confidence = (int)(succeedCount / (double)totalCount * 100);
  302. if (confidence == 0)
  303. confidence = 1;
  304. if (confidence == 100)
  305. confidence = 99;
  306. posRes[6] = confidence;
  307. }
  308. return posRes;
  309. }
  310. private static double[] X2D1_PosNoRefCore_Zl(double[] cdbStation, double[] satStation, double[] mainXYZ, double[] adjaXYZ, double dtoSxus, double dtoXdus)
  311. {
  312. double startLon = (int)cdbStation[0] - 10;
  313. double endLon = (int)cdbStation[0] + 10;
  314. double startLat = (int)cdbStation[1] - 10;
  315. double endLat = (int)cdbStation[1] + 10;
  316. List<(double, double, double, double)> list = new List<(double, double, double, double)>();
  317. var recXYZ = PhysicsHelper.GeoToEcef((satStation[0], satStation[1], 0));
  318. var cdbXYZ = PhysicsHelper.GeoToEcef((cdbStation[0], cdbStation[1], 0));
  319. for (double lon = startLon; lon < endLon; lon += 0.0001)
  320. {
  321. int flag = 0;
  322. for (double lat = startLat; lat < endLat; lat += 0.0001)
  323. {
  324. var posXYZ = PhysicsHelper.GeoToEcef((lon, lat, 0));
  325. //目标-主星-接收站的时间(us)
  326. var dt1 = PhysicsHelper.Dto(posXYZ, (mainXYZ[0], mainXYZ[1], mainXYZ[2]), recXYZ) * 1e6;
  327. //目标-超短站的时间(us)
  328. var dt3 = PhysicsHelper.Dto(posXYZ, cdbXYZ) * 1e6;
  329. var dto2 = Math.Abs(dt1 - dt3 - dtoXdus);
  330. if (dto2 > 400)
  331. {
  332. lat += 1;
  333. if (flag < 1)
  334. flag = 1;
  335. continue;
  336. }
  337. else if (dto2 > 200)
  338. {
  339. lat += 0.5;
  340. if (flag < 2)
  341. flag = 2;
  342. continue;
  343. }
  344. else if (dto2 > 100)
  345. {
  346. lat += 0.2;
  347. if (flag < 3)
  348. flag = 3;
  349. continue;
  350. }
  351. else if (dto2 > 10)
  352. {
  353. lat += 0.01;
  354. if (flag < 4)
  355. flag = 4;
  356. continue;
  357. }
  358. //else if (dto2 > 2)
  359. //{
  360. // lat += 0.001;
  361. // if (flag < 5)
  362. // flag = 5;
  363. // continue;
  364. //}
  365. //目标-邻星-接收站的时间(us)
  366. var dt2 = PhysicsHelper.Dto(posXYZ, (adjaXYZ[0], adjaXYZ[1], adjaXYZ[2]), recXYZ) * 1e6;
  367. var dto1 = Math.Abs(dt1 - dt2 - dtoSxus);
  368. if (dto1 > 400)
  369. {
  370. lat += 1;
  371. if (flag < 1)
  372. flag = 1;
  373. continue;
  374. }
  375. if (dto1 > 200)
  376. {
  377. lat += 0.5;
  378. if (flag < 2)
  379. flag = 2;
  380. continue;
  381. }
  382. else if (dto1 > 100)
  383. {
  384. lat += 0.2;
  385. if (flag < 3)
  386. flag = 3;
  387. continue;
  388. }
  389. else if (dto1 > 10)
  390. {
  391. lat += 0.01;
  392. if (flag < 4)
  393. flag = 4;
  394. continue;
  395. }
  396. //else if (dto1 > 2)
  397. //{
  398. // lat += 0.001;
  399. // if (flag < 5)
  400. // flag = 5;
  401. // continue;
  402. //}
  403. list.Add((lon, lat, dto1, dto2));
  404. }
  405. if (flag == 1)
  406. lon += 1;
  407. else if (flag == 2)
  408. lon += 0.5;
  409. else if (flag == 3)
  410. lon += 0.2;
  411. else if (flag == 4)
  412. lon += 0.01;
  413. else if (flag == 5)
  414. lon += 0.001;
  415. }
  416. double[] posRes;
  417. var p1 = list.OrderBy(p => p.Item4 * p.Item4 + p.Item3 * p.Item3).FirstOrDefault();
  418. if (p1 == default)
  419. {
  420. posRes = new double[6] { 999, 999, 0, 999, 999, 0 };
  421. return posRes;
  422. }
  423. var p2 = list.Where(p => PhysicsHelper.DistanceGeo((p1.Item1, p1.Item2, 0), (p.Item1, p.Item2, 0)) > 10000).OrderBy(p => p.Item4 * p.Item4 + p.Item3 * p.Item3).FirstOrDefault();
  424. if (p2 == default)
  425. posRes = new double[6] { p1.Item1, p1.Item2, 0, 999, 999, 0 };
  426. else
  427. posRes = new double[6] { p1.Item1, p1.Item2, 0, p2.Item1, p2.Item2, 0 };
  428. if (posRes[3] != 999)
  429. {
  430. var dis1 = PhysicsHelper.DistanceArcGeo((posRes[3], posRes[4]), (cdbStation[0], cdbStation[1]));
  431. var dis2 = PhysicsHelper.DistanceArcGeo((posRes[0], posRes[1]), (cdbStation[0], cdbStation[1]));
  432. if (dis1 < dis2)
  433. {
  434. var tmp1 = posRes[3];
  435. var tmp2 = posRes[4];
  436. posRes[3] = posRes[0];
  437. posRes[4] = posRes[1];
  438. posRes[0] = tmp1;
  439. posRes[1] = tmp2;
  440. }
  441. }
  442. return posRes;
  443. }
  444. private static double[] ConvertToGeoPoint(double[] res)
  445. {
  446. if (res == null || res.Length == 0)
  447. {
  448. return new double[7] { 999, 999, 0, 999, 999, 0, -1 };
  449. }
  450. else if (res.Length != 3 && res.Length != 6)
  451. {
  452. throw new Exception("定位结果解析异常,长度不是3或6");
  453. }
  454. var list = res.Select(p => Math.Round(p, 4)).ToArray();
  455. if (list.Length == 3)
  456. {
  457. list = list.Concat(new double[4] { 999, 999, 0, -1 }).ToArray();
  458. }
  459. list[2] = list[5] = 0;//高度
  460. if (double.IsNaN(list[0]) || double.IsNaN(list[1]))
  461. {
  462. list[0] = list[1] = 999;
  463. }
  464. if (double.IsNaN(list[3]) || double.IsNaN(list[4]))
  465. {
  466. list[3] = list[4] = 999;
  467. }
  468. if (list[0] < -180 || list[0] > 180)
  469. {
  470. list[0] = list[1] = 999;
  471. }
  472. else if (list[1] < -90 || list[1] > 90)
  473. {
  474. list[0] = list[1] = 999;
  475. }
  476. if (list[3] < -180 || list[3] > 180)
  477. {
  478. list[3] = list[4] = 999;
  479. }
  480. else if (list[4] < -90 || list[4] > 90)
  481. {
  482. list[3] = list[4] = 999;
  483. }
  484. if (list.Length == 6)
  485. {
  486. var listNew = list.ToList();
  487. listNew.Add(-1);
  488. list = listNew.ToArray();
  489. }
  490. return list;
  491. }
  492. private static bool IsGeoPoint(double[] res)
  493. {
  494. if (res.Length != 3) return false;
  495. if (res[0] < -180 || res[0] > 180)
  496. {
  497. return false;
  498. }
  499. else if (res[1] < -90 || res[1] > 90)
  500. {
  501. return false;
  502. }
  503. return true;
  504. }
  505. private static bool IsGeoPoint2(double[] res)
  506. {
  507. if (res.Length < 3) return false;
  508. if (res[0] < -180 || res[0] > 180)
  509. {
  510. return false;
  511. }
  512. else if (res[1] < -90 || res[1] > 90)
  513. {
  514. return false;
  515. }
  516. return true;
  517. }
  518. }
  519. }