GasRecognitionShape.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. using netDxf.Entities;
  2. using netDxf;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace MECF.Framework.UI.Core.DxfScript
  10. {
  11. /// <summary>
  12. /// 名称:RecognizeShape类
  13. /// 作用:识别dxf文件中的图形 转化为自定义对象
  14. /// </summary>
  15. public partial class GasDxfDocument
  16. {
  17. private void RecognizeShape()
  18. {
  19. RecognizeGasAITValve();
  20. RecognizeGasButton();
  21. RecognizeAnalogControl4Jet();
  22. }
  23. //识别文字是否在圆内
  24. private bool IsTextInCircle(GasText text, GasCircle circle)
  25. {
  26. double x, y;
  27. x = text.X;
  28. y = text.Y;
  29. if (circle.Contains(x, y))
  30. {
  31. return true;
  32. }
  33. return false;
  34. }
  35. //判断多线段是否是矩形
  36. private bool IsPolyLineRect(GasPolyLine polyLine)
  37. {
  38. if (polyLine.InnerLines.Count != 4)
  39. {
  40. return false;
  41. }
  42. GasLine lineH1, lineH2, lineV1, lineV2;
  43. lineH1 = lineH2 = lineV1 = lineV2 = null;
  44. for (int i = 0; i < 4; i++)
  45. {
  46. GasLine line = polyLine.InnerLines[i];
  47. if (line.IsHorizental)
  48. {
  49. if (lineH1 == null)
  50. {
  51. lineH1 = line;
  52. }
  53. else if (lineH2 == null)
  54. {
  55. lineH2 = line;
  56. }
  57. else
  58. {
  59. return false;
  60. }
  61. }
  62. else if (line.IsVertical)
  63. {
  64. if (lineV1 == null)
  65. {
  66. lineV1 = line;
  67. }
  68. else if (lineV2 == null)
  69. {
  70. lineV2 = line;
  71. }
  72. else
  73. {
  74. return false;
  75. }
  76. }
  77. }
  78. if (lineH1 != null && lineH2 != null && lineV1 != null && lineV2 != null)
  79. {
  80. if (lineH1.CornerAt(lineV1) && lineH1.CornerAt(lineV2) && lineH2.CornerAt(lineV1) && lineH2.CornerAt(lineV2))
  81. {
  82. return true;
  83. }
  84. }
  85. return false;
  86. }
  87. //判断文字是否在矩形内
  88. private bool IsTextInRect(GasText text, GasPolyLine polyLine)
  89. {
  90. if (!IsPolyLineRect(polyLine))
  91. {
  92. return false;
  93. }
  94. double x, y;
  95. x = text.X;
  96. y = text.Y;
  97. if (!polyLine.Contains(x, y))
  98. {
  99. return false;
  100. }
  101. return true;
  102. }
  103. //识别漏斗
  104. private void RecognizeGasFunnel(DxfDocument dxf, string blockName = "HV")
  105. {
  106. foreach (var entity in dxf.Entities.All)
  107. {
  108. if (entity.Type != EntityType.Insert) continue;
  109. Insert insert = (Insert)entity;
  110. var block = insert.Block;
  111. if (block == null || block.Name != blockName) continue;
  112. GasFunnel gasFunnel = new GasFunnel(insert.Position.X, insert.Position.Y, insert.Position.Z, insert.Scale.X, insert.Scale.Y, insert.Scale.Z, insert.Rotation);
  113. gasFunnel.SetGasLines(insert);
  114. Funnels.Add(gasFunnel);
  115. }
  116. }
  117. //识别阀门
  118. private void RecognizeGasAITValve()
  119. {
  120. //识别可调节阀门
  121. for (int textId = 0; textId < Texts.Count; textId++)
  122. {
  123. //遍历文本
  124. GasText theText = Texts[textId];
  125. for (int circleId = 0; circleId < Circles.Count; circleId++)
  126. {
  127. //针对每个文本,再去遍历圆圈
  128. GasCircle theCircle = Circles[circleId];
  129. if (IsTextInCircle(theText, theCircle))
  130. {
  131. //文本在圆圈内,组成valve
  132. Valves.Add(new GasAITValve(theCircle, theText, null));
  133. Texts.RemoveAt(textId);
  134. Circles.RemoveAt(circleId);
  135. textId--;
  136. circleId--;
  137. break;
  138. }
  139. }
  140. }
  141. //识别不可调节阀门
  142. for (int valveId = 0; valveId < Valves.Count; valveId++)
  143. {
  144. for (int polyId = 0; polyId < PolyLines.Count; polyId++)
  145. {
  146. GasPolyLine thePolyLine = PolyLines[polyId];
  147. if (!IsPolyLineRect(thePolyLine))
  148. {
  149. continue;
  150. }
  151. GasAITValve theValve = Valves[valveId];
  152. double rectWidth = Math.Abs(thePolyLine.InnerLines[0].X1 - thePolyLine.InnerLines[0].X2);
  153. if (rectWidth > 3 * theValve.InnerCircle.R)
  154. {
  155. continue;
  156. }
  157. if (thePolyLine.Contains(theValve.InnerCircle.X, theValve.InnerCircle.Y))
  158. {
  159. theValve.InnerPolyLine = thePolyLine;
  160. PolyLines.RemoveAt(polyId);
  161. polyId--;
  162. theValve.Enable = false;
  163. break;
  164. }
  165. }
  166. }
  167. }
  168. //识别按钮
  169. private void RecognizeGasButton()
  170. {
  171. for (int polyId = 0; polyId < PolyLines.Count; polyId++)
  172. {
  173. GasText foundText = null;
  174. int foundCount = 0;
  175. GasPolyLine thePolyLine = PolyLines[polyId];
  176. if (!IsPolyLineRect(thePolyLine))
  177. {
  178. continue;
  179. }
  180. int textId;
  181. for (textId = 0; textId < Texts.Count; textId++)
  182. {
  183. GasText theText = Texts[textId];
  184. if (!IsTextInRect(theText, thePolyLine))
  185. {
  186. continue;
  187. }
  188. if (foundText == null)
  189. {
  190. foundText = theText;
  191. }
  192. foundCount++;
  193. }
  194. if (foundText != null && foundCount != 2)
  195. {
  196. double minY, maxY;
  197. minY = Math.Min(thePolyLine.InnerLines[0].Y1, thePolyLine.InnerLines[0].Y2);
  198. maxY = Math.Max(thePolyLine.InnerLines[0].Y1, thePolyLine.InnerLines[0].Y2);
  199. minY = Math.Min(thePolyLine.InnerLines[1].Y1, minY);
  200. minY = Math.Min(thePolyLine.InnerLines[1].Y2, minY);
  201. minY = Math.Min(thePolyLine.InnerLines[2].Y1, minY);
  202. minY = Math.Min(thePolyLine.InnerLines[2].Y2, minY);
  203. minY = Math.Min(thePolyLine.InnerLines[3].Y1, minY);
  204. minY = Math.Min(thePolyLine.InnerLines[3].Y2, minY);
  205. maxY = Math.Max(thePolyLine.InnerLines[1].Y1, maxY);
  206. maxY = Math.Max(thePolyLine.InnerLines[1].Y2, maxY);
  207. maxY = Math.Max(thePolyLine.InnerLines[2].Y1, maxY);
  208. maxY = Math.Max(thePolyLine.InnerLines[2].Y2, maxY);
  209. maxY = Math.Max(thePolyLine.InnerLines[3].Y1, maxY);
  210. maxY = Math.Max(thePolyLine.InnerLines[3].Y2, maxY);
  211. if (maxY - minY > 50)
  212. {
  213. continue;
  214. }
  215. Buttons.Add(new GasButton(thePolyLine, foundText));
  216. Texts.Remove(foundText);
  217. PolyLines.RemoveAt(polyId);
  218. polyId--;
  219. }
  220. }
  221. }
  222. //识别analog mfc
  223. private void RecognizeAnalogControl4Jet()
  224. {
  225. for (int buttonId = 0; buttonId < Buttons.Count; buttonId++)
  226. {
  227. GasButton theButton = Buttons[buttonId];
  228. GasText text1, text2;
  229. text1 = text2 = null;
  230. for (int textId = 0; textId < Texts.Count; textId++)
  231. {
  232. if (IsTextInRect(Texts[textId], theButton.InnerPolyLine))
  233. {
  234. if (text1 == null)
  235. {
  236. text1 = Texts[textId];
  237. }
  238. else if (text2 == null)
  239. {
  240. text2 = Texts[textId];
  241. break;
  242. }
  243. }
  244. }
  245. if (text1 == null || text2 == null)
  246. {
  247. continue;
  248. }
  249. GasLine theHLine = null;
  250. GasLine theVLine = null;
  251. bool failed = false;
  252. for (int lineId = 0; lineId < Lines.Count; lineId++)
  253. {
  254. GasLine theLine = Lines[lineId];
  255. double x, y;
  256. x = (theLine.X1 + theLine.X2) / 2;
  257. y = (theLine.Y1 + theLine.Y2) / 2;
  258. if (theButton.Contains(x, y))
  259. {
  260. if (theLine.IsHorizental)
  261. {
  262. if (theHLine == null)
  263. {
  264. double theLineLength = Math.Abs(theLine.X1 - theLine.X2);
  265. double theButtonWidth = Math.Abs(theButton.InnerPolyLine.InnerLines[0].X1 - theButton.InnerPolyLine.InnerLines[0].X2);
  266. if (Math.Abs(theLineLength - theButtonWidth) < GasBaseShape.E)
  267. {
  268. theHLine = theLine;
  269. }
  270. else
  271. {
  272. Lines.RemoveAt(lineId);
  273. lineId--;
  274. }
  275. }
  276. else
  277. {
  278. failed = true;
  279. break;//不是analog,下一个button
  280. }
  281. }
  282. else if (theLine.IsVertical)
  283. {
  284. if (theVLine == null)
  285. {
  286. theVLine = theLine;
  287. }
  288. else
  289. {
  290. failed = true;
  291. break;//不是analog,下一个button
  292. }
  293. }
  294. else
  295. {
  296. continue;//线段不在poly内,下一个线段
  297. }
  298. }
  299. }
  300. if (failed)
  301. {
  302. continue; //不是analog,下一个button
  303. }
  304. if (theHLine == null || theVLine == null)
  305. {
  306. continue;//不是analog,下一个button
  307. }
  308. GasPolyLine polyUp, polyLeft, polyRight;
  309. //按上、右、下、左顺序排列顶点
  310. double x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7;
  311. double x8, y8;//中心点
  312. x1 = Math.Min(theButton.InnerPolyLine.InnerLines[0].X1, theButton.InnerPolyLine.InnerLines[0].X2);
  313. y1 = theButton.InnerPolyLine.InnerLines[0].Y1;
  314. x2 = Math.Max(theButton.InnerPolyLine.InnerLines[0].X1, theButton.InnerPolyLine.InnerLines[0].X2);
  315. y2 = y1;
  316. x3 = x2;
  317. y3 = theHLine.Y1;
  318. x4 = x2;
  319. y4 = theButton.InnerPolyLine.InnerLines[2].Y1;
  320. x5 = theVLine.X1;
  321. y5 = y4;
  322. x6 = x1;
  323. y6 = y4;
  324. x7 = x1;
  325. y7 = y3;
  326. x8 = x5;
  327. y8 = y3;
  328. polyUp = new GasPolyLine();
  329. polyUp.AddLine(new GasLine(x1, y1, x2, y2));
  330. polyUp.AddLine(new GasLine(x2, y2, x3, y3));
  331. polyUp.AddLine(new GasLine(x3, y3, x7, y7));
  332. polyUp.AddLine(new GasLine(x7, y7, x1, y1));
  333. polyLeft = new GasPolyLine();
  334. polyLeft.AddLine(new GasLine(x7, y7, x8, y8));
  335. polyLeft.AddLine(new GasLine(x8, y8, x5, y5));
  336. polyLeft.AddLine(new GasLine(x5, y5, x6, y6));
  337. polyLeft.AddLine(new GasLine(x6, y6, x7, y7));
  338. polyRight = new GasPolyLine();
  339. polyRight.AddLine(new GasLine(x8, y7, x3, y3));
  340. polyRight.AddLine(new GasLine(x3, y3, x4, y4));
  341. polyRight.AddLine(new GasLine(x4, y4, x5, y5));
  342. polyRight.AddLine(new GasLine(x5, y5, x8, y8));
  343. GasText textTop, textLeft, textRight;
  344. textTop = textLeft = textRight = null;
  345. GasButton TopButton, LeftButton, RightButton;
  346. TopButton = LeftButton = RightButton = null;
  347. if (IsTextInRect(theButton.InnerText, polyUp))
  348. {
  349. textTop = theButton.InnerText;
  350. }
  351. else if (IsTextInRect(text1, polyUp))
  352. {
  353. textTop = text1;
  354. }
  355. else if (IsTextInRect(text2, polyUp))
  356. {
  357. textTop = text2;
  358. }
  359. else
  360. {
  361. continue;//没有text,下一个button
  362. }
  363. if (IsTextInRect(theButton.InnerText, polyLeft))
  364. {
  365. textLeft = theButton.InnerText;
  366. }
  367. else if (IsTextInRect(text1, polyLeft))
  368. {
  369. textLeft = text1;
  370. }
  371. else if (IsTextInRect(text2, polyLeft))
  372. {
  373. textLeft = text2;
  374. }
  375. else
  376. {
  377. continue;//没有text,下一个button
  378. }
  379. if (IsTextInRect(theButton.InnerText, polyRight))
  380. {
  381. textRight = theButton.InnerText;
  382. }
  383. else if (IsTextInRect(text1, polyRight))
  384. {
  385. textRight = text1;
  386. }
  387. else if (IsTextInRect(text2, polyRight))
  388. {
  389. textRight = text2;
  390. }
  391. else
  392. {
  393. continue;//没有text,下一个button
  394. }
  395. if (textTop == null || textLeft == null || textRight == null)
  396. {
  397. continue;//没有text,下一个button
  398. }
  399. TopButton = new GasButton(polyUp, textTop);
  400. LeftButton = new GasButton(polyLeft, textLeft);
  401. RightButton = new GasButton(polyRight, textRight);
  402. LeftButton.InnerText.Text = "0.00";
  403. RightButton.InnerText.Text = "slm";
  404. Analogs.Add(new GasAnalogControl4Jet(theButton, TopButton, LeftButton, RightButton));
  405. Lines.Remove(theHLine);
  406. Lines.Remove(theVLine);
  407. Texts.Remove(text1);
  408. Texts.Remove(text2);
  409. Buttons.RemoveAt(buttonId);
  410. buttonId--;
  411. }
  412. }
  413. }
  414. }