Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
365
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.23 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Xml.Linq;
  6.  
  7. namespace Linq2XmlSvgLab
  8. {
  9. public class Solutions
  10. {
  11. private readonly XElement root;
  12. private readonly XNamespace ns = "http://www.w3.org/2000/svg";
  13.  
  14. public Solutions(string svgFileName)
  15. {
  16. root = XElement.Load(svgFileName);
  17. }
  18.  
  19. private IEnumerable<XElement> Rects => root.Descendants(ns + "rect");
  20. private IEnumerable<XElement> Texts => root.Descendants(ns + "text");
  21.  
  22. #region A laborfeladatok megoldásai
  23. // Minden téglalap (rect elem) felsorolása
  24. internal IEnumerable<XElement> GetAllRectangles()
  25. {
  26. return Rects;
  27. }
  28.  
  29. // Hány olyan szöveg van, aminek ez a tartalma?
  30. internal int CountTextsWithValue(string v)
  31. {
  32. return Texts.Where(t => t.Value == v).Count();
  33. }
  34.  
  35. #region Téglalap szűrések
  36. // Minden olyan rect elem felsorolása, aminek a kerete adott vastagságú.
  37. // A keretvastagság (más beállításokkal együtt) a "style" szöveges attribútumban
  38. // szerepel, pl. "stroke-width:2".
  39. internal IEnumerable<XElement> GetRectanglesWithStrokeWidth(int width)
  40. {
  41. return Rects.Where(r => r.Attribute("style").Value.Contains($"stroke-width:{width}"));
  42. }
  43.  
  44. // Adott x koordinátájú téglalapok színének visszaadása szövegesen (pl. piros esetén "#ff0000").
  45. internal IEnumerable<string> GetColorOfRectanglesWithGivenX(double x)
  46. {
  47. return Rects.Where(r => r.GetX() == x)
  48. .Select(r => r.GetFillColor())
  49. .ToList();
  50. }
  51.  
  52. // Az adott ID-jú téglalap pozíciójának (x,y) visszaadása.
  53. internal (double X, double Y) GetRectangleLocationById(string id)
  54. {
  55. return Rects.Where(r => r.GetId().Equals(id))
  56. .SingleOrDefault()
  57. .GetLocation();
  58. }
  59.  
  60. // A legnagyobb y értékkel rendezkező téglalap ID-jának visszaadása.
  61. internal string GetIdOfRectangeWithLargestY()
  62. {
  63. var max = Rects.Max(r => r.GetY());
  64. return Rects.Where(r => r.GetY() == max)
  65. .SingleOrDefault()
  66. .GetId();
  67. }
  68.  
  69. // Minden olyan téglalap ID-jának felsorolása, ami legalább kétszer olyan magas mint széles.
  70. internal IEnumerable<string> GetRectanglesAtLeastTwiceAsHighAsWide()
  71. {
  72. return Rects.Where(r => IsAtLeastTwiceAsHighAsWide(r))
  73. .Select(r => r.GetId())
  74. .ToList();
  75. }
  76. #endregion
  77.  
  78. #region Group kezelés
  79. // Adott ID-jú group-ban lévő téglalapok színét sorolja fel.
  80. internal IEnumerable<string> GetColorsOfRectsInGroup(string id)
  81. {
  82. return Rects.Where(r => r.Parent.GetId() == id)
  83. .Select(r => r.GetFillColor())
  84. .ToList();
  85. }
  86.  
  87. #endregion
  88.  
  89. #region Téglalapok és szövegek viszonya
  90. // Minden olyan rect elem felsorolása, amiben van bármilyen szöveg.
  91. // (Olyan rect, aminek a területén van egy szövegnek a kezdőpontja (x,y).)
  92. internal IEnumerable<XElement> GetRectanglesWithTextInside()
  93. {
  94. var locations = Texts.Select(t => t.GetLocation()).ToList();
  95. return Rects.Where(r => locations.Where(l => IsInside(r, l)).Any());
  96. }
  97.  
  98. // Adott színű téglalapon belüli szöveg visszaadása.
  99. // Feltételezhetjük, hogy csak egyetlen ilyen színű téglalap van és abban egyetlen
  100. // szöveg szerepel.
  101. internal string GetSingleTextInSingleRectangleWithColor(string color)
  102. {
  103. var rect = Rects.Where(r => r.GetFillColor().Equals(color)).SingleOrDefault();
  104. return Texts.Where(t => IsInside(rect, t.GetLocation()))
  105. .Select(t => t.Value)
  106. .SingleOrDefault();
  107. }
  108.  
  109. // Minden téglalapon kívüli szöveg felsorolása.
  110. internal IEnumerable<string> GetTextsOutsideRectangles()
  111. {
  112. return Texts.Where(t => !Rects.Where(r => IsInside(r, t.GetLocation()))
  113. .Any())
  114. .Select(t => t.Value)
  115. .ToList();
  116. }
  117. #endregion
  118.  
  119. #region Téglalapok egymáshoz képesti viszonya
  120. // Az egyetlen olyan téglalap pár visszaadása (id attribútumuk értékével), amik legfeljebb
  121. // adott távolságra vannak egymástól.
  122. // (Itt nem gond, ha foreach-et használsz, de jobb, ha nem.)
  123. internal (string id1, string id2) GetSingleRectanglePairCloseToEachOther(double maxDistance)
  124. {
  125. var alma = Rects.Where(r1 => Rects.Where(r2 => AreClose(r1, r2, maxDistance)).Any())
  126. .Select(r => r.GetId());
  127. return (null, null);
  128. }
  129. #endregion
  130.  
  131. #region ILookup és Aggregate használata
  132. // Egy ILookup visszaadása, mely minden szöveghez megadja az ilyen szöveget tartalmazó
  133. // téglalapok színét. (Az ILookup-ban csak azok a szövegek szerepelnek kulcsként, amikhez van
  134. // is téglalap.)
  135. internal ILookup<string, string> GetBoundingRectangleColorListForEveryText()
  136. {
  137. return null;
  138. }
  139.  
  140. // Minden téglalapon belüli szöveg ABC sorrendben egymás mögé fűzése, ", "-zel elválasztva.
  141. // (Az "OrderBy(s=>s)" rendezése most elegendő lesz.)
  142. // Használd az Aggregate Linq metódust egy StringBuilderrel az összegyűjtéshez!
  143. internal string ConcatenateOrderedTextsInsideRectangles()
  144. {
  145. return string.Empty;
  146. }
  147.  
  148. // Az adott kontúrszélességű (stroke width) téglalapok által együttesen lefedett terület
  149. // szélességét és magasságát adja meg
  150. internal (double Width, double Height) GetEffectiveWidthAndHeight(int strokeThickness)
  151. {
  152. return (Width: 0, Height: 0);
  153.  
  154. }
  155. #endregion
  156. #endregion
  157.  
  158. #region Segédmetódusok
  159. // Ezeknek a metódusoknak az implementálása nem kötelező, csak ajánlás.
  160. // Ezekre a funkciókra lehet, hogy többször is szükséged lesz a feladatok
  161. // megoldása során, így érdemes őket kiszervezni külön metódusokba.
  162. class Boundary
  163. {
  164. public double Left = double.MaxValue;
  165. public double Top = double.MaxValue;
  166. public double Right = double.MinValue;
  167. public double Bottom = double.MinValue;
  168.  
  169. public double Width => Right - Left + 1;
  170. public double Height => Bottom - Top + 1;
  171.  
  172. public void UpdateToCoverRect(XElement rect)
  173. {
  174. Left = Math.Min(Left, rect.GetX());
  175. Right = Math.Max(Right, rect.GetX() + rect.GetWidth() - 1);
  176. Top = Math.Min(Top, rect.GetY());
  177. Bottom = Math.Max(Bottom, rect.GetY() + rect.GetHeight() - 1);
  178. }
  179. }
  180.  
  181. // A kapott rect magassága legalább kétszer akkora, mint a szélessége?
  182. private bool IsAtLeastTwiceAsHighAsWide(XElement rect)
  183. {
  184. return rect.GetWidth() * 2 <= rect.GetHeight();
  185. }
  186.  
  187. // A this.Rects attribútumból felsorolja azokat az elemeket, melyek kitöltési színe a megadott szín.
  188. private IEnumerable<XElement> GetRectanglesWithColor(string color)
  189. {
  190. return Rects.Where(r => r.GetFillColor() == color).ToList(); ;
  191. }
  192.  
  193. // Igaz, ha a megadott pont a rect-en belül van.
  194. // Használhatod a lentebb megírandó GetRectBoundaries-t.
  195. private bool IsInside(XElement rect, (double x, double y) p)
  196. {
  197. var b = GetRectBoundaries(rect);
  198. return b.left < p.x && p.x < b.right && b.bottom > p.y && p.y > b.top;
  199. }
  200.  
  201. // Igaz, ha a két téglalap (r1 és r2) között a távolság egyik tengely
  202. // mentén sem nagyobb, mint maxDistance.
  203. private bool AreClose(XElement r1, XElement r2, double maxDistance)
  204. {
  205. var b1 = new Boundary();
  206. b1.UpdateToCoverRect(r1);
  207. var b2 = new Boundary();
  208. b2.UpdateToCoverRect(r2);
  209.  
  210. return (b1.Top + b2.Bottom < maxDistance || b1.Bottom + b2.Top < maxDistance)
  211. && (b1.Left + b2.Right < maxDistance || b1.Right + b2.Left < maxDistance);
  212. }
  213.  
  214. // Visszaadja egy téglalap határait. Figyelem! Ha left==2 és width==3,
  215. // akkor right==4 és nem 5! Hasonlóan a magasságra is.
  216. private (double left, double top, double right, double bottom) GetRectBoundaries(XElement r)
  217. {
  218. var boundary = new Boundary();
  219. boundary.UpdateToCoverRect(r);
  220. return (boundary.Left, boundary.Top, boundary.Right, boundary.Bottom);
  221. }
  222. #endregion
  223. }
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement