// 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.Collections.ObjectModel;
using System.Drawing;
using System.Linq;
using Core.Common.Base.IO;
using Core.Common.IO.Exceptions;
using Core.Common.IO.Readers;
using log4net;
using Ringtoets.Piping.Data;
using Ringtoets.Piping.Forms.PresentationObjects;
using Ringtoets.Piping.IO.Exceptions;
using Ringtoets.Piping.IO.SoilProfile;
using Ringtoets.Piping.Primitives;
using PipingFormsResources = Ringtoets.Piping.Forms.Properties.Resources;
using RingtoetsFormsResources = Ringtoets.Common.Forms.Properties.Resources;
using RingtoetsPluginResources = Ringtoets.Piping.Plugin.Properties.Resources;
namespace Ringtoets.Piping.Plugin.FileImporter
{
///
/// Imports .soil files (SqlLite database files) created with the DSoilModel application.
///
public class PipingSoilProfilesImporter : FileImporterBase
{
private readonly ILog log = LogManager.GetLogger(typeof(PipingSoilProfilesImporter));
public override string Name
{
get
{
return PipingFormsResources.PipingSoilProfilesCollection_DisplayName;
}
}
public override string Category
{
get
{
return RingtoetsFormsResources.Ringtoets_Category;
}
}
public override Bitmap Image
{
get
{
return PipingFormsResources.PipingSoilProfileIcon;
}
}
public override string FileFilter
{
get
{
return String.Format("{0} {1} (*.soil)|*.soil",
PipingFormsResources.PipingSoilProfilesCollection_DisplayName, RingtoetsPluginResources.Soil_file_name);
}
}
public override ProgressChangedDelegate ProgressChanged { protected get; set; }
public override bool Import(object targetItem, string filePath)
{
var surfaceLinesContext = (StochasticSoilModelContext) targetItem;
if (!IsReferenceLineAvailable(surfaceLinesContext))
{
log.Error(RingtoetsPluginResources.PipingSoilProfilesImporter_Import_Required_referenceline_missing);
return false;
}
var importSoilProfileResult = ReadSoilProfiles(filePath);
if (importSoilProfileResult.CriticalErrorOccurred)
{
return false;
}
if (ImportIsCancelled)
{
HandleUserCancellingImport();
return false;
}
var importStochasticSoilModelResult = ReadStochasticSoilModels(filePath);
if (importStochasticSoilModelResult.CriticalErrorOccurred)
{
return false;
}
if (ImportIsCancelled)
{
HandleUserCancellingImport();
return false;
}
AddSoilProfilesToStochasticSoilModels(importSoilProfileResult.ImportedItems, importStochasticSoilModelResult.ImportedItems);
CheckIfAllProfilesAreUsed(importSoilProfileResult.ImportedItems, importStochasticSoilModelResult.ImportedItems);
AddImportedDataToModel(surfaceLinesContext, importStochasticSoilModelResult.ImportedItems);
return true;
}
private void AddSoilProfilesToStochasticSoilModels(ICollection soilProfiles, ICollection stochasticSoilModels)
{
foreach (var stochasticSoilModel in stochasticSoilModels)
{
foreach (var stochasticSoilProfile in stochasticSoilModel.StochasticSoilProfiles)
{
var soilProfile = soilProfiles.FirstOrDefault(s => s.PipingSoilProfileId == stochasticSoilProfile.SoilProfileId);
if (soilProfile != null)
{
stochasticSoilProfile.SoilProfile = soilProfile;
}
}
}
}
private void CheckIfAllProfilesAreUsed(ICollection soilProfiles, ICollection stochasticSoilModels)
{
foreach (var soilProfile in soilProfiles.Where(soilProfile => !PipingSoilProfileIsUsed(soilProfile, stochasticSoilModels)))
{
log.WarnFormat(RingtoetsPluginResources.PipingSoilProfilesImporter_CheckIfAllProfilesAreUsed_SoilProfile_0_is_not_used_in_any_stochastic_soil_model, soilProfile.Name);
}
}
private static bool PipingSoilProfileIsUsed(PipingSoilProfile soilProfile, ICollection stochasticSoilModels)
{
return stochasticSoilModels.Any(stochasticSoilModel => stochasticSoilModel.StochasticSoilProfiles.Any(stochasticSoilProfile => stochasticSoilProfile.SoilProfile == soilProfile));
}
private void AddImportedDataToModel(StochasticSoilModelContext target, ICollection readStochasticSoilModels)
{
var targetCollection = target.FailureMechanism.StochasticSoilModels;
var stochasticSoilModelCount = readStochasticSoilModels.Count;
var currentIndex = 1;
foreach (var readStochasticSoilModel in readStochasticSoilModels)
{
NotifyProgress(RingtoetsPluginResources.PipingSoilProfilesImporter_Adding_imported_data_to_model, currentIndex++, stochasticSoilModelCount);
if (!ValidateStochasticSoilModel(readStochasticSoilModel))
{
continue;
}
var stochasticSoilModel = targetCollection.FirstOrDefault(ssm => ssm.Id == readStochasticSoilModel.Id);
if (stochasticSoilModel != null)
{
log.WarnFormat(RingtoetsPluginResources.PipingSoilProfilesImporter_AddImportedDataToModel_Stochastisch_soil_model_0_already_exists, stochasticSoilModel.Name);
}
targetCollection.Add(readStochasticSoilModel);
}
}
private bool ValidateStochasticSoilModel(StochasticSoilModel stochasticSoilModel)
{
if (stochasticSoilModel.StochasticSoilProfiles.Count(s => s.SoilProfile == null) > 0)
{
log.WarnFormat(RingtoetsPluginResources.PipingSoilProfilesImporter_ValidateStochasticSoilModel_No_profiles_found_in_stochastic_soil_model_0, stochasticSoilModel.Name);
return false;
}
if (stochasticSoilModel.Geometry.Count == 0)
{
log.WarnFormat("Er zijn geen coordinaten gevonden in het stochastich ondersgrondmodel '{0}', deze wordt overgeslagen.", stochasticSoilModel.Name);
return false;
}
if (!stochasticSoilModel.StochasticSoilProfiles.Where(s => s.SoilProfile != null).Sum(s => s.Probability).Equals(1.0))
{
log.WarnFormat("De som van de kans van voorkomen in het stochastich ondersgrondmodel '{0}' is niet gelijk aan 1.", stochasticSoilModel.Name);
}
return true;
}
private static bool IsReferenceLineAvailable(StochasticSoilModelContext targetItem)
{
return targetItem.AssessmentSection.ReferenceLine != null;
}
private void HandleException(string path, Exception e)
{
var message = string.Format(RingtoetsPluginResources.PipingSoilProfilesImporter_CriticalErrorMessage_0_File_Skipped,
e.Message);
log.Error(message);
}
private void HandleUserCancellingImport()
{
log.Info(RingtoetsPluginResources.PipingSoilProfilesImporter_Import_Import_cancelled);
ImportIsCancelled = false;
}
#region read stochastic soil models
private ReadResult ReadStochasticSoilModels(string path)
{
NotifyProgress(RingtoetsPluginResources.PipingSoilProfilesImporter_Reading_database, 1, 1);
try
{
using (var stochasticSoilModelReader = new StochasticSoilModelReader(path))
{
return GetStochasticSoilModelReadResult(path, stochasticSoilModelReader);
}
}
catch (CriticalFileReadException e)
{
HandleException(path, e);
}
return new ReadResult(true);
}
private ReadResult GetStochasticSoilModelReadResult(string path, StochasticSoilModelReader stochasticSoilModelReader)
{
var totalNumberOfSteps = stochasticSoilModelReader.PipingStochasticSoilModelCount;
var currentStep = 1;
var soilModels = new Collection();
while (stochasticSoilModelReader.HasNext)
{
if (ImportIsCancelled)
{
return new ReadResult(false);
}
try
{
NotifyProgress("Inlezen van de ondergrondsmodellen uit de D-Soil Model database.", currentStep++, totalNumberOfSteps);
soilModels.Add(stochasticSoilModelReader.ReadStochasticSoilModel());
}
catch (PipingSoilProfileReadException e)
{
var message = string.Format("{0} " +
"Dit ondergrondsmodel wordt overgeslagen.",
e.Message);
log.Error(message);
}
catch (CriticalFileReadException e)
{
var message = string.Format(RingtoetsPluginResources.PipingSoilProfilesImporter_CriticalErrorMessage_0_File_Skipped,
path, e.Message);
log.Error(message);
return new ReadResult(true);
}
}
return new ReadResult(false)
{
ImportedItems = soilModels
};
}
#endregion
#region read soil profiles
private ReadResult ReadSoilProfiles(string path)
{
NotifyProgress(RingtoetsPluginResources.PipingSoilProfilesImporter_Reading_database, 1, 1);
try
{
using (var soilProfileReader = new PipingSoilProfileReader(path))
{
return GetProfileReadResult(path, soilProfileReader);
}
}
catch (CriticalFileReadException e)
{
HandleException(path, e);
}
return new ReadResult(true);
}
private ReadResult GetProfileReadResult(string path, PipingSoilProfileReader soilProfileReader)
{
var totalNumberOfSteps = soilProfileReader.Count;
var currentStep = 1;
var profiles = new Collection();
while (soilProfileReader.HasNext)
{
if (ImportIsCancelled)
{
return new ReadResult(false);
}
try
{
NotifyProgress(RingtoetsPluginResources.PipingSoilProfilesImporter_ReadingSoilProfiles, currentStep++, totalNumberOfSteps);
profiles.Add(soilProfileReader.ReadProfile());
}
catch (PipingSoilProfileReadException e)
{
var message = string.Format(RingtoetsPluginResources.PipingSoilProfilesImporter_ReadSoilProfiles_ParseErrorMessage_0_SoilProfile_skipped,
e.Message);
log.Error(message);
}
catch (CriticalFileReadException e)
{
var message = string.Format(RingtoetsPluginResources.PipingSoilProfilesImporter_CriticalErrorMessage_0_File_Skipped,
path, e.Message);
log.Error(message);
return new ReadResult(true);
}
}
return new ReadResult(false)
{
ImportedItems = profiles
};
}
#endregion
}
}