1 /**
2  * \file NETGeographicLib/Rhumb.cpp
3  * \brief Implementation for NETGeographicLib::Rhumb and NETGeographicLib::RhumbLine class
4  *
5  * NETGeographicLib is copyright (c) Scott Heiman (2013)
6  * GeographicLib is Copyright (c) Charles Karney (2010-2012)
7  * <charles@karney.com> and licensed under the MIT/X11 License.
8  * For more information, see
9  * https://geographiclib.sourceforge.io/
10  **********************************************************************/
11 #include "stdafx.h"
12 #include "GeographicLib/Rhumb.hpp"
13 #include "Rhumb.h"
14 #include "NETGeographicLib.h"
15 
16 using namespace NETGeographicLib;
17 
18 //*****************************************************************************
19 Rhumb::!Rhumb(void)
20 {
21     if ( m_pRhumb != NULL )
22     {
23         delete m_pRhumb;
24         m_pRhumb = NULL;
25     }
26 }
27 
28 //*****************************************************************************
Rhumb(double a,double f,bool exact)29 Rhumb::Rhumb(double a, double f, bool exact)
30 {
31     try
32     {
33         m_pRhumb = new GeographicLib::Rhumb( a, f, exact );
34     }
35     catch ( GeographicLib::GeographicErr& err )
36     {
37         throw gcnew GeographicErr( err.what() );
38     }
39     catch ( std::bad_alloc )
40     {
41         throw gcnew System::Exception("Failed to allocate memory for a Rhumb.");
42     }
43 }
44 
45 //*****************************************************************************
46 void Rhumb::Direct(double lat1, double lon1, double azi12, double s12,
47             [System::Runtime::InteropServices::Out] double% lat2,
48             [System::Runtime::InteropServices::Out] double% lon2,
49             [System::Runtime::InteropServices::Out] double% S12)
50 {
51     double ilat2, ilon2, iS12;
52     m_pRhumb->Direct( lat1, lon1, azi12, s12, ilat2, ilon2, iS12 );
53     lat2 = ilat2;
54     lon2 = ilon2;
55     S12 = iS12;
56 }
57 
58 //*****************************************************************************
59 void Rhumb::Direct(double lat1, double lon1, double azi12, double s12,
60             [System::Runtime::InteropServices::Out] double% lat2,
61             [System::Runtime::InteropServices::Out] double% lon2)
62 {
63     double ilat2, ilon2;
64     m_pRhumb->Direct( lat1, lon1, azi12, s12, ilat2, ilon2 );
65     lat2 = ilat2;
66     lon2 = ilon2;
67 }
68 
69 //*****************************************************************************
70 void Rhumb::GenDirect(double lat1, double lon1, double azi12, double s12,
71                 Rhumb::mask outmask,
72                 [System::Runtime::InteropServices::Out] double% lat2,
73                 [System::Runtime::InteropServices::Out] double% lon2,
74                 [System::Runtime::InteropServices::Out] double% S12)
75 {
76     double ilat2, ilon2, iS12;
77     unsigned int iMask = (unsigned int)outmask;
78     m_pRhumb->GenDirect( lat1, lon1, azi12, s12, iMask, ilat2, ilon2, iS12 );
79     lat2 = ilat2;
80     lon2 = ilon2;
81     S12 = iS12;
82 }
83 
84 //*****************************************************************************
85 void Rhumb::Inverse(double lat1, double lon1, double lat2, double lon2,
86             [System::Runtime::InteropServices::Out] double% s12,
87             [System::Runtime::InteropServices::Out] double% azi12,
88             [System::Runtime::InteropServices::Out] double% S12)
89 {
90     double is12, iazi12, iS12;
91     m_pRhumb->Inverse( lat1, lon1, lat2, lon2, is12, iazi12, iS12 );
92     s12 = is12;
93     azi12 = iazi12;
94     S12 = iS12;
95 }
96 
97 //*****************************************************************************
98 void Rhumb::Inverse(double lat1, double lon1, double lat2, double lon2,
99                 [System::Runtime::InteropServices::Out] double% s12,
100                 [System::Runtime::InteropServices::Out] double% azi12)
101 {
102     double is12, iazi12;
103     m_pRhumb->Inverse( lat1, lon1, lat2, lon2, is12, iazi12 );
104     s12 = is12;
105     azi12 = iazi12;
106 }
107 
108 //*****************************************************************************
109 void Rhumb::GenInverse(double lat1, double lon1, double lat2, double lon2,
110                 Rhumb::mask outmask,
111                 [System::Runtime::InteropServices::Out] double% s12,
112                 [System::Runtime::InteropServices::Out] double% azi12,
113                 [System::Runtime::InteropServices::Out] double% S12)
114 {
115     double is12, iazi12, iS12;
116     unsigned int iMask = (unsigned int)outmask;
117     m_pRhumb->GenInverse( lat1, lon1, lat2, lon2, iMask, is12, iazi12, iS12 );
118     s12 = is12;
119     azi12 = iazi12;
120     S12 = iS12;
121 }
122 
123 //*****************************************************************************
124 RhumbLine^ Rhumb::Line(double lat1, double lon1, double azi12)
125 {
126     return gcnew RhumbLine( new GeographicLib::RhumbLine(m_pRhumb->Line( lat1, lon1, azi12 )) );
127 }
128 
129 //*****************************************************************************
get()130 double Rhumb::EquatorialRadius::get() { return m_pRhumb->EquatorialRadius(); }
131 
132 //*****************************************************************************
get()133 double Rhumb::Flattening::get() { return m_pRhumb->Flattening(); }
134 
135 //*****************************************************************************
get()136 double Rhumb::EllipsoidArea::get() { return m_pRhumb->EllipsoidArea(); }
137 
138 //*****************************************************************************
139 Rhumb^ Rhumb::WGS84()
140 {
141     return gcnew Rhumb( GeographicLib::Constants::WGS84_a(),
142                         GeographicLib::Constants::WGS84_f(), false );
143 }
144 
145 //*****************************************************************************
146 System::IntPtr^ Rhumb::GetUnmanaged()
147 {
148     return gcnew System::IntPtr( const_cast<void*>(reinterpret_cast<const void*>(m_pRhumb)) );
149 }
150 
151 //*****************************************************************************
152 // RhumbLine functions
153 //*****************************************************************************
154 RhumbLine::!RhumbLine(void)
155 {
156     if ( m_pRhumbLine != NULL )
157     {
158         delete m_pRhumbLine;
159         m_pRhumbLine = NULL;
160     }
161 }
162 
163 //*****************************************************************************
RhumbLine(GeographicLib::RhumbLine * pRhumbLine)164 RhumbLine::RhumbLine( GeographicLib::RhumbLine* pRhumbLine )
165 {
166     if ( pRhumbLine == NULL )
167         throw gcnew System::Exception("Invalid pointer in RhumbLine constructor.");
168     m_pRhumbLine = pRhumbLine;
169 }
170 
171 //*****************************************************************************
172 void RhumbLine::Position(double s12,
173               [System::Runtime::InteropServices::Out] double% lat2,
174               [System::Runtime::InteropServices::Out] double% lon2,
175               [System::Runtime::InteropServices::Out] double% S12)
176 {
177     double ilat2, ilon2, iS12;
178     m_pRhumbLine->Position( s12, ilat2, ilon2, iS12);
179     lat2 = ilat2;
180     lon2 = ilon2;
181     S12 = iS12;
182 }
183 
184 //*****************************************************************************
185 void RhumbLine::Position(double s12,
186         [System::Runtime::InteropServices::Out] double% lat2,
187         [System::Runtime::InteropServices::Out] double% lon2)
188 {
189     double ilat2, ilon2;
190     m_pRhumbLine->Position( s12, ilat2, ilon2 );
191     lat2 = ilat2;
192     lon2 = ilon2;
193 }
194 
195 //*****************************************************************************
196 void RhumbLine::GenPosition(double s12, RhumbLine::mask outmask,
197                  [System::Runtime::InteropServices::Out] double% lat2,
198                  [System::Runtime::InteropServices::Out] double% lon2,
199                  [System::Runtime::InteropServices::Out] double% S12)
200 {
201     double ilat2, ilon2, iS12;
202     unsigned int iMask = (unsigned int)outmask;
203     m_pRhumbLine->GenPosition( s12, iMask, ilat2, ilon2, iS12);
204     lat2 = ilat2;
205     lon2 = ilon2;
206     S12 = iS12;
207 }
208 
209 //*****************************************************************************
get()210 double RhumbLine::Latitude::get()
211 {
212     return m_pRhumbLine->Latitude();
213 }
214 
215 //*****************************************************************************
get()216 double RhumbLine::Longitude::get()
217 {
218     return m_pRhumbLine->Longitude();
219 }
220 
221 //*****************************************************************************
get()222 double RhumbLine::Azimuth::get()
223 {
224     return m_pRhumbLine->Azimuth();
225 }
226 
227 //*****************************************************************************
get()228 double RhumbLine::EquatorialRadius::get()
229 {
230     return m_pRhumbLine->EquatorialRadius();
231 }
232 
233 //*****************************************************************************
get()234 double RhumbLine::Flattening::get()
235 {
236     return m_pRhumbLine->Flattening();
237 }
238