#include #include #include #include #include #include #include #include namespace scwx { namespace qt { namespace manager { static const std::string logPrefix_ = "[scwx::qt::manager::radar_manager] "; static constexpr uint32_t NUM_RADIAL_GATES_0_5_DEGREE = common::MAX_0_5_DEGREE_RADIALS * common::MAX_DATA_MOMENT_GATES; static constexpr uint32_t NUM_RADIAL_GATES_1_DEGREE = common::MAX_1_DEGREE_RADIALS * common::MAX_DATA_MOMENT_GATES; static constexpr uint32_t NUM_COORIDNATES_0_5_DEGREE = NUM_RADIAL_GATES_0_5_DEGREE * 2; static constexpr uint32_t NUM_COORIDNATES_1_DEGREE = NUM_RADIAL_GATES_1_DEGREE * 2; class RadarManagerImpl { public: explicit RadarManagerImpl() {} ~RadarManagerImpl() = default; std::vector coordinates0_5Degree_; std::vector coordinates1Degree_; }; RadarManager::RadarManager() : p(std::make_unique()) {} RadarManager::~RadarManager() = default; RadarManager::RadarManager(RadarManager&&) noexcept = default; RadarManager& RadarManager::operator=(RadarManager&&) noexcept = default; const std::vector& RadarManager::coordinates(common::RadialSize radialSize) const { switch (radialSize) { case common::RadialSize::_0_5Degree: return p->coordinates0_5Degree_; case common::RadialSize::_1Degree: return p->coordinates1Degree_; } throw std::exception("Invalid radial size"); } void RadarManager::Initialize() { BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Initialize()"; boost::timer::cpu_timer timer; // Calculate coordinates timer.start(); std::vector& coordinates0_5Degree = p->coordinates0_5Degree_; coordinates0_5Degree.resize(NUM_COORIDNATES_0_5_DEGREE); GeographicLib::Geodesic geodesic(GeographicLib::Constants::WGS84_a(), GeographicLib::Constants::WGS84_f()); const QMapbox::Coordinate radar(38.6986, -90.6828); auto radialGates = boost::irange(0, NUM_RADIAL_GATES_0_5_DEGREE); std::for_each( std::execution::par_unseq, radialGates.begin(), radialGates.end(), [&](uint32_t radialGate) { const uint16_t gate = static_cast(radialGate % common::MAX_DATA_MOMENT_GATES); const uint16_t radial = static_cast(radialGate / common::MAX_DATA_MOMENT_GATES); const float angle = radial * 0.5f - 0.25f; // 0.5 degree radial const float range = (gate + 1) * 250.0f; // 0.25km gate size const size_t offset = radialGate * 2; double latitude; double longitude; geodesic.Direct( radar.first, radar.second, angle, range, latitude, longitude); coordinates0_5Degree[offset] = latitude; coordinates0_5Degree[offset + 1] = longitude; }); timer.stop(); BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Coordinates (0.5 degree) calculated in " << timer.format(6, "%ws"); } } // namespace manager } // namespace qt } // namespace scwx