//#define INCLUDE_ALL_LINE_TYPES using System; using System.Collections.Generic; using System.IO; using System.Linq; using Deltares.Geotechnics; using Deltares.Geotechnics.SurfaceLines; using Deltares.Maps; namespace Deltares.Dam.Data.Importers { public class LocationCharacteristicPointImporter { // define file names private const string CharacteristicLinesFile = "Kruin_dijkring10.shp"; public const string CharacteristicLineAttributeName = "TEMP_ID"; private const string LocationsFile = "Locations.shp"; public const string LocationDikeAttributeName = "DIKERINGID"; public const string LocationIDAttributeName = "LOCATION"; const string DikeTopPolderLineID = "kruin-binnen"; const string DikeTopAtPolderLineID = "kruin-buiten"; #if INCLUDE_ALL_LINE_TYPES private IEnumerable supportedLineTypes = new[] { DikeTopPolderLineID, DikeTopAtPolderLineID }; #else private readonly IEnumerable supportedLineTypes = new[] { DikeTopPolderLineID }; #endif private string dataFolder; private readonly IEnumerable locations; public LocationCharacteristicPointImporter(IEnumerable locations) { if (locations == null) throw new ArgumentNullException("locations"); this.locations = locations; } public LocationCharacteristicPointImporter(string dataFolder, IEnumerable locations): this(locations) { LoadRepositories(dataFolder); } private void LoadRepositories(string dataFolder) { if (dataFolder == null) throw new ArgumentNullException("dataFolder"); this.dataFolder = dataFolder; ValidateDataFolder(); var profileLocationsShapeFile = new ShapeFileLocation(this.dataFolder, LocationsFile); // Get all the locations from the profile data shape file using a repository this.ProfileLocationsRepository = FeatureRepository.CreateFromShapeFile(profileLocationsShapeFile); var shapeFile = new ShapeFileLocation(this.dataFolder, CharacteristicLinesFile); this.CharacteristicLineRepository = FeatureRepository.CreateFromShapeFile(shapeFile); // Load and validate the attributes required to import the locations ThrowWhenDataFileNotValid(this.ProfileLocationsRepository, LocationIDAttributeName, LocationsFile); ThrowWhenDataFileNotValid(this.ProfileLocationsRepository, LocationDikeAttributeName, LocationsFile); ThrowWhenDataFileNotValid(this.CharacteristicLineRepository, CharacteristicLineAttributeName, CharacteristicLinesFile); } public IFeatureRepository CharacteristicLineRepository { get; set; } public IFeatureRepository ProfileLocationsRepository { get; set; } /// /// /// /// Preconditions: /// - A valid data folder needs to given /// - A set of "locations" with their characteristic points table and initialized id's available from the waterboard /// - The required files need to be in the data folder (one for the characteristics points, /// - A set of (characteristic) lines wich have to be retrieved from the files /// /// Postconditions: /// - Some locations (the result of a join from the Location shape file and the existing location list from the Waterboard) have new characteristic point values /// /// /// /// /// /// public void Import() { ThrowWhenRepositoryIsInvalid(this.CharacteristicLineRepository, CharacteristicLineAttributeName); ThrowWhenRepositoryIsInvalid(this.ProfileLocationsRepository, LocationIDAttributeName); ThrowWhenRepositoryIsInvalid(this.ProfileLocationsRepository, LocationDikeAttributeName); // TODO Test both repositories on geometry type (must be linestring) // Find the intersection points between the geometries var results = this.ProfileLocationsRepository.GetIntersectionPoints(this.CharacteristicLineRepository); var work = results.GetResultsHavingCount(1); foreach (var intersectionResult in work) { IFeature profile, characteristicLine; if (intersectionResult.Source.Attributes.Exists(CharacteristicLineAttributeName)) { profile = intersectionResult.Target; characteristicLine = intersectionResult.Source; } else { profile = intersectionResult.Source; characteristicLine = intersectionResult.Target; } string lineTypeID = characteristicLine.Attributes[CharacteristicLineAttributeName].ToString(); if (!supportedLineTypes.Contains(lineTypeID)) { LogMessage(); continue; } var locationList = locations.ToList(); var locname = profile.Attributes[LocationIDAttributeName].ToString(); // Get the surface line for the location having the location ID var surfaceLine = locationList.First(loc => loc.Name == locname).SurfaceLine2; var dikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); dikeTopAtPolder.X = intersectionResult.IntersectionPoints.ElementAt(0).X; dikeTopAtPolder.Y = intersectionResult.IntersectionPoints.ElementAt(0).Y; } } private static void LogMessage() { } private static IEnumerable GetAllFiles(string path) { if (!Directory.Exists(path)) throw new DirectoryNotFoundException(string.Format("Data folder '{0}' not found", path)); return Directory.GetFiles(path); } private static bool IsRepositoryValid(IFeatureRepository repository, string attributeName) { if (repository == null) return false; bool keyAndValueExist = !repository.Features.Any(geom => !geom.Attributes.Exists(attributeName) || geom.Attributes[attributeName] == null); return keyAndValueExist; } private static void ThrowWhenRepositoryIsInvalid(IFeatureRepository repository, string attributeName) { if (!IsRepositoryValid(repository, attributeName)) { throw new InvalidOperationException( string.Format("The geometry repository doesn't contain the required attribute '{0}'", attributeName)); } } private static void ThrowWhenDataFileNotValid(IFeatureRepository repository, string attributeName, string fileName) { if (!IsRepositoryValid(repository, attributeName)) { throw new ArgumentException( string.Format("The ShapeFile '{0}' doesn't contain the required attribute '{1}'", fileName, attributeName)); } } private void ValidateDataFolder() { // Get all the shape files from the data folder var files = GetAllFiles(this.dataFolder); // Validate the existence of the required files if (!files.Any(file => file.EndsWith(CharacteristicLinesFile))) throw new FileNotFoundException(string.Format("The folder '{0}' doesn't contain the required file '{1}'", this.dataFolder, CharacteristicLinesFile)); if (!files.Any(file => file.EndsWith(LocationsFile))) throw new FileNotFoundException( string.Format("The folder '{0}' doesn't contain the required file '{1}'", this.dataFolder, LocationsFile)); } } }