ADD: new track message, Entity class and Position class
This commit is contained in:
94
libs/geographiclib/src/CassiniSoldner.cpp
Normal file
94
libs/geographiclib/src/CassiniSoldner.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* \file CassiniSoldner.cpp
|
||||
* \brief Implementation for GeographicLib::CassiniSoldner class
|
||||
*
|
||||
* Copyright (c) Charles Karney (2009-2022) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* https://geographiclib.sourceforge.io/
|
||||
**********************************************************************/
|
||||
|
||||
#include <GeographicLib/CassiniSoldner.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Squelch warnings about enum-float expressions
|
||||
# pragma warning (disable: 5055)
|
||||
#endif
|
||||
|
||||
namespace GeographicLib {
|
||||
|
||||
using namespace std;
|
||||
|
||||
CassiniSoldner::CassiniSoldner(const Geodesic& earth)
|
||||
: _earth(earth) {}
|
||||
|
||||
CassiniSoldner::CassiniSoldner(real lat0, real lon0, const Geodesic& earth)
|
||||
: _earth(earth)
|
||||
{ Reset(lat0, lon0); }
|
||||
|
||||
void CassiniSoldner::Reset(real lat0, real lon0) {
|
||||
_meridian = _earth.Line(lat0, lon0, real(0),
|
||||
Geodesic::LATITUDE | Geodesic::LONGITUDE |
|
||||
Geodesic::DISTANCE | Geodesic::DISTANCE_IN |
|
||||
Geodesic::AZIMUTH);
|
||||
real f = _earth.Flattening();
|
||||
Math::sincosd(LatitudeOrigin(), _sbet0, _cbet0);
|
||||
_sbet0 *= (1 - f);
|
||||
Math::norm(_sbet0, _cbet0);
|
||||
}
|
||||
|
||||
void CassiniSoldner::Forward(real lat, real lon, real& x, real& y,
|
||||
real& azi, real& rk) const {
|
||||
if (!Init())
|
||||
return;
|
||||
real dlon = Math::AngDiff(LongitudeOrigin(), lon);
|
||||
real sig12, s12, azi1, azi2;
|
||||
sig12 = _earth.Inverse(lat, -fabs(dlon), lat, fabs(dlon), s12, azi1, azi2);
|
||||
sig12 *= real(0.5);
|
||||
s12 *= real(0.5);
|
||||
if (s12 == 0) {
|
||||
real da = Math::AngDiff(azi1, azi2)/2;
|
||||
if (fabs(dlon) <= Math::qd) {
|
||||
azi1 = Math::qd - da;
|
||||
azi2 = Math::qd + da;
|
||||
} else {
|
||||
azi1 = -Math::qd - da;
|
||||
azi2 = -Math::qd + da;
|
||||
}
|
||||
}
|
||||
if (signbit(dlon)) {
|
||||
azi2 = azi1;
|
||||
s12 = -s12;
|
||||
sig12 = -sig12;
|
||||
}
|
||||
x = s12;
|
||||
azi = Math::AngNormalize(azi2);
|
||||
GeodesicLine perp(_earth.Line(lat, dlon, azi, Geodesic::GEODESICSCALE));
|
||||
real t;
|
||||
perp.GenPosition(true, -sig12,
|
||||
Geodesic::GEODESICSCALE,
|
||||
t, t, t, t, t, t, rk, t);
|
||||
|
||||
real salp0, calp0;
|
||||
Math::sincosd(perp.EquatorialAzimuth(), salp0, calp0);
|
||||
real
|
||||
sbet1 = lat >=0 ? calp0 : -calp0,
|
||||
cbet1 = fabs(dlon) <= Math::qd ? fabs(salp0) : -fabs(salp0),
|
||||
sbet01 = sbet1 * _cbet0 - cbet1 * _sbet0,
|
||||
cbet01 = cbet1 * _cbet0 + sbet1 * _sbet0,
|
||||
sig01 = atan2(sbet01, cbet01) / Math::degree();
|
||||
_meridian.GenPosition(true, sig01,
|
||||
Geodesic::DISTANCE,
|
||||
t, t, t, y, t, t, t, t);
|
||||
}
|
||||
|
||||
void CassiniSoldner::Reverse(real x, real y, real& lat, real& lon,
|
||||
real& azi, real& rk) const {
|
||||
if (!Init())
|
||||
return;
|
||||
real lat1, lon1;
|
||||
real azi0, t;
|
||||
_meridian.Position(y, lat1, lon1, azi0);
|
||||
_earth.Direct(lat1, lon1, azi0 + Math::qd, x, lat, lon, azi, rk, t);
|
||||
}
|
||||
|
||||
} // namespace GeographicLib
|
||||
Reference in New Issue
Block a user