This commit is contained in:
Timur A. Fatkhullin 2025-10-09 01:09:27 +03:00
parent e0e10395fb
commit 04272b8e1d
4 changed files with 268 additions and 35 deletions

View File

@ -533,16 +533,62 @@ enum class MccCoordPairKind : size_t {
}; };
static constexpr std::string_view MCC_COORDPAIR_KIND_RADEC_ICRS_STR = "RADEC-IRCS";
static constexpr std::string_view MCC_COORDPAIR_KIND_RADEC_APP_STR = "RADEC-APP";
static constexpr std::string_view MCC_COORDPAIR_KIND_HADEC_APP_STR = "HADEC-APP";
static constexpr std::string_view MCC_COORDPAIR_KIND_AZALT_STR = "AZALT";
static constexpr std::string_view MCC_COORDPAIR_KIND_AZZD_STR = "AZZD";
static constexpr std::string_view MCC_COORDPAIR_KIND_XY_STR = "XY";
static constexpr std::string_view MCC_COORDPAIR_KIND_LATLON_STR = "LATLON";
static constexpr std::string_view MCC_COORDPAIR_KIND_GENERIC_STR = "GENERIC";
static constexpr std::string_view MCC_COORDPAIR_KIND_UNKNOWN_STR = "UNKNOWN";
template <MccCoordPairKind KIND> template <MccCoordPairKind KIND>
static constexpr std::string_view MccCoordPairKindStr = static constexpr std::string_view MccCoordPairKindStr =
KIND == MccCoordPairKind::COORDS_KIND_RADEC_ICRS ? "RADEC-IRCS" KIND == MccCoordPairKind::COORDS_KIND_RADEC_ICRS ? MCC_COORDPAIR_KIND_RADEC_ICRS_STR
: KIND == MccCoordPairKind::COORDS_KIND_RADEC_APP ? "RADEC-APP" : KIND == MccCoordPairKind::COORDS_KIND_RADEC_APP ? MCC_COORDPAIR_KIND_RADEC_APP_STR
: KIND == MccCoordPairKind::COORDS_KIND_HADEC_APP ? "HADEC-APP" : KIND == MccCoordPairKind::COORDS_KIND_HADEC_APP ? MCC_COORDPAIR_KIND_HADEC_APP_STR
: KIND == MccCoordPairKind::COORDS_KIND_AZALT ? "Azimuth-Altitude" : KIND == MccCoordPairKind::COORDS_KIND_AZALT ? MCC_COORDPAIR_KIND_AZALT_STR
: KIND == MccCoordPairKind::COORDS_KIND_AZZD ? "Azimuth-Zendist" : KIND == MccCoordPairKind::COORDS_KIND_AZZD ? MCC_COORDPAIR_KIND_AZZD_STR
: KIND == MccCoordPairKind::COORDS_KIND_XY ? "X-Y" : KIND == MccCoordPairKind::COORDS_KIND_XY ? MCC_COORDPAIR_KIND_XY_STR
: KIND == MccCoordPairKind::COORDS_KIND_LATLON ? "Latitude-Longitude" : KIND == MccCoordPairKind::COORDS_KIND_LATLON ? MCC_COORDPAIR_KIND_LATLON_STR
: "UNKNOWN"; : KIND == MccCoordPairKind::COORDS_KIND_GENERIC ? MCC_COORDPAIR_KIND_GENERIC_STR
: MCC_COORDPAIR_KIND_UNKNOWN_STR;
static constexpr std::string_view MccCoordPairKindToStr(MccCoordPairKind KIND)
{
return KIND == MccCoordPairKind::COORDS_KIND_RADEC_ICRS ? MCC_COORDPAIR_KIND_RADEC_ICRS_STR
: KIND == MccCoordPairKind::COORDS_KIND_RADEC_APP ? MCC_COORDPAIR_KIND_RADEC_APP_STR
: KIND == MccCoordPairKind::COORDS_KIND_HADEC_APP ? MCC_COORDPAIR_KIND_HADEC_APP_STR
: KIND == MccCoordPairKind::COORDS_KIND_AZALT ? MCC_COORDPAIR_KIND_AZALT_STR
: KIND == MccCoordPairKind::COORDS_KIND_AZZD ? MCC_COORDPAIR_KIND_AZZD_STR
: KIND == MccCoordPairKind::COORDS_KIND_XY ? MCC_COORDPAIR_KIND_XY_STR
: KIND == MccCoordPairKind::COORDS_KIND_LATLON ? MCC_COORDPAIR_KIND_LATLON_STR
: KIND == MccCoordPairKind::COORDS_KIND_GENERIC ? MCC_COORDPAIR_KIND_GENERIC_STR
: MCC_COORDPAIR_KIND_UNKNOWN_STR;
}
template <mcc::traits::mcc_char_range R>
static constexpr MccCoordPairKind MccCoordStrToPairKind(R&& spair)
{
if constexpr (std::is_pointer_v<std::decay_t<R>>) {
return MccCoordStrToPairKind(std::string_view{spair});
}
const auto hash = mcc::utils::FNV1aHash(std::forward<R>(spair));
return hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_RADEC_ICRS_STR) ? MccCoordPairKind::COORDS_KIND_RADEC_ICRS
: hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_RADEC_APP_STR) ? MccCoordPairKind::COORDS_KIND_RADEC_APP
: hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_HADEC_APP_STR) ? MccCoordPairKind::COORDS_KIND_HADEC_APP
: hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_AZALT_STR) ? MccCoordPairKind::COORDS_KIND_AZZD
: hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_AZZD_STR) ? MccCoordPairKind::COORDS_KIND_AZALT
: hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_XY_STR) ? MccCoordPairKind::COORDS_KIND_XY
: hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_LATLON_STR) ? MccCoordPairKind::COORDS_KIND_LATLON
: hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_GENERIC_STR) ? MccCoordPairKind::COORDS_KIND_GENERIC
: MccCoordPairKind::COORDS_KIND_GENERIC;
}
} // namespace mcc } // namespace mcc

