// Copyright (C) Stichting Deltares 2019. All rights reserved. // // This file is part of the application DAM - Clients Library. // // 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; using System.Collections.Generic; using System.Linq; using Deltares.Dam.Data.CsvImporters; using Deltares.Geotechnics.Exception; using Deltares.Geotechnics.GeotechnicalGeometry; using Deltares.Geotechnics.Soils; using Deltares.Geotechnics.SurfaceLines; using Deltares.Standard.EventPublisher; using Deltares.Standard.Language; using Deltares.Standard.Logging; namespace Deltares.Dam.Data.IO { public class CombineImportedDataException : ApplicationException { public CombineImportedDataException(string message) : base(message) { } } public class CombineImportedData { private WaterBoard waterBoard; private readonly IList errorMessages = new List(); public WaterBoard WaterBoard { get { return waterBoard; } set { waterBoard = value; } } public IEnumerable LocationRecords { get; set; } public IEnumerable SegmentRecords { get; set; } public IEnumerable SoilProfilerecords { get; set; } public IEnumerable SurfaceLineRecords { get; set; } public IEnumerable CharacteristicPointsRecords { get; set; } public IEnumerable ScenarioRecords { get; set; } public IList ErrorMessages { get { return errorMessages; } } /// /// Adds the dikes from locations to water board. /// /// The water board. private void AddDikesFromLocationsToWaterBoard(WaterBoard targetWaterBoard) { if (LocationRecords == null) return; // Create list of unique dikering ids var dikeRingIdList = new List(); foreach (var locationRecord in LocationRecords) { if (!String.IsNullOrEmpty(locationRecord.DikeRingId)) { if (!dikeRingIdList.Contains(locationRecord.DikeRingId)) { dikeRingIdList.Add(locationRecord.DikeRingId); } } } // if no dikeringIds assigned, then use default dike and assign it to the locations (if there are any) if ((dikeRingIdList.Count <= 0) && LocationRecords.Any()) { string defaultDikeRingId = "Dike from CSV"; if (targetWaterBoard.Dikes.Count > 0) { defaultDikeRingId = targetWaterBoard.Dikes[0].Name; } foreach (var locationRecord in LocationRecords) { locationRecord.DikeRingId = defaultDikeRingId; } dikeRingIdList.Add(defaultDikeRingId); } // Add dikeringids if not yet in waterboard foreach (var dikeRingId in dikeRingIdList) { var dike = targetWaterBoard.Dikes.FirstOrDefault(d => d.Name.Equals(dikeRingId)); if (dike == null) { targetWaterBoard.Dikes.Add(new Dike() { Name = dikeRingId }); } } } /// /// Adds the imported CSV data to dikes. /// public void AddCsvDataToDikes() { if (waterBoard == null) { var damProjectDataNotAssignedForImport = LocalizationManager.GetTranslatedText(GetType(), "damProjectDataNotAssignedForImport"); throw new CombineImportedDataException(damProjectDataNotAssignedForImport); } AddDikesFromLocationsToWaterBoard(waterBoard); foreach (var dike in waterBoard.Dikes) { TransferLocationsData(dike); TransferSoilProfilesData(dike); TransferSegmentData(dike); // Use InvokeWithoutPublishingEvents for performance reasons after introducing SurfaceLine2 DataEventPublisher.InvokeWithoutPublishingEvents(() => { TransferSurfaceLines(dike); }); } } public void AddScenarioDataToDikes() { foreach (var dike in waterBoard.Dikes) { if (ScenarioRecords != null) { TransferScenarios(dike); } } } private bool CheckForValidSegmentId(int segmentRecordId, string segmentId) { if (String.IsNullOrEmpty(segmentId)) { var segmentRecordHasNoId = LocalizationManager.GetTranslatedText(GetType(), "segmentRecordHasNoId"); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, String.Format("Record {0} : {1}", segmentRecordId, segmentRecordHasNoId)); ErrorMessages.Add(logmessage); return false; } return true; } /// /// Check if either a 1D-geometry or a 2D-geometry is specified /// /// /// /// private bool CheckForAnySoilGeometry(string segmentId, string soilProfileId, string soilGeometry2DName) { if ((String.IsNullOrEmpty(soilProfileId)) && (String.IsNullOrEmpty(soilGeometry2DName))) { var segmentHasNoProfileOrGeometry = LocalizationManager.GetTranslatedText(GetType(), "segmentHasNoProfileOrGeometry"); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, String.Format("{0} : {1}", segmentId, segmentHasNoProfileOrGeometry)); ErrorMessages.Add(logmessage); return false; } return true; } /// /// Check if both a 1D-geometry or a 2D-geometry is specified (which is not allowed) /// /// /// /// private bool CheckForDoubleSoilGeometry(string segmentId, string soilProfileId, string soilGeometry2DName) { if ((!String.IsNullOrEmpty(soilProfileId)) && (!String.IsNullOrEmpty(soilGeometry2DName))) { var segmentHasProfileAndGeometry = LocalizationManager.GetTranslatedText(GetType(), "segmentHasProfileAndGeometry"); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, String.Format("{0} : {1}", segmentId, segmentHasProfileAndGeometry)); ErrorMessages.Add(logmessage); return false; } return true; } // Before using this, the Locations and (for 1D profiles) SoilProfiles must be known!? private void TransferSegmentData(Dike dike) { if (SegmentRecords == null) return; if (waterBoard.Segments.Count > 0) { foreach (var segmentRecord in SegmentRecords) { // look for existing segments by Id. If found, remove them from the waterboard as they are to be (re)read here. var oldSegments = waterBoard.Segments.Where(s => s.Name == segmentRecord.SegmentId).ToList(); foreach (var oldSegment in oldSegments) { waterBoard.Segments.Remove(oldSegment); } } } var soilProfileLookup = dike.SoilProfiles != null ? dike.SoilProfiles.ToDictionary(sp => sp.Name, sp => sp) : null; foreach (var segmentRecord in SegmentRecords) { if (CheckForValidSegmentId(segmentRecord.SegmentRecordId, segmentRecord.SegmentId) && (CheckForDoubleSoilGeometry(segmentRecord.SegmentId, segmentRecord.SoilProfileId, segmentRecord.SoilGeometry2DName)) && (CheckForAnySoilGeometry(segmentRecord.SegmentId, segmentRecord.SoilProfileId, segmentRecord.SoilGeometry2DName))) { bool newSegment = false; //check if new segment is needed var segment = waterBoard.GetSegmentByName(segmentRecord.SegmentId); if (segment == null) { newSegment = true; segment = new Segment(); } segment.Name = segmentRecord.SegmentId; if (!String.IsNullOrEmpty(segmentRecord.SoilGeometry2DName)) { segment.AddSoilGeometry2DProbability(segmentRecord.SoilGeometry2DName, segmentRecord.Probability, segmentRecord.SegmentFailureMechanismType); } if (!String.IsNullOrEmpty(segmentRecord.SoilProfileId)) { if (soilProfileLookup == null) { var dikeHasNoSoilProfiles = LocalizationManager.GetTranslatedText(GetType(), "dikeHasNoSoilProfiles"); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, String.Format("{0} : {1}", dike.Name, dikeHasNoSoilProfiles)); ErrorMessages.Add(logmessage); } else { var soilProfileName = segmentRecord.SoilProfileId; SoilProfile1D soilProfile = soilProfileLookup.ContainsKey(soilProfileName) ? soilProfileLookup[soilProfileName] : null; if (soilProfile == null) { //#Bka: do not give message here as it might be that an old project is being loaded which does not have a full // dataset (such as old HHNK projects by Irene), leading to a very large list with non relevant errors as the locations // for which this check is performed are not all used. // var soilProfileForSegmentDoesNotExist = // LocalizationManager.GetTranslatedText(this.GetType(), // "soilProfileForSegmentDoesNotExist"); // LogMessage logmessage = new LogMessage(LogMessageType.Error, null, // String.Format("{0} : {1}:{2}", // segmentRecord.SegmentId, // soilProfileForSegmentDoesNotExist, // segmentRecord.SoilProfileId)); // ErrorMessages.Add(logmessage); } else { segment.AddSoilProfileProbability(soilProfile, segmentRecord.Probability, segmentRecord.SegmentFailureMechanismType); } } } // Note Bka: coupling of segment to location still needs to be done. But can only be achieved when location has info on segment or segment id //segment.Locations.AddRange(dike.Locations.Where(l => l.Segment.Name == segmentRecord.SegmentId)); // var segId = dike.Locations[0].SegmentId; // if (segId == segmentRecord.SegmentId) // dike.Locations[0].Segment = segment; if (newSegment) { waterBoard.Segments.Add(segment); var segmentId = segmentRecord.SegmentId; var locationsWithSegmentId = waterBoard.Locations.Where(x => x.SegmentId == segmentId); foreach (var location in locationsWithSegmentId) { location.Segment = segment; } } } } } private void TransferSoilProfilesData(Dike dike) { if (SoilProfilerecords == null) return; bool newSoilProfile = false; var orgId = ""; SoilProfile1D soilProfile = null; var layerIndex = 0; foreach (var soilProfileRecord in SoilProfilerecords) { if ((String.IsNullOrEmpty(soilProfileRecord.SoilProfileId)) || (String.IsNullOrEmpty(soilProfileRecord.SoilName))) { var noIdForSoilProfileRecordError = LocalizationManager.GetTranslatedText(this.GetType(), "noIdOrSoilForSoilProfileRecordError"); LogMessage logmessage = new LogMessage(LogMessageType.Error, this, String.Format("Record {0} : {1}", soilProfileRecord.SoilProfileRecordId, noIdForSoilProfileRecordError)); ErrorMessages.Add(logmessage); AddErrorMessage("noIdOrSoilForSoilProfileRecordError", soilProfileRecord); } else { // see if a next profile is to be converted from the csv data. If not, layer needs to be added to the current profile if (orgId != soilProfileRecord.SoilProfileId) { // first add current profile (if it exists) to dike. if (soilProfile != null) { if (newSoilProfile) { try { soilProfile.ValidateDirect(); dike.SoilProfiles.Add(soilProfile); } catch (SoilProfileLayersNotSortedDescendingException e) { LogMessage logmessage = new LogMessage(LogMessageType.Error, null, e.Message); ErrorMessages.Add(logmessage); } layerIndex = 0; } newSoilProfile = false; } // determine the next profile (existing or new) soilProfile = dike.SoilProfiles.FirstOrDefault(s => s.Name == soilProfileRecord.SoilProfileId); if (soilProfile == null) { soilProfile = new SoilProfile1D(); newSoilProfile = true; } // clear layers of existing profile if (soilProfile.Layers != null) { soilProfile.Layers.Clear(); } else { var existingSoilProfileHasNoLayers = LocalizationManager.GetTranslatedText(this.GetType(), "existingSoilProfileHasNoLayers"); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, String.Format("{0} : {1}", soilProfileRecord.SoilProfileId, existingSoilProfileHasNoLayers)); ErrorMessages.Add(logmessage); } soilProfile.Name = soilProfileRecord.SoilProfileId; orgId = soilProfileRecord.SoilProfileId; } // if this is a dummy layer to set the bottom level for the entire profile, then do so if (soilProfileRecord.SoilName == SoilProfile1D.SoilProfileBottomLevelId) { soilProfile.BottomLevel = soilProfileRecord.TopLevel; } else { // else set the layer SoilLayer1D layer = new SoilLayer1D(); layer.TopLevel = soilProfileRecord.TopLevel; var soilIndex = dike.SoilList.GetSoilIndexByName(soilProfileRecord.SoilName); if (soilIndex == -1) { var soil = new Soil { Name = soilProfileRecord.SoilName }; dike.SoilList.Soils.Add(soil); soilIndex = dike.SoilList.Soils.Count - 1; } layer.Soil = dike.SoilList.Soils[soilIndex]; layer.Name = "Layer" + (layerIndex); layerIndex++; soilProfile.Layers.Add(layer); } } } // finally add last current profile to dike. if ((soilProfile != null) && (newSoilProfile)) { try { if ((soilProfile.Layers == null) || (soilProfile.Layers.Count == 0)) { throw new SoilProfileLayersNotSortedDescendingException(String.Format("Soilprofile '{0}' has no layers", soilProfile.Name)); } soilProfile.ValidateDirect(); dike.SoilProfiles.Add(soilProfile); } catch (SoilProfileLayersNotSortedDescendingException e) { LogMessage logmessage = new LogMessage(LogMessageType.Error, null, e.Message); ErrorMessages.Add(logmessage); } } // Make sure all soilprofiles last layer have a height foreach (var soilProfile1 in dike.SoilProfiles) { try { soilProfile1.EnsureLastLayerHasHeight(); } catch (Exception e) { //var error = new StringBuilder(); string error = String.Format("Error postprocessing soilprofile '{0}': {1}", soilProfile1.Name, e.Message); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, error); ErrorMessages.Add(logmessage); } } } internal bool CheckCharacteristicPointsForCoincidingLocations(SurfaceLine2 surfaceLine2, out CharacteristicPointType type1, out CharacteristicPointType type2) { var doubleFound = false; type1 = CharacteristicPointType.None; type2 = CharacteristicPointType.None; var points = surfaceLine2.CharacteristicPoints; foreach (var characteristicPoint in surfaceLine2.CharacteristicPoints) { if (!doubleFound) { // Find the coinciding points var doublePoints = points.Where(x => Math.Abs(x.X - characteristicPoint.X) < 1e-4 && Math.Abs(x.Y - characteristicPoint.Y) < 1e-4 && Math.Abs(x.Z - characteristicPoint.Z) < 1e-4); if (doublePoints.Count() > 1) { // if there are coinciding points, see if the types clash. Only valid coinciding points are traffic loads // which may coincide with any other type of point var firstType = doublePoints.First().CharacteristicPointType; var skip = 0; foreach (var doublePoint in doublePoints) { if (skip > 0 && !doubleFound && firstType != CharacteristicPointType.TrafficLoadInside && firstType != CharacteristicPointType.TrafficLoadOutside) { if (doublePoint.CharacteristicPointType != CharacteristicPointType.TrafficLoadInside && doublePoint.CharacteristicPointType != CharacteristicPointType.TrafficLoadOutside) { doubleFound = doublePoint.CharacteristicPointType != firstType; if (doubleFound) { type1 = firstType; type2 = doublePoint.CharacteristicPointType; } } } firstType = doublePoint.CharacteristicPointType; skip++; } } } } return !doubleFound; } private void TransferSurfaceLines(Dike dike) { if (SurfaceLineRecords == null) return; foreach (var surfaceLineRecord in SurfaceLineRecords) { if (String.IsNullOrEmpty(surfaceLineRecord.SurfaceLineId)) { var noIdForSurfaceLineRecordError = LocalizationManager.GetTranslatedText(GetType(), "noIdSurfaceLineRecordError"); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, String.Format("Record {0} : {1}", surfaceLineRecord.SurfaceLineRecordId, noIdForSurfaceLineRecordError)); ErrorMessages.Add(logmessage); } else { bool newSurfaceLine = false; SurfaceLine2 surfaceLine = dike.SurfaceLines2.FirstOrDefault(s => s.Name == surfaceLineRecord.SurfaceLineId); if (surfaceLine == null) { surfaceLine = new SurfaceLine2 { Geometry = new LocalizedGeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; newSurfaceLine = true; } surfaceLine.Name = surfaceLineRecord.SurfaceLineId; // first add all points from the surface line csv for (int i = 0; i < surfaceLineRecord.Xcoors.Count; i++) { // empty points will not be added if (surfaceLineRecord.Xcoors[i] != -1 || surfaceLineRecord.Ycoors[i] != -1 || surfaceLineRecord.Zcoors[i] != -1) surfaceLine.EnsurePointOfType(surfaceLineRecord.Xcoors[i], surfaceLineRecord.Ycoors[i], surfaceLineRecord.Zcoors[i], null); } // Add the surface line to the dike if (newSurfaceLine) { dike.SurfaceLines2.Add(surfaceLine); } // now see if all characteristic points belonging to this surface line are part of the surface line var characteristicPointsRecord = CharacteristicPointsRecords.FirstOrDefault(s => s.SurfaceLineId == surfaceLine.Name); bool charCheck = true; if (characteristicPointsRecord != null) { foreach (var point in characteristicPointsRecord.Points) { // ignore unset points if (!((point.X == -1) && (point.Y == -1) && (point.Z == -1))) { var tppoint = surfaceLine.Geometry.GetPointAt(point.X, point.Y, point.Z); if (tppoint != null) { surfaceLine.EnsurePointOfType(point.X, point.Y, point.Z, point.Type); } else { var charPointNotFoundInSurfaceError = LocalizationManager.GetTranslatedText(GetType(), "charPointNotFoundInSurfaceError"); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, String.Format("{0} : {1} {2}", surfaceLine.Name, charPointNotFoundInSurfaceError, point.Type)); ErrorMessages.Add(logmessage); charCheck = false; } } } } else { var noCharPointsFoundForSurfaceError = LocalizationManager.GetTranslatedText(GetType(), "noCharPointsFoundForSurfaceError"); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, String.Format("{0} : {1}", surfaceLine.Name, noCharPointsFoundForSurfaceError)); ErrorMessages.Add(logmessage); charCheck = false; } // Check on illegal coinciding characteristic points if (charCheck) { charCheck = CheckOnCoincidingPoints(surfaceLine); } if (!charCheck) { surfaceLine.Dispose(); dike.SurfaceLines2.Remove(surfaceLine); } } } } internal bool CheckOnCoincidingPoints(SurfaceLine2 surfaceLine) { bool charCheck; CharacteristicPointType firstType; CharacteristicPointType secondType; charCheck = CheckCharacteristicPointsForCoincidingLocations(surfaceLine, out firstType, out secondType); if (!charCheck) { var coincidingCharPointsFoundForSurfaceError = LocalizationManager.GetTranslatedText(GetType(), "CoincidingCharPointsFoundForSurfaceError"); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, String.Format("{0} : {1} : {2} : {3}", surfaceLine.Name, coincidingCharPointsFoundForSurfaceError, firstType.ToString(), secondType.ToString())); ErrorMessages.Add(logmessage); } return charCheck; } private void TransferScenarios(Dike dike) { if (ScenarioRecords == null) return; var dikeLocationLookup = dike.Locations.ToDictionary(l => l.Name, l => l); foreach (var scenarioRecord in ScenarioRecords) { bool recordError = false; if (string.IsNullOrEmpty(scenarioRecord.LocationId)) { var noLocationIdForScenarioRecordError = LocalizationManager.GetTranslatedText(GetType(), "noLocationIdForScenarioRecordError"); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, string.Format("Record {0} : {1}", scenarioRecord.ScenarioRecordId, noLocationIdForScenarioRecordError)); ErrorMessages.Add(logmessage); recordError = true; } // faassen: location id was of type int with default value -1 if empty. Now it is string and null as the default value if (scenarioRecord.LocationScenarioId == null) { var invalidLocationScenarioIdForScenarioRecordError = LocalizationManager.GetTranslatedText(GetType(), "invalidLocationScenarioIdForScenarioRecordError"); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, string.Format("Record {0} : {1}", scenarioRecord.ScenarioRecordId, invalidLocationScenarioIdForScenarioRecordError)); ErrorMessages.Add(logmessage); recordError = true; } var dikeLocation = dikeLocationLookup.ContainsKey(scenarioRecord.LocationId) ? dikeLocationLookup[scenarioRecord.LocationId] : null; if (dikeLocation == null) { var locationNotFoundForScenarioRecordError = LocalizationManager.GetTranslatedText(GetType(), "locationNotFoundForScenarioRecordError"); LogMessage logmessage = new LogMessage(LogMessageType.Error, this, string.Format("Record {0} : {1}", scenarioRecord.ScenarioRecordId, locationNotFoundForScenarioRecordError)); ErrorMessages.Add(logmessage); recordError = true; } if (!recordError) { // Add to location scenario list var dikeScenario = dikeLocation.Scenarios.FirstOrDefault(s => s.Location.Name == scenarioRecord.LocationId && s.LocationScenarioID == scenarioRecord.LocationScenarioId.ToString()); if (dikeScenario != null) { var duplicateScenarioRecordError = LocalizationManager.GetTranslatedText(GetType(), "duplicateScenarioRecordError"); string errorMessage = string.Format(duplicateScenarioRecordError, dikeLocation.Name, dikeScenario.LocationScenarioID); LogMessage logmessage = new LogMessage(LogMessageType.Error, null, string.Format("Record {0} : {1}", scenarioRecord.ScenarioRecordId, errorMessage)); ErrorMessages.Add(logmessage); } else { var modelFactors = new ModelFactors(); if (scenarioRecord.SafetyFactorStabilityInnerSlope.HasValue) { modelFactors.RequiredSafetyFactorStabilityInnerSlope = scenarioRecord.SafetyFactorStabilityInnerSlope.Value; } if (scenarioRecord.SafetyFactorStabilityOuterSlope.HasValue) { modelFactors.RequiredSafetyFactorStabilityOuterSlope = scenarioRecord.SafetyFactorStabilityOuterSlope.Value; } if (scenarioRecord.SafetyFactorPiping.HasValue) { modelFactors.RequiredSafetyFactorPiping = scenarioRecord.SafetyFactorPiping.Value; } if (scenarioRecord.UpliftCriterionStability.HasValue) { modelFactors.UpliftCriterionStability = scenarioRecord.UpliftCriterionStability.Value; } if (scenarioRecord.UpliftCriterionPiping.HasValue) { modelFactors.UpliftCriterionPiping = scenarioRecord.UpliftCriterionPiping.Value; } var scenario = new Scenario { Location = dikeLocation, LocationScenarioID = scenarioRecord.LocationScenarioId, ModelFactors = modelFactors }; var locationRecord = LocationRecords.FirstOrDefault(l => l.LocationId == scenarioRecord.LocationId); // set values in scenario (1 from scenariorecord, 2 from locationrecord, 3 default) scenario.PlLineOffsetBelowDikeToeAtPolder = scenarioRecord.PlLineOffsetBelowDikeToeAtPolder ?? (locationRecord.PlLineOffsetBelowDikeToeAtPolder ?? scenario.PlLineOffsetBelowDikeToeAtPolder); scenario.PlLineOffsetBelowDikeTopAtPolder = scenarioRecord.PlLineOffsetBelowDikeTopAtPolder ?? (locationRecord.PlLineOffsetBelowDikeTopAtPolder ?? scenario.PlLineOffsetBelowDikeTopAtPolder); scenario.PlLineOffsetBelowDikeTopAtRiver = scenarioRecord.PlLineOffsetBelowDikeTopAtRiver ?? (locationRecord.PlLineOffsetBelowDikeTopAtRiver ?? scenario.PlLineOffsetBelowDikeTopAtRiver); scenario.PlLineOffsetBelowShoulderBaseInside = scenarioRecord.PlLineOffsetBelowShoulderBaseInside ?? (locationRecord.PlLineOffsetBelowShoulderBaseInside ?? scenario.PlLineOffsetBelowShoulderBaseInside); // set values in scenario (1 from scenariorecord, 2 from locationrecord) scenario.PlLineOffsetBelowDikeCrestMiddle = scenarioRecord.PlLineOffsetBelowDikeCrestMiddle ?? locationRecord.PlLineOffsetBelowDikeCrestMiddle; scenario.PlLineOffsetFactorBelowShoulderCrest = scenarioRecord.PlLineOffsetFactorBelowShoulderCrest ?? locationRecord.PlLineOffsetFactorBelowShoulderCrest; scenario.UsePlLineOffsetBelowDikeCrestMiddle = scenarioRecord.UsePlLineOffsetBelowDikeCrestMiddle ?? locationRecord.UsePlLineOffsetBelowDikeCrestMiddle; scenario.UsePlLineOffsetFactorBelowShoulderCrest = scenarioRecord.UsePlLineOffsetFactorBelowShoulderCrest ?? locationRecord.UsePlLineOffsetFactorBelowShoulderCrest; scenario.HeadPl3 = scenarioRecord.HeadPl3 ?? locationRecord.HeadPl3; scenario.HeadPl4 = scenarioRecord.HeadPl4 ?? locationRecord.HeadPl4; scenario.DikeTableHeight = scenarioRecord.DikeTableHeight ?? locationRecord.DikeTableHeight; scenario.RiverLevel = scenarioRecord.RiverLevel ?? locationRecord.RiverLevel; scenario.RiverLevelLow = scenarioRecord.RiverLevelLow ?? locationRecord.RiverLevelLow; dikeLocation.Scenarios.Add(scenario); } } } } /// /// Transfers the locations data. /// /// The dike. private void TransferLocationsData(Dike dike) { if (LocationRecords == null) return; foreach (var locationRecord in LocationRecords) { if (locationRecord.DikeRingId.Equals(dike.Name)) { // Check if id is defined if (String.IsNullOrEmpty(locationRecord.LocationId)) { AddErrorMessage("noIdLocationRecordError", locationRecord); continue; } // See if location already exist; else create one and add it to the dike Location location = dike.Locations.FirstOrDefault(s => s.Name == locationRecord.LocationId); if (location == null) { var errorInrecord = false; location = new Location(); location.SetDefaultValues(); location.Name = locationRecord.LocationId; location.SurfaceLineId = locationRecord.SurfaceLineId; location.SegmentId = locationRecord.SegmentId; if (locationRecord.DikeRingId != null) { location.DikeRingId = locationRecord.DikeRingId; } if (location.DampingFactorPL3 < 0 || location.DampingFactorPL3 > 1) { AddErrorMessage("DampingFactorPl3BeyondLimits", locationRecord); errorInrecord = true; } if (location.DampingFactorPL4 < 0 || location.DampingFactorPL4 > 1) { AddErrorMessage("DampingFactorPl4BeyondLimits", locationRecord); errorInrecord = true; } location.HeadPL2 = locationRecord.HeadPl2; if (null != locationRecord.DikeEmbankmentMaterial) { location.DikeEmbankmentMaterial = locationRecord.DikeEmbankmentMaterial; } if (null != locationRecord.ShoulderEmbankmentMaterial) { location.ShoulderEmbankmentMaterial = locationRecord.ShoulderEmbankmentMaterial; } location.XRd = locationRecord.GeoX.GetValueOrDefault(location.XRd); location.YRd = locationRecord.GeoY.GetValueOrDefault(location.YRd); location.PolderLevel = locationRecord.PolderLevel.GetValueOrDefault(location.PolderLevel); location.XSoilGeometry2DOrigin = locationRecord.XSoilGeometry2DOrigin.GetValueOrDefault(location.XSoilGeometry2DOrigin); location.DampingFactorPL3 = locationRecord.DampingFactorPl3.GetValueOrDefault(location.DampingFactorPL3); location.DampingFactorPL4 = locationRecord.DampingFactorPl4.GetValueOrDefault(location.DampingFactorPL4); location.PenetrationLength = locationRecord.PenetrationLength.GetValueOrDefault(location.PenetrationLength); location.TrafficLoad = locationRecord.TrafficLoad.GetValueOrDefault(location.TrafficLoad); location.TL_DegreeOfConsolidation = locationRecord.TL_DegreeOfConsolidation; location.PLLineCreationMethod = locationRecord.PLLineCreationMethod.GetValueOrDefault(location.PLLineCreationMethod); if (locationRecord.IntrusionVerticalWaterPressure.HasValue) { location.IntrusionVerticalWaterPressure = locationRecord.IntrusionVerticalWaterPressure.Value; } location.StabilityShoulderGrowSlope = locationRecord.StabilityShoulderGrowSlope.GetValueOrDefault(location.StabilityShoulderGrowSlope); location.StabilityShoulderGrowDeltaX = locationRecord.StabilityShoulderGrowDeltaX.GetValueOrDefault(location.StabilityShoulderGrowDeltaX); location.StabilitySlopeAdaptionDeltaX = locationRecord.StabilitySlopeAdaptionDeltaX.GetValueOrDefault(location.StabilitySlopeAdaptionDeltaX); location.MinimalCircleDepth = locationRecord.MinimalCircleDepth.GetValueOrDefault(location.MinimalCircleDepth); location.DistanceToEntryPoint = locationRecord.DistanceToEntryPoint.GetValueOrDefault(location.DistanceToEntryPoint); location.SlopeDampingPiezometricHeightPolderSide = locationRecord.SlopeDampingPiezometricHeightPolderSide.GetValueOrDefault(location.SlopeDampingPiezometricHeightPolderSide); location.StabilityDesignMethod = locationRecord.StabilityDesignMethod.GetValueOrDefault(location.StabilityDesignMethod); location.SlopeAdaptionStartCotangent = locationRecord.SlopeAdaptionStartCotangent.GetValueOrDefault(location.SlopeAdaptionStartCotangent); location.SlopeAdaptionEndCotangent = locationRecord.SlopeAdaptionEndCotangent.GetValueOrDefault(location.SlopeAdaptionEndCotangent); location.SlopeAdaptionStepCotangent = locationRecord.SlopeAdaptionStepCotangent.GetValueOrDefault(location.SlopeAdaptionStepCotangent); location.StabilityZoneType = locationRecord.StabilityZoneType.GetValueOrDefault(location.StabilityZoneType); location.ForbiddenZoneFactor = locationRecord.ForbiddenZoneFactor.GetValueOrDefault(location.ForbiddenZoneFactor); location.ZoneAreaRestSlopeCrestWidth = locationRecord.ZoneAreaRestSlopeCrestWidth.GetValueOrDefault(location.ZoneAreaRestSlopeCrestWidth); location.NewDepthDitch = locationRecord.NewDepthDitch.GetValueOrDefault(location.NewDepthDitch); location.NewDikeSlopeInside = locationRecord.NewDikeSlopeInside.GetValueOrDefault(location.NewDikeSlopeInside); location.NewDikeSlopeOutside = locationRecord.NewDikeSlopeOutside.GetValueOrDefault(location.NewDikeSlopeOutside); location.NewDikeTopWidth = locationRecord.NewDikeTopWidth.GetValueOrDefault(location.NewDikeTopWidth); location.NewMaxHeightShoulderAsFraction = locationRecord.NewMaxHeightShoulderAsFraction.GetValueOrDefault(location.NewMaxHeightShoulderAsFraction); location.NewMinDistanceDikeToeStartDitch = locationRecord.NewMinDistanceDikeToeStartDitch.GetValueOrDefault(location.NewMinDistanceDikeToeStartDitch); location.NewShoulderBaseSlope = locationRecord.NewShoulderBaseSlope.GetValueOrDefault(location.NewShoulderBaseSlope); location.NewShoulderTopSlope = locationRecord.NewShoulderTopSlope.GetValueOrDefault(location.NewShoulderTopSlope); location.NewSlopeAngleDitch = locationRecord.NewSlopeAngleDitch.GetValueOrDefault(location.NewSlopeAngleDitch); location.NewWidthDitchBottom = locationRecord.NewWidthDitchBottom.GetValueOrDefault(location.NewWidthDitchBottom); location.UseNewDikeSlopeInside = locationRecord.UseNewDikeSlopeInside.GetValueOrDefault(location.UseNewDikeSlopeInside); location.UseNewDikeSlopeOutside = locationRecord.UseNewDikeSlopeOutside.GetValueOrDefault(location.UseNewDikeSlopeOutside); location.UseNewDikeTopWidth = locationRecord.UseNewDikeTopWidth.GetValueOrDefault(location.UseNewDikeTopWidth); location.UseNewDitchDefinition = locationRecord.UseNewDitchDefinition.GetValueOrDefault(location.UseNewDitchDefinition); location.UseNewMaxHeightShoulderAsFraction = locationRecord.UseNewMaxHeightShoulderAsFraction.GetValueOrDefault(location.UseNewMaxHeightShoulderAsFraction); location.UseNewMinDistanceDikeToeStartDitch = locationRecord.UseNewMinDistanceDikeToeStartDitch.GetValueOrDefault(location.UseNewMinDistanceDikeToeStartDitch); location.UseNewShoulderBaseSlope = locationRecord.UseNewShoulderBaseSlope.GetValueOrDefault(location.UseNewShoulderBaseSlope); location.UseNewShoulderTopSlope = locationRecord.UseNewShoulderTopSlope.GetValueOrDefault(location.UseNewShoulderTopSlope); if (!errorInrecord) { dike.Locations.Add(location); } else { location.Dispose(); } } } } } private void AddErrorMessage(string errorMessageTranslationId, CsvImporterLocations.LocationRecord locationRecord) { AddErrorMessage(errorMessageTranslationId, locationRecord.LocationRecordId); } private void AddErrorMessage(string errorMessageTranslationId, CsvImporterSoilProfiles.SoilProfileRecord soilProfileRecord) { AddErrorMessage(errorMessageTranslationId, soilProfileRecord.SoilProfileRecordId); } private void AddErrorMessage(string errorMessageTranslationId, int id) { var noIdForSoilProfileRecordError = LocalizationManager.GetTranslatedText(GetType(), errorMessageTranslationId); var logmessage = new LogMessage( LogMessageType.Error, this, String.Format("Record {0} : {1}", id, noIdForSoilProfileRecordError ) ); ErrorMessages.Add(logmessage); } } }