// Copyright (C) Stichting Deltares 2023. All rights reserved.
//
// This file is part of the application DAM - Live.
//
// DAM - Live is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero 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.Diagnostics;
using System.IO;
using System.Linq;
using Deltares.Dam.Data.CsvImporters;
using Deltares.Dam.Data.DataPlugins.Configuration;
using Deltares.Dam.Data.Importers;
using Deltares.Dam.Data.IO;
using Deltares.Geometry;
using Deltares.Geotechnics.IO;
using Deltares.Geotechnics.Soils;
using Deltares.Geotechnics.SurfaceLines;
using Deltares.Maps;
using Deltares.Standard;
using Deltares.Standard.Logging;
using GeoAPI.Geometries;
using ProgressDelegate = Deltares.DamEngine.Data.Standard.Calculation.ProgressDelegate;
namespace Deltares.Dam.Data.DataPlugins;
// TODO: Import PL1-lines
///
/// ImportMode
///
internal enum ImportMode
{
DikeRingAndLocationData,
All
}
///
/// Exception for DataPluginImporter
///
public class DataPluginImporterException : ApplicationException
{
public DataPluginImporterException() {}
public DataPluginImporterException(string message)
: base(message) {}
public DataPluginImporterException(string message, Exception inner)
: base(message, inner) {}
}
///
/// DataPlugin implementation to import from files
///
public class DataPluginImporter : IDataPlugin
{
private readonly IFeatureRepository repository = new FeatureRepository();
private bool isAllDataImported;
private bool isDikeRingAndLocationDataImported;
private WaterBoard waterBoard;
private List attributes;
private DamProjectType damProjectType;
private string damProjectFolder;
///
/// Initializes a new instance of the class.
///
public DataPluginImporter()
{
InitializeWaterBoard();
attributes = new List();
}
///
/// Gets or sets the attributes.
///
///
/// The attributes.
///
/// value
public IEnumerable Attributes
{
get
{
return attributes;
}
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
isAllDataImported = false;
attributes = value as List ?? value.ToList();
}
}
///
/// Sets the type of the dam project.
///
///
/// The type of the dam project.
///
public DamProjectType DamProjectType
{
set
{
damProjectType = value;
}
}
///
/// Gets the import log messages.
///
///
/// The import log messages.
///
public List ImportLogMessages { get; } = new List();
///
/// Gets or sets the dam project folder.
///
///
/// The dam project folder.
///
public string DamProjectFolder
{
get
{
return damProjectFolder;
}
set
{
if (damProjectFolder != value)
{
damProjectFolder = value;
Clear();
}
}
}
///
/// Gets the data folder.
///
///
/// The data folder.
///
public string DataFolder { get; private set; }
///
/// Get data source definitions
///
///
public IEnumerable DataSources { get; private set; }
///
/// Get info for WaterBoard
///
///
public Info WaterBoardInfo
{
get
{
ThrowIfDataNotRead();
return new Info
{
Name = waterBoard.Name,
Description = waterBoard.Description,
Source = DataSourceManager.GetSource(waterBoard, "Name")
};
}
}
///
/// Gets the map geometry identifier list.
///
///
/// The map geometry identifier list.
///
public IEnumerable MapGeometryIdList
{
get
{
ThrowIfDataNotRead();
return repository.FeatureIds.Select(id => id.ToString());
}
}
///
/// Returns a that represents this instance.
///
///
/// A that represents this instance.
///
public override string ToString()
{
return "DataPluginImporter";
}
///
/// Define data sources
///
///
///
public void SetDataSources(string dataFolder, IEnumerable dataSources)
{
isAllDataImported = false;
DataFolder = dataFolder;
DataSources = dataSources;
}
///
/// Gets the surface line identifier list.
///
/// The dike ring identifier.
///
public IEnumerable GetSurfaceLineIdList(string dikeRingId)
{
Dike dike = GetDike(dikeRingId);
return dike.SurfaceLines2.Select(surfaceLine => surfaceLine.Name);
}
///
/// Gets the dike ring identifier list.
///
///
public IEnumerable GetDikeRingIdList()
{
ImportDikeRingAndLocationData();
return waterBoard.Dikes.Select(dike => dike.Name);
}
///
/// Imports the data for dike rings.
///
/// The dike ring ids.
/// The progress.
public void ImportDataForDikeRings(IEnumerable dikeRingIds,
ProgressDelegate progress)
{
isAllDataImported = false;
isDikeRingAndLocationDataImported = false;
ImportAllData(dikeRingIds, progress);
}
///
/// Gets the scenario list.
///
/// The dike ring identifier.
/// The location identifier.
///
public IEnumerable GetScenarioList(string dikeRingId, string locationId)
{
Location location = GetLocation(dikeRingId, locationId);
return location.Scenarios.Select(scenario => scenario.LocationScenarioID);
}
///
/// Gets the dike ring information.
///
/// The dike ring identifier.
///
public Info GetDikeRingInfo(string dikeRingId)
{
Dike dike = GetDike(dikeRingId);
return new Info
{
Name = dike.Name,
Description = dike.Description,
Source = DataSourceManager.GetSource(dike, "Name")
};
}
///
/// Gets the dike parameters.
///
/// The dike ring identifier.
///
public IEnumerable GetDikeParameters(string dikeRingId)
{
Dike dike = GetDike(dikeRingId);
Dictionary nameValuePairs = dike.GetParametersAsNameValuePairs();
return GetParametersFromDictionary(nameValuePairs, dike);
}
///
/// Gets the location identifier list.
///
/// The dike ring identifier.
///
public IEnumerable GetLocationIdList(string dikeRingId)
{
ImportDikeRingAndLocationData();
Dike dike = GetDike(dikeRingId);
return dike.Locations.Select(location => location.Name);
}
///
/// Gets the location information.
///
/// The dike ring identifier.
/// The location identifier.
///
public Info GetLocationInfo(string dikeRingId, string locationId)
{
Location location = GetLocation(dikeRingId, locationId);
return new Info
{
Name = location.Name,
Description = "",
Source = DataSourceManager.GetSource(location, "Name")
};
}
///
/// Gets the location details.
///
/// The dike ring identifier.
/// The location identifier.
///
public IEnumerable GetLocationDetails(string dikeRingId, string locationId)
{
Location location = GetLocation(dikeRingId, locationId);
Dictionary nameValuePairs = location.GetParametersAsNameValuePairs();
return GetParametersFromDictionary(nameValuePairs, location);
}
///
/// Gets the scenario details.
///
/// The dike ring identifier.
/// The location identifier.
/// The scenario identifier.
///
public IEnumerable GetScenarioDetails(string dikeRingId, string locationId, string scenarioId)
{
Location location = GetLocation(dikeRingId, locationId);
Scenario scenario = GetScenario(dikeRingId, locationId, scenarioId);
if (scenario == null)
{
yield break;
}
Dictionary nameValuePairs = scenario.GetParametersAsNameValuePairs();
foreach (KeyValuePair nameValuePair in nameValuePairs)
{
yield return new NameValueParameter
{
ParameterName = nameValuePair.Key,
ParameterValue = nameValuePair.Value,
Source = DataSourceManager.GetSource(location, nameValuePair.Key)
};
}
}
public void DisposeImportedItem(string dikeRingId)
{
GetDike(dikeRingId).Dispose();
}
///
/// Gets the surface line points.
///
/// The dike ring identifier.
/// The surface line identifier.
///
public IList GetSurfaceLinePoints(string dikeRingId, string surfaceLineId)
{
SurfaceLine2 surfaceLine = GetSurfaceLine(dikeRingId, surfaceLineId);
var surfaceLinePoints = new List();
for (var pointIndex = 0; pointIndex < surfaceLine.Geometry.Points.Count(); pointIndex++)
{
surfaceLinePoints.Add(surfaceLine.Geometry.Points[pointIndex]);
}
return surfaceLinePoints;
}
///
/// Gets the surface line characteristic points.
///
/// The dike ring identifier.
/// The surface line identifier.
///
public IEnumerable GetSurfaceLineCharacteristicPoints(string dikeRingId,
string surfaceLineId)
{
SurfaceLine2 surfaceLine = GetSurfaceLine(dikeRingId, surfaceLineId);
foreach (CharacteristicPointType type in Enum.GetValues(typeof(CharacteristicPointType)))
{
// get & check point
GeometryPoint point = surfaceLine.CharacteristicPoints.GetGeometryPoint(type);
if (point == null)
{
continue;
}
if ((point.X == -1.0) && (point.Y == -1.0) && (point.Z == -1.0))
{
continue;
}
// create point
yield return new DpCharacteristicPoint
{
Id = type.ToString(),
X = point.X,
Y = point.Y,
Z = point.Z
};
}
}
///
/// Gets the segment identifier list.
///
/// The dike ring identifier.
///
public IEnumerable GetSegmentIdList(string dikeRingId)
{
ThrowIfDataNotRead();
return waterBoard.Segments.Select(segment => segment.Name);
}
///
/// Gets the profile1 d identifier list for segment.
///
/// The dike ring identifier.
/// The segment identifier.
/// Type of the segment failure mechanism.
///
public IEnumerable GetProfile1DIdListForSegment(string dikeRingId, string segmentId, FailureMechanismSystemType segmentFailureMechanismType)
{
ThrowIfDataNotRead();
Segment segment = GetSegment(segmentId);
foreach (SoilGeometryProbability soilGeometryProbability in segment.SoilProfileProbabilities)
{
if (soilGeometryProbability.SoilProfile != null)
{
if ((soilGeometryProbability.SegmentFailureMechanismType == null) || (soilGeometryProbability.SegmentFailureMechanismType.Value == segmentFailureMechanismType))
{
yield return soilGeometryProbability.SoilGeometryName;
}
}
}
}
///
/// Gets the profile2 d identifier list for segment.
///
/// The dike ring identifier.
/// The segment identifier.
/// Type of the segment failure mechanism.
///
public IEnumerable GetProfile2DIdListForSegment(string dikeRingId, string segmentId, FailureMechanismSystemType segmentFailureMechanismType)
{
ThrowIfDataNotRead();
Segment segment = GetSegment(segmentId);
foreach (SoilGeometryProbability soilGeometryProbability in segment.SoilProfileProbabilities)
{
if (soilGeometryProbability.SoilProfile == null)
{
if ((soilGeometryProbability.SegmentFailureMechanismType == null) || (soilGeometryProbability.SegmentFailureMechanismType.Value == segmentFailureMechanismType))
{
yield return soilGeometryProbability.SoilGeometryName;
}
}
}
}
///
/// Gets the segment profile1 d details.
///
/// The dike ring identifier.
/// The segment identifier.
/// The profile1 d identifier.
///
public IEnumerable GetSegmentProfile1DDetails(string dikeRingId, string segmentId,
string profile1DId, FailureMechanismSystemType segmentFailureMechanismType)
{
Segment segment = GetSegment(segmentId);
Dictionary nameValuePairs = segment.GetParametersForSoilProfile1DAsNameValuePairs(profile1DId, segmentFailureMechanismType);
return GetParametersFromDictionary(nameValuePairs, segment);
}
///
/// Gets the segment profile2 d details.
///
/// The dike ring identifier.
/// The segment identifier.
/// The profile2 d identifier.
///
public IEnumerable GetSegmentProfile2DDetails(string dikeRingId, string segmentId,
string profile2DId, FailureMechanismSystemType failureMechanismSystemType)
{
Segment segment = GetSegment(segmentId);
Dictionary nameValuePairs = segment.GetParametersForSoilProfile2DAsNameValuePairs(profile2DId, failureMechanismSystemType);
return GetParametersFromDictionary(nameValuePairs, segment);
}
///
/// Gets the soil profile1 d identifier list.
///
/// The dike ring identifier.
///
public IEnumerable GetSoilProfile1DIdList(string dikeRingId)
{
Dike dike = GetDike(dikeRingId);
return dike.SoilProfiles.Select(soilProfile => soilProfile.Name);
}
///
/// Gets the soil profile1 d details.
///
/// The dike ring identifier.
/// The soil profile1 d identifier.
///
public DpSoilProfile GetSoilProfile1DDetails(string dikeRingId, string soilProfile1DId)
{
SoilProfile1D soilProfile = GetSoilProfile(dikeRingId, soilProfile1DId);
var dpSoilProfile = new DpSoilProfile
{
Layers = new List()
};
for (var layerIndex = 0; layerIndex < soilProfile.Layers.Count; layerIndex++)
{
var dpLayer = new DpLayer
{
TopLevel = soilProfile.Layers[layerIndex].TopLevel,
SoilName = soilProfile.Layers[layerIndex].Soil.Name
};
dpSoilProfile.Layers.Add(dpLayer);
}
var bottomLevelLayer = new DpLayer
{
TopLevel = soilProfile.BottomLevel,
SoilName = SoilProfile1D.SoilProfileBottomLevelId
};
dpSoilProfile.Layers.Add(bottomLevelLayer);
return dpSoilProfile;
}
///
/// Gets the soil profile2 d identifier list.
///
/// The dike ring identifier.
///
///
public IEnumerable GetSoilProfile2DIdList(string dikeRingId)
{
ThrowIfDataNotRead();
throw new NotImplementedException();
}
///
/// Gets the soil profile2 d details.
///
/// The dike ring identifier.
/// The soil profile2 d identifier.
///
///
public string GetSoilProfile2DDetails(string dikeRingId, string soilProfile2DId)
{
ThrowIfDataNotRead();
throw new NotImplementedException();
}
///
/// Gets the soil identifier list.
///
/// The dike ring identifier.
///
public IEnumerable GetSoilIdList(string dikeRingId)
{
Dike dike = GetDike(dikeRingId);
IEnumerable soilNames = dike.SoilList.Soils.Select(soil => soil.Name).ToList();
return soilNames;
}
///
/// Gets the soil aquifer values.
///
/// The dike ring identifier.
///
public IEnumerable GetSoilAquiferValues(string dikeRingId)
{
Dike dike = GetDike(dikeRingId);
var res = new List();
foreach (Soil soil in dike.SoilList.Soils)
{
if (dike.SoilList.AquiferDictionary.ContainsKey(soil))
{
var nvp = new NameValueParameter();
nvp.ParameterName = soil.Name;
nvp.ParameterValue = dike.SoilList.AquiferDictionary[soil].ToString();
nvp.Source = DataSourceSystemType.MSoilBase;
res.Add(nvp);
}
}
return res;
}
///
/// Gets the soil details.
///
/// The dike ring identifier.
/// The soil identifier.
///
public IEnumerable GetSoilDetails(string dikeRingId, string soilId)
{
Soil soil = GetSoil(dikeRingId, soilId);
Dictionary nameValuePairs = SoilUtils.GetParametersAsNameValuePairs(soil);
return GetParametersFromDictionary(nameValuePairs, soil);
}
///
/// Gets the map geometry.
///
/// The map geometry identifier.
///
public string GetMapGeometry(string mapGeometryId)
{
ThrowIfDataNotRead();
IGeometry geom = GetGeometryById(mapGeometryId);
return geom.AsText();
}
///
/// Gets the map geometry attributes.
///
/// The map geometry identifier.
///
public IEnumerable GetMapGeometryAttributes(string mapGeometryId)
{
ThrowIfDataNotRead();
IGeometry geom = GetGeometryById(mapGeometryId);
IEnumerable> geomAttributes = repository.GetAttributes(geom);
return geomAttributes
.Select(kvp =>
new NameValueParameter
{
ParameterName = kvp.Key,
ParameterValue = kvp.Value.ToString()
}).ToList();
}
private void InitializeWaterBoard()
{
if (waterBoard != null)
{
waterBoard.Dispose();
}
waterBoard = new WaterBoard();
}
///
/// Clears this instance.
///
private void Clear()
{
InitializeWaterBoard();
isAllDataImported = false;
isDikeRingAndLocationDataImported = false;
}
///
/// Gets the dike.
///
/// The dike ring identifier.
///
private Dike GetDike(string dikeRingId)
{
ThrowIfDataNotRead();
return waterBoard.Dikes.First(d => d.Name.Equals(dikeRingId));
}
///
/// Gets the or create dike.
///
/// The dike ring identifier.
///
private Dike GetOrCreateDike(string dikeRingId)
{
// first check to see if this dike is already known, if not create it
Dike dike = null;
// try to get it
if (waterBoard.Dikes.Any())
{
string id = dikeRingId;
dike = waterBoard.Dikes.FirstOrDefault(x => x.Name.Equals(id));
}
// not found, create it
if (dike == null)
{
dike = new Dike
{
Name = dikeRingId
};
waterBoard.Dikes.Add(dike);
}
return dike;
}
///
/// Gets the segment.
///
/// The segment identifier.
///
private Segment GetSegment(string segmentID)
{
ThrowIfDataNotRead();
return waterBoard.Segments.First(s => s.Name.Equals(segmentID));
}
///
/// Gets the location.
///
/// The dike ring identifier.
/// The location identifier.
///
private Location GetLocation(string dikeRingId, string locationId)
{
Dike dike = GetDike(dikeRingId);
return dike.Locations.First(l => l.Name.Equals(locationId));
}
///
/// Gets a soil.
///
/// The dike ring identifier.
/// The soil identifier.
///
private Soil GetSoil(string dikeRingId, string soilId)
{
Dike dike = GetDike(dikeRingId);
Soil soil = dike.SoilList.GetSoilByName(soilId);
return soil;
}
///
/// Gets a soil profile.
///
/// The dike ring identifier.
/// The soil profile1 d identifier.
///
private SoilProfile1D GetSoilProfile(string dikeRingId, string soilProfile1DId)
{
Dike dike = GetDike(dikeRingId);
return dike.SoilProfiles.First(p => p.Name.Equals(soilProfile1DId));
}
///
/// Gets a scenario.
///
/// The dike ring identifier.
/// The location identifier.
/// The scenario identifier.
///
private Scenario GetScenario(string dikeRingId, string locationId, string scenarioId)
{
Dike dike = GetDike(dikeRingId);
Location location = dike.Locations.FirstOrDefault(l => l.Name.Equals(locationId));
return (location == null ? null : location.Scenarios.FirstOrDefault(s => s.LocationScenarioID.Equals(scenarioId)));
}
///
/// Gets a surface line.
///
/// The dike ring identifier.
/// The surface line identifier.
///
private SurfaceLine2 GetSurfaceLine(string dikeRingId, string surfaceLineId)
{
Dike dike = GetDike(dikeRingId);
return dike.SurfaceLines2.First(x => x.Name.Equals(surfaceLineId));
}
///
/// Gets the parameters from dictionary.
///
/// The dictionary.
/// The source.
///
private IEnumerable GetParametersFromDictionary(
Dictionary dictionary, object source)
{
IEnumerable pairs = dictionary.Select(nameValuePair => new NameValueParameter
{
ParameterName = nameValuePair.Key,
ParameterValue = nameValuePair.Value,
Source = DataSourceManager.GetSource(source, nameValuePair.Key)
});
return new List(pairs);
}
///
/// Import all csv files
///
/// The import folder.
/// The import mode.
/// The progress.
/// The CSV importer.
///
private bool ImportCsvFiles(string importFolder,
ImportMode importMode, ProgressDelegate progress, ref CsvImporter csvImporter)
{
DataSourceManager.CurrentSource = DataSourceSystemType.Csv;
bool isImportOnlyLocations = (importMode == ImportMode.DikeRingAndLocationData);
csvImporter.ImportCsvDataFromDirectory(importFolder, isImportOnlyLocations, progress, damProjectType);
// add messages
List messages = csvImporter.ErrorMessages;
ImportLogMessages.AddRange(messages);
DataSourceManager.CurrentSource = DataSourceSystemType.User;
// check for fatal messages
bool importOk = messages.All(m => m.MessageType != LogMessageType.FatalError);
return importOk;
}
///
/// Import name of the specified soilbase to all dikerings with id as specified in dikeRingIds.
/// Note that it does NOT import the soils in the database themselves.
/// If dikeringId not found then a new dike is created for that dikeRingId.
///
/// path where the data can be found
///
private void ImportMSoilBaseName(string importFolder, IEnumerable dikeRingIds)
{
if (dikeRingIds == null)
{
return;
}
DataSourceManager.CurrentSource = DataSourceSystemType.MSoilBase;
foreach (string dikeRingId in dikeRingIds)
{
Dike dike = GetOrCreateDike(dikeRingId);
dike.SoilDatabaseName = importFolder;
}
DataSourceManager.CurrentSource = DataSourceSystemType.User;
}
///
/// Import the specified MGeobase to all dikerings with id as specified in dikeRingIds
/// Note that this does import the 1D soil profiles together with the soils and their parameters.
/// If dikeringId not found then a new dike is created for that dikeRingId
///
/// path where the data can be found
///
private void ImportMGeobase(string importFolder, IEnumerable dikeRingIds)
{
if (dikeRingIds == null)
{
return;
}
DataSourceManager.CurrentSource = DataSourceSystemType.MGeobase;
foreach (string dikeRingId in dikeRingIds)
{
// first check to see if this dike is already known, if not create it
Dike dike = GetOrCreateDike(dikeRingId);
dike.SoilDatabaseName = importFolder;
dike.AddSoilProfilesFromDB();
}
DataSourceManager.CurrentSource = DataSourceSystemType.User;
}
///
/// Import data from Iris shapefiles
///
/// path where the data can be found
private void ImportIrisFiles(string importFolder)
{
DataSourceManager.CurrentSource = DataSourceSystemType.Iris;
// get locations (locationid and beginpoint and endpoint in RD) from "locations.shp" (LocationsNew)
// get line of buitenkruinlijn
// voeg aan elke locatie snijpunt met buitenkruinlijn toe (geen snijpunt is exception)
// nu heeft locatie een begin-, eind- en buitenrkuinpunt
// get line of binnenkruinlijn
// voeg aan elke locatie snijpunt met binnenkruinlijn toe (geen snijpunt is exception)
// nu heeft locatie een begin-, eind-, binnen- en buitenrkuinpunt
// er is al een lijst met locaties in Waterboard WaterBoard.Dike[0].Locations (LocationsOrg)
// LocationOrg.GeometryPoint[DikeTopAtRiver] = LocationNew.buitenkuinpunt
// LocationOrg.GeometryPoint[DikeTopAtPolder] = LocationNew.binnnenkuinpunt
// Als LocationNew.id niet gevonden kan worden in LocationsOrg dan exception
// Get all locations from waterboard
IEnumerable locations = GetAllLocations();
var importer = new LocationCharacteristicPointImporter(importFolder, locations);
importer.Import();
DataSourceManager.CurrentSource = DataSourceSystemType.User;
}
///
/// Get background shapefile for this waterboard
///
/// path where the data can be found
private void ImportBackgroundShapeFiles(string importFolder)
{
DataSourceManager.CurrentSource = DataSourceSystemType.Gis;
var reader = new ShapeFileReader(importFolder)
{
IgnoreAttributeData = true
};
var importer = new FeatureImporter(repository, reader);
importer.Import();
DataSourceManager.CurrentSource = DataSourceSystemType.User;
}
///
/// Get all locations for all dikes
///
///
private IEnumerable GetAllLocations()
{
return waterBoard.Dikes.SelectMany(dike => dike.Locations);
}
///
/// Pre conditions:
/// - A list of waterboard locations with initialized x,y values
/// - shape file ccontaining the attributes and data
///
/// Post condition:
/// - Location properties (in relation to the attributes) are set
///
///
///
///
///
///
private void ImportDataShapeFiles(string importFolder, IEnumerable dataAttributes,
ImportMode importMode, IEnumerable dikeRingIds,
ProgressDelegate progress,
ref List locationRecords)
{
DataSourceManager.CurrentSource = DataSourceSystemType.Gis;
if (importFolder == null)
{
throw new ArgumentNullException("importFolder");
}
var importErrorLogFile = @"shapefiletrace.log";
if (!string.IsNullOrEmpty(DamProjectFolder))
{
importErrorLogFile = Path.Combine(DamProjectFolder, importErrorLogFile);
}
List dataAttributesList = dataAttributes as List ?? dataAttributes.ToList();
var exceptions = new List();
var locationImporter = LocationShapeFileImporter.Create(
locationRecords, dataAttributesList, importFolder);
if (locationImporter != null)
{
locationImporter.Import();
locationRecords = locationImporter.ImportedItems.ToList();
}
// Skip reading properties when only dikering and locationdata is required
if (importMode == ImportMode.All)
{
//
// Location Property Importer
// This is where all the attribute values are read form the shapefiles
//
var importer = new LocationPropertyImporter(importFolder, dataAttributesList)
{
Targets = locationRecords
};
importer.Import(progress);
exceptions.AddRange(importer.ImportErrors);
foreach (string importerMessage in importer.ImproperAttributeMessages)
{
var lm = new LogMessage(LogMessageType.Error, this, importerMessage);
ImportLogMessages.Add(lm);
}
}
using (var sw = new StreamWriter(importErrorLogFile, false))
{
if (!exceptions.Any())
{
return;
}
foreach (Exception error in exceptions)
{
//defaultWriter.Write(error.Message);
sw.WriteLine("Date: {0}, Error type: {1}, Message: {2}",
DateTime.Now.ToShortDateString(), error.GetType().Name, error.Message);
var lm = new LogMessage(LogMessageType.Error, this, error.Message);
ImportLogMessages.Add(lm);
}
}
}
///
/// Gets the geometry by identifier.
///
/// The map geometry identifier.
///
/// mapGeometryId
/// Can't find a geometry with this id
private IGeometry GetGeometryById(string mapGeometryId)
{
if (mapGeometryId == null)
{
throw new ArgumentNullException("mapGeometryId");
}
var id = new Guid(mapGeometryId);
IGeometry geom = repository.GetGeometryById(id);
if (geom == null)
{
throw new ArgumentException("Can't find a geometry with this id");
}
return geom;
}
///
/// Import only Dikering and location id's
///
private void ImportDikeRingAndLocationData()
{
if (isDikeRingAndLocationDataImported || isAllDataImported)
{
return;
}
var csvImporter = new CsvImporter();
foreach (DataSource dataSource in DataSources)
{
ImportDikeRingAndLocationData(dataSource, ref csvImporter);
}
var combineImportedData = new CombineImportedData
{
WaterBoard = waterBoard,
LocationRecords = csvImporter.LocationRecords
};
combineImportedData.AddCsvDataToDikes();
isDikeRingAndLocationDataImported = true;
}
///
/// Gets the data location.
///
/// The data source.
///
private string GetDataLocation(DataSource dataSource)
{
string dataLocation = dataSource.DataLocation;
if (!string.IsNullOrEmpty(DataFolder)
&& (!Directory.Exists(dataLocation) || !File.Exists(dataLocation)))
{
dataLocation = Path.Combine(DataFolder, dataLocation);
}
return dataLocation;
}
///
/// Imports the dike ring and location data.
///
/// The data source.
///
///
private void ImportDikeRingAndLocationData(DataSource dataSource, ref CsvImporter csvImporter)
{
string dataLocation = GetDataLocation(dataSource);
switch (dataSource.DataSourceType)
{
case DataSourceType.CsvFiles:
// New importer
ImportCsvFiles(dataLocation, ImportMode.DikeRingAndLocationData, null, ref csvImporter);
break;
case DataSourceType.DataShapeFiles:
List locationRecords = csvImporter.LocationRecords;
ImportShapeFile(dataLocation, ref locationRecords);
csvImporter.LocationRecords = locationRecords;
break;
case DataSourceType.Iris:
case DataSourceType.BackgroundShapeFiles:
case DataSourceType.MSoilBase:
case DataSourceType.MGeobase:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
///
/// Imports the data.
///
/// The data source.
/// The dike ring identifier list.
/// The import mode.
/// The progress.
/// The CSV importer.
///
private void ImportData2(DataSource dataSource,
IEnumerable dikeRingIdList, ImportMode importMode,
ProgressDelegate progress, ref CsvImporter csvImporter)
{
string dataLocation = GetDataLocation(dataSource);
switch (dataSource.DataSourceType)
{
case DataSourceType.CsvFiles:
// New importer
ImportCsvFiles(dataLocation, importMode, progress, ref csvImporter);
break;
case DataSourceType.Iris:
ImportIrisFiles(dataLocation);
break;
case DataSourceType.DataShapeFiles:
List locationRecords = csvImporter.LocationRecords;
ImportDataShapeFiles(dataLocation, attributes, importMode, dikeRingIdList, progress, ref locationRecords);
csvImporter.LocationRecords = locationRecords;
break;
case DataSourceType.BackgroundShapeFiles:
if (importMode == ImportMode.All)
{
ImportBackgroundShapeFiles(dataLocation);
}
break;
case DataSourceType.MSoilBase:
ImportMSoilBaseName(dataLocation, dikeRingIdList);
break;
case DataSourceType.MGeobase:
ImportMGeobase(dataLocation, dikeRingIdList);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
///
/// Imports the shape file.
///
/// The data location.
/// The location records.
private void ImportShapeFile(string dataLocation, ref List locationRecords)
{
// get locations
DataAttribute configuredAttribute =
attributes.SingleOrDefault(a => a.AttributeId.Equals(
LocationShapeFileAttributeMap.LocationAttributeId,
StringComparison.InvariantCultureIgnoreCase));
if (configuredAttribute == null)
{
return;
}
var locationImporter = LocationShapeFileImporter.Create(
locationRecords, attributes, dataLocation);
if (locationImporter != null)
{
locationImporter.Import();
locationRecords = locationImporter.ImportedItems.ToList();
}
}
///
/// Imports all data.
///
/// The dike ring ids.
/// The progress.
private void ImportAllData(IEnumerable dikeRingIds, ProgressDelegate progress)
{
// do nothing if all data is already imported
if (isAllDataImported)
{
return;
}
ImportData(ImportMode.All, dikeRingIds, progress);
isAllDataImported = true;
}
///
/// Import all data
///
private void ImportData(ImportMode importMode, IEnumerable dikeRingIds, ProgressDelegate progress)
{
ThrowIfNoDataDefinitions();
if (!isDikeRingAndLocationDataImported)
{
// If locations and dikeringIds were not read yet then we start with a new waterboard
// Else continue with waterboard that was created when importing the locations
InitializeWaterBoard();
}
waterBoard.Description = "Waterschap";
var csvImporter = new CsvImporter();
List dikeRingIdList = dikeRingIds == null ? null : dikeRingIds as List ?? dikeRingIds.ToList();
foreach (DataSource dataSource in DataSources)
{
// Skip Iris because it needs the locations
// Data from shapefiles is added to locationrecords from csvImporter
if (dataSource.DataSourceType != DataSourceType.Iris)
{
ImportData2(dataSource, dikeRingIdList, importMode, progress, ref csvImporter);
}
}
// create and fill the locations, scenarios etc. with the data from csv and shapefiles
AddCsvDataToDikes(csvImporter);
// Now that the locations are defined, read Iris data
foreach (DataSource dataSource in DataSources)
{
if (dataSource.DataSourceType == DataSourceType.Iris)
{
ImportData2(dataSource, dikeRingIdList, importMode, progress, ref csvImporter);
}
}
AddScenarioDataToDikes(csvImporter);
if (importMode == ImportMode.All)
{
CorrectSegmentAssignments();
}
}
///
/// Adds the scenario data to dikes.
///
/// The CSV importer.
private void AddScenarioDataToDikes(CsvImporter csvImporter)
{
if (csvImporter != null)
{
DataSourceManager.CurrentSource = DataSourceSystemType.Csv;
var combineImportedData = new CombineImportedData
{
WaterBoard = waterBoard,
LocationRecords = csvImporter.LocationRecords,
ScenarioRecords = csvImporter.ScenariosRecords
};
combineImportedData.AddScenarioDataToDikes();
ImportLogMessages.AddRange(combineImportedData.ErrorMessages);
Debug.Assert(ReferenceEquals(waterBoard, combineImportedData.WaterBoard));
waterBoard = combineImportedData.WaterBoard;
}
}
///
/// Adds the CSV data to dikes.
///
/// The CSV importer.
private void AddCsvDataToDikes(CsvImporter csvImporter)
{
if (csvImporter != null)
{
DataSourceManager.CurrentSource = DataSourceSystemType.Csv;
var combineImportedData = new CombineImportedData
{
WaterBoard = waterBoard,
LocationRecords = csvImporter.LocationRecords,
CharacteristicPointsRecords = csvImporter.CharacteristicPointsRecords,
ScenarioRecords = csvImporter.ScenariosRecords,
SegmentRecords = csvImporter.SegmentRecords,
SoilProfilerecords = csvImporter.SoilProfilesRecords,
SurfaceLineRecords = csvImporter.SurfaceLinesRecords
};
combineImportedData.AddCsvDataToDikes();
ImportLogMessages.AddRange(combineImportedData.ErrorMessages);
Debug.Assert(ReferenceEquals(waterBoard, combineImportedData.WaterBoard));
waterBoard = combineImportedData.WaterBoard;
}
}
///
/// When segment shapefile has assigned new segmentIds the segment object has to be re-assigned
///
private void CorrectSegmentAssignments()
{
foreach (Dike dike in waterBoard.Dikes)
{
foreach (Location location in dike.Locations)
{
location.Segment = waterBoard.Segments.FirstOrDefault(s => s.Name.Equals(location.SegmentId));
}
}
}
///
/// Check if data definitions already specified
///
private void ThrowIfNoDataDefinitions()
{
if (DataSources == null || !DataSources.Any())
{
throw new DataPluginImporterException("No data sources defined");
}
}
///
/// Check if data has been read
///
private void ThrowIfDataNotRead()
{
if (!isAllDataImported)
{
throw new DataPluginImporterException("Data has not been imported yet");
}
}
}