1 /**
2  * \file NETGeographicLib\GeodesicPanel.cs
3  * \brief NETGeographicLib.Geodesic example
4  *
5  * NETGeographicLib.Geodesic,
6  * NETGeographicLib.GeodesicLine,
7  * NETGeographicLib.GeodesicExact,
8  * NETGeographicLib.GeodesicLineExact
9  *
10  * NETGeographicLib is copyright (c) Scott Heiman (2013)
11  * GeographicLib is Copyright (c) Charles Karney (2010-2012)
12  * <charles@karney.com> and licensed under the MIT/X11 License.
13  * For more information, see
14  * https://geographiclib.sourceforge.io/
15  **********************************************************************/
16 using System;
17 using System.Collections.Generic;
18 using System.ComponentModel;
19 using System.Drawing;
20 using System.Data;
21 using System.Linq;
22 using System.Text;
23 using System.Windows.Forms;
24 using NETGeographicLib;
25 
26 namespace Projections
27 {
28     public partial class GeodesicPanel : UserControl
29     {
30         public string warning = "GeographicLib Error";
31         public string warning2 = "Data Conversion Error";
32 
33         enum Function
34         {
35             Direct = 0,
36             Inverse = 1
37         };
38         Function m_function = Function.Direct;
39 
40         enum Variable
41         {
42             Distance = 0,
43             ArcLength = 2
44         };
45         Variable m_variable = Variable.Distance;
46 
47         enum Classes
48         {
49             GEODESIC = 0,
50             GEODESICEXACT= 1,
51             GEODESICLINE = 2,
52             GEODESICLINEEXACT = 3
53         };
54         Classes m_class = Classes.GEODESIC;
55 
56         Geodesic m_geodesic = null;
57 
GeodesicPanel()58         public GeodesicPanel()
59         {
60             InitializeComponent();
61             m_tooltips.SetToolTip(button1, "Performs the selected function with the selected class");
62             m_tooltips.SetToolTip(m_setButton, "Sets the ellipsoid attributes");
63             m_tooltips.SetToolTip(m_validateButton, "Validates Geodesic, GeodesicExact, GeodesicLine, and GeodesicLineExact interfaces");
64             try
65             {
66                 m_geodesic = new Geodesic();
67             }
68             catch (GeographicErr err)
69             {
70                 MessageBox.Show(err.Message, warning, MessageBoxButtons.OK, MessageBoxIcon.Error);
71             }
72 
73             m_equatorialRadiusTextBox.Text = m_geodesic.EquatorialRadius.ToString();
74             m_flatteningTextBox.Text = m_geodesic.Flattening.ToString();
75             m_functionComboBox.SelectedIndex = 0;
76             m_classComboBox.SelectedIndex = 0;
77         }
78 
79         // gets the equatorial radius and flattening and creates a new Geodesic
OnSet(object sender, EventArgs e)80         private void OnSet(object sender, EventArgs e)
81         {
82             try
83             {
84                 double radius = Double.Parse(m_equatorialRadiusTextBox.Text);
85                 double flattening = Double.Parse(m_flatteningTextBox.Text);
86                 m_geodesic = new Geodesic(radius, flattening);
87             }
88             catch (GeographicErr err)
89             {
90                 MessageBox.Show(err.Message, warning, MessageBoxButtons.OK, MessageBoxIcon.Error);
91             }
92             catch (Exception err2)
93             {
94                 MessageBox.Show(err2.Message, warning2, MessageBoxButtons.OK, MessageBoxIcon.Error);
95             }
96         }
97 
98         // Gets the input parameters and calls the appropriate function
OnForward(object sender, EventArgs e)99         private void OnForward(object sender, EventArgs e)
100         {
101             double origLatitude = 0.0, origLongitude = 0.0, origAzimuth = 0.0,
102                 distance = 0.0, finalLatitude = 0.0, finalLongitude = 0.0;
103             // get & validate inputs
104             try
105             {
106                 if ( m_function == Function.Direct )
107                 {
108                     distance = Double.Parse( m_variable == Variable.Distance ?
109                         m_distanceTextBox.Text : m_ArcLengthTextBox.Text );
110                     origAzimuth = Double.Parse( m_originAzimuthTextBox.Text );
111                     if ( origAzimuth < -180.0 || origAzimuth > 180.0 )
112                     {
113                         m_originAzimuthTextBox.Focus();
114                         throw new Exception( "Range Error: -180 <= initial azimuth <= 180 degrees" );
115                     }
116                 }
117                 else
118                 {
119                     finalLatitude = Double.Parse( m_finalLatitudeTextBox.Text );
120                     if (finalLatitude < -90.0 || finalLatitude > 90.0)
121                     {
122                         m_finalLatitudeTextBox.Focus();
123                         throw new Exception("Range Error: -90 <= final latitude <= 90 degrees");
124                     }
125                     finalLongitude = Double.Parse( m_finalLongitudeTextBox.Text );
126                     if (finalLongitude < -540.0 || finalLongitude > 540.0)
127                     {
128                         m_finalLongitudeTextBox.Focus();
129                         throw new Exception("Range Error: -540 <= final longitude <= 540 degrees");
130                     }
131                 }
132                 origLatitude = Double.Parse( m_originLatitudeTextBox.Text );
133                 if (origLatitude < -90.0 || origLatitude > 90.0)
134                 {
135                     m_originLatitudeTextBox.Focus();
136                     throw new Exception("Range Error: -90 <= initial latitude <= 90 degrees");
137                 }
138                 origLongitude = Double.Parse(m_originLongitudeTextBox.Text);
139                 if (origLongitude < -540.0 || origLongitude > 540.0)
140                 {
141                     m_originLongitudeTextBox.Focus();
142                     throw new Exception("Range Error: -540 <= initial longitude <= 540 degrees");
143                 }
144             }
145             catch ( Exception xcpt )
146             {
147                 MessageBox.Show(xcpt.Message, warning2, MessageBoxButtons.OK, MessageBoxIcon.Error);
148                 return;
149             }
150 
151             // excute the appropriate function.
152             double finalAzimuth = 0.0, reducedLength = 0.0, M12 = 0.0, M21 = 0.0,
153                 S12 = 0.0, arcDistance = 0.0;
154             int sw = (int)m_function | (int)m_variable;
155             if (sw == 3) sw = 1; // cases 1 & 3 are identical.
156             try
157             {
158                 switch (m_class)
159                 {
160                     case Classes.GEODESIC:
161                         switch (sw)
162                         {
163                             case 0: // function == Direct, variable == distance
164                                 m_ArcLengthTextBox.Text =
165                                     m_geodesic.Direct(origLatitude, origLongitude, origAzimuth, distance,
166                                         out finalLatitude, out finalLongitude, out finalAzimuth, out reducedLength,
167                                         out M12, out M21, out S12).ToString();
168                                 m_finalLatitudeTextBox.Text = finalLatitude.ToString();
169                                 m_finalLongitudeTextBox.Text = finalLongitude.ToString();
170                                 break;
171                             case 1: // function == Inverse, variable == distance
172                                 m_ArcLengthTextBox.Text =
173                                     m_geodesic.Inverse(origLatitude, origLongitude, finalLatitude, finalLongitude,
174                                         out distance, out origAzimuth, out finalAzimuth, out reducedLength, out M12,
175                                         out M21, out S12).ToString();
176                                 m_distanceTextBox.Text = distance.ToString();
177                                 m_originAzimuthTextBox.Text = origAzimuth.ToString();
178                                 break;
179                             case 2: // function == Direct, variable == arc length
180                                 m_geodesic.ArcDirect(origLatitude, origLongitude, origAzimuth, distance,
181                                     out finalLatitude, out finalLongitude, out finalAzimuth, out arcDistance,
182                                     out reducedLength, out M12, out M21, out S12);
183                                 m_distanceTextBox.Text = arcDistance.ToString();
184                                 m_finalLatitudeTextBox.Text = finalLatitude.ToString();
185                                 m_finalLongitudeTextBox.Text = finalLongitude.ToString();
186                                 break;
187                         }
188                         m_finalAzimuthTextBox.Text = finalAzimuth.ToString();
189                         m_reducedLengthTextBox.Text = reducedLength.ToString();
190                         m_M12TextBox.Text = M12.ToString();
191                         m_M21TextBox.Text = M21.ToString();
192                         m_S12TextBox.Text = S12.ToString();
193                         break;
194                     case Classes.GEODESICEXACT:
195                         GeodesicExact ge = new GeodesicExact(m_geodesic.EquatorialRadius, m_geodesic.Flattening);
196                         switch (sw)
197                         {
198                             case 0: // function == Direct, variable == distance
199                                 m_ArcLengthTextBox.Text =
200                                     ge.Direct(origLatitude, origLongitude, origAzimuth, distance,
201                                         out finalLatitude, out finalLongitude, out finalAzimuth, out reducedLength,
202                                         out M12, out M21, out S12).ToString();
203                                 m_finalLatitudeTextBox.Text = finalLatitude.ToString();
204                                 m_finalLongitudeTextBox.Text = finalLongitude.ToString();
205                                 break;
206                             case 1: // function == Inverse, variable == distance
207                                 m_ArcLengthTextBox.Text =
208                                     ge.Inverse(origLatitude, origLongitude, finalLatitude, finalLongitude,
209                                         out distance, out origAzimuth, out finalAzimuth, out reducedLength, out M12,
210                                         out M21, out S12).ToString();
211                                 m_distanceTextBox.Text = distance.ToString();
212                                 m_originAzimuthTextBox.Text = origAzimuth.ToString();
213                                 break;
214                             case 2: // function == Direct, variable == arc length
215                                 ge.ArcDirect(origLatitude, origLongitude, origAzimuth, distance,
216                                     out finalLatitude, out finalLongitude, out finalAzimuth, out arcDistance,
217                                     out reducedLength, out M12, out M21, out S12);
218                                 m_distanceTextBox.Text = arcDistance.ToString();
219                                 m_finalLatitudeTextBox.Text = finalLatitude.ToString();
220                                 m_finalLongitudeTextBox.Text = finalLongitude.ToString();
221                                 break;
222                         }
223                         m_finalAzimuthTextBox.Text = finalAzimuth.ToString();
224                         m_reducedLengthTextBox.Text = reducedLength.ToString();
225                         m_M12TextBox.Text = M12.ToString();
226                         m_M21TextBox.Text = M21.ToString();
227                         m_S12TextBox.Text = S12.ToString();
228                         break;
229                     case Classes.GEODESICLINE:
230                         GeodesicLine gl = new GeodesicLine(m_geodesic, origLatitude, origLongitude, origAzimuth, Mask.ALL);
231                         switch (sw)
232                         {
233                             case 0: // function == Direct, variable == distance
234                                 m_ArcLengthTextBox.Text =
235                                     gl.Position(distance,
236                                         out finalLatitude, out finalLongitude, out finalAzimuth, out reducedLength,
237                                         out M12, out M21, out S12).ToString();
238                                 m_finalLatitudeTextBox.Text = finalLatitude.ToString();
239                                 m_finalLongitudeTextBox.Text = finalLongitude.ToString();
240                                 break;
241                             case 1: // function == Inverse, variable == distance
242                                 throw new Exception("GeodesicLine does not have an Inverse function");
243                             case 2: // function == Direct, variable == arc length
244                                 gl.ArcPosition(distance,
245                                     out finalLatitude, out finalLongitude, out finalAzimuth, out arcDistance,
246                                     out reducedLength, out M12, out M21, out S12);
247                                 m_distanceTextBox.Text = arcDistance.ToString();
248                                 m_finalLatitudeTextBox.Text = finalLatitude.ToString();
249                                 m_finalLongitudeTextBox.Text = finalLongitude.ToString();
250                                 break;
251                         }
252                         m_finalAzimuthTextBox.Text = finalAzimuth.ToString();
253                         m_reducedLengthTextBox.Text = reducedLength.ToString();
254                         m_M12TextBox.Text = M12.ToString();
255                         m_M21TextBox.Text = M21.ToString();
256                         m_S12TextBox.Text = S12.ToString();
257                         break;
258                     case Classes.GEODESICLINEEXACT:
259                         GeodesicLineExact gle = new GeodesicLineExact(origLatitude, origLongitude, origAzimuth, Mask.ALL);
260                         switch (sw)
261                         {
262                             case 0: // function == Direct, variable == distance
263                                 m_ArcLengthTextBox.Text =
264                                     gle.Position(distance,
265                                         out finalLatitude, out finalLongitude, out finalAzimuth, out reducedLength,
266                                         out M12, out M21, out S12).ToString();
267                                 m_finalLatitudeTextBox.Text = finalLatitude.ToString();
268                                 m_finalLongitudeTextBox.Text = finalLongitude.ToString();
269                                 break;
270                             case 1: // function == Inverse, variable == distance
271                                 throw new Exception("GeodesicLineExact does not have an Inverse function");
272                             case 2: // function == Direct, variable == arc length
273                                 gle.ArcPosition(distance,
274                                     out finalLatitude, out finalLongitude, out finalAzimuth, out arcDistance,
275                                     out reducedLength, out M12, out M21, out S12);
276                                 m_distanceTextBox.Text = arcDistance.ToString();
277                                 m_finalLatitudeTextBox.Text = finalLatitude.ToString();
278                                 m_finalLongitudeTextBox.Text = finalLongitude.ToString();
279                                 break;
280                         }
281                         m_finalAzimuthTextBox.Text = finalAzimuth.ToString();
282                         m_reducedLengthTextBox.Text = reducedLength.ToString();
283                         m_M12TextBox.Text = M12.ToString();
284                         m_M21TextBox.Text = M21.ToString();
285                         m_S12TextBox.Text = S12.ToString();
286                         break;
287                 }
288             }
289             catch (Exception err)
290             {
291                 MessageBox.Show(err.Message, warning, MessageBoxButtons.OK, MessageBoxIcon.Error);
292             }
293         }
294         // gui stuff
OnDistance(object sender, EventArgs e)295         private void OnDistance(object sender, EventArgs e)
296         {
297             m_distanceTextBox.ReadOnly = false;
298             m_ArcLengthTextBox.ReadOnly = true;
299             m_variable = Variable.Distance;
300         }
301 
302         // gui stuff
OnArcLength(object sender, EventArgs e)303         private void OnArcLength(object sender, EventArgs e)
304         {
305             m_distanceTextBox.ReadOnly = true;
306             m_ArcLengthTextBox.ReadOnly = false;
307             m_variable = Variable.ArcLength;
308         }
309 
310         // gui stuff
OnFunction(object sender, EventArgs e)311         private void OnFunction(object sender, EventArgs e)
312         {
313             m_function = (Function)m_functionComboBox.SelectedIndex;
314             switch (m_function)
315             {
316                 case Function.Direct:
317                     m_distanceTextBox.ReadOnly = m_variable == Variable.ArcLength;
318                     m_ArcLengthTextBox.ReadOnly = m_variable == Variable.Distance;
319                     m_originAzimuthTextBox.ReadOnly = false;
320                     m_finalLatitudeTextBox.ReadOnly = true;
321                     m_finalLongitudeTextBox.ReadOnly = true;
322                     break;
323                 case Function.Inverse:
324                     m_distanceTextBox.ReadOnly = true;
325                     m_ArcLengthTextBox.ReadOnly = true;
326                     m_originAzimuthTextBox.ReadOnly = true;
327                     m_finalLatitudeTextBox.ReadOnly = false;
328                     m_finalLongitudeTextBox.ReadOnly = false;
329                     break;
330             }
331         }
332         // gui stuff
OnClassChanged(object sender, EventArgs e)333         private void OnClassChanged(object sender, EventArgs e)
334         {
335             m_class = (Classes)m_classComboBox.SelectedIndex;
336         }
337 
338         // a simple validation function...does not change GUI elements
OnValidate(object sender, EventArgs e)339         private void OnValidate(object sender, EventArgs e)
340         {
341             double finalAzimuth = 0.0, reducedLength = 0.0, M12 = 0.0, M21 = 0.0,
342                 S12 = 0.0, arcDistance = 0.0, finalLatitude = 0.0, finalLongitude = 0.0,
343                 distance = 0.0;
344             try
345             {
346                 Geodesic g = new Geodesic();
347                 g = new Geodesic(g.EquatorialRadius, g.Flattening);
348                 arcDistance = g.Direct(32.0, -86.0, 45.0, 20000.0, out finalLatitude, out finalLongitude,
349                     out finalAzimuth, out reducedLength, out M12, out M21,
350                     out S12);
351                 double flat = 0.0, flon = 0.0, faz = 0.0, frd = 0.0, fm12 = 0.0, fm21 = 0.0, fs12 = 0.0, fad = 0.0;
352                 fad = g.Direct(32.0, -86.0, 45.0, 20000.0, out flat, out flon);
353                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude)
354                     throw new Exception("Geodesic.Direct #1 failed");
355                 fad = g.Direct(32.0, -86.0, 45.0, 20000.0, out flat, out flon, out faz);
356                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
357                     faz != finalAzimuth)
358                     throw new Exception("Geodesic.Direct #2 failed");
359                 fad = g.Direct(32.0, -86.0, 45.0, 20000.0, out flat, out flon, out faz, out frd);
360                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
361                     faz != finalAzimuth || frd != reducedLength)
362                     throw new Exception("Geodesic.Direct #3 failed");
363                 fad = g.Direct(32.0, -86.0, 45.0, 20000.0, out flat, out flon, out faz, out fm12, out fm21);
364                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
365                     faz != finalAzimuth || fm12 != M12 || fm21 != M21)
366                     throw new Exception("Geodesic.Direct #4 failed");
367                 fad = g.Direct(32.0, -86.0, 45.0, 20000.0, out flat, out flon, out faz, out frd, out fm12, out fm21);
368                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
369                     faz != finalAzimuth || frd != reducedLength || fm12 != M12 || fm21 != M21)
370                     throw new Exception("Geodesic.Direct #5 failed");
371                 double outd = 0.0;
372                 fad = g.GenDirect(32.0, -86.0, 45.0, false, 20000.0, Geodesic.mask.ALL, out flat, out flon, out faz, out outd, out frd, out fm12, out fm21, out fs12);
373                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
374                     faz != finalAzimuth || frd != reducedLength || fm12 != M12 || fm21 != M21 ||
375                     outd != 20000.0 || fs12 != S12)
376                     throw new Exception("Geodesic.GenDirect (false) failed");
377                 g.ArcDirect(32.0, -86.0, 45.0, 1.0, out finalLatitude, out finalLongitude, out finalAzimuth,
378                     out arcDistance, out reducedLength, out M12, out M21, out S12);
379                 g.ArcDirect(32.0, -86.0, 45.0, 1.0, out flat, out flon);
380                 if (flat != finalLatitude || flon != finalLongitude)
381                     throw new Exception("Geodesic.ArcDirect #1 failed");
382                 g.ArcDirect(32.0, -86.0, 45.0, 1.0, out flat, out flon, out faz);
383                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth)
384                     throw new Exception("Geodesic.ArcDirect #2 failed");
385                 g.ArcDirect(32.0, -86.0, 45.0, 1.0, out flat, out flon, out faz, out fad);
386                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
387                     fad != arcDistance)
388                     throw new Exception("Geodesic.ArcDirect #3 failed");
389                 g.ArcDirect(32.0, -86.0, 45.0, 1.0, out flat, out flon, out faz, out fad, out frd);
390                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
391                     fad != arcDistance || frd != reducedLength)
392                     throw new Exception("Geodesic.ArcDirect #4 failed");
393                 g.ArcDirect(32.0, -86.0, 45.0, 1.0, out flat, out flon, out faz, out fad, out fm12, out fm21);
394                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
395                     fad != arcDistance || fm12 != M12 || fm21 != M21)
396                     throw new Exception("Geodesic.ArcDirect #5 failed");
397                 fad = g.GenDirect(32.0, -86.0, 45.0, true, 1.0, Geodesic.mask.ALL, out flat, out flon,
398                     out faz, out outd, out frd, out fm12, out fm21, out fs12);
399                 if (outd != arcDistance || flat != finalLatitude || flon != finalLongitude ||
400                     faz != finalAzimuth || frd != reducedLength || fm12 != M12 || fm21 != M21 ||
401                     fs12 != S12 || fad != 1.0)
402                     throw new Exception("Geodesic.GenDirect (true) failed");
403                 double initAzimuth = 0.0, iaz = 0.0;
404                 arcDistance = g.Inverse(32.0, -86.0, 33.0, -87.0, out distance, out initAzimuth, out finalAzimuth,
405                     out reducedLength, out M12, out M21, out S12);
406                 fad = g.Inverse(32.0, -86.0, 33.0, -87.0, out outd);
407                 if (fad != arcDistance || outd != distance)
408                     throw new Exception("Geodesic.Inverse #1 failed");
409                 fad = g.Inverse(32.0, -86.0, 33.0, -87.0, out iaz, out faz);
410                 if (fad != arcDistance || iaz != initAzimuth || faz != finalAzimuth)
411                     throw new Exception("Geodesic.Inverse #2 failed");
412                 fad = g.Inverse(32.0, -86.0, 33.0, -87.0, out outd, out iaz, out faz);
413                 if (fad != arcDistance || outd != distance || faz != finalAzimuth ||
414                     outd != distance)
415                     throw new Exception("Geodesic.Inverse #3 failed");
416                 fad = g.Inverse(32.0, -86.0, 33.0, -87.0, out outd, out iaz, out faz, out frd);
417                 if (fad != arcDistance || outd != distance || faz != finalAzimuth ||
418                     outd != distance || frd != reducedLength)
419                     throw new Exception("Geodesic.Inverse #4 failed");
420                 fad = g.Inverse(32.0, -86.0, 33.0, -87.0, out outd, out iaz, out faz, out fm12, out fm21 );
421                 if (fad != arcDistance || outd != distance || faz != finalAzimuth ||
422                     outd != distance || fm12 != M12 || fm21 != M21 )
423                     throw new Exception("Geodesic.Inverse #5 failed");
424                 fad = g.Inverse(32.0, -86.0, 33.0, -87.0, out outd, out iaz, out faz, out frd, out fm12, out fm21);
425                 if (fad != arcDistance || outd != distance || faz != finalAzimuth ||
426                     outd != distance || fm12 != M12 || fm21 != M21 || frd != reducedLength)
427                     throw new Exception("Geodesic.Inverse #6 failed");
428                 GeodesicLine gl = g.Line(32.0, -86.0, 45.0, Mask.ALL);
429                 gl = g.InverseLine(32.0, -86.0, 33.0, -87.0, Mask.ALL);
430                 gl = g.DirectLine(32.0, -86.0, 45.0, 10000.0, Mask.ALL);
431                 gl = g.ArcDirectLine(32.0, -86.0, 45.0, 10000.0, Mask.ALL);
432                 gl = new GeodesicLine(32.0, -86.0, 45.0, Mask.ALL);
433                 gl = new GeodesicLine(g, 32.0, -86.0, 45.0, Mask.ALL);
434                 arcDistance = gl.Position(10000.0, out finalLatitude, out finalLongitude, out finalAzimuth,
435                     out reducedLength, out M12, out M21, out S12);
436                 fad = gl.Position(10000.0, out flat, out flon);
437                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude)
438                     throw new Exception("GeodesicLine.Position #1 failed");
439                 fad = gl.Position(10000.0, out flat, out flon, out faz);
440                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
441                     faz != finalAzimuth)
442                     throw new Exception("GeodesicLine.Position #2 failed");
443                 fad = gl.Position(10000.0, out flat, out flon, out faz, out frd);
444                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
445                     faz != finalAzimuth || frd != reducedLength)
446                     throw new Exception("GeodesicLine.Position #3 failed");
447                 fad = gl.Position(10000.0, out flat, out flon, out faz, out fm12, out fm21);
448                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
449                     faz != finalAzimuth || fm12 != M12 || fm21 != M21)
450                     throw new Exception("GeodesicLine.Position #4 failed");
451                 fad = gl.Position(10000.0, out flat, out flon, out faz, out frd, out fm12, out fm21);
452                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
453                     faz != finalAzimuth || fm12 != M12 || fm21 != M21 || frd != reducedLength )
454                     throw new Exception("GeodesicLine.Position #5 failed");
455                 fad = gl.GenPosition(false, 10000.0, GeodesicLine.mask.ALL, out flat, out flon, out faz, out outd, out frd, out fm12, out fm21, out fs12);
456                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
457                     faz != finalAzimuth || outd != 10000.0 || fm12 != M12 || fm21 != M21 ||
458                     frd != reducedLength || fs12 != S12 )
459                     throw new Exception("GeodesicLine.GenPosition (false) failed");
460                 gl.ArcPosition(1.0, out finalLatitude, out finalLongitude, out finalAzimuth,
461                     out distance, out reducedLength, out M12, out M21, out S12);
462                 gl.ArcPosition(1.0, out flat, out flon);
463                 if (flat != finalLatitude || flon != finalLongitude)
464                     throw new Exception("GeodesicLine.ArcPosition #1 failed");
465                 gl.ArcPosition(1.0, out flat, out flon, out faz);
466                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth)
467                     throw new Exception("GeodesicLine.ArcPosition #2 failed");
468                 gl.ArcPosition(1.0, out flat, out flon, out faz, out outd);
469                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
470                     outd != distance)
471                     throw new Exception("GeodesicLine.ArcPosition #3 failed");
472                 gl.ArcPosition(1.0, out flat, out flon, out faz, out outd, out frd);
473                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
474                     outd != distance || frd != reducedLength)
475                     throw new Exception("GeodesicLine.ArcPosition #4 failed");
476                 gl.ArcPosition(1.0, out flat, out flon, out faz, out outd, out fm12, out fm21);
477                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
478                     outd != distance || fm12 != M12 || fm21 != M21)
479                     throw new Exception("GeodesicLine.ArcPosition #5 failed");
480                 gl.ArcPosition(1.0, out flat, out flon, out faz, out outd, out frd, out fm12, out fm21);
481                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
482                     outd != distance || fm12 != M12 || fm21 != M21 || frd != reducedLength)
483                     throw new Exception("GeodesicLine.ArcPosition #6 failed");
484                 fad = gl.GenPosition(true, 1.0, GeodesicLine.mask.ALL, out flat, out flon, out faz, out outd, out frd, out fm12, out fm21, out fs12);
485                 if (fad != 1.0 || flat != finalLatitude || flon != finalLongitude ||
486                     faz != finalAzimuth || outd != distance || fm12 != M12 || fm21 != M21 ||
487                     frd != reducedLength || fs12 != S12)
488                     throw new Exception("GeodesicLine.GenPosition (false) failed");
489 
490                 GeodesicExact ge = new GeodesicExact();
491                 ge = new GeodesicExact(g.EquatorialRadius, g.Flattening);
492                 arcDistance = ge.Direct(32.0, -86.0, 45.0, 20000.0, out finalLatitude, out finalLongitude,
493                     out finalAzimuth, out reducedLength, out M12, out M21,
494                     out S12);
495                 fad = ge.Direct(32.0, -86.0, 45.0, 20000.0, out flat, out flon);
496                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude)
497                     throw new Exception("GeodesicExact.Direct #1 failed");
498                 fad = ge.Direct(32.0, -86.0, 45.0, 20000.0, out flat, out flon, out faz);
499                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
500                     faz != finalAzimuth)
501                     throw new Exception("GeodesicExact.Direct #2 failed");
502                 fad = ge.Direct(32.0, -86.0, 45.0, 20000.0, out flat, out flon, out faz, out frd);
503                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
504                     faz != finalAzimuth || frd != reducedLength)
505                     throw new Exception("GeodesicExact.Direct #3 failed");
506                 fad = ge.Direct(32.0, -86.0, 45.0, 20000.0, out flat, out flon, out faz, out fm12, out fm21);
507                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
508                     faz != finalAzimuth || fm12 != M12 || fm21 != M21)
509                     throw new Exception("GeodesicExact.Direct #4 failed");
510                 fad = ge.Direct(32.0, -86.0, 45.0, 20000.0, out flat, out flon, out faz, out frd, out fm12, out fm21);
511                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
512                     faz != finalAzimuth || frd != reducedLength || fm12 != M12 || fm21 != M21)
513                     throw new Exception("GeodesicExact.Direct #5 failed");
514                 fad = ge.GenDirect(32.0, -86.0, 45.0, false, 20000.0, GeodesicExact.mask.ALL, out flat, out flon, out faz, out outd, out frd, out fm12, out fm21, out fs12);
515                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
516                     faz != finalAzimuth || frd != reducedLength || fm12 != M12 || fm21 != M21 ||
517                     outd != 20000.0 || fs12 != S12)
518                     throw new Exception("GeodesicExact.GenDirect (false) failed");
519                 ge.ArcDirect(32.0, -86.0, 45.0, 1.0, out finalLatitude, out finalLongitude, out finalAzimuth,
520                     out arcDistance, out reducedLength, out M12, out M21, out S12);
521                 ge.ArcDirect(32.0, -86.0, 45.0, 1.0, out flat, out flon);
522                 if (flat != finalLatitude || flon != finalLongitude)
523                     throw new Exception("GeodesicExact.ArcDirect #1 failed");
524                 ge.ArcDirect(32.0, -86.0, 45.0, 1.0, out flat, out flon, out faz);
525                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth)
526                     throw new Exception("GeodesicExact.ArcDirect #2 failed");
527                 ge.ArcDirect(32.0, -86.0, 45.0, 1.0, out flat, out flon, out faz, out fad);
528                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
529                     fad != arcDistance)
530                     throw new Exception("GeodesicExact.ArcDirect #3 failed");
531                 ge.ArcDirect(32.0, -86.0, 45.0, 1.0, out flat, out flon, out faz, out fad, out frd);
532                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
533                     fad != arcDistance || frd != reducedLength)
534                     throw new Exception("GeodesicExact.ArcDirect #4 failed");
535                 ge.ArcDirect(32.0, -86.0, 45.0, 1.0, out flat, out flon, out faz, out fad, out fm12, out fm21);
536                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
537                     fad != arcDistance || fm12 != M12 || fm21 != M21)
538                     throw new Exception("GeodesicExact.ArcDirect #5 failed");
539                 fad = ge.GenDirect(32.0, -86.0, 45.0, true, 1.0, GeodesicExact.mask.ALL, out flat, out flon, out faz, out outd, out frd, out fm12, out fm21, out fs12);
540                 if (outd != arcDistance || flat != finalLatitude || flon != finalLongitude ||
541                     faz != finalAzimuth || frd != reducedLength || fm12 != M12 || fm21 != M21 ||
542                     fad != 1.0 || fs12 != S12)
543                     throw new Exception("GeodesicExact.GenDirect (true) failed");
544                 arcDistance = ge.Inverse(32.0, -86.0, 33.0, -87.0, out distance, out initAzimuth, out finalAzimuth,
545                     out reducedLength, out M12, out M21, out S12);
546                 fad = ge.Inverse(32.0, -86.0, 33.0, -87.0, out outd);
547                 if (fad != arcDistance || outd != distance)
548                     throw new Exception("GeodesicExact.Inverse #1 failed");
549                 fad = ge.Inverse(32.0, -86.0, 33.0, -87.0, out iaz, out faz);
550                 if (fad != arcDistance || iaz != initAzimuth || faz != finalAzimuth)
551                     throw new Exception("GeodesicExact.Inverse #2 failed");
552                 fad = ge.Inverse(32.0, -86.0, 33.0, -87.0, out outd, out iaz, out faz);
553                 if (fad != arcDistance || outd != distance || faz != finalAzimuth ||
554                     outd != distance)
555                     throw new Exception("GeodesicExact.Inverse #3 failed");
556                 fad = ge.Inverse(32.0, -86.0, 33.0, -87.0, out outd, out iaz, out faz, out frd);
557                 if (fad != arcDistance || outd != distance || faz != finalAzimuth ||
558                     outd != distance || frd != reducedLength)
559                     throw new Exception("GeodesicExact.Inverse #4 failed");
560                 fad = ge.Inverse(32.0, -86.0, 33.0, -87.0, out outd, out iaz, out faz, out fm12, out fm21);
561                 if (fad != arcDistance || outd != distance || faz != finalAzimuth ||
562                     outd != distance || fm12 != M12 || fm21 != M21)
563                     throw new Exception("GeodesicExact.Inverse #5 failed");
564                 fad = ge.Inverse(32.0, -86.0, 33.0, -87.0, out outd, out iaz, out faz, out frd, out fm12, out fm21);
565                 if (fad != arcDistance || outd != distance || faz != finalAzimuth ||
566                     outd != distance || fm12 != M12 || fm21 != M21 || frd != reducedLength)
567                     throw new Exception("GeodesicExact.Inverse #6 failed");
568                 GeodesicLineExact gle = ge.Line(32.0, -86.0, 45.0, Mask.ALL);
569                 gle = ge.InverseLine(32.0, -86.0, 33.0, -87.0, Mask.ALL);
570                 gle = ge.DirectLine(32.0, -86.0, 45.0, 10000.0, Mask.ALL);
571                 gle = ge.ArcDirectLine(32.0, -86.0, 45.0, 10000.0, Mask.ALL);
572                 gle = new GeodesicLineExact(32.0, -86.0, 45.0, Mask.ALL);
573                 gle = new GeodesicLineExact(ge, 32.0, -86.0, 45.0, Mask.ALL);
574                 arcDistance = gle.Position(10000.0, out finalLatitude, out finalLongitude, out finalAzimuth,
575                     out reducedLength, out M12, out M21, out S12);
576                 fad = gle.Position(10000.0, out flat, out flon);
577                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude)
578                     throw new Exception("GeodesicLineExact.Position #1 failed");
579                 fad = gle.Position(10000.0, out flat, out flon, out faz);
580                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
581                     faz != finalAzimuth)
582                     throw new Exception("GeodesicLineExact.Position #2 failed");
583                 fad = gle.Position(10000.0, out flat, out flon, out faz, out frd);
584                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
585                     faz != finalAzimuth || frd != reducedLength)
586                     throw new Exception("GeodesicLineExact.Position #3 failed");
587                 fad = gle.Position(10000.0, out flat, out flon, out faz, out fm12, out fm21);
588                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
589                     faz != finalAzimuth || fm12 != M12 || fm21 != M21)
590                     throw new Exception("GeodesicLineExact.Position #4 failed");
591                 fad = gle.Position(10000.0, out flat, out flon, out faz, out frd, out fm12, out fm21);
592                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
593                     faz != finalAzimuth || fm12 != M12 || fm21 != M21 || frd != reducedLength)
594                     throw new Exception("GeodesicLineExact.Position #5 failed");
595                 fad = gle.GenPosition(false, 10000.0, GeodesicLineExact.mask.ALL, out flat, out flon, out faz, out outd, out frd, out fm12, out fm21, out fs12);
596                 if (fad != arcDistance || flat != finalLatitude || flon != finalLongitude ||
597                     faz != finalAzimuth || outd != 10000.0 || fm12 != M12 || fm21 != M21 ||
598                     frd != reducedLength || fs12 != S12)
599                     throw new Exception("GeodesicLineExact.GenPosition (false) failed");
600                 gle.ArcPosition(1.0, out finalLatitude, out finalLongitude, out finalAzimuth,
601                     out distance, out reducedLength, out M12, out M21, out S12);
602                 gle.ArcPosition(1.0, out flat, out flon);
603                 if (flat != finalLatitude || flon != finalLongitude)
604                     throw new Exception("GeodesicLineExact.ArcPosition #1 failed");
605                 gle.ArcPosition(1.0, out flat, out flon, out faz);
606                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth)
607                     throw new Exception("GeodesicLineExact.ArcPosition #2 failed");
608                 gle.ArcPosition(1.0, out flat, out flon, out faz, out outd);
609                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
610                     outd != distance)
611                     throw new Exception("GeodesicLineExact.ArcPosition #3 failed");
612                 gle.ArcPosition(1.0, out flat, out flon, out faz, out outd, out frd);
613                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
614                     outd != distance || frd != reducedLength)
615                     throw new Exception("GeodesicLineExact.ArcPosition #4 failed");
616                 gle.ArcPosition(1.0, out flat, out flon, out faz, out outd, out fm12, out fm21);
617                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
618                     outd != distance || fm12 != M12 || fm21 != M21)
619                     throw new Exception("GeodesicLineExact.ArcPosition #5 failed");
620                 gle.ArcPosition(1.0, out flat, out flon, out faz, out outd, out frd, out fm12, out fm21);
621                 if (flat != finalLatitude || flon != finalLongitude || faz != finalAzimuth ||
622                     outd != distance || fm12 != M12 || fm21 != M21 || frd != reducedLength)
623                     throw new Exception("GeodesicLineExact.ArcPosition #6 failed");
624                 fad = gle.GenPosition(true, 1.0, GeodesicLineExact.mask.ALL, out flat, out flon, out faz, out outd, out frd, out fm12, out fm21, out fs12);
625                 if (fad != 1.0 || flat != finalLatitude || flon != finalLongitude ||
626                     faz != finalAzimuth || outd != distance || fm12 != M12 || fm21 != M21 ||
627                     frd != reducedLength || fs12 != S12)
628                     throw new Exception("GeodesicLineExact.GenPosition (false) failed");
629             }
630             catch (Exception xcpt)
631             {
632                 MessageBox.Show(xcpt.Message, "Interface Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
633                 return;
634             }
635 
636             MessageBox.Show("No errors detected", "Interfaces OK", MessageBoxButtons.OK, MessageBoxIcon.Information);
637         }
638     }
639 }
640