...
This commit is contained in:
parent
a8dd511366
commit
d417c03f59
240
mcc/mcc_coord.h
240
mcc/mcc_coord.h
@ -1,7 +1,9 @@
|
|||||||
#include "mcc_angle.h"
|
#include "mcc_angle.h"
|
||||||
|
#include "mcc_ccte_iers.h"
|
||||||
#include "mcc_defaults.h"
|
#include "mcc_defaults.h"
|
||||||
#include "mcc_generics.h"
|
#include "mcc_generics.h"
|
||||||
|
|
||||||
|
#include <erfa.h>
|
||||||
|
|
||||||
namespace mcc
|
namespace mcc
|
||||||
{
|
{
|
||||||
@ -157,41 +159,41 @@ using MccGenXY = MccNamedCoordPair<MccAngleX, MccAngleY>;
|
|||||||
using MccGeoLONLAT = MccNamedCoordPair<MccAngleLON, MccAngleLAT>;
|
using MccGeoLONLAT = MccNamedCoordPair<MccAngleLON, MccAngleLAT>;
|
||||||
|
|
||||||
|
|
||||||
struct mcc_skycoord_interface_t {
|
struct mcc_skypoint_interface_t {
|
||||||
virtual ~mcc_skycoord_interface_t() = default;
|
virtual ~mcc_skypoint_interface_t() = default;
|
||||||
|
|
||||||
template <std::derived_from<mcc_skycoord_interface_t> SelfT, mcc_angle_c XT, mcc_angle_c YT>
|
// template <std::derived_from<mcc_skypoint_interface_t> SelfT, mcc_angle_c XT, mcc_angle_c YT>
|
||||||
SelfT& from(this SelfT&& self, XT&& x, YT&& y)
|
// SelfT& from(this SelfT&& self, XT&& x, YT&& y)
|
||||||
{
|
// {
|
||||||
return std::forward<SelfT>(self).from(std::forward<XT>(x), std::forward<YT>(y));
|
// return std::forward<SelfT>(self).from(std::forward<XT>(x), std::forward<YT>(y));
|
||||||
}
|
// }
|
||||||
|
|
||||||
template <std::derived_from<mcc_skycoord_interface_t> SelfT, mcc_coord_pair_c PT>
|
template <std::derived_from<mcc_skypoint_interface_t> SelfT, mcc_coord_pair_c PT>
|
||||||
SelfT& from(this SelfT&& self, PT&& cpair)
|
auto from(this SelfT&& self, PT&& cpair)
|
||||||
{
|
{
|
||||||
return std::forward<SelfT>(self).from(std::forward<PT>(cpair));
|
return std::forward<SelfT>(self).from(std::forward<PT>(cpair));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::derived_from<mcc_skycoord_interface_t> SelfT, mcc_coord_pair_c PT>
|
template <std::derived_from<mcc_skypoint_interface_t> SelfT, mcc_coord_pair_c PT>
|
||||||
SelfT& operator=(this SelfT&& self, PT&& cpair)
|
auto operator=(this SelfT&& self, PT&& cpair)
|
||||||
{
|
{
|
||||||
return std::forward<SelfT>(self).operator=(std::forward<PT>(cpair));
|
return std::forward<SelfT>(self).operator=(std::forward<PT>(cpair));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <std::derived_from<mcc_skycoord_interface_t> SelfT, mcc_coord_pair_c PT, mcc_coord_pair_c... PTs>
|
template <std::derived_from<mcc_skypoint_interface_t> SelfT, mcc_coord_pair_c PT, mcc_coord_pair_c... PTs>
|
||||||
SelfT& to(this SelfT&& self, PT& cpair, PTs&... cpairs)
|
auto to(this SelfT&& self, PT& cpair, PTs&... cpairs)
|
||||||
{
|
{
|
||||||
return std::forward<SelfT>(self).to(cpair, cpairs...);
|
return std::forward<SelfT>(self).to(cpair, cpairs...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::derived_from<mcc_skycoord_interface_t> SelfT, mcc_coord_pair_c PT>
|
template <std::derived_from<mcc_skypoint_interface_t> SelfT, mcc_coord_pair_c PT>
|
||||||
operator PT(this SelfT&& self)
|
operator PT(this SelfT&& self)
|
||||||
{
|
{
|
||||||
return std::forward<SelfT>(self).operator PT();
|
return std::forward<SelfT>(self).operator PT();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::derived_from<mcc_skycoord_interface_t> SelfT, mcc_coord_pair_c PT, mcc_coord_pair_c... PTs>
|
template <std::derived_from<mcc_skypoint_interface_t> SelfT, mcc_coord_pair_c PT, mcc_coord_pair_c... PTs>
|
||||||
operator std::tuple<PT, PTs...>(this SelfT&& self)
|
operator std::tuple<PT, PTs...>(this SelfT&& self)
|
||||||
{
|
{
|
||||||
return std::forward<SelfT>(self).operator std::tuple<PT, PTs...>();
|
return std::forward<SelfT>(self).operator std::tuple<PT, PTs...>();
|
||||||
@ -199,16 +201,220 @@ struct mcc_skycoord_interface_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept mcc_skycoord_c = std::derived_from<T, mcc_skycoord_interface_t> && requires(T t) {
|
concept mcc_skypoint_c = std::derived_from<T, mcc_skypoint_interface_t> && requires(T t) {
|
||||||
typename T::meteo_t;
|
typename T::meteo_t;
|
||||||
{ T::meteo(std::declval<typename T::meteo_t const&>()) };
|
{ T::meteo(std::declval<typename T::meteo_t const&>()) };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MccSkyPoint : public mcc_skycoord_interface_t
|
/* MCC-LIBRARY DEFAULT SKY POINT CLASS IMPLEMENTATION BASED ON ERFA-LIBRARY */
|
||||||
|
|
||||||
|
|
||||||
|
class MccSkyPoint : public mcc_skypoint_interface_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static constexpr double MJD0 = 2400000.5;
|
||||||
|
|
||||||
|
struct meteo_t {
|
||||||
|
double temperature; // Temperature in C
|
||||||
|
double humidity; // humidity in % ([0.0, 1.0])
|
||||||
|
double pressure; // atmospheric presure in hPa=mB
|
||||||
|
};
|
||||||
|
|
||||||
|
static ccte::iers::MccLeapSeconds iersLeapSeconds()
|
||||||
|
{
|
||||||
|
return _leapSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool updateLeapSeconds(traits::mcc_input_char_range auto const& filename)
|
||||||
|
{
|
||||||
|
std::lock_guard lock{_leapSecondsMutex};
|
||||||
|
|
||||||
|
return _leapSeconds.load(filename);
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool updateIersBulletinA(traits::mcc_input_char_range auto const& filename)
|
||||||
|
{
|
||||||
|
std::lock_guard lock{_bulletinAMutex};
|
||||||
|
|
||||||
|
return _bulletinA.load(filename);
|
||||||
|
};
|
||||||
|
|
||||||
|
static ccte::iers::MccIersBulletinA iersBulletinA()
|
||||||
|
{
|
||||||
|
return _bulletinA;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setMeteo(meteo_t meteo)
|
||||||
|
{
|
||||||
|
std::lock_guard lock{_meteoMutex};
|
||||||
|
|
||||||
|
_currentMeteo = std::move(meteo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static meteo_t getMeteo()
|
||||||
|
{
|
||||||
|
return _currentMeteo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MccSkyPoint() {}
|
||||||
|
|
||||||
|
template <mcc_coord_pair_c PT>
|
||||||
|
MccSkyPoint(const PT& coord_pair) : MccSkyPoint()
|
||||||
|
{
|
||||||
|
auto self = from(coord_pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
MccSkyPoint(const MccSkyPoint&) = default;
|
||||||
|
MccSkyPoint(MccSkyPoint&&) = default;
|
||||||
|
|
||||||
|
MccSkyPoint& operator=(const MccSkyPoint&) = default;
|
||||||
|
MccSkyPoint& operator=(MccSkyPoint&&) = default;
|
||||||
|
|
||||||
|
virtual ~MccSkyPoint() = default;
|
||||||
|
|
||||||
|
MccCelestialCoordEpoch epoch() const
|
||||||
|
{
|
||||||
|
return _epoch;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <mcc_coord_pair_c PT>
|
||||||
|
MccSkyPoint& from(const PT& coord_pair)
|
||||||
|
{
|
||||||
|
_x = coord_pair.x();
|
||||||
|
_y = coord_pair.y();
|
||||||
|
|
||||||
|
_pairKind = coord_pair.pairKind;
|
||||||
|
|
||||||
|
if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) {
|
||||||
|
_epoch = MccCelestialCoordEpoch(); // J2000.0
|
||||||
|
} else {
|
||||||
|
_epoch.fromMJD(coord_pair.MJD());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MccSkyPoint& operator=(mcc_coord_pair_c auto const& coord_pair)
|
||||||
|
{
|
||||||
|
return from(coord_pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <mcc_coord_pair_c PT, mcc_coord_pair_c... PTs>
|
||||||
|
auto to(PT& cpair, PTs&... cpairs)
|
||||||
|
{
|
||||||
|
toHelper(cpair);
|
||||||
|
|
||||||
|
if constexpr (sizeof...(PTs)) {
|
||||||
|
to(cpairs...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// IERS related static members
|
||||||
|
static inline ccte::iers::MccLeapSeconds _leapSeconds{};
|
||||||
|
static inline ccte::iers::MccIersBulletinA _bulletinA{};
|
||||||
|
|
||||||
|
static inline std::mutex _leapSecondsMutex{}, _bulletinAMutex{};
|
||||||
|
|
||||||
|
// meteo related static members
|
||||||
|
|
||||||
|
static inline meteo_t _currentMeteo{.temperature = 10.0, .humidity = 0.5, .pressure = 1010.0};
|
||||||
|
static inline std::mutex _meteoMutex{};
|
||||||
|
|
||||||
|
|
||||||
|
double _x{0.0}, _y{0.0};
|
||||||
|
MccCoordPairKind _pairKind{MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
|
||||||
|
MccCelestialCoordEpoch _epoch{}; // J2000.0
|
||||||
|
|
||||||
|
template <mcc_coord_pair_c PT>
|
||||||
|
auto toHelper(PT& cpair)
|
||||||
|
{
|
||||||
|
double ra_icrs, dec_icrs, ra_obs, dec_obs, ha_obs, az_obs, zd_obs, lst, eo;
|
||||||
|
|
||||||
|
static_assert(PT::pairKind == MccCoordPairKind::COORDS_KIND_GENERIC, "UNSUPPORTED SKY POINT TRANSFORMATION!");
|
||||||
|
static_assert(PT::pairKind == MccCoordPairKind::COORDS_KIND_UNKNOWN, "UNSUPPORTED SKY POINT TRANSFORMATION!");
|
||||||
|
|
||||||
|
if (_pairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS &&
|
||||||
|
PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) {
|
||||||
|
cpair = PT(PT::x_t(_x), PT::y_t(_y), _epoch);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_pairKind == PT::pairKind && utils::isEqual(_epoch.MJD(), cpair.MJD())) {
|
||||||
|
cpair = PT(PT::x_t(_x), PT::y_t(_y), _epoch);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MccCoordPairKind pkind = _pairKind;
|
||||||
|
if (!utils::isEqual(_epoch.MJD(), cpair.MJD())) { // convert stored pair to ICRS one (ra_icrs, dec_icrs)
|
||||||
|
if (_pairKind != MccCoordPairKind::COORDS_KIND_RADEC_ICRS) {
|
||||||
|
pkind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS;
|
||||||
|
// convert here!!!
|
||||||
|
if (_pairKind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
|
||||||
|
// cct_engine.appToICRS(...)
|
||||||
|
} else if (_pairKind == MccCoordPairKind::COORDS_KIND_RADEC_OBS) {
|
||||||
|
// cct_engine.obsToICRS(...)
|
||||||
|
} else if (_pairKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||||
|
// cct_engine.appToICRS(...)
|
||||||
|
} else if (_pairKind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) {
|
||||||
|
// cct_engine.obsToICRS(...)
|
||||||
|
} else if (_pairKind == MccCoordPairKind::COORDS_KIND_AZZD) {
|
||||||
|
// cct_engine.obsToICRS(...)
|
||||||
|
} else if (_pairKind == MccCoordPairKind::COORDS_KIND_AZALT) {
|
||||||
|
// cct_engine.obsToICRS(...)
|
||||||
|
} else { // unsupported transformation!!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ra_icrs = _x;
|
||||||
|
dec_icrs = _y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// here, APP or OBS to ICRS
|
||||||
|
if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS &&
|
||||||
|
PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) {
|
||||||
|
cpair = PT(PT::x_t(ra_icrs), PT::y_t(dec_icrs), MccCelestialCoordEpoch{});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) {
|
||||||
|
if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
|
||||||
|
// cct_engine.icrsToApp(...)
|
||||||
|
} else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_OBS) {
|
||||||
|
// cct_engine.icrsToObs(...)
|
||||||
|
} else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||||
|
// cct_engine.icrsToApp(...)
|
||||||
|
} else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) {
|
||||||
|
// cct_engine.icrsToObs(...)
|
||||||
|
} else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZZD) {
|
||||||
|
// cct_engine.icrsToObs(...)
|
||||||
|
} else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZALT) {
|
||||||
|
// cct_engine.icrsToObs(...)
|
||||||
|
} else {
|
||||||
|
static_assert(false, "UNSUPPORTED SKY POINT TRANSFORMATION!");
|
||||||
|
}
|
||||||
|
} else if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
|
||||||
|
if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_OBS) {
|
||||||
|
} else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||||
|
// ha = lst + eo - ra?
|
||||||
|
} else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) {
|
||||||
|
} else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZZD) {
|
||||||
|
} else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZALT) {
|
||||||
|
} else {
|
||||||
|
static_assert(false, "UNSUPPORTED SKY POINT TRANSFORMATION!");
|
||||||
|
}
|
||||||
|
} else if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_OBS) {
|
||||||
|
} else if (pkind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||||
|
} else if (pkind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) {
|
||||||
|
} else if (pkind == MccCoordPairKind::COORDS_KIND_AZZD) {
|
||||||
|
} else if (pkind == MccCoordPairKind::COORDS_KIND_AZALT) {
|
||||||
|
} else { // unsupported transformation!!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace mcc
|
} // end namespace mcc
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user