Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Xml.Linq;
- namespace Linq2XmlSvgLab
- {
- public class Solutions
- {
- private readonly XElement root;
- private readonly XNamespace ns = "http://www.w3.org/2000/svg";
- public Solutions(string svgFileName)
- {
- root = XElement.Load(svgFileName);
- }
- private IEnumerable<XElement> Rects => root.Descendants(ns + "rect");
- private IEnumerable<XElement> Texts => root.Descendants(ns + "text");
- #region A laborfeladatok megoldásai
- // Minden téglalap (rect elem) felsorolása
- internal IEnumerable<XElement> GetAllRectangles()
- {
- return Rects;
- }
- // Hány olyan szöveg van, aminek ez a tartalma?
- internal int CountTextsWithValue(string v)
- {
- return Texts.Where(t => t.Value == v).Count();
- }
- #region Téglalap szűrések
- // Minden olyan rect elem felsorolása, aminek a kerete adott vastagságú.
- // A keretvastagság (más beállításokkal együtt) a "style" szöveges attribútumban
- // szerepel, pl. "stroke-width:2".
- internal IEnumerable<XElement> GetRectanglesWithStrokeWidth(int width)
- {
- return Rects.Where(r => r.Attribute("style").Value.Contains($"stroke-width:{width}"));
- }
- // Adott x koordinátájú téglalapok színének visszaadása szövegesen (pl. piros esetén "#ff0000").
- internal IEnumerable<string> GetColorOfRectanglesWithGivenX(double x)
- {
- return Rects.Where(r => r.GetX() == x)
- .Select(r => r.GetFillColor())
- .ToList();
- }
- // Az adott ID-jú téglalap pozíciójának (x,y) visszaadása.
- internal (double X, double Y) GetRectangleLocationById(string id)
- {
- return Rects.Where(r => r.GetId().Equals(id))
- .SingleOrDefault()
- .GetLocation();
- }
- // A legnagyobb y értékkel rendezkező téglalap ID-jának visszaadása.
- internal string GetIdOfRectangeWithLargestY()
- {
- var max = Rects.Max(r => r.GetY());
- return Rects.Where(r => r.GetY() == max)
- .SingleOrDefault()
- .GetId();
- }
- // Minden olyan téglalap ID-jának felsorolása, ami legalább kétszer olyan magas mint széles.
- internal IEnumerable<string> GetRectanglesAtLeastTwiceAsHighAsWide()
- {
- return Rects.Where(r => IsAtLeastTwiceAsHighAsWide(r))
- .Select(r => r.GetId())
- .ToList();
- }
- #endregion
- #region Group kezelés
- // Adott ID-jú group-ban lévő téglalapok színét sorolja fel.
- internal IEnumerable<string> GetColorsOfRectsInGroup(string id)
- {
- return Rects.Where(r => r.Parent.GetId() == id)
- .Select(r => r.GetFillColor())
- .ToList();
- }
- #endregion
- #region Téglalapok és szövegek viszonya
- // Minden olyan rect elem felsorolása, amiben van bármilyen szöveg.
- // (Olyan rect, aminek a területén van egy szövegnek a kezdőpontja (x,y).)
- internal IEnumerable<XElement> GetRectanglesWithTextInside()
- {
- var locations = Texts.Select(t => t.GetLocation()).ToList();
- return Rects.Where(r => locations.Where(l => IsInside(r, l)).Any());
- }
- // Adott színű téglalapon belüli szöveg visszaadása.
- // Feltételezhetjük, hogy csak egyetlen ilyen színű téglalap van és abban egyetlen
- // szöveg szerepel.
- internal string GetSingleTextInSingleRectangleWithColor(string color)
- {
- var rect = Rects.Where(r => r.GetFillColor().Equals(color)).SingleOrDefault();
- return Texts.Where(t => IsInside(rect, t.GetLocation()))
- .Select(t => t.Value)
- .SingleOrDefault();
- }
- // Minden téglalapon kívüli szöveg felsorolása.
- internal IEnumerable<string> GetTextsOutsideRectangles()
- {
- return Texts.Where(t => !Rects.Where(r => IsInside(r, t.GetLocation()))
- .Any())
- .Select(t => t.Value)
- .ToList();
- }
- #endregion
- #region Téglalapok egymáshoz képesti viszonya
- // Az egyetlen olyan téglalap pár visszaadása (id attribútumuk értékével), amik legfeljebb
- // adott távolságra vannak egymástól.
- // (Itt nem gond, ha foreach-et használsz, de jobb, ha nem.)
- internal (string id1, string id2) GetSingleRectanglePairCloseToEachOther(double maxDistance)
- {
- var alma = Rects.Where(r1 => Rects.Where(r2 => AreClose(r1, r2, maxDistance)).Any())
- .Select(r => r.GetId());
- return (null, null);
- }
- #endregion
- #region ILookup és Aggregate használata
- // Egy ILookup visszaadása, mely minden szöveghez megadja az ilyen szöveget tartalmazó
- // téglalapok színét. (Az ILookup-ban csak azok a szövegek szerepelnek kulcsként, amikhez van
- // is téglalap.)
- internal ILookup<string, string> GetBoundingRectangleColorListForEveryText()
- {
- return null;
- }
- // Minden téglalapon belüli szöveg ABC sorrendben egymás mögé fűzése, ", "-zel elválasztva.
- // (Az "OrderBy(s=>s)" rendezése most elegendő lesz.)
- // Használd az Aggregate Linq metódust egy StringBuilderrel az összegyűjtéshez!
- internal string ConcatenateOrderedTextsInsideRectangles()
- {
- return string.Empty;
- }
- // Az adott kontúrszélességű (stroke width) téglalapok által együttesen lefedett terület
- // szélességét és magasságát adja meg
- internal (double Width, double Height) GetEffectiveWidthAndHeight(int strokeThickness)
- {
- return (Width: 0, Height: 0);
- }
- #endregion
- #endregion
- #region Segédmetódusok
- // Ezeknek a metódusoknak az implementálása nem kötelező, csak ajánlás.
- // Ezekre a funkciókra lehet, hogy többször is szükséged lesz a feladatok
- // megoldása során, így érdemes őket kiszervezni külön metódusokba.
- class Boundary
- {
- public double Left = double.MaxValue;
- public double Top = double.MaxValue;
- public double Right = double.MinValue;
- public double Bottom = double.MinValue;
- public double Width => Right - Left + 1;
- public double Height => Bottom - Top + 1;
- public void UpdateToCoverRect(XElement rect)
- {
- Left = Math.Min(Left, rect.GetX());
- Right = Math.Max(Right, rect.GetX() + rect.GetWidth() - 1);
- Top = Math.Min(Top, rect.GetY());
- Bottom = Math.Max(Bottom, rect.GetY() + rect.GetHeight() - 1);
- }
- }
- // A kapott rect magassága legalább kétszer akkora, mint a szélessége?
- private bool IsAtLeastTwiceAsHighAsWide(XElement rect)
- {
- return rect.GetWidth() * 2 <= rect.GetHeight();
- }
- // A this.Rects attribútumból felsorolja azokat az elemeket, melyek kitöltési színe a megadott szín.
- private IEnumerable<XElement> GetRectanglesWithColor(string color)
- {
- return Rects.Where(r => r.GetFillColor() == color).ToList(); ;
- }
- // Igaz, ha a megadott pont a rect-en belül van.
- // Használhatod a lentebb megírandó GetRectBoundaries-t.
- private bool IsInside(XElement rect, (double x, double y) p)
- {
- var b = GetRectBoundaries(rect);
- return b.left < p.x && p.x < b.right && b.bottom > p.y && p.y > b.top;
- }
- // Igaz, ha a két téglalap (r1 és r2) között a távolság egyik tengely
- // mentén sem nagyobb, mint maxDistance.
- private bool AreClose(XElement r1, XElement r2, double maxDistance)
- {
- var b1 = new Boundary();
- b1.UpdateToCoverRect(r1);
- var b2 = new Boundary();
- b2.UpdateToCoverRect(r2);
- return (b1.Top + b2.Bottom < maxDistance || b1.Bottom + b2.Top < maxDistance)
- && (b1.Left + b2.Right < maxDistance || b1.Right + b2.Left < maxDistance);
- }
- // Visszaadja egy téglalap határait. Figyelem! Ha left==2 és width==3,
- // akkor right==4 és nem 5! Hasonlóan a magasságra is.
- private (double left, double top, double right, double bottom) GetRectBoundaries(XElement r)
- {
- var boundary = new Boundary();
- boundary.UpdateToCoverRect(r);
- return (boundary.Left, boundary.Top, boundary.Right, boundary.Bottom);
- }
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement