using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Linq; using Deltares.Geotechnics.Soils; using Deltares.Geotechnics.SurfaceLines; using Deltares.Probabilistic; using Deltares.Standard; using Deltares.Standard.EventPublisher; using Deltares.Standard.IO; using Deltares.Standard.Language; using Deltares.Standard.Logging; using Deltares.Standard.Reflection; namespace Deltares.DeltaModel { /// /// Class responsible for populating the delta model /// public class DeltaModelFactory : ITransactionDataFactory { private readonly DeltaModel deltaModel; private readonly List modifiedLists = new List(); /// /// Default constructor /// /// Delta model to be populated public DeltaModelFactory(DeltaModel deltaModel) { this.deltaModel = deltaModel; } public void SetAquiferDictionary(Dictionary dict) { deltaModel.Soils.AquiferDictionary = dict; } /// /// Sends the modified lists to the data event publisher. /// public void SendModifiedLists() { foreach (var modifiedList in modifiedLists) { DataEventPublisher.DataListModified(modifiedList); } } /// /// Find an existing object or creates an object with a certain specification and populates the delta model with it /// /// Unique identifier of the object to be find/created /// Type of object to be find/created /// /// The found/created object public virtual object GetObject(string key, Type objectType, Enum subType) { var item = GetExistingObject(key, objectType, subType); if (item == null) { item = CreateItem(key, subType, objectType); var list = GetList(objectType, subType); if (!modifiedLists.Contains(list)) { DataEventPublisher.BeforeChange(list); modifiedLists.Add(list); } list.Add(item); } return item; } /// /// Find an object with a certain specification /// /// Unique identifier of the object to be found /// Type of object to be found /// /// The existing object public virtual object GetExistingObject(string key, Type objectType, Enum subType) { var type = objectType; // special case, SoilProfile can be either 1D or 2D if (type == typeof(SoilProfile)) { var profile = deltaModel.SoilProfiles1D.FirstOrDefault(p => p.Name == key) as SoilProfile; profile = profile ?? deltaModel.SoilProfiles2D.FirstOrDefault(p => p.Name == key); return profile; } var list = GetList(type, subType); if (!string.IsNullOrEmpty(key)) { if (typeof(IIdentifier).IsAssignableFrom(type)) { return list.Cast().FirstOrDefault(item => item.Id.ToString().Equals(key)); } if (typeof(IStringIdentifier).IsAssignableFrom(type)) { return list.Cast().FirstOrDefault(item => item.Id.ToString().Equals(key)); } if (typeof(IName).IsAssignableFrom(type)) { return list.Cast().FirstOrDefault(item => item.Name.Equals(key)); } if (type == typeof(ProbabilityDefinition)) { return list.Cast().FirstOrDefault(item => item.Probability.Equals(Convert.ToDouble(key))); } } return null; } /// /// Find an existing object or creates an object with a certain specification and populates the delta model with it /// /// Unique identifier of the object to be found/created /// /// The found/created object public T GetObject(string key, Enum subType) { var returnObject = GetObject(key, typeof(T), subType); if (returnObject is T) { return (T)returnObject; } return default(T); } /// /// Find an object with a certain specification /// /// Unique identifier of the object to be found /// /// The existing object public T GetExistingObject(string key, Enum subType) { var returnObject = GetExistingObject(key, typeof(T), subType); if (returnObject is T) { return (T)returnObject; } return default(T); } public bool ShouldRegister(RegisteredItem registeredItem) { // specific workaround: for Surfacelines imported in RD (absolute) coordinates, the additional information from crossections shapefile (angle offset etc.) needs to be ignored (RT-1270) var dikeLocation = registeredItem.Subject as DikeLocation; if (dikeLocation != null && registeredItem.PropertyName.StartsWith(dikeLocation.GetMemberName(cl => cl.SurfaceLine))) { var surfaceLine = dikeLocation.SurfaceLine; if (surfaceLine != null) { if (surfaceLine.IsLocalized) { LogManager.Add(new LogMessage(LogMessageType.Warning, registeredItem.Subject, String.Format( (string) LocalizationManager.GetTranslatedText(typeof(DeltaModelFactory), "SurfacelinePropertyNotset_propertyname"), (object) registeredItem.PropertyName))); return false; } } } return true; } public virtual void ProcessImportedItems(ImporterProgressDelegate progress) { MapIsAquiferFromSoilToLayers(); foreach (var soil in deltaModel.Soils.Soils) { if (soil.Color.Name == "ffffffff") { soil.Color = DefaultSoilColor(soil.SoilType); } } foreach (var schematizedSurfaceLine in deltaModel.SchematizedSurfaceLines) { schematizedSurfaceLine.CharacteristicPoints.RefreshHeight(); } } protected virtual object CreateItem(string key, Enum subType, Type type) { var newItem = Activator.CreateInstance(type); if (newItem is IIdentifier) { ((IIdentifier) newItem).Id = Convert.ToInt32(key); } else if (newItem is IStringIdentifier) { ((IStringIdentifier) newItem).Id = key; } else if (newItem is IName) { ((IName) newItem).Name = key; } if (newItem is CharacteristicLine) { ((CharacteristicLine) newItem).PointType = (CharacteristicPointType) subType; } else if (newItem is ProbabilityDefinition) { ((ProbabilityDefinition) newItem).Probability = Convert.ToDouble(key); } else if (newItem is BlockRevetmentCrossSection) { ((BlockRevetmentCrossSection) newItem).DikeLine = deltaModel.DikeLines.First(); // No support for multiple dike lines yet } else if (newItem is DikeCrossSection) { var dikeCrossSection = (DikeCrossSection) newItem; if (dikeCrossSection.DikeLine == null) { dikeCrossSection.DikeLine = deltaModel.DikeLines.First(); // No support for multiple dike lines yet } } return newItem; } /// /// Gets the list in the delta model corresponding with the item type /// /// Item type /// The subtype of the item /// List protected virtual IList GetList(Type type, Enum subType) { return deltaModel.GetListForType(type); } private void MapIsAquiferFromSoilToLayers() { if (deltaModel.Soils.AquiferDictionary.Count > 0) { foreach (var soilProfile1D in deltaModel.SoilProfiles1D) { foreach (var soilLayer1D in soilProfile1D.Layers) { if (deltaModel.Soils.AquiferDictionary.ContainsKey(soilLayer1D.Soil)) { soilLayer1D.IsAquifer = deltaModel.Soils.AquiferDictionary[soilLayer1D.Soil]; } } } foreach (var soilProfile2D in deltaModel.SoilProfiles2D) { foreach (var soilLayer2D in soilProfile2D.Surfaces) { if (deltaModel.Soils.AquiferDictionary.ContainsKey(soilLayer2D.Soil)) { soilLayer2D.IsAquifer = deltaModel.Soils.AquiferDictionary[soilLayer2D.Soil]; } } } } } // default soil colors, private static Color DefaultSoilColor(SoilType type) { switch (type) { case SoilType.Sand: return Color.LightYellow; case SoilType.Clay: return Color.LightGray; case SoilType.Gravel: return Color.Gray; case SoilType.Loam: return Color.DarkKhaki; case SoilType.Peat: return Color.SaddleBrown; default: return Color.White; } } public virtual void Start() { // nothing to do } public virtual void Commit() { // nothing to do } public virtual void Abort() { ClearAllLists(); } protected virtual void ClearAllLists() { deltaModel.ClearAllLists(); } } }