// Copyright (C) Stichting Deltares 2023. All rights reserved. // // This file is part of the application DAM - UI. // // DAM - UI 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.Collections.Generic; using System.ComponentModel; using Deltares.Geographic; using Deltares.Standard.Attributes; using Deltares.Standard.EventPublisher; using Deltares.Standard.Validation; namespace Deltares.Dam.Data { using System; using System.Xml.Serialization; using Deltares.Standard; public interface ILocationJob { Location Location { get; } } public class LocationJob : DamJob, ILocationJob, IGeographicPoint, IVisibleEnabled { private TimeSerie waterLevelTimeSerie = new TimeSerie(); private LocationResult locationResult = new LocationResult(); private static string currentProfileName = ""; private static string currentScenarioName = ""; private static string currentCalculation = ""; private static DateTime currentTime = DateTime.Today; private static DamProjectType damProjectType = DamProjectType.Calamity; private double designRequiredFactor = 0.0; public LocationJob() { } public LocationJob(object subject) : base(subject) { } /// /// TODO: what todo when location is null? /// public double XRd { get { return this.Location == null ? 0 : this.Location.XRd; } } public double YRd { get { return this.Location == null ? 0 : this.Location.YRd; } } [XmlIgnore] [Validate] public Location Location { get { return this.Subject as Location; } set { this.Subject = value; } } public TimeSerie WaterLevelTimeSerie { get { return waterLevelTimeSerie; } set { DataEventPublisher.BeforeChange(this, "WaterLevelTimeSerie"); waterLevelTimeSerie = value; DataEventPublisher.AfterChange(this, "WaterLevelTimeSerie"); } } public virtual LocationResult LocationResult { get { return locationResult; } set { DataEventPublisher.BeforeChange(this, "LocationResult"); locationResult = value; DataEventPublisher.AfterChange(this, "LocationResult"); } } private bool HasUsableStabilityTimeSerieEntries() { var res = false; foreach (var timeSerieEntry in locationResult.StabilityTimeSerie.Entries) { if (!double.IsNaN(timeSerieEntry.Value)) { res = true; break; } } return res; } public bool HasLocationResults { get { if (locationResult == null) return false; return ((locationResult.PipingTimeSerie != null && locationResult.PipingTimeSerie.Entries.Count > 0) || (locationResult.StabilityTimeSerie != null && locationResult.StabilityTimeSerie.Entries.Count > 0 && HasUsableStabilityTimeSerieEntries())); } } public LocationResult GetLocationResultWithStabilityTimeSerie(string locationName) { LocationResult result = null; if (locationResult != null && locationResult.StabilityTimeSerie != null && locationResult.StabilityTimeSerie.LocationId == locationName && locationResult.StabilityTimeSerie.Entries != null && locationResult.StabilityTimeSerie.Entries.Count > 1) { result = locationResult; } return result; } public LocationResult GetFirstLocationResultWithStabilityTimeSerie() { LocationResult result = null; if (locationResult != null && locationResult.StabilityTimeSerie != null && locationResult.StabilityTimeSerie.Entries != null && locationResult.StabilityTimeSerie.Entries.Count > 1) { result = locationResult; } return result; } public CsvExportData GetFirstDesignResult() { if (this.HasDesignScenarioResults) { Scenario scenario = Location.Scenarios[0]; if (scenario != null && scenario.CalculationResults.Count > 0) { return scenario.CalculationResults[0]; } } return null; } public CsvExportData GetDesignResultByProfileScenarioAndCalculationName(string profileName, string scenarioName, string calculationName) { if (this.HasDesignScenarioResults) { foreach (var scenario in Location.Scenarios) { foreach (var calculationResult in scenario.CalculationResults) { if (calculationResult.ProfileName == profileName && calculationResult.ScenarioName == scenarioName && calculationResult.StabilityModel.ToString() == calculationName) return calculationResult; } } } return null; } /// /// Gets a value indicating whether this instance has (Design) scenario results. /// /// /// true if this instance has scenario results; otherwise, false. /// public bool HasDesignScenarioResults { get { List scenarios = Location.Scenarios; foreach (var scenario in scenarios) { foreach (var calculationResult in scenario.CalculationResults) { if ((calculationResult.SafetyFactor != null) || (calculationResult.CalculationResult == CalculationResult.UnexpectedError) ) { return true; } } } return false; } } /// /// Get lowest safetyfactor of all scenarios /// /// private double GetLowestRealSafetyFactorFromDesignScenarios() { var res = double.MaxValue; List scenarios = Location.Scenarios; foreach (var scenario in scenarios) { foreach (var calculationResult in scenario.CalculationResults) { if (calculationResult.CalculationResult == CalculationResult.UnexpectedError) { res = -1; } if (calculationResult.SafetyFactor != null) { if (calculationResult.SafetyFactor.Value < res) { res = calculationResult.SafetyFactor.Value; if (calculationResult.RequiredSafetyFactor != null) { designRequiredFactor = calculationResult.RequiredSafetyFactor.Value; } } } } } if (res == double.MaxValue) res = DamGlobalConstants.NoRunValue; return res; } [Data] [Label("Safety factor")] [XmlIgnore] [Format("F3")] public double SafetyFactor { get { if (DamProjectType == DamProjectType.Calamity) { if (HasLocationResults) { TimeSerie timeSerie = this.LocationResult.StabilityTimeSerie; return timeSerie.GetValue(CurrentTime); } return DamGlobalConstants.NoRunValue; } if (DamProjectType == DamProjectType.Design) { return GetLowestRealSafetyFactorFromDesignScenarios(); } return DamGlobalConstants.NoRunValue; } } [Data] [Format("F3")] public double RequiredFactorOfSafety { get { if (DamProjectType == DamProjectType.Design) { return designRequiredFactor; } return 1.0; } } [Data] [XmlIgnore] [Label("Result")] public JobResult Result { get { return JobResultInterpreter.GetJobResult(SafetyFactor, RequiredFactorOfSafety, true); } } [XmlIgnore] [Browsable(false)] public double X { get { return this.XRd; } set { if (Location != null) Location.XRd = value; } } [XmlIgnore] [Browsable(false)] public double Y { get { return this.YRd; } set { if (Location != null) Location.YRd = value; } } [XmlIgnore] [Browsable(false)] public static string CurrentProfileName { get { return currentProfileName; } set { currentProfileName = value; } } [XmlIgnore] [Browsable(false)] public static string CurrentScenarioName { get { return currentScenarioName; } set { currentScenarioName = value; } } [XmlIgnore] [Browsable(false)] public static string CurrentCalculation { get { return currentCalculation; } set { currentCalculation = value; } } [XmlIgnore] [Browsable(false)] public static DateTime CurrentTime { get { return currentTime; } set { currentTime = value; } } [XmlIgnore] [Browsable(false)] public static DamProjectType DamProjectType { get { return damProjectType; } set { damProjectType = value; } } public bool IsEnabled(string property) { return true; } public bool IsVisible(string property) { switch (property) { case "SafetyFactor": return this.Result != JobResult.NoRun && this.Result != JobResult.Failed; case "RequiredFactorOfSafety": return this.Result != JobResult.NoRun && this.Result != JobResult.Failed; case "WaterLevelTimeSerie": return HasLocationResults; default: return true; } } public override string ToString() { return this.Location != null ? this.Location.ToString() : ""; } } }