// Copyright (C) Stichting Deltares 2023. All rights reserved.
//
// This file is part of the application DAM - UI.
//
// DAM - UI 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.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Deltares.Dam.Data;
using Deltares.Dam.Data.DataPlugins.Configuration;
using Deltares.Dam.Data.Importers;
using Deltares.Dam.Data.UISupport;
using Deltares.Standard.EventPublisher;
using Deltares.Standard.Forms.DExpress;
using Deltares.Standard.Language;
using Deltares.Standard.Logging;
using Deltares.Standard.Maps;
using DotSpatial.Projections;
using DotSpatial.Projections.Forms;
namespace Deltares.Dam.Forms
{
///
/// This dialog imports base data into DAM
///
public partial class DamNewProjectDialog : Form
{
private DAMNewProjectData damNewProjectData;
private string currentSourceFileName = "";
///
/// Constructor
///
public DamNewProjectDialog()
{
InitializeComponent();
// Header stuff
Name = "New Project";
ProjectSpecificationsGroupControl.Text = LocalizationManager.GetTranslatedText(this, "NewDamProjectDialogProjectSpecificationGroup");
Text = LocalizationManager.GetTranslatedText(this, "NewDamProjectDialogCaption");
// Project type
BindSupport.BindTextAndValue(this, DamCalculationTypeLabel, DamCalculationTypeComboBox, typeof(DAMNewProjectData), "DamProjectType");
// DAM datasources file
BindSupport.BindTextAndValue(this, DatasourcesFileNameLabel, DatasourcesFileNameEdit, typeof(DAMNewProjectData), "DamDataSourceFileName");
// DAM project file
BindSupport.BindTextAndValue(this, DestinationProjectFilenameLabel, DestinationProjectFilenameTextEdit, typeof(DAMNewProjectData), "DamProjectFileName");
// Sensor configuration file
BindSupport.BindTextAndValue(this, SensorConfigurationFilenameLabel, SensorConfigurationFilenameTextEdit, typeof(DAMNewProjectData), "SensorConfigurationFileName");
// Select dikerings
SelectDikeRingsLabel.Text = LocalizationManager.GetTranslatedText(this, "SelectDikerings");
// projection button & name:
BindSupport.Bind(this, ProjectionButton, typeof(DAMNewProjectData), "SelectProjection");
BindSupport.Bind(this, projectionMemoEdit, typeof(DAMNewProjectData), "DataSourceProjectionName");
BindSupport.Bind(this, SensorConfigurationFilenameButton, typeof(DAMNewProjectData), "SelectSensorConfigurationFile");
FormsSupport.RepairRightAnchoredControls(this);
DataEventPublisher.IsDataEventPublishStopped = false;
}
///
///
/// The text associated with this control.
public override sealed string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
}
}
///
/// Gets or sets the dam new project data.
///
///
/// The dam new project data.
///
public DAMNewProjectData DamNewProjectData
{
get
{
return damNewProjectData;
}
set
{
damNewProjectData = value;
if (String.IsNullOrEmpty(damNewProjectData.DamProjectFileName))
{
if (!string.IsNullOrWhiteSpace(DamNewProjectData.DamDataSourceFileName))
{
DamNewProjectData.DamProjectFileName = Path.ChangeExtension(DamNewProjectData.DamDataSourceFileName, ".damx");
}
}
DatasourcesFileNameUpdated();
BindSupport.Assign(this, value);
}
}
///
/// Handler for file select
///
///
///
private void DatasourcesFileNameButtonClick(object sender, EventArgs e)
{
SelectFileDialog.Filter = LocalizationManager.GetTranslatedText(this, "DamImportDefinitionFilesFilterText");
SelectFileDialog.FileName = damNewProjectData.DamDataSourceFileName;
SelectFileDialog.CheckFileExists = true;
if (!string.IsNullOrWhiteSpace(damNewProjectData.DamDataSourceFileName))
{
SelectFileDialog.InitialDirectory = Path.GetDirectoryName(damNewProjectData.DamDataSourceFileName);
}
if (SelectFileDialog.ShowDialog() == DialogResult.OK)
{
damNewProjectData.DamDataSourceFileName = SelectFileDialog.FileName;
DatasourcesFileNameUpdated();
}
}
///
/// Check if DamProjectFileName can be used
///
private bool IsValidDestinationProjectFileName(string filename)
{
if (damNewProjectData.DamProjectFileName == "")
{
LocalizedMessageBox.Show(this, "SpecifyDestinationFileName");
return false;
}
if (File.Exists(filename))
{
Object[] args =
{
filename
};
return LocalizedMessageBox.Show(this, "FileAlreadyExistsOverwriteItQuestion", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, args) == DialogResult.Yes;
}
return true;
}
///
/// Determines whether [is valid sensor configuration filename] [the specified filename].
///
/// The filename.
///
private bool IsValidSensorConfigurationFilename(string filename)
{
if (String.IsNullOrEmpty(filename) || !File.Exists(filename))
{
LocalizedMessageBox.Show(this, "SpecifySensorConfigurationFileName");
return false;
}
return true;
}
///
/// Handler for ok-button
///
///
///
private void OkButtonClick(object sender, EventArgs e)
{
// Check if specified file exists
if ((damNewProjectData.DamDataSourceFileName == "") ||
(File.Exists(damNewProjectData.DamDataSourceFileName) != true))
{
LocalizedMessageBox.Show(this, "SelectValidFile");
DialogResult = DialogResult.None;
return;
}
// Check if configuration file exists
if ((damNewProjectData.DamProjectType == DamProjectType.DamLiveConfiguration) && (!IsValidSensorConfigurationFilename(damNewProjectData.SensorConfigurationFileName)))
{
DialogResult = DialogResult.None;
return;
}
// Check if destination is valid
if (!IsValidDestinationProjectFileName(damNewProjectData.DamProjectFileName))
{
DialogResult = DialogResult.None;
return;
}
// Check if at least 1 dikering is selected
var selectedDikeRings = new List();
for (var i = 0; i < DikeRingsCheckedListBox.Items.Count; i++)
{
// Add selected items to list
if (DikeRingsCheckedListBox.GetItemChecked(i))
{
selectedDikeRings.Add(DikeRingsCheckedListBox.GetItemText(i));
}
}
if (selectedDikeRings.Count < 1)
{
LocalizedMessageBox.Show(this, "SelectAtLeastOneDikering");
DialogResult = DialogResult.None;
return;
}
damNewProjectData.SelectedDikeRingIds = selectedDikeRings;
}
///
/// Handler for change of source datafile
///
///
///
private void DatasourcesFileNameEditModified(object sender, EventArgs e)
{
DatasourcesFileNameUpdated();
}
///
/// Update checkboxlist after update of source datafile
///
private void DatasourcesFileNameUpdated()
{
string sourceFileName = DamNewProjectData.DamDataSourceFileName;
UpdateControlsForDataSource(sourceFileName);
UpdateProjectionInfo(sourceFileName);
DamNewProjectData.DamProjectFileName = Path.ChangeExtension(sourceFileName, ".damx");
}
///
/// Update projection info from LocationID shapefile (if one is included)
///
///
private void UpdateProjectionInfo(string sourceFileName)
{
try
{
if (!string.IsNullOrWhiteSpace(sourceFileName) && File.Exists(sourceFileName))
{
DataSourceContainer dataSourceContainer = DataSourceContainer.Deserialize(sourceFileName);
// if a projection is defined in the defx file, this overrules the info from LocationID shp/prj file
DamNewProjectData.DataSourceEsriProjection = dataSourceContainer.DataSourceEsriProjection;
DamNewProjectData.DataSourceProjectionUserDefined = false;
if (string.IsNullOrEmpty(DamNewProjectData.DataSourceEsriProjection))
{
// take projection from LocationID shapefile
string damProjectFolder = Path.GetDirectoryName(sourceFileName);
DataSource shapeFileDataSource = dataSourceContainer.DataSourceList.FirstOrDefault(s => s.DataSourceType == DataSourceType.DataShapeFiles);
if (damProjectFolder != null && shapeFileDataSource != null)
{
string shapeFileFolder = Path.Combine(damProjectFolder, shapeFileDataSource.DataLocation);
DataAttribute shapeAttribute = dataSourceContainer.DataAttributes.FirstOrDefault(s => s.AttributeId.ToLower() == CsvColumnNames.LocationColumnName);
if (shapeAttribute != null)
{
string shapeFilePath = Path.Combine(shapeFileFolder, shapeAttribute.DataSource);
if (File.Exists(shapeFilePath))
{
ProjectionInfo projection = DotSpatialUtil.GetShapeFileProjection(shapeFilePath);
if (projection != null)
{
// workaround for MWDAM-751, RD projection not always correct coming from ESRI definition
if ((projection.Name != null && projection.Name.ToLower() == "rd_new") ||
(projection.Transform != null && projection.Transform.Name != null && projection.Transform.Name.ToLower() == "double_stereographic"))
{
projection = KnownCoordinateSystems.Projected.NationalGrids.DutchRD;
}
DamNewProjectData.DataSourceEsriProjection = projection.ToEsriString();
DamNewProjectData.DataSourceProjectionName = projection.Name ?? projection.ToString();
DamNewProjectData.DataSourceProjectionUserDefined = false;
}
}
}
}
}
}
}
catch (Exception e)
{
LogManager.Add(new LogMessage(LogMessageType.Error, this, e.Message));
}
}
///
/// Updates the controls based on the new data source.
///
/// Name of the source file.
private void UpdateControlsForDataSource(string sourceFileName)
{
try
{
if (!string.IsNullOrWhiteSpace(sourceFileName) && File.Exists(sourceFileName))
{
if (!currentSourceFileName.Equals(sourceFileName))
{
DataSourceContainer dataSourceContainer = DataSourceContainer.Deserialize(sourceFileName);
UpdateDikeRingCheckedListbox(sourceFileName, dataSourceContainer);
UpdateSensorConfigurationFilename(sourceFileName, dataSourceContainer);
}
}
}
catch (Exception e)
{
Object[] args =
{
Environment.NewLine,
DamNewProjectData.DamDataSourceFileName,
Environment.NewLine + Environment.NewLine,
Environment.NewLine,
e.Message
};
LocalizedMessageBox.ShowError(this, "CannotReadDikeringsFromImportDefinition", args);
}
}
///
/// Updates the sensor configuration filename.
///
/// Name of the source file.
/// The data source container.
private void UpdateSensorConfigurationFilename(string sourceFileName, DataSourceContainer dataSourceContainer)
{
string damProjectFolder = Path.GetDirectoryName(sourceFileName);
if (!String.IsNullOrEmpty(dataSourceContainer.SensorConfigurationFilename))
{
DamNewProjectData.SensorConfigurationFileName =
Path.GetFullPath(Path.Combine(damProjectFolder, dataSourceContainer.SensorConfigurationFilename));
}
}
///
/// Updates the dike ring checked listbox.
///
/// Name of the source file.
/// The data source container.
private void UpdateDikeRingCheckedListbox(string sourceFileName, DataSourceContainer dataSourceContainer)
{
string damProjectFolder = Path.GetDirectoryName(sourceFileName);
List importLogMessages = null;
List dikeRingIds = null;
DataEventPublisher.InvokeWithoutPublishingEvents(() =>
{
dikeRingIds = WaterBoardImporter.ImportDikeRingIds(
damProjectFolder, dataSourceContainer,
DamNewProjectData.DamProjectType, out importLogMessages).ToList();
});
DikeRingsCheckedListBox.Items.Clear();
if (dikeRingIds.Count > 0)
{
DikeRingsCheckedListBox.Items.AddRange(dikeRingIds.ToArray());
DikeRingsCheckedListBox.Items[0].CheckState = CheckState.Checked;
}
else
{
string paragraphSepatator = Environment.NewLine + Environment.NewLine;
string openingMessage = LocalizationManager.GetTranslatedText(this, "NoDikeRingsFound");
var output = new StringBuilder();
foreach (LogMessage logMessage in importLogMessages)
{
output.Append(logMessage.Message + Environment.NewLine);
}
LocalizedMessageBox.ShowTranslatedText(openingMessage + paragraphSepatator + output);
}
currentSourceFileName = sourceFileName;
}
///
/// Browse for destination filename
///
///
///
private void DestinationProjectFilenameButtonClick(object sender, EventArgs e)
{
SelectFileDialog.Filter = LocalizationManager.GetTranslatedText(this, "DamProjectFilesFilterText");
SelectFileDialog.FileName = damNewProjectData.DamProjectFileName;
SelectFileDialog.CheckFileExists = false;
if (!string.IsNullOrWhiteSpace(damNewProjectData.DamProjectFileName))
{
SelectFileDialog.InitialDirectory = Path.GetDirectoryName(damNewProjectData.DamProjectFileName);
}
if (SelectFileDialog.ShowDialog() == DialogResult.OK)
{
damNewProjectData.DamProjectFileName = SelectFileDialog.FileName;
}
}
///
/// Handles the Click event of the SensorConfigurationFilenameButton control.
///
/// The source of the event.
/// The instance containing the event data.
private void SensorConfigurationFilenameButton_Click(object sender, EventArgs e)
{
var selectFileDialog = new OpenFileDialog();
selectFileDialog.Filter = LocalizationManager.GetTranslatedText(this, "SensorConfigurationFilterText");
selectFileDialog.FileName = DamNewProjectData.SensorConfigurationFileName ?? "";
selectFileDialog.CheckFileExists = true;
if (selectFileDialog.ShowDialog() == DialogResult.OK)
{
DamNewProjectData.SensorConfigurationFileName = selectFileDialog.FileName;
}
}
///
/// Handles the Click event of the ProjectionButton control.
///
/// The source of the event.
/// The instance containing the event data.
private void ProjectionButton_Click(object sender, EventArgs e)
{
DataEventPublisher.InvokeAndPublish(() =>
{
var dlg = new ProjectionSelectDialog();
if (!string.IsNullOrEmpty(DamNewProjectData.DataSourceEsriProjection))
{
dlg.SelectedCoordinateSystem = ProjectionInfo.FromEsriString(DamNewProjectData.DataSourceEsriProjection);
}
else
{
dlg.SelectedCoordinateSystem = KnownCoordinateSystems.Projected.NationalGrids.DutchRD;
}
dlg.ShowDialog();
if (dlg.DialogResult == DialogResult.OK)
{
DamNewProjectData.DataSourceEsriProjection = dlg.SelectedCoordinateSystem.ToEsriString();
DamNewProjectData.DataSourceProjectionName = dlg.SelectedCoordinateSystem.Name ?? dlg.SelectedCoordinateSystem.ToString();
DamNewProjectData.DataSourceProjectionUserDefined = true;
}
});
}
}
}