/** * \file NETGeographicLib/Geodesic.cpp * \brief Implementation for NETGeographicLib::Geodesic class * * 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/ **********************************************************************/ #include "stdafx.h" #include #include #include "Geodesic.h" #include "GeodesicLine.h" #include "NETGeographicLib.h" using namespace NETGeographicLib; const char BADALLOC[] = "Failed to allocate memory for a GeographicLib::Geodesic"; //***************************************************************************** Geodesic::!Geodesic() { if ( m_pGeodesic != NULL ) { delete m_pGeodesic; m_pGeodesic = NULL; } } //***************************************************************************** Geodesic::Geodesic(double a, double f) { try { m_pGeodesic = new GeographicLib::Geodesic( a, f ); } catch ( std::bad_alloc err ) { throw gcnew GeographicErr( BADALLOC ); } catch ( GeographicLib::GeographicErr err ) { throw gcnew GeographicErr( err.what() ); } } //***************************************************************************** Geodesic::Geodesic() { try { m_pGeodesic = new GeographicLib::Geodesic( GeographicLib::Geodesic::WGS84() ); } catch ( std::bad_alloc ) { throw gcnew GeographicErr( BADALLOC ); } } //***************************************************************************** double Geodesic::Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21, [System::Runtime::InteropServices::Out] double% S12) { double llat2, llon2, lazi2, lm12, lM12, lM21, lS12; double out = m_pGeodesic->Direct(lat1, lon1, azi1, s12, llat2, llon2, lazi2, lm12, lM12, lM21, lS12); lat2 = llat2; lon2 = llon2; azi2 = lazi2; m12 = lm12; M12 = lM12; M21 = lM21; S12 = lS12; return out; } //***************************************************************************** double Geodesic::Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2) { double llat2, llon2; double out = m_pGeodesic->Direct(lat1, lon1, azi1, s12, llat2, llon2 ); lat2 = llat2; lon2 = llon2; return out; } //***************************************************************************** double Geodesic::Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2) { double llat2, llon2, lazi2; double out = m_pGeodesic->Direct(lat1, lon1, azi1, s12, llat2, llon2, lazi2 ); lat2 = llat2; lon2 = llon2; azi2 = lazi2; return out; } //***************************************************************************** double Geodesic::Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12) { double llat2, llon2, lazi2, lm12; double out = m_pGeodesic->Direct(lat1, lon1, azi1, s12, llat2, llon2, lazi2, lm12 ); lat2 = llat2; lon2 = llon2; azi2 = lazi2; m12 = lm12; return out; } //***************************************************************************** double Geodesic::Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21) { double llat2, llon2, lazi2, lM12, lM21; double out = m_pGeodesic->Direct(lat1, lon1, azi1, s12, llat2, llon2, lazi2, lM12, lM21); lat2 = llat2; lon2 = llon2; azi2 = lazi2; M12 = lM12; M21 = lM21; return out; } //***************************************************************************** double Geodesic::Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21) { double llat2, llon2, lazi2, lm12, lM12, lM21; double out = m_pGeodesic->Direct(lat1, lon1, azi1, s12, llat2, llon2, lazi2, lm12, lM12, lM21 ); lat2 = llat2; lon2 = llon2; azi2 = lazi2; m12 = lm12; M12 = lM12; M21 = lM21; return out; } //***************************************************************************** void Geodesic::ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21, [System::Runtime::InteropServices::Out] double% S12) { double llat2, llon2, lazi2, ls12, lm12, lM12, lM21, lS12; m_pGeodesic->ArcDirect(lat1, lon1, azi1, a12, llat2, llon2, lazi2, ls12, lm12, lM12, lM21, lS12); lat2 = llat2; lon2 = llon2; azi2 = lazi2; s12 = ls12; m12 = lm12; M12 = lM12; M21 = lM21; S12 = lS12; } //***************************************************************************** void Geodesic::ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2) { double llat2, llon2; m_pGeodesic->ArcDirect(lat1, lon1, azi1, a12, llat2, llon2 ); lat2 = llat2; lon2 = llon2; } //***************************************************************************** void Geodesic::ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2) { double llat2, llon2, lazi2; m_pGeodesic->ArcDirect(lat1, lon1, azi1, a12, llat2, llon2, lazi2 ); lat2 = llat2; lon2 = llon2; azi2 = lazi2; } //***************************************************************************** void Geodesic::ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12) { double llat2, llon2, lazi2, ls12; m_pGeodesic->ArcDirect(lat1, lon1, azi1, a12, llat2, llon2, lazi2, ls12 ); lat2 = llat2; lon2 = llon2; azi2 = lazi2; s12 = ls12; } //***************************************************************************** void Geodesic::ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% m12) { double llat2, llon2, lazi2, ls12, lm12; m_pGeodesic->ArcDirect(lat1, lon1, azi1, a12, llat2, llon2, lazi2, ls12, lm12 ); lat2 = llat2; lon2 = llon2; azi2 = lazi2; s12 = ls12; m12 = lm12; } //***************************************************************************** void Geodesic::ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21) { double llat2, llon2, lazi2, ls12, lM12, lM21; m_pGeodesic->ArcDirect(lat1, lon1, azi1, a12, llat2, llon2, lazi2, ls12, lM12, lM21 ); lat2 = llat2; lon2 = llon2; azi2 = lazi2; s12 = ls12; M12 = lM12; M21 = lM21; } //***************************************************************************** void Geodesic::ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21) { double llat2, llon2, lazi2, ls12, lm12, lM12, lM21; m_pGeodesic->ArcDirect(lat1, lon1, azi1, a12, llat2, llon2, lazi2, ls12, lm12, lM12, lM21); lat2 = llat2; lon2 = llon2; azi2 = lazi2; m12 = lm12; s12 = ls12; M12 = lM12; M21 = lM21; } //***************************************************************************** double Geodesic::GenDirect(double lat1, double lon1, double azi1, bool arcmode, double s12_a12, Geodesic::mask outmask, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21, [System::Runtime::InteropServices::Out] double% S12) { double llat2, llon2, lazi2, lm12, lM12, lM21, ls12, lS12; double out = m_pGeodesic->GenDirect(lat1, lon1, azi1, arcmode, s12_a12, static_cast(outmask), llat2, llon2, lazi2, ls12, lm12, lM12, lM21, lS12); lat2 = llat2; lon2 = llon2; azi2 = lazi2; m12 = lm12; M12 = lM12; M21 = lM21; s12 = ls12; S12 = lS12; return out; } //***************************************************************************** double Geodesic::Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21, [System::Runtime::InteropServices::Out] double% S12) { double ls12, lazi1, lazi2, lm12, lM12, lM21, lS12; double out = m_pGeodesic->Inverse(lat1, lon1, lat2, lon2, ls12, lazi1, lazi2, lm12, lM12, lM21, lS12); s12 = ls12; azi1 = lazi1; azi2 = lazi2; m12 = lm12; M12 = lM12; M21 = lM21; S12 = lS12; return out; } //***************************************************************************** double Geodesic::Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12) { double ls12; double out = m_pGeodesic->Inverse(lat1, lon1, lat2, lon2, ls12 ); s12 = ls12; return out; } //***************************************************************************** double Geodesic::Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2) { double lazi1, lazi2; double out = m_pGeodesic->Inverse(lat1, lon1, lat2, lon2, lazi1, lazi2); azi1 = lazi1; azi2 = lazi2; return out; } //***************************************************************************** double Geodesic::Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2) { double ls12, lazi1, lazi2; double out = m_pGeodesic->Inverse(lat1, lon1, lat2, lon2, ls12, lazi1, lazi2 ); azi1 = lazi1; azi2 = lazi2; s12 = ls12; return out; } //***************************************************************************** double Geodesic::Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12) { double ls12, lazi1, lazi2, lm12; double out = m_pGeodesic->Inverse(lat1, lon1, lat2, lon2, ls12, lazi1, lazi2, lm12 ); azi1 = lazi1; azi2 = lazi2; s12 = ls12; m12 = lm12; return out; } //***************************************************************************** double Geodesic::Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21) { double ls12, lazi1, lazi2, lM12, lM21; double out = m_pGeodesic->Inverse(lat1, lon1, lat2, lon2, ls12, lazi1, lazi2, lM12, lM21 ); azi1 = lazi1; azi2 = lazi2; s12 = ls12; M12 = lM12; M21 = lM21; return out; } //***************************************************************************** double Geodesic::Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21) { double ls12, lazi1, lazi2, lm12, lM12, lM21; double out = m_pGeodesic->Inverse(lat1, lon1, lat2, lon2, ls12, lazi1, lazi2, lm12, lM12, lM21 ); azi1 = lazi1; azi2 = lazi2; s12 = ls12; m12 = lm12; M12 = lM12; M21 = lM21; return out; } //***************************************************************************** double Geodesic::GenInverse(double lat1, double lon1, double lat2, double lon2, Geodesic::mask outmask, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21, [System::Runtime::InteropServices::Out] double% S12) { double ls12, lazi1, lazi2, lm12, lM12, lM21, lS12; double out = m_pGeodesic->GenInverse(lat1, lon1, lat2, lon2, static_cast(outmask), ls12, lazi1, lazi2, lm12, lM12, lM21, lS12); azi1 = lazi1; azi2 = lazi2; s12 = ls12; m12 = lm12; M12 = lM12; M21 = lM21; S12 = lS12; return out; } //***************************************************************************** System::IntPtr^ Geodesic::GetUnmanaged() { return gcnew System::IntPtr( const_cast(reinterpret_cast(m_pGeodesic)) ); } //***************************************************************************** GeodesicLine^ Geodesic::Line(double lat1, double lon1, double azi1, NETGeographicLib::Mask caps ) { return gcnew GeodesicLine( this, lat1, lon1, azi1, caps ); } //***************************************************************************** GeodesicLine^ Geodesic::InverseLine(double lat1, double lon1, double lat2, double lon2, NETGeographicLib::Mask caps) { return gcnew GeodesicLine(m_pGeodesic->InverseLine(lat1, lon1, lat2, lon2, static_cast(caps))); } //***************************************************************************** GeodesicLine^ Geodesic::DirectLine(double lat1, double lon1, double azi1, double s12, NETGeographicLib::Mask caps) { return gcnew GeodesicLine(m_pGeodesic->DirectLine(lat1, lon1, azi1, s12, static_cast(caps))); } //***************************************************************************** GeodesicLine^ Geodesic::ArcDirectLine(double lat1, double lon1, double azi1, double a12, NETGeographicLib::Mask caps) { return gcnew GeodesicLine(m_pGeodesic->ArcDirectLine(lat1, lon1, azi1, a12, static_cast(caps))); } //***************************************************************************** GeodesicLine^ Geodesic::GenDirectLine(double lat1, double lon1, double azi1, bool arcmode, double s12_a12, NETGeographicLib::Mask caps) { return gcnew GeodesicLine(m_pGeodesic->GenDirectLine(lat1, lon1, azi1, arcmode, s12_a12, static_cast(caps))); } //***************************************************************************** double Geodesic::EquatorialRadius::get() { return m_pGeodesic->EquatorialRadius(); } //***************************************************************************** double Geodesic::Flattening::get() { return m_pGeodesic->Flattening(); } //***************************************************************************** double Geodesic::EllipsoidArea::get() { return m_pGeodesic->EllipsoidArea(); }