// 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 Lesser 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 Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser 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.IO; using System.Linq; using Core.Common.Base.Geometry; using Core.Common.IO.Exceptions; using Core.Common.Utils.Builders; using Core.Components.Gis.Data; using Core.Components.Gis.Features; using Core.Components.Gis.Geometries; using DotSpatial.Data; using DotSpatial.Topology; using CoreCommonUtilsResources = Core.Common.Utils.Properties.Resources; using GisIOResources = Core.Components.Gis.IO.Properties.Resources; namespace Core.Components.Gis.IO.Readers { /// /// Class to be used to read polylines from a shapefile. /// public class PolylineShapeFileReader : ShapeFileReaderBase { private int readIndex; /// /// Initializes a new instance of the class. /// /// The shapefile path. /// When is invalid. /// 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 PolylineShapeFileReader(string shapeFilePath) : base(shapeFilePath) { try { ShapeFile = new LineShapefile(shapeFilePath); } catch (ArgumentException exception) { string message = new FileReaderErrorMessageBuilder(shapeFilePath) .Build(GisIOResources.LineShapeFileReader_File_contains_geometries_not_line); throw new CriticalFileReadException(message, exception); } catch (IOException exception) { var message = new FileReaderErrorMessageBuilder(shapeFilePath).Build(CoreCommonUtilsResources.Error_General_IO_Import_ErrorMessage); throw new CriticalFileReadException(message, exception); } } /// /// Reads a line shape from the file. /// /// The representing the read line shape, or /// null when at the end of the shapefile. public override FeatureBasedMapData ReadFeature(string name = null) { if (readIndex == GetNumberOfFeatures()) { return null; } try { IFeature lineFeature = GetFeature(readIndex); return ConvertSingleLineFeatureToMapLineData(lineFeature, !string.IsNullOrWhiteSpace(name) ? name : GisIOResources.PolylineShapeFileReader_ReadLine_Line); } finally { readIndex++; } } public override FeatureBasedMapData ReadShapeFile(string name = null) { List featureList = new List(); while (readIndex != GetNumberOfFeatures()) { featureList.Add(ReadFeatureLine()); } return ConvertMultiLineFeatureToMapLineData(featureList, !string.IsNullOrWhiteSpace(name) ? name : GisIOResources.PolylineShapeFileReader_ReadLine_Line); } /// /// Gets the single line feature at the given index. /// /// The index of which feature to retrieve. /// The feature that consists out of 1 whole polyline. public override IFeature GetFeature(int index) { return ShapeFile.Features[index]; } private IFeature ReadFeatureLine() { try { return GetFeature(readIndex); } finally { readIndex++; } } private MapLineData ConvertSingleLineFeatureToMapLineData(IFeature lineFeature, string name) { MapFeature feature = CreateMapFeatureForLineFeature(lineFeature); CopyMetaDataIntoFeature(feature, readIndex); return new MapLineData(name) { Features = new[] { feature } }; } private MapLineData ConvertMultiLineFeatureToMapLineData(List lineFeatures, string name) { var mapFeatureList = new List(); for (var featureIndex = 0; featureIndex < lineFeatures.Count; featureIndex++) { IFeature lineFeature = lineFeatures[featureIndex]; MapFeature feature = CreateMapFeatureForLineFeature(lineFeature); CopyMetaDataIntoFeature(feature, featureIndex); mapFeatureList.Add(feature); } return new MapLineData(name) { Features = mapFeatureList.ToArray() }; } private static MapFeature CreateMapFeatureForLineFeature(IFeature lineFeature) { var geometries = new List(); for (int i = 0; i < lineFeature.BasicGeometry.NumGeometries; i++) { var polylineGeometry = lineFeature.BasicGeometry.GetBasicGeometryN(i); MapGeometry mapGeometry = new MapGeometry(GetMapGeometryPointCollections(polylineGeometry.Coordinates)); geometries.Add(mapGeometry); } return new MapFeature(geometries); } private static IEnumerable[] GetMapGeometryPointCollections(IEnumerable lineCoordinates) { return new[] { lineCoordinates.Select(c => new Point2D(c.X, c.Y)) }; } } }