diff --git a/cxx/mount_pz.h b/cxx/mount_pz.h index 911ceb0..a176666 100644 --- a/cxx/mount_pz.h +++ b/cxx/mount_pz.h @@ -103,23 +103,37 @@ private: enum class MccAltLimitKind { MIN_ALT_LIMIT, MAX_ALT_LIMIT }; -template +template class MccAltLimitPZ { public: - static constexpr MccAltLimitKind altLimitType = LIMIT; + static constexpr MccAltLimitKind altLimitKind = KIND; MccAltLimitPZ(const MccAngle& alt_limit) : _altLimit(alt_limit) { _altLimit.normalize(); } + std::string_view name() const + { + return KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "MINALT-ZONE" + : KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "MAXALT-ZONE" + : "ALTLIMIT-UNKNOWN"; + } + + std::string_view desc() const + { + return KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "Minimal altitude prohibited zone" + : KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "Maximal altitude prohibited zone" + : "Unknown altitude prohibited zone"; + } + bool inZone(const MccAngle& x, const MccAngle& y, const MccProhibitedZone::pzcontext_t& context) { if (context.coords_kind == MccProhibitedZone::COORDS_KIND_AZALT) { // trivial case - if constexpr (LIMIT == MccAltLimitKind::MIN_ALT_LIMIT) { + if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) { return y <= _altLimit; - } else if constexpr (LIMIT == MccAltLimitKind::MAX_ALT_LIMIT) { + } else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) { return y >= _altLimit; } } else if (context.coords_kind == MccProhibitedZone::COORDS_KIND_RADEC_APP) { @@ -135,6 +149,64 @@ public: const MccProhibitedZone::pzcontext_t& context, traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now()) { + if (context.coords_kind == MccProhibitedZone::COORDS_KIND_RADEC_APP) { + auto dd = astrom::mcc_time_to_alt(_altLimit, x, y, context.lat, context.lon, utc, context.dut1, + context.tt_tai, context.tai_utc); + if (std::isnan(dd.first)) { // error! + throw std::system_error(std::make_error_code(std::errc::invalid_argument)); + } + + if (std::isinf(dd.first)) { // never reach zone + return dd.first; + } + + + if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) { + if (dd.first <= dd.second) { // in zone + return decltype(dd.first)(0.0); + } + } else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) { + if (dd.first >= dd.second) { // in zone + return decltype(dd.first)(0.0); + } + } + + return dd.second; + } else { + throw std::system_error(std::make_error_code(std::errc::operation_not_supported)); + } + } + + auto timeFrom(const MccAngle& x, + const MccAngle& y, + const MccProhibitedZone::pzcontext_t& context, + traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now()) + { + if (context.coords_kind == MccProhibitedZone::COORDS_KIND_RADEC_APP) { + auto dd = astrom::mcc_time_to_alt(_altLimit, x, y, context.lat, context.lon, utc, context.dut1, + context.tt_tai, context.tai_utc); + if (std::isnan(dd.first)) { // error! + throw std::system_error(std::make_error_code(std::errc::invalid_argument)); + } + + if (std::isinf(dd.first)) { // never reach zone + return dd.first; + } + + if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) { + if (dd.first > dd.second) { // not in zone + return decltype(dd.first)(0.0); + } + } else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) { + if (dd.first < dd.second) { // not in zone + return decltype(dd.first)(0.0); + } + } + + return dd.first; + } else { + throw std::system_error(std::make_error_code(std::errc::operation_not_supported)); + } } private: