// Copyright (C) Stichting Deltares 2016. 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 Core.Common.Base.Data;
using Core.Common.Base.Geometry;
using log4net;
using Ringtoets.Common.Data;
using Ringtoets.Common.Data.Calculation;
using Ringtoets.Common.Forms.Helpers;
using Ringtoets.Piping.Data;
using Ringtoets.Piping.Forms.Properties;
using Ringtoets.Piping.Primitives;
namespace Ringtoets.Piping.Forms
{
///
/// Class holds methods to help views when dealing with
///
public static class PipingCalculationConfigurationHelper
{
private static readonly ILog log = LogManager.GetLogger(typeof(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.
/// General input to assign to each generated piping calculation.
/// Semi probabilistic input to assign to each generated piping calculation.
/// A structure of matching combinations of and
/// profiles of intersecting .
/// Throw when either:
///
/// - is null
/// - is null
/// - is null
/// - is null
///
public static IEnumerable GenerateCalculationItemsStructure(IEnumerable surfaceLines, IEnumerable soilModels, GeneralPipingInput generalInput, NormProbabilityPipingInput normProbabilityInput)
{
if (surfaceLines == null)
{
throw new ArgumentNullException("surfaceLines");
}
if (soilModels == null)
{
throw new ArgumentNullException("soilModels");
}
if (generalInput == null)
{
throw new ArgumentNullException("generalInput");
}
if (normProbabilityInput == null)
{
throw new ArgumentNullException("normProbabilityInput");
}
List groups = new List();
foreach (var surfaceLine in surfaceLines)
{
var group = CreateCalculationGroup(surfaceLine, soilModels, generalInput, normProbabilityInput);
if (group.GetCalculations().Any())
{
groups.Add(group);
}
else
{
log.WarnFormat(
Resources.PipingCalculationConfigurationHelper_GenerateCalculationsStructure_No_PipingSoilProfile_found_for_RingtoetsPipingSurfaceLine_0_skipped,
surfaceLine.Name);
}
}
return groups;
}
///
/// Gets the stochastic soil models matching the input of a calculation.
///
/// The surface line used to match a .
/// The available stochastic soil models.
/// The (sub)set of stochastic soil models 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 GetStochasticSoilModelsForSurfaceLine(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 soilModelObjectsForCalculation = new List();
foreach (StochasticSoilModel stochasticSoilModel in availableSoilModels.Where(sm => sm.StochasticSoilProfiles.Any()))
{
if (DoesSoilModelGeometryIntersectWithSurfaceLineGeometry(stochasticSoilModel, surfaceLineSegments))
{
soilModelObjectsForCalculation.Add(stochasticSoilModel);
}
}
return soilModelObjectsForCalculation;
}
private static ICalculationBase CreateCalculationGroup(RingtoetsPipingSurfaceLine surfaceLine, IEnumerable soilModels, GeneralPipingInput generalInput, NormProbabilityPipingInput normProbabilityInput)
{
var pipingCalculationGroup = new CalculationGroup(surfaceLine.Name, true);
var stochasticSoilModels = GetStochasticSoilModelsForSurfaceLine(surfaceLine, soilModels);
foreach (var stochasticSoilModel in stochasticSoilModels)
{
foreach (var soilProfile in stochasticSoilModel.StochasticSoilProfiles)
{
pipingCalculationGroup.Children.Add(CreatePipingCalculation(surfaceLine, stochasticSoilModel, soilProfile, pipingCalculationGroup.Children, generalInput, normProbabilityInput));
}
}
return pipingCalculationGroup;
}
private static ICalculationBase CreatePipingCalculation(RingtoetsPipingSurfaceLine surfaceLine, StochasticSoilModel stochasticSoilModel, StochasticSoilProfile stochasticSoilProfile, IEnumerable calculations, GeneralPipingInput generalInput, NormProbabilityPipingInput normProbabilityInput)
{
var nameBase = string.Format("{0} {1}", surfaceLine.Name, stochasticSoilProfile);
var name = NamingHelper.GetUniqueName(calculations, nameBase, c => c.Name);
return new PipingCalculationScenario(generalInput, normProbabilityInput)
{
Name = name,
InputParameters =
{
SurfaceLine = surfaceLine,
StochasticSoilModel = stochasticSoilModel,
StochasticSoilProfile = stochasticSoilProfile
},
Contribution = (RoundedDouble) stochasticSoilProfile.Probability
};
}
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);
}
}
}