// Copyright (C) Stichting Deltares 2017. 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.Collections.ObjectModel; using System.Linq; using Core.Common.Base.Geometry; using Core.Common.Geometry; using Ringtoets.MacroStabilityInwards.Primitives; namespace Ringtoets.MacroStabilityInwards.Data.SoilProfile { /// /// Class for constructing soil profiles for which the geometry of the layers lay under a surface line. /// public static class MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory { /// /// Creates a new . /// /// The soil profile containing layers under the . /// The surface line for which determines the top of the . /// A new containing geometries from the /// under the . /// Thrown when any parameter is null. /// Thrown when the given type /// is not supported. public static MacroStabilityInwardsSoilProfileUnderSurfaceLine Create(IMacroStabilityInwardsSoilProfile soilProfile, MacroStabilityInwardsSurfaceLine surfaceLine) { if (soilProfile == null) { throw new ArgumentNullException(nameof(soilProfile)); } if (surfaceLine == null) { throw new ArgumentNullException(nameof(surfaceLine)); } var profile1D = soilProfile as MacroStabilityInwardsSoilProfile1D; if (profile1D != null) { return Create(profile1D, surfaceLine); } var profile2D = soilProfile as MacroStabilityInwardsSoilProfile2D; if (profile2D != null) { return Create(profile2D); } throw new NotSupportedException(); } private static MacroStabilityInwardsSoilProfileUnderSurfaceLine Create(MacroStabilityInwardsSoilProfile1D soilProfile, MacroStabilityInwardsSurfaceLine surfaceLine) { Point2D[] localizedSurfaceLine = surfaceLine.LocalGeometry.ToArray(); double geometryBottom = Math.Min(soilProfile.Bottom, localizedSurfaceLine.Min(p => p.Y)) - 1; IEnumerable surfaceLineGeometry = AdvancedMath2D.CompleteLineToPolygon(localizedSurfaceLine, geometryBottom); IEnumerable layerGeometries = soilProfile.Layers.Select( layer => As2DGeometry( layer, soilProfile, localizedSurfaceLine.First().X, localizedSurfaceLine.Last().X)); return GeometriesToIntersections(layerGeometries, surfaceLineGeometry); } private static MacroStabilityInwardsSoilProfileUnderSurfaceLine Create(MacroStabilityInwardsSoilProfile2D soilProfile) { IEnumerable layersUnderSurfaceLine = soilProfile.Layers.Select( layer => new MacroStabilityInwardsSoilLayerUnderSurfaceLine( RingToPoints(layer.OuterRing), layer.Holes.Select(RingToPoints), ToUnderSurfaceLineProperties(layer.Properties))); return new MacroStabilityInwardsSoilProfileUnderSurfaceLine(layersUnderSurfaceLine); } private static MacroStabilityInwardsSoilLayerPropertiesUnderSurfaceLine ToUnderSurfaceLineProperties( MacroStabilityInwardsSoilLayerProperties properties) { var props = new MacroStabilityInwardsSoilLayerPropertiesUnderSurfaceLine( new MacroStabilityInwardsSoilLayerPropertiesUnderSurfaceLine.ConstructionProperties { AbovePhreaticLevelMean = properties.AbovePhreaticLevelMean, AbovePhreaticLevelCoefficientOfVariation = properties.AbovePhreaticLevelCoefficientOfVariation, UsePop = properties.UsePop, IsAquifer = properties.IsAquifer, ShearStrengthModel = properties.ShearStrengthModel, MaterialName = properties.MaterialName }); props.AbovePhreaticLevelDesignVariable = MacroStabilityInwardsSemiProbabilisticDesignValueFactory.GetAbovePhreaticLevel(props).GetDesignValue(); return props; } private static Point2D[] RingToPoints(Ring ring) { return ring.Points.ToArray(); } private static MacroStabilityInwardsSoilProfileUnderSurfaceLine GeometriesToIntersections(IEnumerable layerGeometries, IEnumerable surfaceLineGeometry) { var collection = new Collection(); IEnumerable surfaceLineGeometryArray = surfaceLineGeometry.ToArray(); foreach (TempSoilLayerGeometry layer in layerGeometries) { foreach (Point2D[] soilLayerArea in GetSoilLayerWithSurfaceLineIntersection(surfaceLineGeometryArray, layer.OuterLoop)) { collection.Add(new MacroStabilityInwardsSoilLayerUnderSurfaceLine(soilLayerArea, ToUnderSurfaceLineProperties(layer.Properties))); } } return new MacroStabilityInwardsSoilProfileUnderSurfaceLine(collection); } private static TempSoilLayerGeometry As2DGeometry(MacroStabilityInwardsSoilLayer1D layer, MacroStabilityInwardsSoilProfile1D soilProfile, double minX, double maxX) { double top = layer.Top; double bottom = top - soilProfile.GetLayerThickness(layer); return new TempSoilLayerGeometry(new[] { new Point2D(minX, top), new Point2D(maxX, top), new Point2D(maxX, bottom), new Point2D(minX, bottom) }, layer.Properties); } private static IEnumerable GetSoilLayerWithSurfaceLineIntersection(IEnumerable surfaceLineGeometry, IEnumerable soilLayerGeometry) { return AdvancedMath2D.PolygonIntersectionWithPolygon(surfaceLineGeometry, soilLayerGeometry).Where(arr => arr.Length > 2); } private class TempSoilLayerGeometry { public TempSoilLayerGeometry(Point2D[] outerLoop, MacroStabilityInwardsSoilLayerProperties properties) { OuterLoop = outerLoop; Properties = properties; InnerLoops = Enumerable.Empty(); } public Point2D[] OuterLoop { get; } public MacroStabilityInwardsSoilLayerProperties Properties { get; } public IEnumerable InnerLoops { get; } } } }