ContourSearch.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. 
  2. using Unity.Mathematics;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Reflection.Metadata.Ecma335;
  7. using System.Runtime.ExceptionServices;
  8. using System.Runtime.InteropServices;
  9. using System.Security.Cryptography.X509Certificates;
  10. using System.Diagnostics.Eventing.Reader;
  11. using BHJD.DEMdll.Public;
  12. using System.Reflection;
  13. using Newtonsoft.Json;
  14. using QuYuSaoMiao.Entity;
  15. using static BHJD.DEMdll.Public.IHttpHelper;
  16. namespace QuYuSaoMiao
  17. {
  18. public class ContourSearch
  19. {
  20. public static DemHelper DemHelper()
  21. {
  22. IDbHelper db = Factory.Load("10.130.100.5", "5432", "postgres", "postgres", "rescue_patrol_platform");
  23. DemHelper ddemHelper = new DemHelper(db);
  24. return ddemHelper;
  25. }
  26. public static double[,] MaxMinPoly(List<double[]> poly)//多边形矩形边界
  27. {
  28. List<double> PolyLon = new List<double>();
  29. List<double> PolyLat = new List<double>();
  30. foreach (double[] element in poly)
  31. {
  32. PolyLon.Add(element[0]);
  33. PolyLat.Add(element[1]);
  34. }
  35. double[,] MM1 = new double[2, 2];
  36. MM1[0, 0] = PolyLon.Min();//经度最小(西界)
  37. MM1[0, 1] = PolyLon.Max();//经度最大(东界)
  38. MM1[1, 0] = PolyLat.Min();//纬度最小(南界)
  39. MM1[1, 1] = PolyLat.Max();//纬度最大(北界)
  40. return MM1;
  41. }
  42. public static bool isinpoly(double[] zuobiao, List<double[]> poly, DemHelper demHelper)//已经替换成在边界内算法
  43. {
  44. double[,] polyOut = MaxMinPoly(poly);
  45. if (zuobiao[0] <= polyOut[0, 0] || zuobiao[0] >= polyOut[0, 1] || zuobiao[1] <= polyOut[1, 0] || zuobiao[1] >= polyOut[1, 1])
  46. { return false; }
  47. else
  48. {
  49. string polystring = "MULTIPOLYGON(((";
  50. foreach (double[] element in poly)
  51. {
  52. double e0 = element[0];
  53. double e1 = element[1];
  54. polystring = polystring + element[0] + " " + element[1] + ",";
  55. }
  56. polystring = polystring + poly[0][0] + " " + poly[0][1] + ")))";
  57. string pointstring = "POINT (" + zuobiao[0] + " " + zuobiao[1] + ")";
  58. // Console.WriteLine("isinpoly?");
  59. //Console.WriteLine(pointstring+polystring);
  60. string r1 = demHelper.doDetermine(pointstring, polystring);
  61. // Console.WriteLine(r1);
  62. //double[,] polyOut = MaxMinPoly(poly);
  63. //if (zuobiao[0] <= polyOut[0, 0] || zuobiao[0] >= polyOut[0, 1] || zuobiao[1] <= polyOut[1, 0] || zuobiao[1] >= polyOut[1, 1])
  64. // { return false; }
  65. // else
  66. //{
  67. return (r1 == "True" ? true : false);
  68. // }
  69. }
  70. }
  71. //格点生成方法:输入前四个为经纬度上下限,数组为多边形,后两个是经纬度分辨率。输出0经,1纬,2高,3是否被侦察的【01】变量。
  72. public static List<double[]> NPGenerate(double lonmin, double lonmax, double latmin, double latmax, List<double[]> juxing, double netscalelon, double netscalelat, DemHelper demHelper)
  73. {
  74. Console.WriteLine("格点生成");
  75. List<double[]> netpoints = new List<double[]>();
  76. for (double[] netpointprev = new double[3] { lonmin, latmax, 0 }; netpointprev[1] >= latmin; netpointprev[1] = netpointprev[1] - netscalelat)
  77. {
  78. for (netpointprev[0] = lonmin; netpointprev[0] <= lonmax; netpointprev[0] = netpointprev[0] + netscalelon)
  79. {
  80. if (isinpoly(netpointprev, juxing, demHelper) == true)
  81. {
  82. double HH = 0;//需要替换为该点【netpointprev[0], netpointprev[1]】高程
  83. double[] netpointtemp = new double[3] { netpointprev[0], netpointprev[1], HH };
  84. //netpointtemp = netpointprev;
  85. netpoints.Add(netpointtemp);
  86. }
  87. }
  88. }
  89. return netpoints;
  90. }
  91. //格点初始化
  92. public static List<bool> NPprem(List<double[]> NPcoo)
  93. {
  94. List<bool> NPprem0 = new List<bool>();
  95. int i = 0;
  96. foreach (double[] element in NPcoo)
  97. {
  98. //object[] NPrentemp = new object[4] { element[0], element[1], element[2], false };
  99. NPprem0.Add(false);
  100. i++;
  101. }
  102. return NPprem0;
  103. }
  104. //格点显示,可以不用
  105. public static void ListPoints(List<double[]> NPtoRead)
  106. {
  107. int i1 = 0;
  108. int i2 = 0;
  109. int i3;
  110. int irow;
  111. int iLine = 1;
  112. Console.Write("{");
  113. foreach (double[] element in NPtoRead)
  114. {
  115. if (i1 != 0 && element[1] != NPtoRead[i1 - 1][1])
  116. {
  117. i3 = i1 - 1;
  118. irow = i3 - i2 + 1;
  119. i2 = i1;
  120. iLine++;
  121. Console.Write("<本行格点数:" + irow + ">}" + Environment.NewLine + "{");
  122. }
  123. string lontax = element[0].ToString("F5");
  124. string lattax = element[1].ToString("F5");
  125. Console.Write("【E" + lontax + " | N" + lattax + " | h" + element[2] + "】\t");
  126. i1++;
  127. }
  128. i3 = i1 - 1;
  129. irow = i3 - i2 + 1;
  130. i2 = i1;
  131. Console.Write("<本行格点数:" + irow + ">}" + Environment.NewLine);
  132. int numberP = NPtoRead.Count;
  133. Console.WriteLine("行数:" + iLine + ";格点数量:" + numberP);
  134. }
  135. //两点间距计算,输出米
  136. public static double distance(double[] P1, double[] P2, DemHelper demHelper)
  137. {
  138. //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;
  139. //double D = Math.Pow(Math.Pow(DL, 2) + Math.Pow(P1[2] - P2[2], 2), 0.5);
  140. //return D;
  141. double3 p1 = new double3();
  142. double3 p2 = new double3();
  143. p1.x = P1[0];
  144. p1.y = P1[1];
  145. p1.z = P1[2];
  146. p2.x = P2[0];
  147. p2.y = P2[1];
  148. p2.z = P2[2];
  149. double D1 = demHelper.getDistance(p1, p2);
  150. //double DD1 = D1;
  151. //Console.WriteLine("距离:" + D1);
  152. return D1;
  153. }
  154. //两点间高度角计算,从P1到P2
  155. public static double angleH(double[] P1, double[] P2, DemHelper demHelper)
  156. {
  157. if (P1[2] == P2[2])
  158. { return 0; }
  159. else if (P1[0] == P2[0] && P1[1] == P2[1])
  160. {
  161. if (P1[2] < P2[2])
  162. { return 90; }
  163. else { return -90; }
  164. }
  165. else
  166. {
  167. //if (P1[2] < P2[2])
  168. //{
  169. double angleH = Math.Asin((P2[2] - P1[2]) / distance(P1, P2, demHelper)) * (180 / Math.PI);
  170. return angleH;
  171. //}
  172. //else
  173. //{
  174. // double angleH = Math.Asin((P2[2] - P1[2]) / distance(P1, P2)) * (180 / Math.PI);
  175. // return angleH;
  176. //}
  177. }
  178. }
  179. //MoveTo,输入单位坐标、目标坐标,输出时步结束时的单位坐标
  180. public static double[] MoveTo(double[] aircraft, double[] target, double V, double TimeStep, DemHelper demHelper)
  181. {
  182. double[] direction = { (target[0] - aircraft[0]) / distance(aircraft, target, demHelper), (target[1] - aircraft[1]) / distance(aircraft, target, demHelper), (target[2] - aircraft[2]) / distance(aircraft, target, demHelper) };
  183. double[] delta = { direction[0] * V * TimeStep, direction[1] * V * TimeStep, direction[2] * V * TimeStep };
  184. double[] next = { aircraft[0] + delta[0], aircraft[1] + delta[1], aircraft[2] + delta[2] };
  185. return next;
  186. }
  187. public static bool isBlocked(double[] P1, double[] P2, DemHelper demHelper)//是否被地形遮挡
  188. {
  189. double3 p1 = new double3();
  190. double3 p2 = new double3();
  191. p1.x = P1[0];
  192. p1.y = P1[1];
  193. p1.z = P1[2];
  194. p2.x = P2[0];
  195. p2.y = P2[1];
  196. p2.z = P2[2];
  197. //string r2 = demHelper.doIntervisibility(p1, p2);//这三行代码用于运行判定
  198. // Console.WriteLine(r2);
  199. //return (r2 == "True" ? false : true);
  200. return false;
  201. }
  202. //是否符合观察条件
  203. public static bool IsInSight(double[] aircraft, double[] netpoint, double LSight, double angleH0, double angleH1, DemHelper demHelper)//-90,-45
  204. {
  205. if (distance(aircraft, netpoint, demHelper) <= LSight && angleH0 <= angleH(aircraft, netpoint, demHelper) && angleH1 >= angleH(aircraft, netpoint, demHelper) && isBlocked(aircraft, netpoint, demHelper) == false)
  206. { return true; }
  207. else
  208. { return false; }
  209. }
  210. //路径生成,输入区域边界,扫描线间距,扫描高度
  211. public static List<double[]> scanroute(List<double[]> poly, double ScanRange, double hSC, bool isRealHeight, bool isSurround, int SurroundNum, DemHelper demHelper)
  212. {
  213. List<double[]> scanroute = new List<double[]>();
  214. double HH = 1;//需要替换为该点高程
  215. if (isSurround == false)
  216. {
  217. double[,] RactEdge = MaxMinPoly(poly);
  218. double[] searchpoint = { RactEdge[0, 0] + 0.5 * (ScanRange / (6371004 * Math.Cos(RactEdge[1, 0] * Math.PI / 180) * 2 * Math.PI / 360)), RactEdge[1, 0], HH + hSC };
  219. bool isLastIn = false;
  220. int ZF = 1;
  221. if (isinpoly(searchpoint, poly, demHelper) == true)
  222. {
  223. scanroute.Add(searchpoint);
  224. isLastIn = true;
  225. }
  226. searchpoint[1] = searchpoint[1] + ZF * 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360));
  227. for (; ; searchpoint[1] = searchpoint[1] + ZF * 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360)))
  228. {
  229. double[] searchpoint1 = { searchpoint[0], searchpoint[1] - ZF * 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360)), isRealHeight == true ? HH + hSC : hSC };
  230. double[] searchpoint0 = { searchpoint[0], searchpoint[1], isRealHeight == true ? HH + hSC : hSC };
  231. if (isinpoly(searchpoint, poly, demHelper) == true && isLastIn == false)
  232. {
  233. scanroute.Add(searchpoint1);
  234. isLastIn = true;
  235. }
  236. else if (isLastIn == true && isinpoly(searchpoint, poly, demHelper) == false)
  237. {
  238. scanroute.Add(searchpoint0);
  239. isLastIn = false;
  240. if (ZF == 1)
  241. {
  242. searchpoint[0] = searchpoint[0] + ScanRange / (6371004 * Math.Cos(RactEdge[1, 0] * Math.PI / 180) * 2 * Math.PI / 360);
  243. searchpoint[1] = RactEdge[1, 1] + 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360));
  244. }
  245. else
  246. {
  247. searchpoint[0] = searchpoint[0] + ScanRange / (6371004 * Math.Cos(RactEdge[1, 0] * Math.PI / 180) * 2 * Math.PI / 360);
  248. searchpoint[1] = RactEdge[1, 0] - 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360));
  249. }
  250. ZF = -ZF;
  251. }
  252. if (searchpoint[0] > RactEdge[0, 1])
  253. { break; }
  254. }
  255. return scanroute;
  256. }
  257. else
  258. {
  259. int len = poly.Count;
  260. for (int i = 0; i < len; i++)
  261. {
  262. double[] p = poly[i];
  263. double[] p1 = poly[i == 0 ? len - 1 : i - 1];
  264. double[] p2 = poly[i == len - 1 ? 0 : i + 1];
  265. double v1EW = (p1[0] - p[0]) * (6371004 * Math.Cos(p[1] * Math.PI / 180) * 2 * Math.PI / 360);
  266. double v1SN = (p1[1] - p[1]) * (6371004 * 2 * Math.PI / 360);
  267. double n1 = Math.Sqrt(v1EW * v1EW + v1SN * v1SN);
  268. v1EW /= n1;
  269. v1SN /= n1;
  270. double v2EW = (p2[0] - p[0]) * (6371004 * Math.Cos(p[1] * Math.PI / 180) * 2 * Math.PI / 360);
  271. double v2SN = (p2[1] - p[1]) * (6371004 * 2 * Math.PI / 360);
  272. double n2 = Math.Sqrt(v2EW * v2EW + v2SN * v2SN);
  273. v2EW /= n2;
  274. v2SN /= n2;
  275. if (v1EW != v2EW)
  276. {
  277. double l = -ScanRange / Math.Sqrt((1 - (v1EW * v2EW + v1SN * v2SN)) / 2);
  278. double vEW = v1EW + v2EW;
  279. double vSN = v1SN + v2SN;
  280. double n = l / Math.Sqrt(vEW * vEW + vSN * vSN);
  281. vEW *= n;
  282. vSN *= n;
  283. double VEW = vEW / (6371004 * Math.Cos(p[1] * Math.PI / 180) * 2 * Math.PI / 360);
  284. double VSN = vSN / (6371004 * 2 * Math.PI / 360);
  285. double[] searchpoint = { p[0] + VEW, p[1] + VSN, isRealHeight == true ? HH + hSC : hSC };//H需替换为该点高程
  286. scanroute.Add(searchpoint);
  287. }
  288. }
  289. int len2 = scanroute.Count;
  290. if (SurroundNum >= 2)
  291. {
  292. for (int i = 2; i <= SurroundNum; i++)
  293. {
  294. for (int j = 0; j < len2; j++)
  295. {
  296. scanroute.Add(scanroute[j]);
  297. }
  298. }
  299. }
  300. return scanroute;
  301. }
  302. }
  303. //航线转object
  304. public static List<object[]> RouteInput(string TurningPointName, List<double[]> TurningPointLocation, string TurningPointType, double TurningPointVelocity, double SegmentFlightFuelConsumption, double SegmentFlightTime, double TurningRadius)
  305. {
  306. List<object[]> SCIP = new List<object[]>();
  307. int i = 0;
  308. foreach (double[] element in TurningPointLocation)
  309. {
  310. object[] SCIPtemt = { $"{TurningPointName}{i}", element, $"{TurningPointType}", TurningPointVelocity, SegmentFlightFuelConsumption, SegmentFlightTime, TurningRadius };
  311. SCIP.Add(SCIPtemt);
  312. i++;
  313. }
  314. return SCIP;
  315. }
  316. //扫描线显示,不用管
  317. public static void ListscanRoute(List<double[]> SCtoRead)
  318. {
  319. Console.WriteLine("【showSC】");
  320. foreach (double[] element in SCtoRead)
  321. {
  322. string lontax = element[0].ToString("F5");
  323. string lattax = element[1].ToString("F5");
  324. Console.WriteLine("【E" + lontax + " | N" + lattax + " | h" + element[2] + "】\t");
  325. }
  326. }
  327. //最高点输入(等待替换)
  328. public static double[] TopInPloy(List<double[]> poly)
  329. {
  330. double[] Top = new double[3] { 113.999, 39.9995, 220 };
  331. return Top;
  332. }
  333. public static List<List<double[]>> ContourInPoly()
  334. {
  335. List<List<double[]>> ContourAdded = new List<List<double[]>>();
  336. List<double[]> ContourAdding = new List<double[]>();
  337. ContourAdding.Add(new double[3] { 113.9992, 39.9997, 100 });
  338. ContourAdding.Add(new double[3] { 113.9992, 39.9993, 100 });
  339. ContourAdding.Add(new double[3] { 113.9988, 39.9993, 100 });
  340. ContourAdding.Add(new double[3] { 113.9988, 39.9997, 100 });
  341. ContourAdded.Add(ContourAdding);
  342. ContourAdding.Clear();
  343. ContourAdding.Add(new double[3] { 113.9991, 39.9996, 200 });
  344. ContourAdding.Add(new double[3] { 113.9991, 39.9994, 200 });
  345. ContourAdding.Add(new double[3] { 113.9989, 39.9994, 200 });
  346. ContourAdding.Add(new double[3] { 113.9989, 39.9996, 200 });
  347. ContourAdded.Add(ContourAdding);
  348. return ContourAdded;
  349. }
  350. public static List<object[]> ContourCatalogue()
  351. //输出:0-编号
  352. //1-(double)海拔高度
  353. //2-是否为环线
  354. //3-是否被搜索过
  355. //4-被分割的第一个多边形(若为环线只放第一个,第二个空着)
  356. //5-被分割的第二个多边形,
  357. //顺序与等高线对应
  358. {
  359. List<double[]> Area1 = new List<double[]>();
  360. List<double[]> Area2 = new List<double[]>();
  361. Area1.Add(new double[2] { 113.9992, 39.9997 });
  362. Area1.Add(new double[2] { 113.9992, 39.9993 });
  363. Area1.Add(new double[2] { 113.9988, 39.9993 });
  364. Area1.Add(new double[2] { 113.9988, 39.9997 });
  365. List<object[]> Catalogue = new List<object[]>();
  366. Catalogue.Add(new object[] { 0, (double)100, true, false, Area1, Area2 });
  367. Area1.Clear();
  368. Area2.Clear();
  369. Area1.Add(new double[2] { 113.9991, 39.9996 });
  370. Area1.Add(new double[2] { 113.9991, 39.9994 });
  371. Area1.Add(new double[2] { 113.9989, 39.9994 });
  372. Area1.Add(new double[2] { 113.9989, 39.9996 });
  373. Catalogue.Add(new object[] { 1, (double)200, true, false, Area1, Area2 });
  374. return Catalogue;
  375. }
  376. public static double distance1(double[] P1, double[] P2)
  377. {
  378. 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;
  379. double D = Math.Pow(Math.Pow(DL, 2) + Math.Pow(P1[2] - P2[2], 2), 0.5);
  380. return D;
  381. }
  382. public static double Area(List<double[]> Area)//求面积(待替换)
  383. {
  384. Area.RemoveAt(Area.Count - 1);
  385. double EarthRadius = 6371.004; // 地球半径,单位:千米
  386. double area = 0;
  387. int count = Area.Count;
  388. double[] p0 = Area[0];
  389. for (int i = 0; i < count; i++)
  390. {
  391. double[] p1 = Area[i];
  392. double[] p2 = Area[(i + 1) % count];
  393. double X1 = EarthRadius * Math.Cos(Math.PI / 180 * p0[1])*2*Math.PI / 360 * (p1[0] - p0[0]);
  394. double Y1 = EarthRadius * 2 * Math.PI / 360 * (p1[1] - p0[1]);
  395. double X2 = EarthRadius * Math.Cos(Math.PI / 180 * p0[1]) * 2 * Math.PI / 360 * (p2[0] - p0[0]);
  396. double Y2 = EarthRadius * 2 * Math.PI / 360 * (p2[1] - p0[1]);
  397. area +=( X1 * Y2 - X2 * Y1)/2;
  398. }
  399. //area = area * EarthRadius * EarthRadius / 2;
  400. Console.WriteLine("A=" + area);
  401. return Math.Abs(area);
  402. }
  403. /// <summary>
  404. /// 获取搜寻次序
  405. /// </summary>
  406. /// <param name="ContourInPoly">多边形内等高线</param>
  407. /// <param name="ContourCatalogue">多边形目录</param>
  408. /// <param name="ContourHighest">最高等高线</param>
  409. /// <param name="ContourInterval">等高线间隔</param>
  410. /// <param name="HighestPoint">最高点</param>
  411. /// <param name="poly">多边形边界</param>
  412. /// <param name="demHelper">Demhelper</param>
  413. /// <returns></returns>
  414. public static List<int> ContourOrder(List<List<double[]>> ContourInPoly, List<object[]> ContourCatalogue, double ContourHighest, double ContourLowest, double ContourInterval, double[] HighestPoint, List<double[]> poly, DemHelper demHelper)
  415. //核心算法1
  416. //输入:多边形内等高线,多边形目录,最高等高线,等高线间隔,最高点,多边形边界,Demhelper
  417. //输出:搜寻次序
  418. {
  419. //总初始化
  420. int ContourToSearch = -1;
  421. double ContourHigh = ContourHighest;
  422. double AreaToSrerch = -1;
  423. double[] BasePiont = HighestPoint;
  424. List<int> ContourOrder = new List<int>();
  425. double Spoly = Area(poly);
  426. int TotalContour = ContourInPoly.Count;//等高线条数
  427. double ContourHighestSearching = ContourHighest;
  428. //输出等高线最高点距离
  429. List<double> DistanceToTop = new List<double>();
  430. double DTemp = -1;
  431. foreach (List<double[]> element in ContourInPoly)
  432. {
  433. foreach (double[] element1 in element)
  434. {
  435. //找的等高线点数组中,距离最高点距离最近的点
  436. if (DTemp < 0 || DTemp > distance1(HighestPoint, element1))
  437. {
  438. DTemp = distance1(HighestPoint, element1);
  439. }
  440. }
  441. DistanceToTop.Add(DTemp);
  442. DTemp = -1;
  443. }
  444. //输出element【4】面积
  445. List<double> Area4 = new List<double>();
  446. foreach (object[] element in ContourCatalogue)
  447. {
  448. Area4.Add(Area((List<double[]>)element[4]));
  449. }
  450. //大循环
  451. for (; ContourOrder.Count <= TotalContour;)
  452. {
  453. for (; ; )
  454. {
  455. ContourToSearch = -1;
  456. AreaToSrerch = -1;
  457. foreach (object[] element in ContourCatalogue)
  458. {
  459. double[] BasePiont2 = new double[2] { BasePiont[0], BasePiont[1] };
  460. bool isin = isinpoly(BasePiont2, (List<double[]>)element[4], demHelper);
  461. if ((bool)element[2] == true && (double)element[1] <= ContourHigh + 1 && (double)element[1] >= ContourHigh - 1 && (bool)element[3] == false &&
  462. (isin == true)
  463. )//遍历最高的环形等高线,若某环线包含该点(含边缘),则搜索该线
  464. {
  465. ContourToSearch = (int)element[0];
  466. break;
  467. }
  468. //Console.WriteLine("搜索高度"+ ContourHigh);
  469. if ((double)element[1] <= ContourHigh+1 && (double)element[1] >= ContourHigh - 1 && (bool)element[3] == false
  470. && (ContourToSearch <0 ||
  471. ((AreaToSrerch < 0 || Area4[(int)element[0]] <= AreaToSrerch) && isin== true) ||
  472. ((AreaToSrerch < 0 || Spoly - Area4[(int)element[0]] <= AreaToSrerch) && isin != true)
  473. ))//遍历最高的开放等高线及不包含点的环状等高线,若其包含该点的部分最小,搜索该线
  474. {
  475. //Console.WriteLine("点在外搜索");
  476. ContourToSearch = (int)element[0];
  477. if (isinpoly(BasePiont2, (List<double[]>)element[4], demHelper) == true)
  478. { AreaToSrerch = Area4[(int)element[0]]; }
  479. else
  480. { AreaToSrerch = Spoly - Area4[(int)element[0]]; }
  481. }
  482. }
  483. // Console.WriteLine("ATS=" + AreaToSrerch);
  484. if (ContourToSearch == -1)//找不到符合过滤条件的等高线后,结束循环
  485. {
  486. Console.WriteLine("大循环结束");
  487. break;
  488. }
  489. else//连续搜下一道
  490. {
  491. ContourOrder.Add(ContourToSearch);
  492. Console.WriteLine(ContourToSearch + "," + ContourCatalogue[ContourToSearch][1] + "," +"连续搜索");
  493. ContourCatalogue[ContourToSearch][3] = true;
  494. BasePiont = ContourInPoly[ContourToSearch][0];//上一级等高线满足搜索后,该级闭合等高线的第一个点,作为下级等高线搜索的初始化点
  495. ContourToSearch = -1;
  496. ContourHigh = ContourHigh - ContourInterval;
  497. }
  498. }
  499. double DToTop = -1;
  500. foreach (object[] element in ContourCatalogue)
  501. {
  502. if ((double)element[1] == ContourHighestSearching && (bool)element[3] == false && (DToTop < 0 || DistanceToTop[(int)element[0]] < DToTop))
  503. {
  504. DToTop = DistanceToTop[(int)element[0]];
  505. ContourToSearch = (int)element[0];
  506. }
  507. }
  508. if (DToTop >= 0)
  509. {
  510. ContourOrder.Add(ContourToSearch);
  511. Console.WriteLine(ContourToSearch + "," + ContourCatalogue[ContourToSearch][1] + "," + "从头搜索");
  512. ContourCatalogue[ContourToSearch][3] = true;
  513. BasePiont = ContourInPoly[ContourToSearch][0];
  514. ContourToSearch = -1;
  515. ContourHigh = ContourHighestSearching - ContourInterval;
  516. }
  517. else
  518. {
  519. ContourHighestSearching = ContourHighestSearching - ContourInterval;
  520. }
  521. if (ContourHighestSearching < ContourLowest)
  522. {
  523. break;
  524. }
  525. }
  526. return ContourOrder;
  527. }
  528. public static List<double[]> ContourSearch1(List<double[]> Poly, double interval, int MinLength, double TrueH, int JG, DemHelper demHelper)
  529. //等高线搜寻整体算法!输入:【边界(wkt格式),等高线高度间隔,最小等高线节点数,真高,输出节点间隔,DemHelper】
  530. {
  531. //string wkt = "MULTIPOLYGON(((100.0035 30.9071,100.1728 30.9607,100.3523 30.8667,100.3512 30.6900,100.1569 30.6427,99.9509 30.7802,99.9907 30.8641,100.0035 30.9071)))";
  532. //数组转string
  533. string wkt= "MULTIPOLYGON(((";
  534. int stringcount = 0;
  535. foreach (double[]polyPiont in Poly)
  536. {
  537. wkt += polyPiont[0] + " " + polyPiont[1] ;
  538. stringcount++;
  539. if(stringcount<Poly.Count)
  540. { wkt += ","; }
  541. }
  542. wkt += ")))";
  543. Console.WriteLine(wkt);
  544. //数组转string end
  545. List<double[]> routePoints = new List<double[]>();
  546. List<double[]> juxing1 = new List<double[]>();
  547. string wktstr = wkt.Replace("MULTIPOLYGON", "").Replace("(", "").Replace(")", "");
  548. string[] pts = wktstr.Split(",");
  549. for (int i = 0; i < pts.Count(); i++)// pts.Count()-1
  550. {
  551. string[] pt = pts[i].Split(" ");
  552. double lon = Convert.ToDouble(pt[0]);
  553. double lat = Convert.ToDouble(pt[1]);
  554. juxing1.Add(new double[2] { lon, lat });
  555. }
  556. //(2)获取多边形内等高线
  557. HttpCmd cmd = new HttpCmd
  558. {
  559. m_RequestType = HttpRequestType.POST,
  560. m_Addr = "http://10.130.100.5:7785//rescue-platform-service/api/v1/dem/getContoursBywkt",
  561. m_Args = new List<string> { "wkt", "interval" }
  562. };
  563. string jsonstr = "{\"wkt\":\"" + wkt + "\",\"interval\":" + interval + "}";
  564. IHttpHelper m_HttpHelper = Factory.Load();
  565. string response = m_HttpHelper.HttpPost(cmd, jsonstr);
  566. ContourMsg data = JsonConvert.DeserializeObject<ContourMsg>(response);
  567. List<List<double[]>> ContourInPoly = new List<List<double[]>>();
  568. if (data == null || data.code != 200)
  569. {
  570. Console.WriteLine("******等高线生成出错!******");
  571. return routePoints;
  572. }
  573. List<List<double[]>> ContourAdded = new List<List<double[]>>();
  574. for (int i = 0; i < data.lstContours.Count; i++)
  575. {
  576. List<double[]> ContourAdding = data.lstContours[i].lstPoints;
  577. ContourInPoly.Add(ContourAdding);
  578. }
  579. //(3)获取多边形内最高点
  580. List<double> maxPoint = data.maxPoint;
  581. double[] TopInPloy = new double[3] { maxPoint[0], maxPoint[1], maxPoint[2] };
  582. Console.WriteLine("******最高点******" + "\r\n" + maxPoint[0] + maxPoint[1] + maxPoint[2]);
  583. //(4)等高线索引生成
  584. List<object[]> ContourCatalogue = new List<object[]>();
  585. for (int i = 0; i < data.lstContours.Count; i++)
  586. {
  587. Contour contour = data.lstContours[i];
  588. List<double[]> lstPoints = contour.lstPoints;
  589. double elev = contour.elev;
  590. bool ifclosed = contour.ifclosed;
  591. List<double[]> Area1 = new List<double[]>();
  592. List<double[]> Area2 = new List<double[]>();
  593. for (int j = 0; j < lstPoints.Count; j++)
  594. {
  595. double lon = lstPoints[j][0];
  596. double lat = lstPoints[j][1];
  597. Area1.Add(new double[2] { lon, lat });
  598. }
  599. bool isCircle = false;
  600. if (ContourInPoly[i][0] == ContourInPoly[i][ContourInPoly[i].Count - 1])
  601. {
  602. isCircle = true;
  603. }
  604. bool isTooShort = false;
  605. if (ContourInPoly[i].Count <= MinLength)
  606. {
  607. isTooShort = true;
  608. }
  609. ContourCatalogue.Add(new object[] { i, elev, isCircle, isTooShort, Area1, Area2 });
  610. }
  611. //(5)遍历顺序生成
  612. double maxElev = data.lstContours[0].elev;
  613. double minElev = data.lstContours[data.lstContours.Count - 1].elev;
  614. List<int> ContourOrder1 = ContourOrder(ContourInPoly, ContourCatalogue, maxElev, minElev, interval, TopInPloy, juxing1, demHelper);
  615. //(6)生成航路点集合
  616. string wkt_route = "";
  617. double[] EndPiont = TopInPloy;
  618. double[] StartPoint = new double[3];
  619. //string csvFilePath = "output.csv";//需csv输出则取消注释1/5
  620. //using (var writer = new StreamWriter(csvFilePath))//需csv输出则取消注释2/5
  621. //{//需csv输出则取消注释3/5
  622. foreach (int i in ContourOrder1)
  623. {
  624. //Console.WriteLine(i+ ","+ ContourCatalogue[i][1]);
  625. object[] contourObj = ContourCatalogue[i];
  626. List<double[]> contourPts = new List<double[]>();
  627. //等高线起点终点排序算法
  628. if ((bool)contourObj[2] == true)
  629. {
  630. double Dtemp = -1;
  631. int StartPointMark = -1;
  632. for (int j = 0; j < ContourInPoly[i].Count; j++)
  633. {
  634. if (distance1(ContourInPoly[i][j], EndPiont) < Dtemp || Dtemp < 0)
  635. {
  636. StartPoint = ContourInPoly[i][j];
  637. Dtemp =distance1(ContourInPoly[i][j], EndPiont);
  638. StartPointMark = j;
  639. }
  640. }
  641. EndPiont = ContourInPoly[i][StartPointMark];//改变终点
  642. for (int j1 = StartPointMark; j1 < ContourInPoly[i].Count; j1 += JG)
  643. {
  644. double[] CIP1 = new double[3] { ContourInPoly[i][j1][0], ContourInPoly[i][j1][1], ContourInPoly[i][j1][2] + TrueH };
  645. contourPts.Add(CIP1);
  646. }
  647. for (int j1 = 0; j1 < StartPointMark; j1 += JG)
  648. {
  649. double[] CIP1 = new double[3] { ContourInPoly[i][j1][0], ContourInPoly[i][j1][1], ContourInPoly[i][j1][2] + TrueH };
  650. contourPts.Add(CIP1);
  651. }
  652. }
  653. else
  654. {
  655. int StartPointMark = -1;
  656. if (distance1(ContourInPoly[i][0], EndPiont) > distance1(ContourInPoly[i][ContourInPoly[i].Count - 1], EndPiont))
  657. {
  658. StartPointMark = ContourInPoly[i].Count - 1;
  659. StartPoint = ContourInPoly[i][ContourInPoly[i].Count - 1];
  660. EndPiont = ContourInPoly[i][0];//改变终点
  661. for (int j = ContourInPoly[i].Count - 1; j >= 0; j -= JG)
  662. {
  663. double[] CIP1 = new double[3] { ContourInPoly[i][j][0], ContourInPoly[i][j][1], ContourInPoly[i][j][2] + TrueH };
  664. contourPts.Add(CIP1);
  665. }
  666. }
  667. else
  668. {
  669. StartPointMark = 0;
  670. StartPoint = ContourInPoly[i][0];
  671. EndPiont = ContourInPoly[i][ContourInPoly[i].Count - 1];//改变终点
  672. for (int j = 0; j < ContourInPoly[i].Count; j += JG)
  673. {
  674. double[] CIP1 = new double[3] { ContourInPoly[i][j][0], ContourInPoly[i][j][1], ContourInPoly[i][j][2] + TrueH };
  675. contourPts.Add(CIP1);
  676. }
  677. }
  678. }
  679. for (int k = 0; k < contourPts.Count; k++)
  680. {
  681. double[] item = contourPts[k];
  682. routePoints.Add(item);
  683. wkt_route += String.Format(",{0} {1} {2}", item[0], item[1], item[2]);
  684. //writer.WriteLine(String.Format("{0} ,{1} ,{2}", item[0], item[1], item[2]));//需csv输出则取消注释4/5
  685. }
  686. }
  687. //}//需csv输出则取消注释5/5
  688. if (wkt_route.StartsWith(","))
  689. {
  690. wkt_route = "MULTILINESTRING ((" + wkt_route.Substring(1) + "))";
  691. }
  692. Console.WriteLine("******航路点生成******" + "\r\n" + wkt_route);
  693. ListscanRoute(routePoints);
  694. return routePoints;
  695. }
  696. }
  697. }