using System.Collections.Generic;
using System.Linq;
using Core.Common.Base.Geometry;
using Ringtoets.Common.Forms.Helpers;
using Ringtoets.Piping.Data;
using Ringtoets.Piping.Primitives;
namespace Ringtoets.Piping.Forms
{
///
/// Class holds methods to help views when dealing with
///
public static class PipingCalculationConfigurationHelper
{
///
/// Creates a structure of and based on combination of the
/// and the .
///
/// Surface lines to generate the structure for and to use to configure
/// with.
/// The soil models from which profiles are taken to configure with.
///
public static IEnumerable GenerateCalculationsStructure(IEnumerable surfaceLines, IEnumerable soilModels)
{
if (surfaceLines == null)
{
return Enumerable.Empty();
}
var pipingCalculationGroups = surfaceLines.Select(sl => CreateCalculationGroup(sl, soilModels));
return pipingCalculationGroups;
}
///
/// Gets the piping soil profiles matching the input of a calculation.
///
/// The surface line used to match a .
/// The available soil models.
/// The (sub)set of soil profiles from
/// or empty if no matching instances can be found
/// or when there is not enough information to associate soil profiles to the calculation.
public static IEnumerable GetPipingSoilProfilesForSurfaceLine(RingtoetsPipingSurfaceLine surfaceLine, IEnumerable availableSoilModels)
{
if (surfaceLine == null)
{
return Enumerable.Empty();
}
Segment2D[] surfaceLineSegments = Math2D.ConvertLinePointsToLineSegments(surfaceLine.Points.Select(p => new Point2D(p.X, p.Y))).ToArray();
var soilProfileObjectsForCalculation = new List();
foreach (StochasticSoilModel stochasticSoilModel in availableSoilModels.Where(sm => sm.StochasticSoilProfiles.Any()))
{
if (DoesSoilModelGeometryIntersectWithSurfaceLineGeometry(stochasticSoilModel, surfaceLineSegments))
{
soilProfileObjectsForCalculation.AddRange(stochasticSoilModel.StochasticSoilProfiles.Select(ssp => ssp.SoilProfile));
}
}
return soilProfileObjectsForCalculation;
}
private static IPipingCalculationItem CreateCalculationGroup(RingtoetsPipingSurfaceLine surfaceLine, IEnumerable soilModels)
{
var pipingCalculationGroup = new PipingCalculationGroup(surfaceLine.Name, true);
if (soilModels != null)
{
foreach (var profile in GetPipingSoilProfilesForSurfaceLine(surfaceLine, soilModels))
{
pipingCalculationGroup.Children.Add(CreatePipingCalculation(surfaceLine, profile, pipingCalculationGroup.Children));
}
}
return pipingCalculationGroup;
}
private static IPipingCalculationItem CreatePipingCalculation(RingtoetsPipingSurfaceLine surfaceLine, PipingSoilProfile profile, IEnumerable calculations)
{
var nameBase = string.Format("{0} {1}", surfaceLine.Name, profile.Name);
var name = NamingHelper.GetUniqueName(calculations, nameBase, c => c.Name);
return new PipingCalculation(new GeneralPipingInput(), new SemiProbabilisticPipingInput())
{
Name = name,
InputParameters =
{
SurfaceLine = surfaceLine,
SoilProfile = profile
}
};
}
private static bool DoesSoilModelGeometryIntersectWithSurfaceLineGeometry(StochasticSoilModel stochasticSoilModel, Segment2D[] surfaceLineSegments)
{
IEnumerable soilProfileGeometrySegments = Math2D.ConvertLinePointsToLineSegments(stochasticSoilModel.Geometry);
return soilProfileGeometrySegments.Any(s => DoesSegmentIntersectWithSegmentArray(s, surfaceLineSegments));
}
private static bool DoesSegmentIntersectWithSegmentArray(Segment2D segment, Segment2D[] segmentArray)
{
// Consider intersections and overlaps similarly
return segmentArray.Any(sls => Math2D.GetIntersectionBetweenSegments(segment, sls).IntersectionType != Intersection2DType.DoesNotIntersect);
}
}
}