// 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.Linq;
using Core.Common.Base.Geometry;
using Core.Common.IO.Exceptions;
using Core.Common.Utils;
using Core.Common.Utils.Builders;
using Core.Components.Gis.Data;
using Core.Components.Gis.Features;
using Core.Components.Gis.IO.Readers;
using Ringtoets.Common.Data.FailureMechanism;
using CoreCommonUtilsResources = Core.Common.Utils.Properties.Resources;
using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources;
namespace Ringtoets.Common.IO
{
///
/// Reads instances from a shapefile containing
/// one or multiple line features.
///
public class FailureMechanismSectionReader : IDisposable
{
private const string sectionNameAttributeKey = "Vaknaam";
private readonly PolylineShapeFileReader polylineShapeFileReader;
private readonly string filePath;
///
/// Initializes a new instance of the class.
///
/// The shape file path.
/// is invalid.
/// Thrown when either:
///
/// - points to a file that doesn't exist.
/// - The shapefile has non-line geometries in it.
/// - An unexpected error occurred when reading the shapefile.
///
///
public FailureMechanismSectionReader(string shapeFilePath)
{
FileUtils.ValidateFilePath(shapeFilePath);
filePath = shapeFilePath;
polylineShapeFileReader = new PolylineShapeFileReader(filePath);
}
///
/// Gets the number of failure mechanism sections in the shapefile.
///
/// Thrown when the shapefile does not have
/// a required attribute defined.
public int GetFailureMechanismSectionCount()
{
ValidateExistenceOfRequiredAttributes();
return polylineShapeFileReader.GetNumberOfFeatures();
}
///
/// Reads and consumes an entry in the shapefile, using the data to create a new
/// instance of .
///
/// The read from the file, or null
/// when at the end of the file.
/// Thrown when either:
///
/// - the shapefile does not have a required attribute defined.
/// - the element read from the file is a multi-polyline.
///
public FailureMechanismSection ReadFailureMechanismSection()
{
ValidateExistenceOfRequiredAttributes();
var lineData = ReadMapLineData();
return lineData == null ? null : CreateFailureMechanismSection(lineData);
}
public void Dispose()
{
polylineShapeFileReader.Dispose();
}
///
/// Validates the existence of required attributes.
///
/// Thrown when the shapefile does not have
/// a required attribute defined.
private void ValidateExistenceOfRequiredAttributes()
{
if (!polylineShapeFileReader.HasAttribute(sectionNameAttributeKey))
{
throw CreateCriticalFileReadException(
string.Format(RingtoetsCommonIOResources.FailureMechanismSectionReader_File_lacks_required_Attribute_0_,
sectionNameAttributeKey));
}
}
///
/// Reads a new from the file.
///
///
private MapLineData ReadMapLineData()
{
return polylineShapeFileReader.ReadFeature() as MapLineData;
}
private FailureMechanismSection CreateFailureMechanismSection(MapLineData lineData)
{
var features = lineData.Features.ToArray();
if (features.Length > 1)
{
throw CreateCriticalFileReadException(RingtoetsCommonIOResources.FailureMechanismSectionReader_File_has_unsupported_multiPolyline);
}
var feature = features[0];
string name = GetSectionName(feature);
IEnumerable geometryPoints = GetSectionGeometry(feature);
return new FailureMechanismSection(name, geometryPoints);
}
private string GetSectionName(MapFeature lineFeature)
{
var sectionName = lineFeature.MetaData[sectionNameAttributeKey] as string;
if (string.IsNullOrWhiteSpace(sectionName))
{
throw CreateCriticalFileReadException(RingtoetsCommonIOResources.FailureMechanismSectionReader_File_has_section_without_sectionName);
}
return sectionName;
}
private IEnumerable GetSectionGeometry(MapFeature lineFeature)
{
var mapGeometries = lineFeature.MapGeometries.ToArray();
if (mapGeometries.Length > 1)
{
throw CreateCriticalFileReadException(RingtoetsCommonIOResources.FailureMechanismSectionReader_File_has_unsupported_multiPolyline);
}
return mapGeometries[0].PointCollections.First().Select(p => new Point2D(p.X, p.Y));
}
private CriticalFileReadException CreateCriticalFileReadException(string message)
{
var wrappedMessage = new FileReaderErrorMessageBuilder(filePath).Build(message);
return new CriticalFileReadException(wrappedMessage);
}
}
}