// Copyright (C) Stichting Deltares 2018. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using Core.Common.Base.Geometry; namespace Ringtoets.MacroStabilityInwards.Data.TestUtil { /// /// The class helps to construct collections of points by reading a string (from file or directly) and /// transforming this in objects that can be used in tests. /// public static class Segment2DLoopCollectionHelper { /// /// Creates a loop from a given string. The string needs to be formatted as follows. /// /// First line contains the number of lines (n). /// The n following lines contain a number of digits. /// Each digit is a point and should be unique. /// /// Example string: /// /// "3" + Environment.NewLine + /// "..1.." + Environment.NewLine + /// "3...." + Environment.NewLine + /// "...2." /// /// /// The (correctly formatted) string representing a grid with points. /// The of which describe a loop. public static List CreateFromString(string s) { var points = new SortedDictionary(); string[] lines = s.Split(new[] { Environment.NewLine }, StringSplitOptions.None); int height = int.Parse(lines[0]); var lineIndex = 1; for (int y = height - 1; y >= 0; y--, lineIndex++) { foreach (Tuple tuple in AllIndexesOfDigit(lines[lineIndex])) { points.Add(tuple.Item1, new Point2D(tuple.Item2, y)); } } return CreateLoop(points); } private static List CreateLoop(SortedDictionary points) { var loop = new List(points.Count); int count = points.Values.Count; for (var i = 0; i < count; i++) { Point2D firstPoint = points.Values.ElementAt(i); Point2D secondPoint = points.Values.ElementAt((i + 1) % count); loop.Add(new Segment2D(firstPoint, secondPoint)); } return loop; } /// /// Returns a of if . /// The first item in the tuple contains the digit and the second item contains its index. /// /// The line which contains digits. /// A of of /// which contains the digits and the index of those digits. /// Thrown when the regex magically matches more or less than it should /// have (1 digit). private static IEnumerable> AllIndexesOfDigit(string line) { const string guess = @"\d"; MatchCollection matches = Regex.Matches(line, guess); foreach (Match match in matches) { int digit; try { digit = int.Parse(match.Value); } catch (ArgumentNullException e) { throw new Exception(e.Message, e); } catch (FormatException e) { throw new Exception(e.Message, e); } catch (OverflowException e) { throw new Exception(e.Message, e); } yield return Tuple.Create(digit, match.Index); } } } }