/** * \file NETGeographicLib\AlbersPanel.cs * \brief Example of various projections. * * NETGeographicLib.AlbersEqualArea, * NETGeographicLib.LambertConformalConic, * NETGeographicLib.TransverseMercator, * and NETGeographicLib.TransverseMercatorExact example * * NETGeographicLib is copyright (c) Scott Heiman (2013) * GeographicLib is Copyright (c) Charles Karney (2010-2012) * and licensed under the MIT/X11 License. * For more information, see * https://geographiclib.sourceforge.io/ **********************************************************************/ using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using NETGeographicLib; namespace Projections { public partial class AlbersPanel : UserControl { enum ProjectionTypes { AlbersEqualArea = 0, LambertConformalConic = 1, TransverseMercator = 2, TransverseMercatorExact = 3 } ProjectionTypes m_projection; AlbersEqualArea m_albers = null; LambertConformalConic m_lambert = null; TransverseMercator m_trans = null; TransverseMercatorExact m_transExact = null; public AlbersPanel() { InitializeComponent(); m_projectionComboBox.SelectedIndex = 0; // this calls OnProjection and sets it to an AlbersEqualArea m_constructorComboBox.SelectedIndex = 3; // this calls OnConstructorChanged m_majorRadiusTextBox.Text = m_albers.EquatorialRadius.ToString(); m_flatteningTextBox.Text = m_albers.Flattening.ToString(); m_centralScaleTextBox.Text = m_albers.CentralScale.ToString(); m_originLatitudeTextBox.Text = m_albers.OriginLatitude.ToString(); m_functionComboBox.SelectedIndex = 0; // this calls OnFunction } private void OnConstructorChanged(object sender, EventArgs e) { try { if (m_projectionComboBox.SelectedIndex > 1) { m_originLatitudeTextBox.ReadOnly = true; m_originLatitudeTextBox.Text = "N/A"; if (m_constructorComboBox.SelectedIndex == 0) { m_convertButton.Enabled = true; m_setButton.Enabled = false; m_majorRadiusTextBox.ReadOnly = true; m_flatteningTextBox.ReadOnly = true; m_scaleLabel.Hide(); m_KTextBox.Hide(); m_stdLatLabel.Hide(); m_stdLat1TextBox.Hide(); m_stdLat2Label.Hide(); m_stdLat2TextBox.Hide(); m_sinLat2Label.Hide(); m_sinLat2TextBox.Hide(); m_cosLat2Label.Hide(); m_cosLat2TextBox.Hide(); if (m_projection == ProjectionTypes.TransverseMercator) { m_trans = new TransverseMercator(); m_centralScaleTextBox.Text = m_trans.CentralScale.ToString(); } else { m_transExact = new TransverseMercatorExact(); m_centralScaleTextBox.Text = m_transExact.CentralScale.ToString(); } } else { m_convertButton.Enabled = false; m_setButton.Enabled = true; m_majorRadiusTextBox.ReadOnly = false; m_flatteningTextBox.ReadOnly = false; m_scaleLabel.Show(); m_KTextBox.Show(); m_stdLatLabel.Hide(); m_stdLat1TextBox.Hide(); m_stdLat2Label.Hide(); m_stdLat2TextBox.Hide(); m_sinLat2Label.Hide(); m_sinLat2TextBox.Hide(); m_cosLat2Label.Hide(); m_cosLat2TextBox.Hide(); } } else { m_originLatitudeTextBox.ReadOnly = false; switch (m_constructorComboBox.SelectedIndex) { case 0: m_convertButton.Enabled = false; m_setButton.Enabled = true; m_majorRadiusTextBox.ReadOnly = false; m_flatteningTextBox.ReadOnly = false; m_scaleLabel.Show(); m_KTextBox.Show(); m_stdLatLabel.Show(); m_stdLatLabel.Text = "Standard Latitude (degrees)"; m_stdLat1TextBox.Show(); m_stdLat2Label.Hide(); m_stdLat2TextBox.Hide(); m_sinLat2Label.Hide(); m_sinLat2TextBox.Hide(); m_cosLat2Label.Hide(); m_cosLat2TextBox.Hide(); break; case 1: m_convertButton.Enabled = false; m_setButton.Enabled = true; m_majorRadiusTextBox.ReadOnly = false; m_flatteningTextBox.ReadOnly = false; m_scaleLabel.Show(); m_KTextBox.Show(); m_stdLatLabel.Show(); m_stdLatLabel.Text = "Standard Latitude 1 (degrees)"; m_stdLat1TextBox.Show(); m_stdLat2Label.Text = "Standard Latitude 2 (degrees)"; m_stdLat2Label.Show(); m_stdLat2TextBox.Show(); m_sinLat2Label.Hide(); m_sinLat2TextBox.Hide(); m_cosLat2Label.Hide(); m_cosLat2TextBox.Hide(); break; case 2: m_convertButton.Enabled = false; m_setButton.Enabled = true; m_majorRadiusTextBox.ReadOnly = false; m_flatteningTextBox.ReadOnly = false; m_scaleLabel.Show(); m_KTextBox.Show(); m_stdLatLabel.Show(); m_stdLatLabel.Text = "Sin(Lat1)"; m_stdLat1TextBox.Show(); m_stdLat2Label.Text = "Cos(Lat1)"; m_stdLat2Label.Show(); m_stdLat2TextBox.Show(); m_sinLat2Label.Show(); m_sinLat2TextBox.Show(); m_cosLat2Label.Show(); m_cosLat2TextBox.Show(); break; default: m_convertButton.Enabled = true; m_setButton.Enabled = false; m_majorRadiusTextBox.ReadOnly = true; m_flatteningTextBox.ReadOnly = true; m_scaleLabel.Hide(); m_KTextBox.Hide(); m_stdLatLabel.Hide(); m_stdLat1TextBox.Hide(); m_stdLat2Label.Hide(); m_stdLat2TextBox.Hide(); m_sinLat2Label.Hide(); m_sinLat2TextBox.Hide(); m_cosLat2Label.Hide(); m_cosLat2TextBox.Hide(); break; } if (m_projection == ProjectionTypes.AlbersEqualArea) AlbersConstructorChanged(); } } catch (Exception xcpt) { MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void AlbersConstructorChanged() { switch (m_constructorComboBox.SelectedIndex) { case 3: m_albers = new AlbersEqualArea(AlbersEqualArea.StandardTypes.CylindricalEqualArea); break; case 4: m_albers = new AlbersEqualArea(AlbersEqualArea.StandardTypes.AzimuthalEqualAreaNorth); break; case 5: m_albers = new AlbersEqualArea(AlbersEqualArea.StandardTypes.AzimuthalEqualAreaSouth); break; default: break; } if (m_constructorComboBox.SelectedIndex > 2) { m_majorRadiusTextBox.Text = m_albers.EquatorialRadius.ToString(); m_flatteningTextBox.Text = m_albers.Flattening.ToString(); m_centralScaleTextBox.Text = m_albers.CentralScale.ToString(); m_originLatitudeTextBox.Text = m_albers.OriginLatitude.ToString(); } } private void OnSet(object sender, EventArgs e) { try { switch (m_projection) { case ProjectionTypes.AlbersEqualArea: SetAlbers(); break; case ProjectionTypes.LambertConformalConic: SetLambert(); break; case ProjectionTypes.TransverseMercator: SetTransverse(); break; case ProjectionTypes.TransverseMercatorExact: SetTransverseExact(); break; } } catch (Exception xcpt) { MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } m_convertButton.Enabled = true; } private void SetAlbers() { double s2, s3, s4; double a = Double.Parse(m_majorRadiusTextBox.Text); double f = Double.Parse(m_flatteningTextBox.Text); double k = Double.Parse(m_KTextBox.Text); double s1 = Double.Parse(m_stdLat1TextBox.Text); switch (m_constructorComboBox.SelectedIndex) { case 0: m_albers = new AlbersEqualArea(a, f, s1, k); break; case 1: s2 = Double.Parse(m_stdLat2TextBox.Text); m_albers = new AlbersEqualArea(a, f, s1, s2, k); break; case 2: s2 = Double.Parse(m_stdLat2TextBox.Text); s3 = Double.Parse(m_sinLat2TextBox.Text); s4 = Double.Parse(m_cosLat2TextBox.Text); m_albers = new AlbersEqualArea(a, f, s1, s2, s3, s4, k); break; default: break; } m_centralScaleTextBox.Text = m_albers.CentralScale.ToString(); m_originLatitudeTextBox.Text = m_albers.OriginLatitude.ToString(); } private void SetLambert() { double s2, s3, s4; double a = Double.Parse(m_majorRadiusTextBox.Text); double f = Double.Parse(m_flatteningTextBox.Text); double k = Double.Parse(m_KTextBox.Text); double s1 = Double.Parse(m_stdLat1TextBox.Text); switch (m_constructorComboBox.SelectedIndex) { case 0: m_lambert = new LambertConformalConic(a, f, s1, k); break; case 1: s2 = Double.Parse(m_stdLat2TextBox.Text); m_lambert = new LambertConformalConic(a, f, s1, s2, k); break; case 2: s2 = Double.Parse(m_stdLat2TextBox.Text); s3 = Double.Parse(m_sinLat2TextBox.Text); s4 = Double.Parse(m_cosLat2TextBox.Text); m_lambert = new LambertConformalConic(a, f, s1, s2, s3, s4, k); break; default: break; } m_centralScaleTextBox.Text = m_lambert.CentralScale.ToString(); m_originLatitudeTextBox.Text = m_lambert.OriginLatitude.ToString(); } private void SetTransverse() { switch (m_constructorComboBox.SelectedIndex) { case 1: double a = Double.Parse(m_majorRadiusTextBox.Text); double f = Double.Parse(m_flatteningTextBox.Text); double k = Double.Parse(m_KTextBox.Text); m_trans = new TransverseMercator(a, f, k); break; default: break; } m_centralScaleTextBox.Text = m_trans.CentralScale.ToString(); } private void SetTransverseExact() { switch (m_constructorComboBox.SelectedIndex) { case 1: double a = Double.Parse(m_majorRadiusTextBox.Text); double f = Double.Parse(m_flatteningTextBox.Text); double k = Double.Parse(m_KTextBox.Text); m_transExact = new TransverseMercatorExact(a, f, k, false); break; default: break; } m_centralScaleTextBox.Text = m_transExact.CentralScale.ToString(); } private void OnFunction(object sender, EventArgs e) { switch (m_functionComboBox.SelectedIndex) { case 0: m_latitudeTextBox.ReadOnly = m_longitudeTextBox.ReadOnly = false; m_xTextBox.ReadOnly = m_yTextBox.ReadOnly = true; break; case 1: m_latitudeTextBox.ReadOnly = m_longitudeTextBox.ReadOnly = true; m_xTextBox.ReadOnly = m_yTextBox.ReadOnly = false; break; } } private void OnConvert(object sender, EventArgs e) { try { switch (m_projection) { case ProjectionTypes.AlbersEqualArea: ConvertAlbers(); break; case ProjectionTypes.LambertConformalConic: ConvertLambert(); break; case ProjectionTypes.TransverseMercator: ConvertTransverse(); break; case ProjectionTypes.TransverseMercatorExact: ConvertTransverseExact(); break; } } catch (Exception xcpt) { MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void ConvertAlbers() { double lat = 0.0, lon = 0.0, x = 0.0, y = 0.0, gamma = 0.0, k = 0.0; double lon0 = Double.Parse(m_lon0TextBox.Text); switch (m_functionComboBox.SelectedIndex) { case 0: lat = Double.Parse(m_latitudeTextBox.Text); lon = Double.Parse(m_longitudeTextBox.Text); m_albers.Forward(lon0, lat, lon, out x, out y, out gamma, out k); m_xTextBox.Text = x.ToString(); m_yTextBox.Text = y.ToString(); break; case 1: x = Double.Parse(m_xTextBox.Text); y = Double.Parse(m_yTextBox.Text); m_albers.Reverse(lon0, x, y, out lat, out lon, out gamma, out k); m_latitudeTextBox.Text = lat.ToString(); m_longitudeTextBox.Text = lon.ToString(); break; } m_gammaTextBox.Text = gamma.ToString(); m_azimuthalScaleTextBox.Text = k.ToString(); } private void ConvertLambert() { double lat = 0.0, lon = 0.0, x = 0.0, y = 0.0, gamma = 0.0, k = 0.0; double lon0 = Double.Parse(m_lon0TextBox.Text); switch (m_functionComboBox.SelectedIndex) { case 0: lat = Double.Parse(m_latitudeTextBox.Text); lon = Double.Parse(m_longitudeTextBox.Text); m_lambert.Forward(lon0, lat, lon, out x, out y, out gamma, out k); m_xTextBox.Text = x.ToString(); m_yTextBox.Text = y.ToString(); break; case 1: x = Double.Parse(m_xTextBox.Text); y = Double.Parse(m_yTextBox.Text); m_lambert.Reverse(lon0, x, y, out lat, out lon, out gamma, out k); m_latitudeTextBox.Text = lat.ToString(); m_longitudeTextBox.Text = lon.ToString(); break; } m_gammaTextBox.Text = gamma.ToString(); m_azimuthalScaleTextBox.Text = k.ToString(); } private void ConvertTransverse() { double lat = 0.0, lon = 0.0, x = 0.0, y = 0.0, gamma = 0.0, k = 0.0; double lon0 = Double.Parse(m_lon0TextBox.Text); switch (m_functionComboBox.SelectedIndex) { case 0: lat = Double.Parse(m_latitudeTextBox.Text); lon = Double.Parse(m_longitudeTextBox.Text); m_trans.Forward(lon0, lat, lon, out x, out y, out gamma, out k); m_xTextBox.Text = x.ToString(); m_yTextBox.Text = y.ToString(); break; case 1: x = Double.Parse(m_xTextBox.Text); y = Double.Parse(m_yTextBox.Text); m_trans.Reverse(lon0, x, y, out lat, out lon, out gamma, out k); m_latitudeTextBox.Text = lat.ToString(); m_longitudeTextBox.Text = lon.ToString(); break; } m_gammaTextBox.Text = gamma.ToString(); m_azimuthalScaleTextBox.Text = k.ToString(); } private void ConvertTransverseExact() { double lat = 0.0, lon = 0.0, x = 0.0, y = 0.0, gamma = 0.0, k = 0.0; double lon0 = Double.Parse(m_lon0TextBox.Text); switch (m_functionComboBox.SelectedIndex) { case 0: lat = Double.Parse(m_latitudeTextBox.Text); lon = Double.Parse(m_longitudeTextBox.Text); m_transExact.Forward(lon0, lat, lon, out x, out y, out gamma, out k); m_xTextBox.Text = x.ToString(); m_yTextBox.Text = y.ToString(); break; case 1: x = Double.Parse(m_xTextBox.Text); y = Double.Parse(m_yTextBox.Text); m_transExact.Reverse(lon0, x, y, out lat, out lon, out gamma, out k); m_latitudeTextBox.Text = lat.ToString(); m_longitudeTextBox.Text = lon.ToString(); break; } m_gammaTextBox.Text = gamma.ToString(); m_azimuthalScaleTextBox.Text = k.ToString(); } private void OnProjection(object sender, EventArgs e) { m_projection = (ProjectionTypes)m_projectionComboBox.SelectedIndex; int save = m_constructorComboBox.SelectedIndex; m_constructorComboBox.Items.Clear(); if (m_projectionComboBox.SelectedIndex > 1) // TransverseMercator or TransverseMercatorExact { m_constructorComboBox.Items.Add("Default"); m_constructorComboBox.Items.Add("Constructor #1"); } else { m_constructorComboBox.Items.Add("Constructor #1"); m_constructorComboBox.Items.Add("Constructor #2"); m_constructorComboBox.Items.Add("Constructor #3"); if (m_projection == ProjectionTypes.AlbersEqualArea) { m_constructorComboBox.Items.Add("CylindricalEqualArea"); m_constructorComboBox.Items.Add("AzimuthalEqualAreaNorth"); m_constructorComboBox.Items.Add("AzimuthalEqualAreaSouth"); } } // calls OnConstructor m_constructorComboBox.SelectedIndex = m_constructorComboBox.Items.Count > save ? save : 0; } private void OnValidate(object sender, EventArgs e) { try { const double DEG_TO_RAD = 3.1415926535897932384626433832795 / 180.0; AlbersEqualArea a = new AlbersEqualArea(AlbersEqualArea.StandardTypes.AzimuthalEqualAreaNorth); a = new AlbersEqualArea(AlbersEqualArea.StandardTypes.AzimuthalEqualAreaSouth); double radius = a.EquatorialRadius; double f = a.Flattening; a = new AlbersEqualArea(radius, f, 60.0, 1.0); a = new AlbersEqualArea(radius, f, 60.0, 70.0, 1.0); a = new AlbersEqualArea(radius, f, Math.Sin(88.0 * DEG_TO_RAD), Math.Cos(88.0 * DEG_TO_RAD), Math.Sin(89.0*DEG_TO_RAD), Math.Cos(89.0*DEG_TO_RAD), 1.0); a = new AlbersEqualArea(AlbersEqualArea.StandardTypes.CylindricalEqualArea); double lon0 = 0.0, lat = 32.0, lon = -86.0, x, y, gamma, k, x1, y1; a.Forward(lon0, lat, lon, out x, out y, out gamma, out k); a.Forward(lon0, lat, lon, out x1, out y1); if (x != x1 || y != y1) throw new Exception("Error in AlbersEqualArea.Forward"); a.Reverse(lon0, x, y, out lat, out lon, out gamma, out k); a.Reverse(lon0, x, y, out x1, out y1); if (lat != x1 || lon != y1) throw new Exception("Error in AlbersEqualArea.Reverse"); LambertConformalConic b = new LambertConformalConic(radius, f, 60.0, 1.0); b = new LambertConformalConic(radius, f, 60.0, 65.0, 1.0); b = new LambertConformalConic(radius, f, Math.Sin(88.0 * DEG_TO_RAD), Math.Cos(88.0 * DEG_TO_RAD), Math.Sin(89.0 * DEG_TO_RAD), Math.Cos(89.0 * DEG_TO_RAD), 1.0); b = new LambertConformalConic(); b.SetScale(60.0, 1.0); b.Forward(-87.0, 32.0, -86.0, out x, out y, out gamma, out k); b.Forward(-87.0, 32.0, -86.0, out x1, out y1); if (x != x1 || y != y1) throw new Exception("Error in LambertConformalConic.Forward"); b.Reverse(-87.0, x, y, out lat, out lon, out gamma, out k); b.Reverse(-87.0, x, y, out x1, out y1, out gamma, out k); if (lat != x1 || lon != y1) throw new Exception("Error in LambertConformalConic.Reverse"); TransverseMercator c = new TransverseMercator(radius, f, 1.0); c = new TransverseMercator(); c.Forward(-87.0, 32.0, -86.0, out x, out y, out gamma, out k); c.Forward(-87.0, 32.0, -86.0, out x1, out y1); if (x != x1 || y != y1) throw new Exception("Error in TransverseMercator.Forward"); c.Reverse(-87.0, x, y, out lat, out lon, out gamma, out k); c.Reverse(-87.0, x, y, out x1, out y1); if (lat != x1 || lon != y1) throw new Exception("Error in TransverseMercator.Reverse"); TransverseMercatorExact d = new TransverseMercatorExact(radius, f, 1.0, false); d = new TransverseMercatorExact(); d.Forward(-87.0, 32.0, -86.0, out x, out y, out gamma, out k); d.Forward(-87.0, 32.0, -86.0, out x1, out y1); if (x != x1 || y != y1) throw new Exception("Error in TransverseMercatorExact.Forward"); d.Reverse(-87.0, x, y, out lat, out lon, out gamma, out k); d.Reverse(-87.0, x, y, out x1, out y1); if (lat != x1 || lon != y1) throw new Exception("Error in TransverseMercatorExact.Reverse"); } catch (Exception xcpt) { MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } MessageBox.Show("No errors detected", "OK", MessageBoxButtons.OK, MessageBoxIcon.Information); } } }