// 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.IO;
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.Geometries;
using Core.Components.Gis.IO.Readers;
using Ringtoets.Common.Data.AssessmentSection;
using CoreCommonUtilsResources = Core.Common.Utils.Properties.Resources;
using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources;
using RingtoetsCommonDataResources = Ringtoets.Common.Data.Properties.Resources;
namespace Ringtoets.Common.IO.ReferenceLines
{
///
/// Shapefile reader that reads a based on the line feature in the file.
///
public class ReferenceLineReader
{
///
/// Reads an instance of from a shapefile containing one polyline.
///
/// The file path to the shapefile.
/// The reference line created from the data in the shapefile.
/// Thrown when is invalid.
/// Thrown when either:
///
/// - points to a file that does not exist.
/// - There isn't exactly 1 polyline in the shapefile.
/// - Shapefile contains a multi-polyline.
/// - An unexpected error occurred when reading the shapefile.
///
///
public ReferenceLine ReadReferenceLine(string shapeFilePath)
{
FileUtils.ValidateFilePath(shapeFilePath);
if (!File.Exists(shapeFilePath))
{
string message = new FileReaderErrorMessageBuilder(shapeFilePath)
.Build(CoreCommonUtilsResources.Error_File_does_not_exist);
throw new CriticalFileReadException(message);
}
using (PolylineShapeFileReader lineShapeReader = new PolylineShapeFileReader(shapeFilePath))
{
MapLineData lineMapData = GetReferenceLineMapData(lineShapeReader, shapeFilePath);
return CreateReferenceLine(lineMapData, shapeFilePath);
}
}
///
/// Gets the reference line map data.
///
/// The line shape reader.
/// The shapefile path.
/// The map data representing the reference line.
///
/// When either:
///
/// - There isn't exactly 1 polyline in the shapefile.
/// - The shapefile doesn't contains lines.
///
///
private static MapLineData GetReferenceLineMapData(PolylineShapeFileReader lineShapeReader, string shapeFilePath)
{
if (lineShapeReader.GetNumberOfFeatures() != 1)
{
string message = new FileReaderErrorMessageBuilder(shapeFilePath)
.Build(RingtoetsCommonIOResources.ReferenceLineReader_File_must_contain_1_polyline);
throw new CriticalFileReadException(message);
}
return (MapLineData) lineShapeReader.ReadFeature(RingtoetsCommonDataResources.ReferenceLine_DisplayName);
}
private static ReferenceLine CreateReferenceLine(MapLineData lineMapData, string shapeFilePath)
{
var lineFeatures = lineMapData.Features.ToArray();
if (lineFeatures.Length > 1)
{
string message = new FileReaderErrorMessageBuilder(shapeFilePath)
.Build(RingtoetsCommonIOResources.ReferenceLineReader_File_contains_unsupported_multi_polyline);
throw new CriticalFileReadException(message);
}
var referenceLine = new ReferenceLine();
var referenceLineFeature = lineMapData.Features.First();
var referenceGeometries = referenceLineFeature.MapGeometries.ToArray();
if (referenceGeometries.Length > 1)
{
string message = new FileReaderErrorMessageBuilder(shapeFilePath)
.Build(RingtoetsCommonIOResources.ReferenceLineReader_File_contains_unsupported_multi_polyline);
throw new CriticalFileReadException(message);
}
MapGeometry referenceGeometry = referenceGeometries[0];
referenceLine.SetGeometry(referenceGeometry.PointCollections.First().Select(t => new Point2D(t.X, t.Y)));
return referenceLine;
}
}
}