// Copyright (C) Stichting Deltares 2017. 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.Data; using System.Linq; using Core.Common.IO.Exceptions; using Core.Common.Utils; using Core.Components.Gis.Data; using Core.Components.Gis.Features; using Core.Components.Gis.IO.Properties; using DotSpatial.Data; using CoreCommonUtilsResources = Core.Common.Utils.Properties.Resources; namespace Core.Components.Gis.IO.Writers { /// /// The base class to write data to a shapefile. /// public abstract class ShapeFileWriterBase : IDisposable { protected Shapefile ShapeFile; private bool hasPropertyTable; /// /// Creates a new feature from and adds it to the in-memory shapefile. /// /// The to add to the in-memory shapefile as a feature. /// Thrown when is null. /// Thrown when: /// /// A contains different metadata keys /// than the of the first call to . /// does not contain exactly one . /// /// public void CopyToFeature(FeatureBasedMapData featureBasedMapData) { if (featureBasedMapData == null) { throw new ArgumentNullException(nameof(featureBasedMapData)); } if (featureBasedMapData.Features.Count() != 1) { throw new ArgumentException(Resources.ShapeFileWriterBase_CopyToFeature_Mapdata_can_only_contain_one_feature); } MapFeature mapFeature = featureBasedMapData.Features.First(); EnsureAttributeTableExists(mapFeature); IFeature feature = AddFeature(mapFeature); CopyMetaDataFromMapFeatureToAttributeTable(mapFeature, feature); } /// /// Saves the in-memory shapefile to a file, overwriting when necessary. /// /// The path to the shapefile. /// Thrown when is invalid. /// Thrown when the shapefile cannot be written. public void SaveAs(string filePath) { IOUtils.ValidateFilePath(filePath); try { ShapeFile.SaveAs(filePath, true); } catch (Exception e) { throw new CriticalFileWriteException(string.Format(CoreCommonUtilsResources.Error_General_output_error_0, filePath), e); } } public void Dispose() { ShapeFile?.Close(); } /// /// Create a new feature from a . /// /// The from which to create a feature. /// This cannot be null. /// The created feature. protected abstract IFeature AddFeature(MapFeature mapFeature); private void EnsureAttributeTableExists(MapFeature mapFeature) { if (mapFeature == null) { throw new ArgumentNullException(nameof(mapFeature)); } if (hasPropertyTable) { return; } CreateAttributeTable(mapFeature); hasPropertyTable = true; } private static void CopyMetaDataFromMapFeatureToAttributeTable(MapFeature mapFeature, IFeature feature) { IDictionary metaData = mapFeature.MetaData; List sortedKeys = metaData.Keys.ToList(); sortedKeys.Sort(); foreach (string key in sortedKeys) { object value = metaData[key]; feature.DataRow.BeginEdit(); feature.DataRow[key] = value; feature.DataRow.EndEdit(); } } private void CreateAttributeTable(MapFeature mapFeature) { IDictionary metaData = mapFeature.MetaData; List sortedKeys = metaData.Keys.ToList(); sortedKeys.Sort(); DataColumnCollection columns = ShapeFile.DataTable.Columns; foreach (string key in sortedKeys) { object value = metaData[key]; columns.Add(new DataColumn { DataType = value.GetType(), ColumnName = key }); } } } }