GeDianShengCheng.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. using BHJD.DEMdll.Public;
  2. using Unity.Mathematics;
  3. namespace QuYuSaoMiao
  4. {
  5. public class GeDianShengCheng
  6. {
  7. public static DemHelper DemHelper()
  8. {
  9. IDbHelper db = Factory.Load("10.130.100.5", "5432", "postgres", "postgres", "rescue_patrol_platform");
  10. DemHelper ddemHelper = new DemHelper(db);
  11. return ddemHelper;
  12. }
  13. public static double[,] MaxMinPoly(List<double[]> poly) //多边形矩形边界
  14. {
  15. List<double> PolyLon = new List<double>();
  16. List<double> PolyLat = new List<double>();
  17. foreach (double[] element in poly)
  18. {
  19. PolyLon.Add(element[0]);
  20. PolyLat.Add(element[1]);
  21. }
  22. double[,] MM1 = new double[2, 2];
  23. MM1[0, 0] = PolyLon.Min(); //经度最小(西界)
  24. MM1[0, 1] = PolyLon.Max(); //经度最大(东界)
  25. MM1[1, 0] = PolyLat.Min(); //纬度最小(南界)
  26. MM1[1, 1] = PolyLat.Max(); //纬度最大(北界)
  27. return MM1;
  28. }
  29. public static bool isinpoly(double[] zuobiao, List<double[]> poly, DemHelper demHelper) //已经替换成在边界内算法
  30. {
  31. double[,] polyOut = MaxMinPoly(poly);
  32. if (zuobiao[0] <= polyOut[0, 0] || zuobiao[0] >= polyOut[0, 1] || zuobiao[1] <= polyOut[1, 0] ||
  33. zuobiao[1] >= polyOut[1, 1])
  34. {
  35. return false;
  36. }
  37. else
  38. {
  39. string polystring = "MULTIPOLYGON(((";
  40. foreach (double[] element in poly)
  41. {
  42. double e0 = element[0];
  43. double e1 = element[1];
  44. polystring = polystring + element[0] + " " + element[1] + ",";
  45. }
  46. polystring = polystring + poly[0][0] + " " + poly[0][1] + ")))";
  47. string pointstring = "POINT (" + zuobiao[0] + " " + zuobiao[1] + ")";
  48. // Console.WriteLine("isinpoly?");
  49. //Console.WriteLine(pointstring+polystring);
  50. string r1 = demHelper.doDetermine(pointstring, polystring);
  51. // Console.WriteLine(r1);
  52. //double[,] polyOut = MaxMinPoly(poly);
  53. //if (zuobiao[0] <= polyOut[0, 0] || zuobiao[0] >= polyOut[0, 1] || zuobiao[1] <= polyOut[1, 0] || zuobiao[1] >= polyOut[1, 1])
  54. // { return false; }
  55. // else
  56. //{
  57. return (r1 == "True" ? true : false);
  58. // }
  59. }
  60. }
  61. //格点生成方法:输入前四个为经纬度上下限,数组为多边形,后两个是经纬度分辨率。输出0经,1纬,2高,3是否被侦察的【01】变量。
  62. public static List<double[]> NPGenerate(double lonmin, double lonmax, double latmin, double latmax,
  63. List<double[]> juxing, double netscalelon, double netscalelat, DemHelper demHelper)
  64. {
  65. Console.WriteLine("格点生成");
  66. List<double[]> netpoints = new List<double[]>();
  67. for (double[] netpointprev = new double[3] { lonmin, latmax, 0 };
  68. netpointprev[1] >= latmin;
  69. netpointprev[1] = netpointprev[1] - netscalelat)
  70. {
  71. for (netpointprev[0] = lonmin;
  72. netpointprev[0] <= lonmax;
  73. netpointprev[0] = netpointprev[0] + netscalelon)
  74. {
  75. if (isinpoly(netpointprev, juxing, demHelper) == true)
  76. {
  77. double HH = 0; //需要替换为该点【netpointprev[0], netpointprev[1]】高程
  78. double[] netpointtemp = new double[3] { netpointprev[0], netpointprev[1], HH };
  79. //netpointtemp = netpointprev;
  80. netpoints.Add(netpointtemp);
  81. }
  82. }
  83. }
  84. return netpoints;
  85. }
  86. //格点初始化
  87. public static List<bool> NPprem(List<double[]> NPcoo)
  88. {
  89. List<bool> NPprem0 = new List<bool>();
  90. int i = 0;
  91. foreach (double[] element in NPcoo)
  92. {
  93. //object[] NPrentemp = new object[4] { element[0], element[1], element[2], false };
  94. NPprem0.Add(false);
  95. i++;
  96. }
  97. return NPprem0;
  98. }
  99. //格点显示,可以不用
  100. public static void ListPoints(List<double[]> NPtoRead)
  101. {
  102. int i1 = 0;
  103. int i2 = 0;
  104. int i3;
  105. int irow;
  106. int iLine = 1;
  107. Console.Write("{");
  108. foreach (double[] element in NPtoRead)
  109. {
  110. if (i1 != 0 && element[1] != NPtoRead[i1 - 1][1])
  111. {
  112. i3 = i1 - 1;
  113. irow = i3 - i2 + 1;
  114. i2 = i1;
  115. iLine++;
  116. Console.Write("<本行格点数:" + irow + ">}" + Environment.NewLine + "{");
  117. }
  118. string lontax = element[0].ToString("F5");
  119. string lattax = element[1].ToString("F5");
  120. Console.Write("【E" + lontax + " | N" + lattax + " | h" + element[2] + "】\t");
  121. i1++;
  122. }
  123. i3 = i1 - 1;
  124. irow = i3 - i2 + 1;
  125. i2 = i1;
  126. Console.Write("<本行格点数:" + irow + ">}" + Environment.NewLine);
  127. int numberP = NPtoRead.Count;
  128. Console.WriteLine("行数:" + iLine + ";格点数量:" + numberP);
  129. }
  130. //两点间距计算,输出米
  131. public static double distance(double[] P1, double[] P2, DemHelper demHelper)
  132. {
  133. //double DL = 6371.004 * Math.Acos(Math.Sin(Math.PI / 180 * P1[1]) * Math.Sin(Math.PI / 180 * P2[1]) + Math.Cos(Math.PI / 180 * P1[1]) * Math.Cos(Math.PI / 180 * P2[1]) * Math.Cos(Math.PI / 180 * (P1[0] - P2[0]))) * 1000;
  134. //double D = Math.Pow(Math.Pow(DL, 2) + Math.Pow(P1[2] - P2[2], 2), 0.5);
  135. //return D;
  136. double3 p1 = new double3();
  137. double3 p2 = new double3();
  138. p1.x = P1[0];
  139. p1.y = P1[1];
  140. p1.z = P1[2];
  141. p2.x = P2[0];
  142. p2.y = P2[1];
  143. p2.z = P2[2];
  144. double D1 = demHelper.getDistance(p1, p2);
  145. //double DD1 = D1;
  146. //Console.WriteLine("距离:" + D1);
  147. return D1;
  148. }
  149. //两点间高度角计算,从P1到P2
  150. public static double angleH(double[] P1, double[] P2, DemHelper demHelper)
  151. {
  152. if (P1[2] == P2[2])
  153. {
  154. return 0;
  155. }
  156. else if (P1[0] == P2[0] && P1[1] == P2[1])
  157. {
  158. if (P1[2] < P2[2])
  159. {
  160. return 90;
  161. }
  162. else
  163. {
  164. return -90;
  165. }
  166. }
  167. else
  168. {
  169. //if (P1[2] < P2[2])
  170. //{
  171. double angleH = Math.Asin((P2[2] - P1[2]) / distance(P1, P2, demHelper)) * (180 / Math.PI);
  172. return angleH;
  173. //}
  174. //else
  175. //{
  176. // double angleH = Math.Asin((P2[2] - P1[2]) / distance(P1, P2)) * (180 / Math.PI);
  177. // return angleH;
  178. //}
  179. }
  180. }
  181. //MoveTo,输入单位坐标、目标坐标,输出时步结束时的单位坐标
  182. public static double[] MoveTo(double[] aircraft, double[] target, double V, double TimeStep,
  183. DemHelper demHelper)
  184. {
  185. double[] direction =
  186. {
  187. (target[0] - aircraft[0]) / distance(aircraft, target, demHelper),
  188. (target[1] - aircraft[1]) / distance(aircraft, target, demHelper),
  189. (target[2] - aircraft[2]) / distance(aircraft, target, demHelper)
  190. };
  191. double[] delta = { direction[0] * V * TimeStep, direction[1] * V * TimeStep, direction[2] * V * TimeStep };
  192. double[] next = { aircraft[0] + delta[0], aircraft[1] + delta[1], aircraft[2] + delta[2] };
  193. return next;
  194. }
  195. public static bool isBlocked(double[] P1, double[] P2, DemHelper demHelper) //是否被地形遮挡
  196. {
  197. double3 p1 = new double3();
  198. double3 p2 = new double3();
  199. p1.x = P1[0];
  200. p1.y = P1[1];
  201. p1.z = P1[2];
  202. p2.x = P2[0];
  203. p2.y = P2[1];
  204. p2.z = P2[2];
  205. //string r2 = demHelper.doIntervisibility(p1, p2);//这三行代码用于运行判定
  206. // Console.WriteLine(r2);
  207. //return (r2 == "True" ? false : true);
  208. return false;
  209. }
  210. //是否符合观察条件
  211. public static bool IsInSight(double[] aircraft, double[] netpoint, double LSight, double angleH0,
  212. double angleH1, DemHelper demHelper) //-90,-45
  213. {
  214. if (distance(aircraft, netpoint, demHelper) <= LSight && angleH0 <= angleH(aircraft, netpoint, demHelper) &&
  215. angleH1 >= angleH(aircraft, netpoint, demHelper) && isBlocked(aircraft, netpoint, demHelper) == false)
  216. {
  217. return true;
  218. }
  219. else
  220. {
  221. return false;
  222. }
  223. }
  224. //路径生成,输入区域边界,扫描线间距,扫描高度
  225. /// <summary>
  226. ///
  227. /// </summary>
  228. /// <param name="poly">想定文件 </param>
  229. /// <param name="ScanRange">想定文件 低空:300 高空:</param>
  230. /// <param name="hSC">想定文件 低空 300</param>
  231. /// <param name="isRealHeight">想定文件 true</param>
  232. /// <param name="isSurround">想定文件 true</param>
  233. /// <param name="SurroundNum">想定文件 1</param>
  234. /// <param name="demHelper">想定文件 </param>
  235. /// <returns></returns>
  236. public static List<double[]> scanroute(List<double[]> poly, double ScanRange, double hSC, bool isRealHeight,
  237. bool isSurround, int SurroundNum, DemHelper demHelper)
  238. {
  239. List<double[]> scanroute = new List<double[]>();
  240. double HH = 1; //需要替换为该点高程
  241. if (isSurround == false)
  242. {
  243. double[,] RactEdge = MaxMinPoly(poly);
  244. double[] searchpoint =
  245. {
  246. RactEdge[0, 0] + 0.5 *
  247. (ScanRange / (6371004 * Math.Cos(RactEdge[1, 0] * Math.PI / 180) * 2 * Math.PI / 360)),
  248. RactEdge[1, 0], HH + hSC
  249. };
  250. bool isLastIn = false;
  251. int ZF = 1;
  252. if (isinpoly(searchpoint, poly, demHelper) == true)
  253. {
  254. scanroute.Add(searchpoint);
  255. isLastIn = true;
  256. }
  257. searchpoint[1] = searchpoint[1] + ZF * 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360));
  258. for (;; searchpoint[1] = searchpoint[1] + ZF * 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360)))
  259. {
  260. double[] searchpoint1 =
  261. {
  262. searchpoint[0], searchpoint[1] - ZF * 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360)),
  263. isRealHeight == true ? HH + hSC : hSC
  264. };
  265. double[] searchpoint0 = { searchpoint[0], searchpoint[1], isRealHeight == true ? HH + hSC : hSC };
  266. if (isinpoly(searchpoint, poly, demHelper) == true && isLastIn == false)
  267. {
  268. scanroute.Add(searchpoint1);
  269. isLastIn = true;
  270. }
  271. else if (isLastIn == true && isinpoly(searchpoint, poly, demHelper) == false)
  272. {
  273. scanroute.Add(searchpoint0);
  274. isLastIn = false;
  275. if (ZF == 1)
  276. {
  277. searchpoint[0] = searchpoint[0] + ScanRange /
  278. (6371004 * Math.Cos(RactEdge[1, 0] * Math.PI / 180) * 2 * Math.PI / 360);
  279. searchpoint[1] = RactEdge[1, 1] + 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360));
  280. }
  281. else
  282. {
  283. searchpoint[0] = searchpoint[0] + ScanRange /
  284. (6371004 * Math.Cos(RactEdge[1, 0] * Math.PI / 180) * 2 * Math.PI / 360);
  285. searchpoint[1] = RactEdge[1, 0] - 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360));
  286. }
  287. ZF = -ZF;
  288. }
  289. if (searchpoint[0] > RactEdge[0, 1])
  290. {
  291. break;
  292. }
  293. }
  294. return scanroute;
  295. }
  296. else
  297. {
  298. int len = poly.Count;
  299. for (int i = 0; i < len; i++)
  300. {
  301. double[] p = poly[i];
  302. double[] p1 = poly[i == 0 ? len - 1 : i - 1];
  303. double[] p2 = poly[i == len - 1 ? 0 : i + 1];
  304. double v1EW = (p1[0] - p[0]) * (6371004 * Math.Cos(p[1] * Math.PI / 180) * 2 * Math.PI / 360);
  305. double v1SN = (p1[1] - p[1]) * (6371004 * 2 * Math.PI / 360);
  306. double n1 = Math.Sqrt(v1EW * v1EW + v1SN * v1SN);
  307. v1EW /= n1;
  308. v1SN /= n1;
  309. double v2EW = (p2[0] - p[0]) * (6371004 * Math.Cos(p[1] * Math.PI / 180) * 2 * Math.PI / 360);
  310. double v2SN = (p2[1] - p[1]) * (6371004 * 2 * Math.PI / 360);
  311. double n2 = Math.Sqrt(v2EW * v2EW + v2SN * v2SN);
  312. v2EW /= n2;
  313. v2SN /= n2;
  314. if (v1EW != v2EW)
  315. {
  316. double l = -ScanRange / Math.Sqrt((1 - (v1EW * v2EW + v1SN * v2SN)) / 2);
  317. double vEW = v1EW + v2EW;
  318. double vSN = v1SN + v2SN;
  319. double n = l / Math.Sqrt(vEW * vEW + vSN * vSN);
  320. vEW *= n;
  321. vSN *= n;
  322. double VEW = vEW / (6371004 * Math.Cos(p[1] * Math.PI / 180) * 2 * Math.PI / 360);
  323. double VSN = vSN / (6371004 * 2 * Math.PI / 360);
  324. double[] searchpoint =
  325. { p[0] + VEW, p[1] + VSN, isRealHeight == true ? HH + hSC : hSC }; //H需替换为该点高程
  326. scanroute.Add(searchpoint);
  327. }
  328. }
  329. int len2 = scanroute.Count;
  330. if (SurroundNum >= 2)
  331. {
  332. for (int i = 2; i <= SurroundNum; i++)
  333. {
  334. for (int j = 0; j < len2; j++)
  335. {
  336. scanroute.Add(scanroute[j]);
  337. }
  338. }
  339. }
  340. return scanroute;
  341. }
  342. }
  343. //航线转object
  344. public static List<object[]> RouteInput(string TurningPointName, List<double[]> TurningPointLocation,
  345. string TurningPointType, double TurningPointVelocity, double SegmentFlightFuelConsumption,
  346. double SegmentFlightTime, double TurningRadius)
  347. {
  348. List<object[]> SCIP = new List<object[]>();
  349. int i = 0;
  350. foreach (double[] element in TurningPointLocation)
  351. {
  352. object[] SCIPtemt =
  353. {
  354. $"{TurningPointName}{i}", element, $"{TurningPointType}", TurningPointVelocity,
  355. SegmentFlightFuelConsumption, SegmentFlightTime, TurningRadius
  356. };
  357. SCIP.Add(SCIPtemt);
  358. i++;
  359. }
  360. return SCIP;
  361. }
  362. //扫描线显示,不用管
  363. public static void ListscanRoute(List<double[]> SCtoRead)
  364. {
  365. Console.WriteLine("【showSC】");
  366. foreach (double[] element in SCtoRead)
  367. {
  368. string lontax = element[0].ToString("F5");
  369. string lattax = element[1].ToString("F5");
  370. Console.WriteLine("【E" + lontax + " | N" + lattax + " | h" + element[2] + "】\t");
  371. }
  372. }
  373. }
  374. }