using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using Core.Common.Base; using Core.Common.Base.IO; using Core.Common.Gui.Properties; using log4net; using Ringtoets.Piping.Data; using Ringtoets.Piping.IO; using Ringtoets.Piping.IO.Exceptions; using PipingFormsResources = Ringtoets.Piping.Forms.Properties.Resources; using RingtoetsFormsResources = Ringtoets.Common.Forms.Properties.Resources; using ApplicationResources = Ringtoets.Piping.Plugin.Properties.Resources; namespace Ringtoets.Piping.Plugin.FileImporter { /// /// Imports *.csv files having the following header pattern: /// Id;X1;Y1;Z1;...(Xn;Yn;Zn) /// Where Xn;Yn;Zn form the n-th 3D point describing the geometry of the surface line. /// public class PipingSurfaceLinesCsvImporter : IFileImporter { private readonly ILog log; public PipingSurfaceLinesCsvImporter() { log = LogManager.GetLogger(GetType()); } public string Name { get { return PipingFormsResources.PipingSurfaceLinesCollection_DisplayName; } } public string Category { get { return RingtoetsFormsResources.Ringtoets_Category; } } public Bitmap Image { get { return PipingFormsResources.PipingSurfaceLineIcon; } } public Type SupportedItemType { get { return typeof(ICollection); } } public string FileFilter { get { return String.Format("{0} {1} (*.csv)|*.csv", PipingFormsResources.PipingSurfaceLinesCollection_DisplayName, ApplicationResources.Csv_file_name); } } public bool ShouldCancel { get; set; } public ImportProgressChangedDelegate ProgressChanged { get; set; } public bool CanImportFor(object targetItem) { return targetItem is ICollection; } public object ImportItem(string filePath, object targetItem = null) { var importResult = ReadPipingSurfaceLines(filePath); if (!importResult.CriticalErrorOccurred) { if (!ShouldCancel) { AddImportedDataToModel(targetItem, importResult.ImportedItems); } else { HandleUserCancellingImport(); } } return targetItem; } private void NotifyProgress(string currentStepName, int currentStep, int totalNumberOfSteps) { if (ProgressChanged != null) { ProgressChanged(currentStepName, currentStep, totalNumberOfSteps); } } private PipingReadResult ReadPipingSurfaceLines(string path) { PipingSurfaceLinesCsvReader reader; try { reader = new PipingSurfaceLinesCsvReader(path); } catch (ArgumentException e) { return HandleCriticalError(path, e); } var stepName = String.Format(ApplicationResources.PipingSurfaceLinesCsvImporter_Read_PipingSurfaceLines_0_, Path.GetFileName(path)); int itemCount; try { itemCount = reader.GetSurfaceLinesCount(); NotifyProgress(stepName, 0, itemCount); } catch (CriticalFileReadException e) { reader.Dispose(); return HandleCriticalError(path, e); } var readSurfaceLines = new List(itemCount); for (int i = 0; i < itemCount && !ShouldCancel; i++) { try { var ringtoetsPipingSurfaceLine = reader.ReadLine(); PruneConsecutiveDuplicateGeometryPoints(ringtoetsPipingSurfaceLine); readSurfaceLines.Add(ringtoetsPipingSurfaceLine); } catch (CriticalFileReadException e) { reader.Dispose(); return HandleCriticalError(path, e); } catch (LineParseException e) { var message = string.Format(ApplicationResources.PipingSurfaceLinesCsvImporter_ReadPipingSurfaceLines_ParseErrorMessage_0_SurfaceLine_skipped, e.Message); log.Error(message); } NotifyProgress(stepName, i + 1, itemCount); } reader.Dispose(); return new PipingReadResult(false) { ImportedItems = readSurfaceLines }; } private void PruneConsecutiveDuplicateGeometryPoints(RingtoetsPipingSurfaceLine ringtoetsPipingSurfaceLine) { Point3D[] readPoints = ringtoetsPipingSurfaceLine.Points.ToArray(); var consecutiveDuplicatePointIndices = new List(); Point3D previousPoint = null; for (int j = 0; j < readPoints.Length; j++) { if (j != 0 && readPoints[j].Equals(previousPoint)) { consecutiveDuplicatePointIndices.Add(j); previousPoint = readPoints[j]; } else { previousPoint = readPoints[j]; } } if (consecutiveDuplicatePointIndices.Any()) { log.WarnFormat(Resources.PipingSurfaceLinesCsvImporter_SurfaceLine_0_has_multiple_duplicate_geometry_points_and_is_ignored, ringtoetsPipingSurfaceLine.Name); ringtoetsPipingSurfaceLine.SetGeometry(readPoints.Where((p, index) => !consecutiveDuplicatePointIndices.Contains(index))); } } private PipingReadResult HandleCriticalError(string path, Exception e) { var message = string.Format(ApplicationResources.PipingSurfaceLinesCsvImporter_CriticalErrorMessage_0_File_Skipped, e.Message); log.Error(message); return new PipingReadResult(true); } private void AddImportedDataToModel(object target, ICollection readSurfaceLines) { NotifyProgress(ApplicationResources.PipingSurfaceLinesCsvImporter_Adding_imported_data_to_model, readSurfaceLines.Count, readSurfaceLines.Count); var targetCollection = (ICollection)target; foreach (var readSurfaceLine in readSurfaceLines) { targetCollection.Add(readSurfaceLine); } var observableTarget = targetCollection as IObservable; if (observableTarget != null) { observableTarget.NotifyObservers(); } } private void HandleUserCancellingImport() { log.Info(ApplicationResources.PipingSurfaceLinesCsvImporter_ImportItem_Import_cancelled); } } }