View File

@ -73,8 +73,14 @@ struct MccGenericCelestialPoint {
MccCoordPairKind pair_kind{MccCoordPairKind::COORDS_KIND_RADEC_ICRS}; MccCoordPairKind pair_kind{MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
MccTimePoint time_point{std::chrono::sys_days(std::chrono::year_month_day{std::chrono::January / 1 / 2000}) + // MccTimePoint time_point{std::chrono::sys_days(std::chrono::year_month_day{std::chrono::January / 1 / 2000}) +
std::chrono::hours(12)}; // J2000.0 // std::chrono::hours(12)}; // J2000.0
MccTimePoint time_point{std::chrono::sys_days(std::chrono::year_month_day(
std::chrono::January / std::chrono::day(1) / std::chrono::year(2000))) +
std::chrono::hours(11) + std::chrono::minutes(58) +
std::chrono::milliseconds(55816)}; // J2000.0 UTC
coord_t X{}, Y{}; coord_t X{}, Y{};
}; };

View File

@ -9,6 +9,7 @@
#include <algorithm> #include <algorithm>
#include <string_view> #include <string_view>
#include "mcc_angle.h" #include "mcc_angle.h"
#include "mcc_defaults.h"
#include "mcc_generics.h" #include "mcc_generics.h"
#include "mcc_utils.h" #include "mcc_utils.h"
@ -493,7 +494,137 @@ class MccNetMessage
{ {
static inline utils::MccSimpleDeserializer defaultDeserilizer{MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ}; static inline utils::MccSimpleDeserializer defaultDeserilizer{MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ};
class DefaultDeserializer : protected utils::MccSimpleDeserializer
{
protected:
using base_t = utils::MccSimpleDeserializer;
public: public:
DefaultDeserializer() : base_t(MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ) {}
template <traits::mcc_input_char_range IR, typename VT>
std::error_code operator()(IR&& bytes, VT& value)
{
if constexpr (mcc_celestial_point_c<VT>) {
std::vector<std::string> vs;
auto ec = base_t::operator()(std::forward<IR>(bytes), vs);
if (ec) {
return ec;
}
if (vs.size() < 2) {
return std::make_error_code(std::errc::invalid_argument);
}
MccCelestialPoint pt{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
if (vs.size() > 2) {
pt.pair_kind = MccCoordStrToPairKind(vs[2]);
if (pt.pair_kind == MccCoordPairKind::COORDS_KIND_GENERIC) {
return std::make_error_code(std::errc::invalid_argument);
}
}
if (pt.pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) {
// J2000.0: 11:58:55.816 1 January 2000 UTC
auto tp = std::chrono::sys_days(std::chrono::year_month_day(
std::chrono::January / std::chrono::day(1) / std::chrono::year(2000))) +
std::chrono::hours(11) + std::chrono::minutes(58) + std::chrono::milliseconds(55816);
mcc_tp2tp(tp, pt.time_point);
} else {
if (vs.size() > 3) {
std::chrono::sys_time<std::chrono::system_clock::duration> tp;
std::istringstream iss(std::string{utils::trimSpaces(vs[3])});
std::chrono::from_stream(iss, "%FT%T", tp);
if (iss.fail()) {
return std::make_error_code(std::errc::invalid_argument);
}
mcc_tp2tp(tp, pt.time_point);
} else { // no time point - use NOW
mcc_tp2tp(std::chrono::system_clock::now(), pt.time_point);
}
}
std::optional<double> ang1, ang2;
switch (pt.pair_kind) {
// if sexagesimal then hours:minutes:seconds form
case mcc::MccCoordPairKind::COORDS_KIND_RADEC_ICRS:
case mcc::MccCoordPairKind::COORDS_KIND_RADEC_APP:
case mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP:
ang1 = utils::parsAngleString(vs[0], true);
break;
default:
// if sexagesimal then degrees:arcminutes:arcseconds form
ang1 = utils::parsAngleString(vs[0]);
}
if (!ang1) {
return std::make_error_code(std::errc::invalid_argument);
}
ang2 = utils::parsAngleString(vs[1]);
if (!ang2) {
return std::make_error_code(std::errc::invalid_argument);
}
pt.X = MccAngle(ang1.value(), mcc::MccDegreeTag{});
pt.Y = MccAngle(ang2.value(), mcc::MccDegreeTag{});
mcc_copy_celestial_point(pt, value);
} else {
return base_t::operator()(std::forward<IR>(bytes), value);
}
return {};
}
};
public:
// helper method to convert celestial point to char range
// (actually, to range of strings)
template <traits::mcc_output_char_range R>
static R celestialPointToString(mcc_celestial_point_c auto const& pt,
bool degrees = false,
std::pair<int, int> prec = {2, 1})
{
R res;
if (degrees) {
std::format_to(std::back_inserter(res), "{}{}{}", MccAngle(pt.X).degrees(),
MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ, MccAngle(pt.Y).degrees());
} else {
switch (pt.pair_kind) {
case MccCoordPairKind::COORDS_KIND_RADEC_ICRS:
case MccCoordPairKind::COORDS_KIND_RADEC_APP:
case MccCoordPairKind::COORDS_KIND_HADEC_APP:
std::format_to(std::back_inserter(res), "{}{}", MccAngle(pt.X).sexagesimal(true, prec.first),
MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ);
break;
default:
std::format_to(std::back_inserter(res), "{}{}", MccAngle(pt.X).sexagesimal(false, prec.second),
MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ);
}
std::format_to(std::back_inserter(res), "{}", MccAngle(pt.Y).sexagesimal(false, prec.second));
}
std::format_to(std::back_inserter(res), "{0:}{1:}{2:}{3:%F}T{3:%T}", MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ,
MccCoordPairKindToStr(pt.pair_kind), MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ, pt.time_point);
return res;
}
static std::string celestialPointToString(mcc_celestial_point_c auto const& pt,
bool degrees = false,
std::pair<int, int> prec = {2, 1})
{
return celestialPointToString<std::string>(pt, degrees, prec);
}
typedef BASE_T valid_keys_t; typedef BASE_T valid_keys_t;
typedef BYTEREPR_T byte_repr_t; typedef BYTEREPR_T byte_repr_t;
@ -544,28 +675,6 @@ public:
return _keyword; return _keyword;
} }
// template <traits::mcc_view_or_output_char_range R>
// R params(size_t start_idx, size_t Nelemes = std::numeric_limits<size_t>::max())
// {
// if (start_idx >= _params.size()) {
// return R{};
// }
// auto stop_idx = start_idx + Nelemes - 1;
// if (stop_idx >= _params.size()) {
// stop_idx = _params.size() - 1;
// }
// if constexpr (traits::mcc_char_view<R>) {
// return R{_params[start_idx].begin(), _params[stop_idx].end()};
// } else {
// R r;
// std::ranges::copy(std::string_view{_params[start_idx].begin(), _params[stop_idx].end()},
// std::back_inserter(r));
// return r;
// }
// }
template <std::ranges::range R> template <std::ranges::range R>
R params(size_t start_idx, size_t Nelemes = std::numeric_limits<size_t>::max()) R params(size_t start_idx, size_t Nelemes = std::numeric_limits<size_t>::max())
@ -590,7 +699,7 @@ public:
std::back_inserter(r) = el_t{el.begin(), el.end()}; std::back_inserter(r) = el_t{el.begin(), el.end()};
} }
} else { } else {
static_assert(false, "UNSUPPORTED RANGE ELEMENT TYPE!!!"); static_assert(false, "UNSUPPORTED RANGE TYPE!!!");
} }
return r; return r;
@ -663,6 +772,77 @@ public:
} }
// template <mcc_celestial_point_c CT>
// std::expected<CT, std::error_code> paramCelestialPoint(
// size_t from_idx,
// MccCoordPairKind default_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS)
// {
// if (_params.size() < (from_idx + 2)) {
// return std::unexpected(std::make_error_code(std::errc::message_size));
// }
// MccCelestialPoint pt{.pair_kind = default_kind};
// if (_params.size() > (from_idx + 2)) {
// pt.pair_kind = MccCoordStrToPairKind(_params[from_idx + 2]);
// if (pt.pair_kind == MccCoordPairKind::COORDS_KIND_GENERIC) {
// return std::unexpected(std::make_error_code(std::errc::invalid_argument));
// }
// }
// if (pt.pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) {
// // J2000.0: 11:58:55.816 1 January 2000 UTC
// auto tp = std::chrono::sys_days(std::chrono::year_month_day(std::chrono::January / std::chrono::day(1) /
// std::chrono::year(2000))) +
// std::chrono::hours(11) + std::chrono::minutes(58) + std::chrono::milliseconds(55816);
// mcc_tp2tp(tp, pt.time_point);
// } else {
// if (_params.size() > (from_idx + 3)) {
// std::chrono::sys_time<std::chrono::system_clock::duration> tp;
// std::istringstream iss(std::string{utils::trimSpaces(_params[from_idx + 3])});
// std::chrono::from_stream(iss, "%FT%T", tp);
// if (iss.fail()) {
// return std::unexpected(std::make_error_code(std::errc::invalid_argument));
// }
// mcc_tp2tp(tp, pt.time_point);
// } else { // no time point - use NOW
// mcc_tp2tp(std::chrono::system_clock::now(), pt.time_point);
// }
// }
// std::optional<double> ang1, ang2;
// switch (pt.pair_kind) {
// // if sexagesimal then hours:minutes:seconds form
// case mcc::MccCoordPairKind::COORDS_KIND_RADEC_ICRS:
// case mcc::MccCoordPairKind::COORDS_KIND_RADEC_APP:
// case mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP:
// ang1 = utils::parsAngleString(_params[from_idx], true);
// break;
// default:
// // if sexagesimal then degrees:arcminutes:arcseconds form
// ang1 = utils::parsAngleString(_params[from_idx]);
// }
// if (!ang1) {
// return std::unexpected(std::make_error_code(std::errc::invalid_argument));
// }
// ang2 = utils::parsAngleString(_params[from_idx + 1]);
// if (!ang2) {
// return std::unexpected(std::make_error_code(std::errc::invalid_argument));
// }
// pt.X = MccAngle(ang1.value(), mcc::MccDegreeTag{});
// pt.Y = MccAngle(ang2.value(), mcc::MccDegreeTag{});
// return pt;
// }
template <traits::mcc_view_or_output_char_range R> template <traits::mcc_view_or_output_char_range R>
R byteRepr() const R byteRepr() const
{ {
@ -738,9 +918,9 @@ public:
return ERROR_EMPTY_MESSAGE; return ERROR_EMPTY_MESSAGE;
} }
std::string_view key, val; std::string_view key;
auto prev_msg_buff = _msgBuffer; // auto prev_msg_buff = _msgBuffer;
if constexpr (traits::mcc_output_char_range<BYTEREPR_T>) { if constexpr (traits::mcc_output_char_range<BYTEREPR_T>) {
_msgBuffer = BYTEREPR_T{}; _msgBuffer = BYTEREPR_T{};

View File

@ -49,6 +49,7 @@ int main()
} }
std::cout << ">\n"; std::cout << ">\n";
std::cout << msg2_t::celestialPointToString(mcc::MccCelestialPoint{}) << "\n";
return 0; return 0;
} }