// 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
});
}
}
}
}