From 9f47e0ad726ef99a2c0738820af011f30869498e Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sun, 30 Jun 2024 16:20:38 -0400 Subject: [PATCH 01/22] Began working on distance from location code --- .../source/scwx/qt/manager/alert_manager.cpp | 12 ++- .../source/scwx/qt/types/location_types.cpp | 1 + .../source/scwx/qt/types/location_types.hpp | 1 + .../source/scwx/qt/util/geographic_lib.cpp | 99 ++++++++++++++++++- .../source/scwx/qt/util/geographic_lib.hpp | 17 ++++ .../scwx/qt/util/geographic_lib.test.cpp | 69 +++++++++++++ test/test.cmake | 3 +- 7 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 test/source/scwx/qt/util/geographic_lib.test.cpp diff --git a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp index d68f9226..e50babdd 100644 --- a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp @@ -85,7 +85,8 @@ common::Coordinate AlertManager::Impl::CurrentCoordinate( settings::AudioSettings& audioSettings = settings::AudioSettings::Instance(); common::Coordinate coordinate {}; - if (locationMethod == types::LocationMethod::Fixed) + if (locationMethod == types::LocationMethod::Fixed || + locationMethod == types::LocationMethod::Radius) { coordinate.latitude_ = audioSettings.alert_latitude().GetValue(); coordinate.longitude_ = audioSettings.alert_longitude().GetValue(); @@ -153,6 +154,15 @@ void AlertManager::Impl::HandleAlert(const types::TextEventKey& key, activeAtLocation = util::GeographicLib::AreaContainsPoint( alertCoordinates, currentCoordinate); } + else if (locationMethod == types::LocationMethod::Radius) + { + auto alertCoordinates = segment->codedLocation_->coordinates(); + + activeAtLocation = util::GeographicLib::AreaInRangeOfPoint( + alertCoordinates, + currentCoordinate, + units::length::meters(1e6)); + } else if (locationMethod == types::LocationMethod::County) { // Determine if the alert contains the current county diff --git a/scwx-qt/source/scwx/qt/types/location_types.cpp b/scwx-qt/source/scwx/qt/types/location_types.cpp index b1c759de..f5ad6ac8 100644 --- a/scwx-qt/source/scwx/qt/types/location_types.cpp +++ b/scwx-qt/source/scwx/qt/types/location_types.cpp @@ -14,6 +14,7 @@ namespace types static const std::unordered_map locationMethodName_ {{LocationMethod::Fixed, "Fixed"}, + {LocationMethod::Radius, "Radius"}, {LocationMethod::Track, "Track"}, {LocationMethod::County, "County"}, {LocationMethod::All, "All"}, diff --git a/scwx-qt/source/scwx/qt/types/location_types.hpp b/scwx-qt/source/scwx/qt/types/location_types.hpp index 65d32f1e..30f793c9 100644 --- a/scwx-qt/source/scwx/qt/types/location_types.hpp +++ b/scwx-qt/source/scwx/qt/types/location_types.hpp @@ -14,6 +14,7 @@ namespace types enum class LocationMethod { Fixed, + Radius, Track, County, All, diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp index 89466975..bc4066ce 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp @@ -5,14 +5,16 @@ #include #include +#include +#include #include +#include namespace scwx { namespace qt { -namespace util -{ +namespace util { namespace GeographicLib { @@ -82,6 +84,12 @@ bool AreaContainsPoint(const std::vector& area, return areaContainsPoint; } + + + + + + units::angle::degrees GetAngle(double lat1, double lon1, double lat2, double lon2) { @@ -137,6 +145,93 @@ GetDistance(double lat1, double lon1, double lat2, double lon2) return units::length::meters {distance}; } +bool AreaInRangeOfPoint(const std::vector& area, + const common::Coordinate& point, + const units::length::meters distance) +{ + // Cannot have an area with just two points + if (area.size() <= 2 || (area.size() == 3 && area.front() == area.back())) + { + return false; + } + + + + ::GeographicLib::Gnomonic gnomonic = + ::GeographicLib::Gnomonic(DefaultGeodesic()); + geos::geom::CoordinateSequence sequence {}; + double x; + double y; + + // Using a gnomonic projection with the test point as the center + // latitude/longitude, the projected test point will be at (0, 0) + geos::geom::CoordinateXY zero {}; + + // Create the area coordinate sequence using a gnomonic projection + for (auto& areaCoordinate : area) + { + gnomonic.Forward(point.latitude_, + point.longitude_, + areaCoordinate.latitude_, + areaCoordinate.longitude_, + x, + y); + sequence.add(x, y); + } + + // get a point on the circle with the radius of the range in lat lon. + units::angle::degrees angle = units::angle::degrees(0); + common::Coordinate radiusPoint = GetCoordinate(point, angle, distance); + // get the radius in gnomonic projection + gnomonic.Forward(point.latitude_, + point.longitude_, + radiusPoint.latitude_, + radiusPoint.longitude_, + x, + y); + double gnomonicRadius = sqrt(x * x + y * y); + + // If the sequence is not a ring, add the first point again for closure + if (!sequence.isRing()) + { + sequence.add(sequence.front(), false); + } + + // The sequence should be a ring at this point, but make sure + if (sequence.isRing()) + { + try + { + if (geos::algorithm::PointLocation::isInRing(zero, &sequence)) + { + return true; + } + + // Calculate the distance the point is from the output + geos::algorithm::distance::PointPairDistance distancePair; + auto geometryFactory = + geos::geom::GeometryFactory::getDefaultInstance(); + auto linearRing = geometryFactory->createLinearRing(sequence); + auto polygon = + geometryFactory->createPolygon(std::move(linearRing)); + geos::algorithm::distance::DistanceToPoint::computeDistance(*polygon, + zero, + distancePair); + if (gnomonicRadius > distancePair.getDistance()) + { + return true; + } + + } + catch (const std::exception&) + { + logger_->trace("Invalid area sequence"); + } + } + + return false; +} + } // namespace GeographicLib } // namespace util } // namespace qt diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.hpp b/scwx-qt/source/scwx/qt/util/geographic_lib.hpp index 30f7a63c..93469802 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.hpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.hpp @@ -90,6 +90,23 @@ common::Coordinate GetCoordinate(const common::Coordinate& center, units::length::meters GetDistance(double lat1, double lon1, double lat2, double lon2); + +/** + * Determine if an area/ring, oriented in either direction, is within a + * distance of a point. A point lying on the area boundary is considered to be + * inside the area, and thus always in range. Any part of the area being inside + * the radius counts as inside. + * + * @param [in] area A vector of Coordinates representing the area + * @param [in] point The point to check against the area + * @param [in] distance The max distance in meters + * + * @return true if area is inside the radius of the point + */ +bool AreaInRangeOfPoint(const std::vector& area, + const common::Coordinate& point, + const units::length::meters distance); + } // namespace GeographicLib } // namespace util } // namespace qt diff --git a/test/source/scwx/qt/util/geographic_lib.test.cpp b/test/source/scwx/qt/util/geographic_lib.test.cpp new file mode 100644 index 00000000..0052b028 --- /dev/null +++ b/test/source/scwx/qt/util/geographic_lib.test.cpp @@ -0,0 +1,69 @@ +#include + +#include +#include +#include + +namespace scwx +{ +namespace util +{ + +std::vector area = { + common::Coordinate(37.0193692, -91.8778413), + common::Coordinate(36.9719180, -91.3006973), + common::Coordinate(36.7270831, -91.6815753), +}; + +TEST(geographic_lib, area_in_range_inside) +{ + auto inside = common::Coordinate(36.9241584, -91.6425933); + bool value; + + // inside is always true + value = scwx::qt::util::GeographicLib::AreaInRangeOfPoint( + area, inside, units::length::meters(0)); + EXPECT_EQ(value, true); + value = scwx::qt::util::GeographicLib::AreaInRangeOfPoint( + area, inside, units::length::meters(1e6)); + EXPECT_EQ(value, true); +} + +TEST(geographic_lib, area_in_range_near) +{ + auto near = common::Coordinate(36.8009181, -91.3922700); + bool value; + + value = scwx::qt::util::GeographicLib::AreaInRangeOfPoint( + area, near, units::length::meters(9000)); + EXPECT_EQ(value, false); + value = scwx::qt::util::GeographicLib::AreaInRangeOfPoint( + area, near, units::length::meters(10100)); + EXPECT_EQ(value, true); + value = scwx::qt::util::GeographicLib::AreaInRangeOfPoint( + area, near, units::length::meters(1e6)); + EXPECT_EQ(value, true); +} + +TEST(geographic_lib, area_in_range_far) +{ + auto far = common::Coordinate(37.6481966, -94.2163834); + bool value; + + value = scwx::qt::util::GeographicLib::AreaInRangeOfPoint( + area, far, units::length::meters(9000)); + EXPECT_EQ(value, false); + value = scwx::qt::util::GeographicLib::AreaInRangeOfPoint( + area, far, units::length::meters(10100)); + EXPECT_EQ(value, false); + value = scwx::qt::util::GeographicLib::AreaInRangeOfPoint( + area, far, units::length::meters(100e3)); + EXPECT_EQ(value, false); + value = scwx::qt::util::GeographicLib::AreaInRangeOfPoint( + area, far, units::length::meters(300e3)); + EXPECT_EQ(value, true); +} + + +} // namespace util +} // namespace scwx diff --git a/test/test.cmake b/test/test.cmake index 0643c057..b3cfedd2 100644 --- a/test/test.cmake +++ b/test/test.cmake @@ -28,7 +28,8 @@ set(SRC_QT_MAP_TESTS source/scwx/qt/map/map_provider.test.cpp) set(SRC_QT_MODEL_TESTS source/scwx/qt/model/imgui_context_model.test.cpp) set(SRC_QT_SETTINGS_TESTS source/scwx/qt/settings/settings_container.test.cpp source/scwx/qt/settings/settings_variable.test.cpp) -set(SRC_QT_UTIL_TESTS source/scwx/qt/util/q_file_input_stream.test.cpp) +set(SRC_QT_UTIL_TESTS source/scwx/qt/util/q_file_input_stream.test.cpp + source/scwx/qt/util/geographic_lib.test.cpp) set(SRC_UTIL_TESTS source/scwx/util/float.test.cpp source/scwx/util/rangebuf.test.cpp source/scwx/util/streams.test.cpp From 2bc971eb94a4ba70d389d245dc35f326aeb0326b Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Mon, 1 Jul 2024 16:16:54 -0400 Subject: [PATCH 02/22] added comments and improved code layout --- .../source/scwx/qt/util/geographic_lib.cpp | 91 +++++++++++++++---- .../source/scwx/qt/util/geographic_lib.hpp | 2 + 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp index bc4066ce..602f03af 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp @@ -14,7 +14,8 @@ namespace scwx { namespace qt { -namespace util { +namespace util +{ namespace GeographicLib { @@ -149,15 +150,52 @@ bool AreaInRangeOfPoint(const std::vector& area, const common::Coordinate& point, const units::length::meters distance) { + /* + Uses the gnomonic projection to determine if the area is in the radius. + + The first property needed to make this work is that great circles become + lines in the projection. + The other key property needed to make this work is described bellow + R1 and R2 are the distances from the center point to two points + on the (non-flat) Earth. + R1' and R2' are the distances from the center point to the same + two points in the gnomonic projection. + if R1 > R2 then + R1' > R2' + else if R1 < R2 then + R1' < R2' + else if R1 == R2 then + R1' == R2' + + This can also be written as: + r(d) is a function that takes the distance on Earth and converts it to a + distance on the projection. + R1' = r(R1), R2' = r(R2) + r(d) is increasing + + In this case, R1 is a point the radius away from the center, and R2 is a + (all of the) point(s) on the edge of the area. This means that if the edge + is in the radius R1' on the projection, it is in the radius R1 on the Earth. + + On a spherical geodesic this works fine. R is the radius of Earth. We are + also only concerned with points less than a hemisphere away, therefore + 0 < R1,R2 < pi/2 * R (quarter of circumference because the point is in the + center of the hemisphere) + r(d) = R * tan(d / R) {0 < d < pi/2 * R} + tan(d / R) is increasing for {0 < d < pi/2 * R} + + On non spherical geodesics, this may not work perfectly, but should be a + close approximation. + */ // Cannot have an area with just two points if (area.size() <= 2 || (area.size() == 3 && area.front() == area.back())) { return false; } - - - ::GeographicLib::Gnomonic gnomonic = + // Ensure that the same geodesic is used here as is for the radius + // calculation + ::GeographicLib::Gnomonic gnomonic = ::GeographicLib::Gnomonic(DefaultGeodesic()); geos::geom::CoordinateSequence sequence {}; double x; @@ -176,11 +214,19 @@ bool AreaInRangeOfPoint(const std::vector& area, areaCoordinate.longitude_, x, y); + // Check if the current point is the hemisphere centered on the point + if (std::isnan(x) || std::isnan(y)) + { + return false; + } sequence.add(x, y); } // get a point on the circle with the radius of the range in lat lon. - units::angle::degrees angle = units::angle::degrees(0); + // Has the point be in the general direction of the area, which may help with + // non spherical geodesics + units::angle::degrees angle = GetAngle( + point.latitude_, point.longitude_, area[0].latitude_, area[0].longitude_); common::Coordinate radiusPoint = GetCoordinate(point, angle, distance); // get the radius in gnomonic projection gnomonic.Forward(point.latitude_, @@ -189,7 +235,13 @@ bool AreaInRangeOfPoint(const std::vector& area, radiusPoint.longitude_, x, y); - double gnomonicRadius = sqrt(x * x + y * y); + // radius is greater than quarter circumference of the Earth, but the area + // is closer, so it is in range. + if (std::isnan(x) || std::isnan(y)) + { + return true; + } + double gnomonicRadius = std::sqrt(x * x + y * y); // If the sequence is not a ring, add the first point again for closure if (!sequence.isRing()) @@ -206,22 +258,21 @@ bool AreaInRangeOfPoint(const std::vector& area, { return true; } - - // Calculate the distance the point is from the output - geos::algorithm::distance::PointPairDistance distancePair; - auto geometryFactory = - geos::geom::GeometryFactory::getDefaultInstance(); - auto linearRing = geometryFactory->createLinearRing(sequence); - auto polygon = - geometryFactory->createPolygon(std::move(linearRing)); - geos::algorithm::distance::DistanceToPoint::computeDistance(*polygon, - zero, - distancePair); - if (gnomonicRadius > distancePair.getDistance()) + else if (distance > units::length::meters(0)) { - return true; - } + // Calculate the distance the area is from the point via conversion + // to a polygon. + auto geometryFactory = + geos::geom::GeometryFactory::getDefaultInstance(); + auto linearRing = geometryFactory->createLinearRing(sequence); + auto polygon = + geometryFactory->createPolygon(std::move(linearRing)); + geos::algorithm::distance::PointPairDistance distancePair; + geos::algorithm::distance::DistanceToPoint::computeDistance( + *polygon, zero, distancePair); + return gnomonicRadius >= distancePair.getDistance(); + } } catch (const std::exception&) { diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.hpp b/scwx-qt/source/scwx/qt/util/geographic_lib.hpp index 93469802..a7509442 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.hpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.hpp @@ -96,6 +96,8 @@ GetDistance(double lat1, double lon1, double lat2, double lon2); * distance of a point. A point lying on the area boundary is considered to be * inside the area, and thus always in range. Any part of the area being inside * the radius counts as inside. + * This is limited to having the area be in the same hemisphere centered on + * the point, and radices up to a quarter of the circumference of the Earth. * * @param [in] area A vector of Coordinates representing the area * @param [in] point The point to check against the area From dea53bddb499d0a934dd3c3f2b355d3dd07e6ee3 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Mon, 1 Jul 2024 16:18:14 -0400 Subject: [PATCH 03/22] added inital radar site based alerts (only default radar site) --- .../source/scwx/qt/manager/alert_manager.cpp | 27 +- .../scwx/qt/settings/audio_settings.cpp | 12 + .../scwx/qt/settings/audio_settings.hpp | 1 + .../source/scwx/qt/types/location_types.cpp | 2 +- .../source/scwx/qt/types/location_types.hpp | 2 +- scwx-qt/source/scwx/qt/ui/settings_dialog.cpp | 17 ++ scwx-qt/source/scwx/qt/ui/settings_dialog.ui | 264 ++++++++++-------- 7 files changed, 197 insertions(+), 128 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp index e50babdd..daa7112e 100644 --- a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include @@ -85,8 +87,7 @@ common::Coordinate AlertManager::Impl::CurrentCoordinate( settings::AudioSettings& audioSettings = settings::AudioSettings::Instance(); common::Coordinate coordinate {}; - if (locationMethod == types::LocationMethod::Fixed || - locationMethod == types::LocationMethod::Radius) + if (locationMethod == types::LocationMethod::Fixed) { coordinate.latitude_ = audioSettings.alert_latitude().GetValue(); coordinate.longitude_ = audioSettings.alert_longitude().GetValue(); @@ -101,6 +102,14 @@ common::Coordinate AlertManager::Impl::CurrentCoordinate( coordinate.longitude_ = trackedCoordinate.longitude(); } } + else if (locationMethod == types::LocationMethod::RadarSite) + { + std::string siteId = + settings::GeneralSettings::Instance().default_radar_site().GetValue(); + auto radarSite = config::RadarSite::Get(siteId); + coordinate.latitude_ = radarSite->latitude(); + coordinate.longitude_ = radarSite->longitude(); + } return coordinate; } @@ -119,6 +128,8 @@ void AlertManager::Impl::HandleAlert(const types::TextEventKey& key, audioSettings.alert_location_method().GetValue()); common::Coordinate currentCoordinate = CurrentCoordinate(locationMethod); std::string alertCounty = audioSettings.alert_county().GetValue(); + auto alertRadius = + units::length::meters(audioSettings.alert_radius().GetValue()); auto message = textEventManager_->message_list(key).at(messageIndex); @@ -146,22 +157,16 @@ void AlertManager::Impl::HandleAlert(const types::TextEventKey& key, bool activeAtLocation = (locationMethod == types::LocationMethod::All); if (locationMethod == types::LocationMethod::Fixed || - locationMethod == types::LocationMethod::Track) + locationMethod == types::LocationMethod::Track || + locationMethod == types::LocationMethod::RadarSite) { // Determine if the alert is active at the current coordinte auto alertCoordinates = segment->codedLocation_->coordinates(); - activeAtLocation = util::GeographicLib::AreaContainsPoint( - alertCoordinates, currentCoordinate); - } - else if (locationMethod == types::LocationMethod::Radius) - { - auto alertCoordinates = segment->codedLocation_->coordinates(); - activeAtLocation = util::GeographicLib::AreaInRangeOfPoint( alertCoordinates, currentCoordinate, - units::length::meters(1e6)); + alertRadius); } else if (locationMethod == types::LocationMethod::County) { diff --git a/scwx-qt/source/scwx/qt/settings/audio_settings.cpp b/scwx-qt/source/scwx/qt/settings/audio_settings.cpp index 0ee04b2b..d38bee64 100644 --- a/scwx-qt/source/scwx/qt/settings/audio_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/audio_settings.cpp @@ -37,12 +37,16 @@ public: alertLocationMethod_.SetDefault(defaultAlertLocationMethodValue); alertLatitude_.SetDefault(0.0); alertLongitude_.SetDefault(0.0); + alertRadius_.SetDefault(0.0); ignoreMissingCodecs_.SetDefault(false); alertLatitude_.SetMinimum(-90.0); alertLatitude_.SetMaximum(90.0); alertLongitude_.SetMinimum(-180.0); alertLongitude_.SetMaximum(180.0); + alertRadius_.SetMinimum(0.0); + alertRadius_.SetMaximum(9999999999); + alertLocationMethod_.SetValidator( SCWX_SETTINGS_ENUM_VALIDATOR(types::LocationMethod, @@ -86,6 +90,7 @@ public: SettingsVariable alertLocationMethod_ {"alert_location_method"}; SettingsVariable alertLatitude_ {"alert_latitude"}; SettingsVariable alertLongitude_ {"alert_longitude"}; + SettingsVariable alertRadius_ {"alert_radius"}; SettingsVariable alertCounty_ {"alert_county"}; SettingsVariable ignoreMissingCodecs_ {"ignore_missing_codecs"}; @@ -101,6 +106,7 @@ AudioSettings::AudioSettings() : &p->alertLocationMethod_, &p->alertLatitude_, &p->alertLongitude_, + &p->alertRadius_, &p->alertCounty_, &p->ignoreMissingCodecs_}); RegisterVariables(p->variables_); @@ -133,6 +139,11 @@ SettingsVariable& AudioSettings::alert_longitude() const return p->alertLongitude_; } +SettingsVariable& AudioSettings::alert_radius() const +{ + return p->alertRadius_; +} + SettingsVariable& AudioSettings::alert_county() const { return p->alertCounty_; @@ -166,6 +177,7 @@ bool operator==(const AudioSettings& lhs, const AudioSettings& rhs) lhs.p->alertLocationMethod_ == rhs.p->alertLocationMethod_ && lhs.p->alertLatitude_ == rhs.p->alertLatitude_ && lhs.p->alertLongitude_ == rhs.p->alertLongitude_ && + lhs.p->alertRadius_ == rhs.p->alertRadius_ && lhs.p->alertCounty_ == rhs.p->alertCounty_ && lhs.p->alertEnabled_ == rhs.p->alertEnabled_); } diff --git a/scwx-qt/source/scwx/qt/settings/audio_settings.hpp b/scwx-qt/source/scwx/qt/settings/audio_settings.hpp index 19012e84..6f9318fb 100644 --- a/scwx-qt/source/scwx/qt/settings/audio_settings.hpp +++ b/scwx-qt/source/scwx/qt/settings/audio_settings.hpp @@ -30,6 +30,7 @@ public: SettingsVariable& alert_location_method() const; SettingsVariable& alert_latitude() const; SettingsVariable& alert_longitude() const; + SettingsVariable& alert_radius() const; SettingsVariable& alert_county() const; SettingsVariable& alert_enabled(awips::Phenomenon phenomenon) const; SettingsVariable& ignore_missing_codecs() const; diff --git a/scwx-qt/source/scwx/qt/types/location_types.cpp b/scwx-qt/source/scwx/qt/types/location_types.cpp index f5ad6ac8..ca888332 100644 --- a/scwx-qt/source/scwx/qt/types/location_types.cpp +++ b/scwx-qt/source/scwx/qt/types/location_types.cpp @@ -14,8 +14,8 @@ namespace types static const std::unordered_map locationMethodName_ {{LocationMethod::Fixed, "Fixed"}, - {LocationMethod::Radius, "Radius"}, {LocationMethod::Track, "Track"}, + {LocationMethod::RadarSite, "RadarSite"}, {LocationMethod::County, "County"}, {LocationMethod::All, "All"}, {LocationMethod::Unknown, "?"}}; diff --git a/scwx-qt/source/scwx/qt/types/location_types.hpp b/scwx-qt/source/scwx/qt/types/location_types.hpp index 30f793c9..4da1e701 100644 --- a/scwx-qt/source/scwx/qt/types/location_types.hpp +++ b/scwx-qt/source/scwx/qt/types/location_types.hpp @@ -14,8 +14,8 @@ namespace types enum class LocationMethod { Fixed, - Radius, Track, + RadarSite, County, All, Unknown diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp index bcebaf0a..7d120839 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp @@ -134,6 +134,7 @@ public: &alertAudioLocationMethod_, &alertAudioLatitude_, &alertAudioLongitude_, + &alertAudioRadius_, &alertAudioCounty_, &hoverTextWrap_, &tooltipMethod_, @@ -252,6 +253,7 @@ public: settings::SettingsInterface alertAudioLocationMethod_ {}; settings::SettingsInterface alertAudioLatitude_ {}; settings::SettingsInterface alertAudioLongitude_ {}; + settings::SettingsInterface alertAudioRadius_ {}; settings::SettingsInterface alertAudioCounty_ {}; std::unordered_map> @@ -474,6 +476,7 @@ void SettingsDialogImpl::ConnectSignals() break; case QDialogButtonBox::ButtonRole::ResetRole: // Restore Defaults + logger_->info("ButtonRole Reset"); ResetToDefault(); break; @@ -900,6 +903,10 @@ void SettingsDialogImpl::SetupAudioTab() bool coordinateEntryEnabled = locationMethod == types::LocationMethod::Fixed; + bool radiusEntryEnable = + locationMethod == types::LocationMethod::Fixed || + locationMethod == types::LocationMethod::Track || + locationMethod == types::LocationMethod::RadarSite; bool countyEntryEnabled = locationMethod == types::LocationMethod::County; @@ -912,6 +919,11 @@ void SettingsDialogImpl::SetupAudioTab() self_->ui->resetAlertAudioLongitudeButton->setEnabled( coordinateEntryEnabled); + self_->ui->alertAudioRadiusSpinBox->setEnabled( + radiusEntryEnable); + self_->ui->resetAlertAudioRadiusButton->setEnabled( + radiusEntryEnable); + self_->ui->alertAudioCountyLineEdit->setEnabled(countyEntryEnabled); self_->ui->alertAudioCountySelectButton->setEnabled( countyEntryEnabled); @@ -983,6 +995,11 @@ void SettingsDialogImpl::SetupAudioTab() alertAudioLongitude_.SetResetButton( self_->ui->resetAlertAudioLongitudeButton); + alertAudioRadius_.SetSettingsVariable(audioSettings.alert_radius()); + alertAudioRadius_.SetEditWidget(self_->ui->alertAudioRadiusSpinBox); + alertAudioRadius_.SetResetButton( + self_->ui->resetAlertAudioRadiusButton); + auto& alertAudioPhenomena = types::GetAlertAudioPhenomena(); auto alertAudioLayout = static_cast(self_->ui->alertAudioGroupBox->layout()); diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui index 983d9b34..566b68ad 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui @@ -698,6 +698,62 @@ + + + + + + + ... + + + + :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg + + + + + + + + :/res/icons/font-awesome-6/stop-solid.svg:/res/icons/font-awesome-6/stop-solid.svg + + + + + + + 4 + + + -180.000000000000000 + + + 180.000000000000000 + + + 0.000100000000000 + + + + + + + ... + + + + + + + ... + + + + :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg + + + @@ -709,6 +765,30 @@ + + + + + :/res/icons/font-awesome-6/play-solid.svg:/res/icons/font-awesome-6/play-solid.svg + + + + + + + 4 + + + -90.000000000000000 + + + 90.000000000000000 + + + 0.000100000000000 + + + @@ -716,6 +796,13 @@ + + + + County + + + @@ -723,6 +810,60 @@ + + + + + 0 + 0 + + + + + + + + ... + + + + :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg + + + + + + + Sound + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + true + + + @@ -741,105 +882,31 @@ - - - - - :/res/icons/font-awesome-6/stop-solid.svg:/res/icons/font-awesome-6/stop-solid.svg - - - - - - - ... - - - - :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg - - - - - - - ... - - - - :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg - - - - - - - - :/res/icons/font-awesome-6/play-solid.svg:/res/icons/font-awesome-6/play-solid.svg - - - - - - - Sound - - - - + - County + Radius - - + + 4 - -180.000000000000000 + 0.000000000000000 - 180.000000000000000 + 9999999999999.000000000000000 - 0.000100000000000 + 0.010000000000000 - - - - 4 - - - -90.000000000000000 - - - 90.000000000000000 - - - 0.000100000000000 - - - - - - - - 0 - 0 - - - - - - - - + ... @@ -849,39 +916,6 @@ - - - - ... - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - true - - - From 91eb3d3b878604aeb7cd34fc3f77fcbc02eb29f1 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Tue, 2 Jul 2024 12:30:07 -0400 Subject: [PATCH 04/22] First attempt at using current radar site for alerts --- scwx-qt/source/scwx/qt/main/main_window.cpp | 1 + .../source/scwx/qt/manager/alert_manager.cpp | 44 ++++++++++++++++--- .../source/scwx/qt/manager/alert_manager.hpp | 1 + 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/scwx-qt/source/scwx/qt/main/main_window.cpp b/scwx-qt/source/scwx/qt/main/main_window.cpp index 4cda1e58..718f0e3a 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.cpp +++ b/scwx-qt/source/scwx/qt/main/main_window.cpp @@ -1466,6 +1466,7 @@ void MainWindowImpl::UpdateRadarSite() timelineManager_->SetRadarSite("?"); } + alertManager_->SetRadarSite(radarSite); placefileManager_->SetRadarSite(radarSite); } diff --git a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp index daa7112e..8df6ffb7 100644 --- a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp @@ -76,6 +76,8 @@ public: PositionManager::Instance()}; std::shared_ptr textEventManager_ { TextEventManager::Instance()}; + + std::shared_ptr radarSite_ {}; }; AlertManager::AlertManager() : p(std::make_unique(this)) {} @@ -104,11 +106,23 @@ common::Coordinate AlertManager::Impl::CurrentCoordinate( } else if (locationMethod == types::LocationMethod::RadarSite) { - std::string siteId = - settings::GeneralSettings::Instance().default_radar_site().GetValue(); - auto radarSite = config::RadarSite::Get(siteId); - coordinate.latitude_ = radarSite->latitude(); - coordinate.longitude_ = radarSite->longitude(); + std::shared_ptr radarSite; + if (radarSite_ == nullptr) + { + std::string siteId = + settings::GeneralSettings::Instance().default_radar_site().GetValue(); + radarSite = config::RadarSite::Get(siteId); + } + else + { + radarSite = radarSite_; + } + + if (radarSite != nullptr) + { + coordinate.latitude_ = radarSite->latitude(); + coordinate.longitude_ = radarSite->longitude(); + } } return coordinate; @@ -198,6 +212,26 @@ void AlertManager::Impl::UpdateLocationTracking( positionManager_->EnablePositionUpdates(uuid_, locationEnabled); } +void AlertManager::SetRadarSite(std::shared_ptr radarSite) +{ + if (p->radarSite_ == radarSite) + { + // No action needed + return; + } + + if (radarSite == nullptr) + { + logger_->debug("SetRadarSite: ?"); + } + else + { + logger_->debug("SetRadarSite: {}", radarSite->id()); + } + + p->radarSite_ = radarSite; +} + std::shared_ptr AlertManager::Instance() { static std::weak_ptr alertManagerReference_ {}; diff --git a/scwx-qt/source/scwx/qt/manager/alert_manager.hpp b/scwx-qt/source/scwx/qt/manager/alert_manager.hpp index 5bdfd923..53381c76 100644 --- a/scwx-qt/source/scwx/qt/manager/alert_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/alert_manager.hpp @@ -20,6 +20,7 @@ public: explicit AlertManager(); ~AlertManager(); + void AlertManager::SetRadarSite(const std::string& radarSite); static std::shared_ptr Instance(); private: From 1cdea4b1378ec9ff49df02f797b70026d2d8f2e7 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Tue, 2 Jul 2024 12:31:05 -0400 Subject: [PATCH 05/22] Updated alert_manager.hpp to match last commit --- scwx-qt/source/scwx/qt/manager/alert_manager.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scwx-qt/source/scwx/qt/manager/alert_manager.hpp b/scwx-qt/source/scwx/qt/manager/alert_manager.hpp index 53381c76..2041f360 100644 --- a/scwx-qt/source/scwx/qt/manager/alert_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/alert_manager.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include @@ -20,7 +22,7 @@ public: explicit AlertManager(); ~AlertManager(); - void AlertManager::SetRadarSite(const std::string& radarSite); + void SetRadarSite(std::shared_ptr radarSite); static std::shared_ptr Instance(); private: From 4e6c992eafc2668db756a50726cc763811bab970 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Tue, 2 Jul 2024 13:37:44 -0400 Subject: [PATCH 06/22] update RadarSite text in the UI to 'Radar Site' --- scwx-qt/source/scwx/qt/types/location_types.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scwx-qt/source/scwx/qt/types/location_types.cpp b/scwx-qt/source/scwx/qt/types/location_types.cpp index ca888332..f9df0189 100644 --- a/scwx-qt/source/scwx/qt/types/location_types.cpp +++ b/scwx-qt/source/scwx/qt/types/location_types.cpp @@ -15,7 +15,7 @@ namespace types static const std::unordered_map locationMethodName_ {{LocationMethod::Fixed, "Fixed"}, {LocationMethod::Track, "Track"}, - {LocationMethod::RadarSite, "RadarSite"}, + {LocationMethod::RadarSite, "Radar Site"}, {LocationMethod::County, "County"}, {LocationMethod::All, "All"}, {LocationMethod::Unknown, "?"}}; From b421251bcd0e97bde925565cbe40addf7032b3ae Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sun, 7 Jul 2024 13:14:01 -0400 Subject: [PATCH 07/22] Changed code to find a distance, useful for both in range and general distance. --- .../source/scwx/qt/util/geographic_lib.cpp | 207 +++++++++--------- .../source/scwx/qt/util/geographic_lib.hpp | 18 +- 2 files changed, 122 insertions(+), 103 deletions(-) diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp index 602f03af..2557fd15 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp @@ -31,6 +31,40 @@ const ::GeographicLib::Geodesic& DefaultGeodesic() return geodesic_; } +bool GnomonicAreaContainsCenter(geos::geom::CoordinateSequence sequence) +{ + + // Cannot have an area with just two points + if (sequence.size() <= 2 || + (sequence.size() == 3 && sequence.front() == sequence.back())) + { + return false; + } + bool areaContainsPoint = false; + geos::geom::CoordinateXY zero {}; + // If the sequence is not a ring, add the first point again for closure + if (!sequence.isRing()) + { + sequence.add(sequence.front(), false); + } + + // The sequence should be a ring at this point, but make sure + if (sequence.isRing()) + { + try + { + areaContainsPoint = + geos::algorithm::PointLocation::isInRing(zero, &sequence); + } + catch (const std::exception&) + { + logger_->trace("Invalid area sequence"); + } + } + + return areaContainsPoint; +} + bool AreaContainsPoint(const std::vector& area, const common::Coordinate& point) { @@ -146,60 +180,42 @@ GetDistance(double lat1, double lon1, double lat2, double lon2) return units::length::meters {distance}; } -bool AreaInRangeOfPoint(const std::vector& area, - const common::Coordinate& point, - const units::length::meters distance) +/* + * Uses the gnomonic projection to determine if the area is in the radius. + * + * The basic algorithm is as follows: + * - Get a gnomonic projection centered on the point of the area + * - Find the point on the area which is closest to the center + * - Convert the closest point back to latitude and longitude. + * - Find the distance form the closest point to the point. + * + * The first property needed to make this work is that great circles become + * lines in the projection, which allows the area to be converted to strait + * lines. This is generally true for gnomic projections. + * + * The second property needed to make this work is that a point further away + * on the geodesic must be further away on the projection. This means that + * the closes point on the projection is also the closest point on the geodesic. + * This holds for spherical geodesics and is an approximation non spherical + * geodesics. + * + * This algorithm only works if the area is fully on the hemisphere centered + * on the point. Otherwise, this falls back to centroid based distances. + * + * If the point is inside the area, 0 is always returned. + */ +units::length::meters +GetDistanceAreaPoint(const std::vector& area, + const common::Coordinate& point) { - /* - Uses the gnomonic projection to determine if the area is in the radius. - - The first property needed to make this work is that great circles become - lines in the projection. - The other key property needed to make this work is described bellow - R1 and R2 are the distances from the center point to two points - on the (non-flat) Earth. - R1' and R2' are the distances from the center point to the same - two points in the gnomonic projection. - if R1 > R2 then - R1' > R2' - else if R1 < R2 then - R1' < R2' - else if R1 == R2 then - R1' == R2' - - This can also be written as: - r(d) is a function that takes the distance on Earth and converts it to a - distance on the projection. - R1' = r(R1), R2' = r(R2) - r(d) is increasing - - In this case, R1 is a point the radius away from the center, and R2 is a - (all of the) point(s) on the edge of the area. This means that if the edge - is in the radius R1' on the projection, it is in the radius R1 on the Earth. - - On a spherical geodesic this works fine. R is the radius of Earth. We are - also only concerned with points less than a hemisphere away, therefore - 0 < R1,R2 < pi/2 * R (quarter of circumference because the point is in the - center of the hemisphere) - r(d) = R * tan(d / R) {0 < d < pi/2 * R} - tan(d / R) is increasing for {0 < d < pi/2 * R} - - On non spherical geodesics, this may not work perfectly, but should be a - close approximation. - */ - // Cannot have an area with just two points - if (area.size() <= 2 || (area.size() == 3 && area.front() == area.back())) - { - return false; - } - - // Ensure that the same geodesic is used here as is for the radius + // Ensure that the same geodesic is used here as is for the distance // calculation ::GeographicLib::Gnomonic gnomonic = ::GeographicLib::Gnomonic(DefaultGeodesic()); geos::geom::CoordinateSequence sequence {}; double x; double y; + bool useCentroid = false; // Using a gnomonic projection with the test point as the center // latitude/longitude, the projected test point will be at (0, 0) @@ -214,73 +230,64 @@ bool AreaInRangeOfPoint(const std::vector& area, areaCoordinate.longitude_, x, y); - // Check if the current point is the hemisphere centered on the point + // Check if the current point is in the hemisphere centered on the point + // if not, fall back to using centroid. if (std::isnan(x) || std::isnan(y)) { - return false; + useCentroid = true; } sequence.add(x, y); } - // get a point on the circle with the radius of the range in lat lon. - // Has the point be in the general direction of the area, which may help with - // non spherical geodesics - units::angle::degrees angle = GetAngle( - point.latitude_, point.longitude_, area[0].latitude_, area[0].longitude_); - common::Coordinate radiusPoint = GetCoordinate(point, angle, distance); - // get the radius in gnomonic projection - gnomonic.Forward(point.latitude_, - point.longitude_, - radiusPoint.latitude_, - radiusPoint.longitude_, - x, - y); - // radius is greater than quarter circumference of the Earth, but the area - // is closer, so it is in range. - if (std::isnan(x) || std::isnan(y)) + units::length::meters distance; + + if (useCentroid) { - return true; + common::Coordinate centroid = common::GetCentroid(area); + distance = GetDistance(point.latitude_, + point.longitude_, + centroid.latitude_, + centroid.longitude_); } - double gnomonicRadius = std::sqrt(x * x + y * y); - - // If the sequence is not a ring, add the first point again for closure - if (!sequence.isRing()) + else if (GnomonicAreaContainsCenter(sequence)) { - sequence.add(sequence.front(), false); + distance = units::length::meters(0); } - - // The sequence should be a ring at this point, but make sure - if (sequence.isRing()) + else { - try - { - if (geos::algorithm::PointLocation::isInRing(zero, &sequence)) - { - return true; - } - else if (distance > units::length::meters(0)) - { - // Calculate the distance the area is from the point via conversion - // to a polygon. - auto geometryFactory = - geos::geom::GeometryFactory::getDefaultInstance(); - auto linearRing = geometryFactory->createLinearRing(sequence); - auto polygon = - geometryFactory->createPolygon(std::move(linearRing)); + // Get the closes point on the geometry + auto geometryFactory = geos::geom::GeometryFactory::getDefaultInstance(); + auto lineString = geometryFactory->createLineString(sequence); - geos::algorithm::distance::PointPairDistance distancePair; - geos::algorithm::distance::DistanceToPoint::computeDistance( - *polygon, zero, distancePair); - return gnomonicRadius >= distancePair.getDistance(); - } - } - catch (const std::exception&) - { - logger_->trace("Invalid area sequence"); - } + geos::algorithm::distance::PointPairDistance distancePair; + geos::algorithm::distance::DistanceToPoint::computeDistance( + *lineString, zero, distancePair); + + geos::geom::CoordinateXY closestPoint = distancePair.getCoordinate(0); + + double closestLat; + double closestLon; + + gnomonic.Reverse(point.latitude_, + point.longitude_, + closestPoint.x, + closestPoint.y, + closestLat, + closestLon); + + distance = GetDistance(point.latitude_, + point.longitude_, + closestLat, + closestLon); } + return distance; +} - return false; +bool AreaInRangeOfPoint(const std::vector& area, + const common::Coordinate& point, + const units::length::meters distance) +{ + return GetDistanceAreaPoint(area, point) <= distance; } } // namespace GeographicLib diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.hpp b/scwx-qt/source/scwx/qt/util/geographic_lib.hpp index a7509442..5038d9a9 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.hpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.hpp @@ -90,14 +90,26 @@ common::Coordinate GetCoordinate(const common::Coordinate& center, units::length::meters GetDistance(double lat1, double lon1, double lat2, double lon2); +/** + * Get the distance from an area to a point. If the area is less than a quarter + * radius of the Earth away, this is the closest distance between the area and + * the point. Otherwise it is the distance from the centroid of the area to the + * point. Finally, if the point is in the area, it is always 0. + * + * @param [in] area A vector of Coordinates representing the area + * @param [in] point The point to check against the area + * + * @return true if area is inside the radius of the point + */ +units::length::meters +GetDistanceAreaPoint(const std::vector& area, + const common::Coordinate& point); /** * Determine if an area/ring, oriented in either direction, is within a * distance of a point. A point lying on the area boundary is considered to be * inside the area, and thus always in range. Any part of the area being inside - * the radius counts as inside. - * This is limited to having the area be in the same hemisphere centered on - * the point, and radices up to a quarter of the circumference of the Earth. + * the radius counts as inside. Uses GetDistanceAreaPoint to get the distance. * * @param [in] area A vector of Coordinates representing the area * @param [in] point The point to check against the area From c53836e91aafe4a44e8dd5906a2fec7c1ae1ab87 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 11 Jul 2024 12:56:31 -0400 Subject: [PATCH 08/22] added **BASIC** unit handling to radius field. --- .../source/scwx/qt/manager/alert_manager.cpp | 13 ++++++- .../source/scwx/qt/settings/unit_settings.cpp | 20 +++++++++- .../source/scwx/qt/settings/unit_settings.hpp | 1 + scwx-qt/source/scwx/qt/types/unit_types.cpp | 38 +++++++++++++++++++ scwx-qt/source/scwx/qt/types/unit_types.hpp | 16 ++++++++ .../qt/ui/settings/unit_settings_widget.cpp | 11 ++++++ 6 files changed, 95 insertions(+), 4 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp index 8df6ffb7..8f86a196 100644 --- a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include @@ -138,12 +140,19 @@ void AlertManager::Impl::HandleAlert(const types::TextEventKey& key, } settings::AudioSettings& audioSettings = settings::AudioSettings::Instance(); + settings::UnitSettings& unitSettings = settings::UnitSettings::Instance(); types::LocationMethod locationMethod = types::GetLocationMethod( audioSettings.alert_location_method().GetValue()); common::Coordinate currentCoordinate = CurrentCoordinate(locationMethod); std::string alertCounty = audioSettings.alert_county().GetValue(); - auto alertRadius = - units::length::meters(audioSettings.alert_radius().GetValue()); + + types::DistanceUnits radiusUnits = + types::GetDistanceUnitsFromName(unitSettings.distance_units().GetValue()); + double radiusScale = types::GetDistanceUnitsScale(radiusUnits); + auto alertRadius = units::length::kilometers( + audioSettings.alert_radius().GetValue() / radiusScale); + + logger_->debug("alertRadius: {}", (double)alertRadius); auto message = textEventManager_->message_list(key).at(messageIndex); diff --git a/scwx-qt/source/scwx/qt/settings/unit_settings.cpp b/scwx-qt/source/scwx/qt/settings/unit_settings.cpp index e4cf4073..6114326a 100644 --- a/scwx-qt/source/scwx/qt/settings/unit_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/unit_settings.cpp @@ -26,16 +26,20 @@ public: types::GetOtherUnitsName(types::OtherUnits::Default); std::string defaultSpeedUnitsValue = types::GetSpeedUnitsName(types::SpeedUnits::Knots); + std::string defaultDistanceUnitsValue = + types::GetDistanceUnitsName(types::DistanceUnits::Kilometers); boost::to_lower(defaultAccumulationUnitsValue); boost::to_lower(defaultEchoTopsUnitsValue); boost::to_lower(defaultOtherUnitsValue); boost::to_lower(defaultSpeedUnitsValue); + boost::to_lower(defaultDistanceUnitsValue); accumulationUnits_.SetDefault(defaultAccumulationUnitsValue); echoTopsUnits_.SetDefault(defaultEchoTopsUnitsValue); otherUnits_.SetDefault(defaultOtherUnitsValue); speedUnits_.SetDefault(defaultSpeedUnitsValue); + distanceUnits_.SetDefault(defaultDistanceUnitsValue); accumulationUnits_.SetValidator( SCWX_SETTINGS_ENUM_VALIDATOR(types::AccumulationUnits, @@ -53,6 +57,10 @@ public: SCWX_SETTINGS_ENUM_VALIDATOR(types::SpeedUnits, types::SpeedUnitsIterator(), types::GetSpeedUnitsName)); + distanceUnits_.SetValidator( + SCWX_SETTINGS_ENUM_VALIDATOR(types::DistanceUnits, + types::DistanceUnitsIterator(), + types::GetDistanceUnitsName)); } ~Impl() {} @@ -61,6 +69,7 @@ public: SettingsVariable echoTopsUnits_ {"echo_tops_units"}; SettingsVariable otherUnits_ {"other_units"}; SettingsVariable speedUnits_ {"speed_units"}; + SettingsVariable distanceUnits_ {"speed_units"}; }; UnitSettings::UnitSettings() : @@ -69,7 +78,8 @@ UnitSettings::UnitSettings() : RegisterVariables({&p->accumulationUnits_, &p->echoTopsUnits_, &p->otherUnits_, - &p->speedUnits_}); + &p->speedUnits_, + &p->distanceUnits_}); SetDefaults(); } UnitSettings::~UnitSettings() = default; @@ -97,6 +107,11 @@ SettingsVariable& UnitSettings::speed_units() const return p->speedUnits_; } +SettingsVariable& UnitSettings::distance_units() const +{ + return p->distanceUnits_; +} + UnitSettings& UnitSettings::Instance() { static UnitSettings generalSettings_; @@ -108,7 +123,8 @@ bool operator==(const UnitSettings& lhs, const UnitSettings& rhs) return (lhs.p->accumulationUnits_ == rhs.p->accumulationUnits_ && lhs.p->echoTopsUnits_ == rhs.p->echoTopsUnits_ && lhs.p->otherUnits_ == rhs.p->otherUnits_ && - lhs.p->speedUnits_ == rhs.p->speedUnits_); + lhs.p->speedUnits_ == rhs.p->speedUnits_ && + lhs.p->distanceUnits_ == rhs.p->distanceUnits_); } } // namespace settings diff --git a/scwx-qt/source/scwx/qt/settings/unit_settings.hpp b/scwx-qt/source/scwx/qt/settings/unit_settings.hpp index c849cffb..15518492 100644 --- a/scwx-qt/source/scwx/qt/settings/unit_settings.hpp +++ b/scwx-qt/source/scwx/qt/settings/unit_settings.hpp @@ -29,6 +29,7 @@ public: SettingsVariable& echo_tops_units() const; SettingsVariable& other_units() const; SettingsVariable& speed_units() const; + SettingsVariable& distance_units() const; static UnitSettings& Instance(); diff --git a/scwx-qt/source/scwx/qt/types/unit_types.cpp b/scwx-qt/source/scwx/qt/types/unit_types.cpp index fbab05da..72fde4c2 100644 --- a/scwx-qt/source/scwx/qt/types/unit_types.cpp +++ b/scwx-qt/source/scwx/qt/types/unit_types.cpp @@ -89,12 +89,35 @@ static const std::unordered_map speedUnitsScale_ { {SpeedUnits::User, 1.0f}, {SpeedUnits::Unknown, 1.0f}}; +static const std::unordered_map + distanceUnitsAbbreviation_ {{DistanceUnits::Kilometers, "km"}, + {DistanceUnits::Miles, "mi"}, + {DistanceUnits::User, ""}, + {DistanceUnits::Unknown, ""}}; + +static const std::unordered_map distanceUnitsName_ { + {DistanceUnits::Kilometers, "Kilometers"}, + {DistanceUnits::Miles, "Miles"}, + {DistanceUnits::User, "User-defined"}, + {DistanceUnits::Unknown, "?"}}; + +static constexpr auto distanceUnitsBase_ = units::kilometers {1.0f}; +static const std::unordered_map distanceUnitsScale_ { + {DistanceUnits::Kilometers, + (distanceUnitsBase_ / units::kilometers {1.0f})}, + {DistanceUnits::Miles, + (distanceUnitsBase_ / units::miles {1.0f})}, + {DistanceUnits::User, 1.0f}, + {DistanceUnits::Unknown, 1.0f}}; + + SCWX_GET_ENUM(AccumulationUnits, GetAccumulationUnitsFromName, accumulationUnitsName_) SCWX_GET_ENUM(EchoTopsUnits, GetEchoTopsUnitsFromName, echoTopsUnitsName_) SCWX_GET_ENUM(OtherUnits, GetOtherUnitsFromName, otherUnitsName_) SCWX_GET_ENUM(SpeedUnits, GetSpeedUnitsFromName, speedUnitsName_) +SCWX_GET_ENUM(DistanceUnits, GetDistanceUnitsFromName, distanceUnitsName_) const std::string& GetAccumulationUnitsAbbreviation(AccumulationUnits units) { @@ -146,6 +169,21 @@ float GetSpeedUnitsScale(SpeedUnits units) return speedUnitsScale_.at(units); } +const std::string& GetDistanceUnitsAbbreviation(DistanceUnits units) +{ + return distanceUnitsAbbreviation_.at(units); +} + +const std::string& GetDistanceUnitsName(DistanceUnits units) +{ + return distanceUnitsName_.at(units); +} + +float GetDistanceUnitsScale(DistanceUnits units) +{ + return distanceUnitsScale_.at(units); +} + } // namespace types } // namespace qt } // namespace scwx diff --git a/scwx-qt/source/scwx/qt/types/unit_types.hpp b/scwx-qt/source/scwx/qt/types/unit_types.hpp index fd1a012b..d563b02e 100644 --- a/scwx-qt/source/scwx/qt/types/unit_types.hpp +++ b/scwx-qt/source/scwx/qt/types/unit_types.hpp @@ -56,6 +56,17 @@ typedef scwx::util:: Iterator SpeedUnitsIterator; +enum class DistanceUnits +{ + Kilometers, + Miles, + User, + Unknown +}; +typedef scwx::util:: + Iterator + DistanceUnitsIterator; + const std::string& GetAccumulationUnitsAbbreviation(AccumulationUnits units); const std::string& GetAccumulationUnitsName(AccumulationUnits units); AccumulationUnits GetAccumulationUnitsFromName(const std::string& name); @@ -74,6 +85,11 @@ const std::string& GetSpeedUnitsName(SpeedUnits units); SpeedUnits GetSpeedUnitsFromName(const std::string& name); float GetSpeedUnitsScale(SpeedUnits units); +const std::string& GetDistanceUnitsAbbreviation(DistanceUnits units); +const std::string& GetDistanceUnitsName(DistanceUnits units); +DistanceUnits GetDistanceUnitsFromName(const std::string& name); +float GetDistanceUnitsScale(DistanceUnits units); + } // namespace types } // namespace qt } // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/settings/unit_settings_widget.cpp b/scwx-qt/source/scwx/qt/ui/settings/unit_settings_widget.cpp index 946d21ce..aff11583 100644 --- a/scwx-qt/source/scwx/qt/ui/settings/unit_settings_widget.cpp +++ b/scwx-qt/source/scwx/qt/ui/settings/unit_settings_widget.cpp @@ -102,6 +102,16 @@ public: types::GetSpeedUnitsName); AddRow(speedUnits_, "Speed", speedComboBox); + QComboBox* distanceComboBox = new QComboBox(self); + distanceComboBox->setSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Preferred); + distanceUnits_.SetSettingsVariable(unitSettings.distance_units()); + SCWX_SETTINGS_COMBO_BOX(distanceUnits_, + distanceComboBox, + types::DistanceUnitsIterator(), + types::GetDistanceUnitsName); + AddRow(distanceUnits_, "Distance", distanceComboBox); + QComboBox* otherComboBox = new QComboBox(self); otherComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); @@ -127,6 +137,7 @@ public: settings::SettingsInterface echoTopsUnits_ {}; settings::SettingsInterface otherUnits_ {}; settings::SettingsInterface speedUnits_ {}; + settings::SettingsInterface distanceUnits_ {}; }; UnitSettingsWidget::UnitSettingsWidget(QWidget* parent) : From 146055fb99c4700a85f9357cd4d75d07116d7548 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Mon, 15 Jul 2024 11:33:47 -0400 Subject: [PATCH 09/22] added full unit support for radius field, implemented such that future fields needing units can be done easily --- .../source/scwx/qt/manager/alert_manager.cpp | 11 +---- .../scwx/qt/settings/settings_interface.cpp | 45 ++++++++++++++++++- .../scwx/qt/settings/settings_interface.hpp | 17 +++++++ scwx-qt/source/scwx/qt/types/unit_types.cpp | 10 ++--- scwx-qt/source/scwx/qt/types/unit_types.hpp | 2 +- scwx-qt/source/scwx/qt/ui/settings_dialog.cpp | 19 ++++++++ scwx-qt/source/scwx/qt/ui/settings_dialog.ui | 23 ++++++---- 7 files changed, 103 insertions(+), 24 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp index 8f86a196..890a8e0e 100644 --- a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp @@ -8,8 +8,6 @@ #include #include #include -#include -#include #include #include @@ -140,17 +138,12 @@ void AlertManager::Impl::HandleAlert(const types::TextEventKey& key, } settings::AudioSettings& audioSettings = settings::AudioSettings::Instance(); - settings::UnitSettings& unitSettings = settings::UnitSettings::Instance(); types::LocationMethod locationMethod = types::GetLocationMethod( audioSettings.alert_location_method().GetValue()); common::Coordinate currentCoordinate = CurrentCoordinate(locationMethod); std::string alertCounty = audioSettings.alert_county().GetValue(); - - types::DistanceUnits radiusUnits = - types::GetDistanceUnitsFromName(unitSettings.distance_units().GetValue()); - double radiusScale = types::GetDistanceUnitsScale(radiusUnits); - auto alertRadius = units::length::kilometers( - audioSettings.alert_radius().GetValue() / radiusScale); + auto alertRadius = units::length::kilometers( + audioSettings.alert_radius().GetValue()); logger_->debug("alertRadius: {}", (double)alertRadius); diff --git a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp index 2bf38e80..7a83cd70 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp +++ b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp @@ -40,6 +40,7 @@ public: void UpdateEditWidget(); void UpdateResetButton(); + void UpdateUnitLabel(); SettingsInterface* self_; @@ -49,9 +50,14 @@ public: std::unique_ptr context_ {std::make_unique()}; QWidget* editWidget_ {nullptr}; QAbstractButton* resetButton_ {nullptr}; + QLabel* unitLabel_ {nullptr}; std::function mapFromValue_ {nullptr}; std::function mapToValue_ {nullptr}; + + double unitScale_ {1}; + const std::string * unitAbbreiation_ {nullptr}; + bool unitEnabled_ {false}; }; template @@ -381,6 +387,11 @@ void SettingsInterface::SetEditWidget(QWidget* widget) p->context_.get(), [this](double d) { + if (p->unitEnabled_) + { + d = d / p->unitScale_; + } + const T value = p->variable_->GetValue(); const std::optional staged = p->variable_->GetStaged(); @@ -448,6 +459,11 @@ void SettingsInterface::SetResetButton(QAbstractButton* button) p->UpdateResetButton(); } } +template +void SettingsInterface::SetUnitLabel(QLabel* label) +{ + p->unitLabel_ = label; +} template void SettingsInterface::SetMapFromValueFunction( @@ -463,6 +479,17 @@ void SettingsInterface::SetMapToValueFunction( p->mapToValue_ = function; } +template +void SettingsInterface::SetUnit(const double& scale, + const std::string& abbreviation) +{ + p->unitScale_ = scale; + p->unitAbbreiation_ = &abbreviation; + p->unitEnabled_ = true; + p->UpdateEditWidget(); + p->UpdateUnitLabel(); +} + template template void SettingsInterface::Impl::SetWidgetText(U* widget, const T& currentValue) @@ -559,11 +586,27 @@ void SettingsInterface::Impl::UpdateEditWidget() { if constexpr (std::is_floating_point_v) { - doubleSpinBox->setValue(static_cast(currentValue)); + double doubleValue = static_cast(currentValue); + if (unitEnabled_) + { + doubleValue = doubleValue * unitScale_; + } + doubleSpinBox->setValue(doubleValue); } } } +template +void SettingsInterface::Impl::UpdateUnitLabel() +{ + if (unitLabel_ == nullptr || !unitEnabled_) + { + return; + } + + unitLabel_->setText(QString::fromStdString(*unitAbbreiation_)); +} + template void SettingsInterface::Impl::UpdateResetButton() { diff --git a/scwx-qt/source/scwx/qt/settings/settings_interface.hpp b/scwx-qt/source/scwx/qt/settings/settings_interface.hpp index f5f5bb4a..b049dcc1 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_interface.hpp +++ b/scwx-qt/source/scwx/qt/settings/settings_interface.hpp @@ -7,6 +7,8 @@ #include #include +class QLabel; + namespace scwx { namespace qt @@ -91,6 +93,13 @@ public: */ void SetResetButton(QAbstractButton* button) override; + /** + * Sets the label for units from the settings dialog. + * + * @param label Unit label + */ + void SetUnitLabel(QLabel* label); + /** * If the edit widget displays a different value than what is stored in the * settings variable, a mapping function must be provided in order to convert @@ -109,6 +118,14 @@ public: */ void SetMapToValueFunction(std::function function); + /** + * Sets the unit to be used by this setting. + * + * @param scale The radio of the current unit to the base unit + * @param abbreviation The abreviation to be displayed + */ + void SetUnit(const double& scale, const std::string& abbreviation); + private: class Impl; std::unique_ptr p; diff --git a/scwx-qt/source/scwx/qt/types/unit_types.cpp b/scwx-qt/source/scwx/qt/types/unit_types.cpp index 72fde4c2..09f532b5 100644 --- a/scwx-qt/source/scwx/qt/types/unit_types.cpp +++ b/scwx-qt/source/scwx/qt/types/unit_types.cpp @@ -101,12 +101,12 @@ static const std::unordered_map distanceUnitsName_ { {DistanceUnits::User, "User-defined"}, {DistanceUnits::Unknown, "?"}}; -static constexpr auto distanceUnitsBase_ = units::kilometers {1.0f}; -static const std::unordered_map distanceUnitsScale_ { +static constexpr auto distanceUnitsBase_ = units::kilometers {1.0f}; +static const std::unordered_map distanceUnitsScale_ { {DistanceUnits::Kilometers, - (distanceUnitsBase_ / units::kilometers {1.0f})}, + (distanceUnitsBase_ / units::kilometers {1.0f})}, {DistanceUnits::Miles, - (distanceUnitsBase_ / units::miles {1.0f})}, + (distanceUnitsBase_ / units::miles {1.0f})}, {DistanceUnits::User, 1.0f}, {DistanceUnits::Unknown, 1.0f}}; @@ -179,7 +179,7 @@ const std::string& GetDistanceUnitsName(DistanceUnits units) return distanceUnitsName_.at(units); } -float GetDistanceUnitsScale(DistanceUnits units) +double GetDistanceUnitsScale(DistanceUnits units) { return distanceUnitsScale_.at(units); } diff --git a/scwx-qt/source/scwx/qt/types/unit_types.hpp b/scwx-qt/source/scwx/qt/types/unit_types.hpp index d563b02e..ca29623f 100644 --- a/scwx-qt/source/scwx/qt/types/unit_types.hpp +++ b/scwx-qt/source/scwx/qt/types/unit_types.hpp @@ -88,7 +88,7 @@ float GetSpeedUnitsScale(SpeedUnits units); const std::string& GetDistanceUnitsAbbreviation(DistanceUnits units); const std::string& GetDistanceUnitsName(DistanceUnits units); DistanceUnits GetDistanceUnitsFromName(const std::string& name); -float GetDistanceUnitsScale(DistanceUnits units); +double GetDistanceUnitsScale(DistanceUnits units); } // namespace types } // namespace qt diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp index 7d120839..3336c6e2 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp @@ -14,12 +14,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -999,6 +1001,23 @@ void SettingsDialogImpl::SetupAudioTab() alertAudioRadius_.SetEditWidget(self_->ui->alertAudioRadiusSpinBox); alertAudioRadius_.SetResetButton( self_->ui->resetAlertAudioRadiusButton); + alertAudioRadius_.SetUnitLabel(self_->ui->alertAudioRadiusUnitsLabel); + + auto alertAudioRadiusUpdateUnits = [this](const std::string& newValue) + { + types::DistanceUnits radiusUnits = + types::GetDistanceUnitsFromName(newValue); + double radiusScale = types::GetDistanceUnitsScale(radiusUnits); + std::string abbreviation = + types::GetDistanceUnitsAbbreviation(radiusUnits); + + alertAudioRadius_.SetUnit(radiusScale, abbreviation); + }; + settings::UnitSettings::Instance() + .distance_units() + .RegisterValueStagedCallback(alertAudioRadiusUpdateUnits); + alertAudioRadiusUpdateUnits( + settings::UnitSettings::Instance().distance_units().GetValue()); auto& alertAudioPhenomena = types::GetAlertAudioPhenomena(); auto alertAudioLayout = diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui index 566b68ad..c46de4cd 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui @@ -122,7 +122,7 @@ - 0 + 3 @@ -135,9 +135,9 @@ 0 - -113 - 511 - 669 + 0 + 270 + 647 @@ -610,8 +610,8 @@ 0 0 - 98 - 28 + 80 + 18 @@ -883,7 +883,7 @@ - + Radius @@ -892,7 +892,7 @@ - 4 + 2 0.000000000000000 @@ -916,6 +916,13 @@ + + + + + + + From f7abda15c8a9d7eb7ac77627625b73b3f9adda50 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Mon, 15 Jul 2024 12:46:10 -0400 Subject: [PATCH 10/22] Changed Radar Site mode to use its own selection (+default/follow) --- .../source/scwx/qt/manager/alert_manager.cpp | 17 +- .../scwx/qt/settings/audio_settings.cpp | 8 + .../scwx/qt/settings/audio_settings.hpp | 1 + scwx-qt/source/scwx/qt/ui/settings_dialog.cpp | 96 ++++++++- scwx-qt/source/scwx/qt/ui/settings_dialog.ui | 198 ++++++++++-------- 5 files changed, 228 insertions(+), 92 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp index 890a8e0e..edd2f28b 100644 --- a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp @@ -106,16 +106,23 @@ common::Coordinate AlertManager::Impl::CurrentCoordinate( } else if (locationMethod == types::LocationMethod::RadarSite) { + std::string radarSiteSelection = + audioSettings.alert_radar_site().GetValue(); std::shared_ptr radarSite; - if (radarSite_ == nullptr) + if (radarSiteSelection == "default") { - std::string siteId = - settings::GeneralSettings::Instance().default_radar_site().GetValue(); + std::string siteId = settings::GeneralSettings::Instance() + .default_radar_site() + .GetValue(); radarSite = config::RadarSite::Get(siteId); } + else if (radarSiteSelection == "follow") + { + radarSite = radarSite_; + } else { - radarSite = radarSite_; + radarSite = config::RadarSite::Get(radarSiteSelection); } if (radarSite != nullptr) @@ -145,8 +152,6 @@ void AlertManager::Impl::HandleAlert(const types::TextEventKey& key, auto alertRadius = units::length::kilometers( audioSettings.alert_radius().GetValue()); - logger_->debug("alertRadius: {}", (double)alertRadius); - auto message = textEventManager_->message_list(key).at(messageIndex); for (auto& segment : message->segments()) diff --git a/scwx-qt/source/scwx/qt/settings/audio_settings.cpp b/scwx-qt/source/scwx/qt/settings/audio_settings.cpp index d38bee64..8a9db458 100644 --- a/scwx-qt/source/scwx/qt/settings/audio_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/audio_settings.cpp @@ -38,6 +38,7 @@ public: alertLatitude_.SetDefault(0.0); alertLongitude_.SetDefault(0.0); alertRadius_.SetDefault(0.0); + alertRadarSite_.SetDefault("default"); ignoreMissingCodecs_.SetDefault(false); alertLatitude_.SetMinimum(-90.0); @@ -90,6 +91,7 @@ public: SettingsVariable alertLocationMethod_ {"alert_location_method"}; SettingsVariable alertLatitude_ {"alert_latitude"}; SettingsVariable alertLongitude_ {"alert_longitude"}; + SettingsVariable alertRadarSite_ {"alert_radar_site"}; SettingsVariable alertRadius_ {"alert_radius"}; SettingsVariable alertCounty_ {"alert_county"}; SettingsVariable ignoreMissingCodecs_ {"ignore_missing_codecs"}; @@ -106,6 +108,7 @@ AudioSettings::AudioSettings() : &p->alertLocationMethod_, &p->alertLatitude_, &p->alertLongitude_, + &p->alertRadarSite_, &p->alertRadius_, &p->alertCounty_, &p->ignoreMissingCodecs_}); @@ -139,6 +142,11 @@ SettingsVariable& AudioSettings::alert_longitude() const return p->alertLongitude_; } +SettingsVariable& AudioSettings::alert_radar_site() const +{ + return p->alertRadarSite_; +} + SettingsVariable& AudioSettings::alert_radius() const { return p->alertRadius_; diff --git a/scwx-qt/source/scwx/qt/settings/audio_settings.hpp b/scwx-qt/source/scwx/qt/settings/audio_settings.hpp index 6f9318fb..466c4f3a 100644 --- a/scwx-qt/source/scwx/qt/settings/audio_settings.hpp +++ b/scwx-qt/source/scwx/qt/settings/audio_settings.hpp @@ -31,6 +31,7 @@ public: SettingsVariable& alert_latitude() const; SettingsVariable& alert_longitude() const; SettingsVariable& alert_radius() const; + SettingsVariable& alert_radar_site() const; SettingsVariable& alert_county() const; SettingsVariable& alert_enabled(awips::Phenomenon phenomenon) const; SettingsVariable& ignore_missing_codecs() const; diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp index 3336c6e2..81dc3ce4 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp @@ -105,6 +105,7 @@ public: explicit SettingsDialogImpl(SettingsDialog* self) : self_ {self}, radarSiteDialog_ {new RadarSiteDialog(self)}, + alertAudioRadarSiteDialog_ {new RadarSiteDialog(self)}, gpsSourceDialog_ {new SerialPortDialog(self)}, countyDialog_ {new CountyDialog(self)}, fontDialog_ {new QFontDialog(self)}, @@ -136,6 +137,7 @@ public: &alertAudioLocationMethod_, &alertAudioLatitude_, &alertAudioLongitude_, + &alertAudioRadarSite_, &alertAudioRadius_, &alertAudioCounty_, &hoverTextWrap_, @@ -178,6 +180,7 @@ public: void ShowColorDialog(QLineEdit* lineEdit, QFrame* frame = nullptr); void UpdateRadarDialogLocation(const std::string& id); + void UpdateAlertRadarDialogLocation(const std::string& id); QFont GetSelectedFont(); void SelectFontCategory(types::FontCategory fontCategory); @@ -202,6 +205,7 @@ public: SettingsDialog* self_; RadarSiteDialog* radarSiteDialog_; + RadarSiteDialog* alertAudioRadarSiteDialog_; SerialPortDialog* gpsSourceDialog_; CountyDialog* countyDialog_; QFontDialog* fontDialog_; @@ -255,6 +259,7 @@ public: settings::SettingsInterface alertAudioLocationMethod_ {}; settings::SettingsInterface alertAudioLatitude_ {}; settings::SettingsInterface alertAudioLongitude_ {}; + settings::SettingsInterface alertAudioRadarSite_ {}; settings::SettingsInterface alertAudioRadius_ {}; settings::SettingsInterface alertAudioCounty_ {}; @@ -343,6 +348,30 @@ void SettingsDialogImpl::ConnectSignals() } }); + QObject::connect(self_->ui->alertAudioRadarSiteSelectButton, + &QAbstractButton::clicked, + self_, + [this]() { alertAudioRadarSiteDialog_->show(); }); + + QObject::connect(alertAudioRadarSiteDialog_, + &RadarSiteDialog::accepted, + self_, + [this]() + { + std::string id = + alertAudioRadarSiteDialog_->radar_site(); + + std::shared_ptr radarSite = + config::RadarSite::Get(id); + + if (radarSite != nullptr) + { + self_->ui->alertAudioRadarSiteComboBox + ->setCurrentText(QString::fromStdString( + RadarSiteLabel(radarSite))); + } + }); + QObject::connect(self_->ui->gpsSourceSelectButton, &QAbstractButton::clicked, self_, @@ -509,11 +538,18 @@ void SettingsDialogImpl::SetupGeneralTab() const std::shared_ptr& b) { return a->id() < b->id(); }); + // Add default and follow options to radar sites + self_->ui->alertAudioRadarSiteComboBox->addItem( + QString::fromStdString("default")); + self_->ui->alertAudioRadarSiteComboBox->addItem( + QString::fromStdString("follow")); + // Add sorted radar sites for (std::shared_ptr& radarSite : radarSites) { QString text = QString::fromStdString(RadarSiteLabel(radarSite)); self_->ui->radarSiteComboBox->addItem(text); + self_->ui->alertAudioRadarSiteComboBox->addItem(text); } defaultRadarSite_.SetSettingsVariable(generalSettings.default_radar_site()); @@ -905,6 +941,8 @@ void SettingsDialogImpl::SetupAudioTab() bool coordinateEntryEnabled = locationMethod == types::LocationMethod::Fixed; + bool radarSiteEntryEnable = + locationMethod == types::LocationMethod::RadarSite; bool radiusEntryEnable = locationMethod == types::LocationMethod::Fixed || locationMethod == types::LocationMethod::Track || @@ -921,6 +959,13 @@ void SettingsDialogImpl::SetupAudioTab() self_->ui->resetAlertAudioLongitudeButton->setEnabled( coordinateEntryEnabled); + self_->ui->alertAudioRadarSiteComboBox->setEnabled( + radarSiteEntryEnable); + self_->ui->alertAudioRadarSiteSelectButton->setEnabled( + radarSiteEntryEnable); + self_->ui->resetAlertAudioRadarSiteButton->setEnabled( + radarSiteEntryEnable); + self_->ui->alertAudioRadiusSpinBox->setEnabled( radiusEntryEnable); self_->ui->resetAlertAudioRadiusButton->setEnabled( @@ -997,12 +1042,48 @@ void SettingsDialogImpl::SetupAudioTab() alertAudioLongitude_.SetResetButton( self_->ui->resetAlertAudioLongitudeButton); + alertAudioRadarSite_.SetSettingsVariable(audioSettings.alert_radar_site()); + alertAudioRadarSite_.SetMapFromValueFunction( + [](const std::string& id) -> std::string + { + // Get the radar site associated with the ID + std::shared_ptr radarSite = + config::RadarSite::Get(id); + + if (radarSite == nullptr) + { + // No radar site found, just return the ID + return id; + } + + // Add location details to the radar site + return RadarSiteLabel(radarSite); + }); + alertAudioRadarSite_.SetMapToValueFunction( + [](const std::string& text) -> std::string + { + // Find the position of location details + size_t pos = text.rfind(" ("); + + if (pos == std::string::npos) + { + // No location details found, just return the text + return text; + } + + // Remove location details from the radar site + return text.substr(0, pos); + }); + alertAudioRadarSite_.SetEditWidget(self_->ui->alertAudioRadarSiteComboBox); + alertAudioRadarSite_.SetResetButton( + self_->ui->resetAlertAudioRadarSiteButton); + UpdateAlertRadarDialogLocation(audioSettings.alert_radar_site().GetValue()); + alertAudioRadius_.SetSettingsVariable(audioSettings.alert_radius()); alertAudioRadius_.SetEditWidget(self_->ui->alertAudioRadiusSpinBox); alertAudioRadius_.SetResetButton( self_->ui->resetAlertAudioRadiusButton); alertAudioRadius_.SetUnitLabel(self_->ui->alertAudioRadiusUnitsLabel); - auto alertAudioRadiusUpdateUnits = [this](const std::string& newValue) { types::DistanceUnits radiusUnits = @@ -1304,6 +1385,19 @@ void SettingsDialogImpl::UpdateRadarDialogLocation(const std::string& id) } } +void SettingsDialogImpl::UpdateAlertRadarDialogLocation(const std::string& id) +{ + std::shared_ptr radarSite = config::RadarSite::Get(id); + + if (radarSite != nullptr) + { + alertAudioRadarSiteDialog_->HandleMapUpdate(radarSite->latitude(), + radarSite->longitude()); + } +} + + + QFont SettingsDialogImpl::GetSelectedFont() { std::string fontFamily = fontFamilies_.at(selectedFontCategory_) diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui index c46de4cd..8d69be46 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui @@ -136,7 +136,7 @@ 0 0 - 270 + 511 647 @@ -610,7 +610,7 @@ 0 0 - 80 + 66 18 @@ -691,15 +691,32 @@ Alerts - - + + - Latitude + ... + + + + :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg - - + + + + 2 + + + 0.000000000000000 + + + 9999999999999.000000000000000 + + + 0.010000000000000 + + @@ -712,11 +729,38 @@ - - + + + + + 0 + 0 + + + + + + + + County + + + + + + + ... + - :/res/icons/font-awesome-6/stop-solid.svg:/res/icons/font-awesome-6/stop-solid.svg + :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg + + + + + + + @@ -736,24 +780,6 @@ - - - - ... - - - - - - - ... - - - - :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg - - - @@ -765,14 +791,23 @@ - - - - - :/res/icons/font-awesome-6/play-solid.svg:/res/icons/font-awesome-6/play-solid.svg + + + + ... + + + + ... + + + + + + @@ -789,39 +824,16 @@ - - - - Longitude - - - - - - - County - - - - - - - ... - - - - - - - - 0 - 0 - + + + + + :/res/icons/font-awesome-6/stop-solid.svg:/res/icons/font-awesome-6/stop-solid.svg - + ... @@ -831,6 +843,13 @@ + + + + Latitude + + + @@ -838,7 +857,7 @@ - + @@ -851,7 +870,15 @@ - + + + + + :/res/icons/font-awesome-6/play-solid.svg:/res/icons/font-awesome-6/play-solid.svg + + + + @@ -871,8 +898,8 @@ - - + + ... @@ -882,31 +909,36 @@ - + Radius - - - - 2 + + + + Longitude - - 0.000000000000000 + + + + + + Radar Site - - 9999999999999.000000000000000 - - - 0.010000000000000 + + + + + + ... - + ... @@ -916,12 +948,8 @@ - - - - - - + + From 7581fcde5d26ffa965fdd09698a6eab580281376 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Tue, 16 Jul 2024 10:17:40 -0400 Subject: [PATCH 11/22] Moved to using (likely) public API in geos --- scwx-qt/source/scwx/qt/util/geographic_lib.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp index 2557fd15..84bf2354 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp @@ -5,8 +5,7 @@ #include #include -#include -#include +#include #include #include @@ -258,20 +257,19 @@ GetDistanceAreaPoint(const std::vector& area, // Get the closes point on the geometry auto geometryFactory = geos::geom::GeometryFactory::getDefaultInstance(); auto lineString = geometryFactory->createLineString(sequence); + auto zeroPoint = geometryFactory->createPoint(zero); - geos::algorithm::distance::PointPairDistance distancePair; - geos::algorithm::distance::DistanceToPoint::computeDistance( - *lineString, zero, distancePair); - - geos::geom::CoordinateXY closestPoint = distancePair.getCoordinate(0); + std::unique_ptr closestPoints = + geos::operation::distance::DistanceOp::nearestPoints(lineString.get(), + zeroPoint.get()); double closestLat; double closestLon; gnomonic.Reverse(point.latitude_, point.longitude_, - closestPoint.x, - closestPoint.y, + closestPoints->getX(0), + closestPoints->getY(0), closestLat, closestLon); @@ -279,6 +277,7 @@ GetDistanceAreaPoint(const std::vector& area, point.longitude_, closestLat, closestLon); + } return distance; } From c54d8bff519fd0f2ef9434e5e12fc60b9eb1bd76 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Tue, 16 Jul 2024 10:40:18 -0400 Subject: [PATCH 12/22] fix issue with naming of distance unit settings --- scwx-qt/source/scwx/qt/settings/unit_settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scwx-qt/source/scwx/qt/settings/unit_settings.cpp b/scwx-qt/source/scwx/qt/settings/unit_settings.cpp index 6114326a..33adff19 100644 --- a/scwx-qt/source/scwx/qt/settings/unit_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/unit_settings.cpp @@ -69,7 +69,7 @@ public: SettingsVariable echoTopsUnits_ {"echo_tops_units"}; SettingsVariable otherUnits_ {"other_units"}; SettingsVariable speedUnits_ {"speed_units"}; - SettingsVariable distanceUnits_ {"speed_units"}; + SettingsVariable distanceUnits_ {"distance_units"}; }; UnitSettings::UnitSettings() : From c3a6d861bb433b345b1d0313c2f88dd3df91217f Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Tue, 16 Jul 2024 11:35:17 -0400 Subject: [PATCH 13/22] Added first run of test data --- test/data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/data b/test/data index 0ea32947..b523e5f4 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 0ea32947d6a6e39a69d931b2827056e7bc58cbba +Subproject commit b523e5f4319f447e40f592784d695e7b8e50378c From c072d24de014fb473926e6fd82c58a1fc6f7d537 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Tue, 23 Jul 2024 11:52:39 -0400 Subject: [PATCH 14/22] made alerts use unit setting for distance --- scwx-qt/source/scwx/qt/model/alert_model.cpp | 30 ++++++++++--------- .../source/scwx/qt/model/radar_site_model.cpp | 29 +++++++++--------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/scwx-qt/source/scwx/qt/model/alert_model.cpp b/scwx-qt/source/scwx/qt/model/alert_model.cpp index 76cd5a5c..d4bb1111 100644 --- a/scwx-qt/source/scwx/qt/model/alert_model.cpp +++ b/scwx-qt/source/scwx/qt/model/alert_model.cpp @@ -1,13 +1,16 @@ #include #include #include +#include #include +#include #include #include #include #include #include + #include #include @@ -73,7 +76,6 @@ public: double, types::TextEventHash> distanceMap_; - scwx::common::DistanceType distanceDisplay_; scwx::common::Coordinate previousPosition_; }; @@ -182,18 +184,19 @@ QVariant AlertModel::data(const QModelIndex& index, int role) const case static_cast(Column::Distance): if (role == Qt::DisplayRole) { - if (p->distanceDisplay_ == scwx::common::DistanceType::Miles) - { - return QString("%1 mi").arg( - static_cast(p->distanceMap_.at(textEventKey) * - scwx::common::kMilesPerMeter)); - } - else - { - return QString("%1 km").arg( - static_cast(p->distanceMap_.at(textEventKey) * - scwx::common::kKilometersPerMeter)); - } + const std::string distanceUnitName = + settings::UnitSettings::Instance().distance_units().GetValue(); + types::DistanceUnits distanceUnits = + types::GetDistanceUnitsFromName(distanceUnitName); + double distanceScale = types::GetDistanceUnitsScale(distanceUnits); + std::string abbreviation = + types::GetDistanceUnitsAbbreviation(distanceUnits); + + return QString("%1 %2") + .arg(static_cast(p->distanceMap_.at(textEventKey) * + scwx::common::kKilometersPerMeter * + distanceScale)) + .arg(QString::fromStdString(abbreviation)); } else { @@ -419,7 +422,6 @@ AlertModelImpl::AlertModelImpl() : textEventKeys_ {}, geodesic_(util::GeographicLib::DefaultGeodesic()), distanceMap_ {}, - distanceDisplay_ {scwx::common::DistanceType::Miles}, previousPosition_ {} { } diff --git a/scwx-qt/source/scwx/qt/model/radar_site_model.cpp b/scwx-qt/source/scwx/qt/model/radar_site_model.cpp index 66683ae3..482c9828 100644 --- a/scwx-qt/source/scwx/qt/model/radar_site_model.cpp +++ b/scwx-qt/source/scwx/qt/model/radar_site_model.cpp @@ -1,6 +1,8 @@ #include #include +#include #include +#include #include #include #include @@ -36,7 +38,6 @@ public: radarSites_ {}, geodesic_(util::GeographicLib::DefaultGeodesic()), distanceMap_ {}, - distanceDisplay_ {scwx::common::DistanceType::Miles}, previousPosition_ {} { // Get all loaded radar sites @@ -64,7 +65,6 @@ public: const GeographicLib::Geodesic& geodesic_; std::unordered_map distanceMap_; - scwx::common::DistanceType distanceDisplay_; scwx::common::Coordinate previousPosition_; QIcon starIcon_ {":/res/icons/font-awesome-6/star-solid.svg"}; @@ -213,18 +213,19 @@ QVariant RadarSiteModel::data(const QModelIndex& index, int role) const case static_cast(Column::Distance): if (role == Qt::DisplayRole) { - if (p->distanceDisplay_ == scwx::common::DistanceType::Miles) - { - return QString("%1 mi").arg( - static_cast(p->distanceMap_.at(site->id()) * - scwx::common::kMilesPerMeter)); - } - else - { - return QString("%1 km").arg( - static_cast(p->distanceMap_.at(site->id()) * - scwx::common::kKilometersPerMeter)); - } + const std::string distanceUnitName = + settings::UnitSettings::Instance().distance_units().GetValue(); + types::DistanceUnits distanceUnits = + types::GetDistanceUnitsFromName(distanceUnitName); + double distanceScale = types::GetDistanceUnitsScale(distanceUnits); + std::string abbreviation = + types::GetDistanceUnitsAbbreviation(distanceUnits); + + return QString("%1 %2") + .arg(static_cast(p->distanceMap_.at(site->id()) * + scwx::common::kKilometersPerMeter * + distanceScale)) + .arg(QString::fromStdString(abbreviation)); } else { From 885a85cdccaa36dbc2cadb48afaafc5ad68c8774 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Fri, 26 Jul 2024 10:29:58 -0400 Subject: [PATCH 15/22] Updated more tests --- test/data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/data b/test/data index b523e5f4..5076cbcd 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit b523e5f4319f447e40f592784d695e7b8e50378c +Subproject commit 5076cbcda30b029046d4fc859d5d91cc59dddc5b From 83857575adfb293284aad3382ff885d11252a164 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Fri, 26 Jul 2024 11:19:04 -0400 Subject: [PATCH 16/22] added equality check for alertRadarSite_ --- scwx-qt/source/scwx/qt/settings/audio_settings.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/scwx-qt/source/scwx/qt/settings/audio_settings.cpp b/scwx-qt/source/scwx/qt/settings/audio_settings.cpp index 8a9db458..995ce881 100644 --- a/scwx-qt/source/scwx/qt/settings/audio_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/audio_settings.cpp @@ -185,6 +185,7 @@ bool operator==(const AudioSettings& lhs, const AudioSettings& rhs) lhs.p->alertLocationMethod_ == rhs.p->alertLocationMethod_ && lhs.p->alertLatitude_ == rhs.p->alertLatitude_ && lhs.p->alertLongitude_ == rhs.p->alertLongitude_ && + lhs.p->alertRadarSite_ == rhs.p->alertRadarSite_ && lhs.p->alertRadius_ == rhs.p->alertRadius_ && lhs.p->alertCounty_ == rhs.p->alertCounty_ && lhs.p->alertEnabled_ == rhs.p->alertEnabled_); From 54748ce8128c1da04c4e50f068cf6525807a6b45 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Fri, 26 Jul 2024 11:20:29 -0400 Subject: [PATCH 17/22] fixed naming typo (Abbreiation) --- scwx-qt/source/scwx/qt/settings/settings_interface.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp index 7a83cd70..dd85595e 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp +++ b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp @@ -56,7 +56,7 @@ public: std::function mapToValue_ {nullptr}; double unitScale_ {1}; - const std::string * unitAbbreiation_ {nullptr}; + const std::string * unitAbbreviation_ {nullptr}; bool unitEnabled_ {false}; }; @@ -484,7 +484,7 @@ void SettingsInterface::SetUnit(const double& scale, const std::string& abbreviation) { p->unitScale_ = scale; - p->unitAbbreiation_ = &abbreviation; + p->unitAbbreviation_ = &abbreviation; p->unitEnabled_ = true; p->UpdateEditWidget(); p->UpdateUnitLabel(); @@ -604,7 +604,7 @@ void SettingsInterface::Impl::UpdateUnitLabel() return; } - unitLabel_->setText(QString::fromStdString(*unitAbbreiation_)); + unitLabel_->setText(QString::fromStdString(*unitAbbreviation_)); } template From 801125d87a83f3128cee5db5a340b5499f945542 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Fri, 26 Jul 2024 11:42:48 -0400 Subject: [PATCH 18/22] changed unitAbbreviation_ over to not use pointers --- .../source/scwx/qt/settings/settings_interface.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp index dd85595e..9a24c5ae 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp +++ b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp @@ -55,9 +55,9 @@ public: std::function mapFromValue_ {nullptr}; std::function mapToValue_ {nullptr}; - double unitScale_ {1}; - const std::string * unitAbbreviation_ {nullptr}; - bool unitEnabled_ {false}; + double unitScale_ {1}; + std::optional unitAbbreviation_ {}; + bool unitEnabled_ {false}; }; template @@ -483,9 +483,9 @@ template void SettingsInterface::SetUnit(const double& scale, const std::string& abbreviation) { - p->unitScale_ = scale; - p->unitAbbreviation_ = &abbreviation; - p->unitEnabled_ = true; + p->unitScale_ = scale; + p->unitAbbreviation_ = abbreviation; + p->unitEnabled_ = true; p->UpdateEditWidget(); p->UpdateUnitLabel(); } @@ -604,7 +604,7 @@ void SettingsInterface::Impl::UpdateUnitLabel() return; } - unitLabel_->setText(QString::fromStdString(*unitAbbreviation_)); + unitLabel_->setText(QString::fromStdString(unitAbbreviation_.value_or(""))); } template From 2096eaf6a30ecaa3cca27d5c50d0a07d3e1fb683 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Fri, 26 Jul 2024 11:46:24 -0400 Subject: [PATCH 19/22] switch radarSite paramater to be a const reference --- scwx-qt/source/scwx/qt/manager/alert_manager.cpp | 3 ++- scwx-qt/source/scwx/qt/manager/alert_manager.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp index edd2f28b..64c78d8d 100644 --- a/scwx-qt/source/scwx/qt/manager/alert_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/alert_manager.cpp @@ -219,7 +219,8 @@ void AlertManager::Impl::UpdateLocationTracking( positionManager_->EnablePositionUpdates(uuid_, locationEnabled); } -void AlertManager::SetRadarSite(std::shared_ptr radarSite) +void AlertManager::SetRadarSite( + const std::shared_ptr& radarSite) { if (p->radarSite_ == radarSite) { diff --git a/scwx-qt/source/scwx/qt/manager/alert_manager.hpp b/scwx-qt/source/scwx/qt/manager/alert_manager.hpp index 2041f360..f81054c7 100644 --- a/scwx-qt/source/scwx/qt/manager/alert_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/alert_manager.hpp @@ -22,7 +22,7 @@ public: explicit AlertManager(); ~AlertManager(); - void SetRadarSite(std::shared_ptr radarSite); + void SetRadarSite(const std::shared_ptr& radarSite); static std::shared_ptr Instance(); private: From f8934e6e67f8fce1dce73fa5fc9a157811ccac6e Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Fri, 26 Jul 2024 11:48:26 -0400 Subject: [PATCH 20/22] removed unnecessary logging --- scwx-qt/source/scwx/qt/ui/settings_dialog.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp index 81dc3ce4..d36efb07 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp @@ -507,7 +507,6 @@ void SettingsDialogImpl::ConnectSignals() break; case QDialogButtonBox::ButtonRole::ResetRole: // Restore Defaults - logger_->info("ButtonRole Reset"); ResetToDefault(); break; From 8573984bfaac1e8286466c36005727db1c99cabf Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Fri, 26 Jul 2024 12:12:52 -0400 Subject: [PATCH 21/22] removed usage of trace --- scwx-qt/source/scwx/qt/util/geographic_lib.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp index 84bf2354..bfaf408f 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp @@ -55,9 +55,9 @@ bool GnomonicAreaContainsCenter(geos::geom::CoordinateSequence sequence) areaContainsPoint = geos::algorithm::PointLocation::isInRing(zero, &sequence); } - catch (const std::exception&) + catch (const std::exception& ex) { - logger_->trace("Invalid area sequence"); + logger_->warn("Invalid area sequence. {}", ex.what()); } } From 812658f366ffc1afcc5dd880d42440d9c30b83e1 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Mon, 29 Jul 2024 09:21:49 -0400 Subject: [PATCH 22/22] updated default distance units --- scwx-qt/source/scwx/qt/settings/unit_settings.cpp | 2 +- test/data | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scwx-qt/source/scwx/qt/settings/unit_settings.cpp b/scwx-qt/source/scwx/qt/settings/unit_settings.cpp index 33adff19..c2cb0f11 100644 --- a/scwx-qt/source/scwx/qt/settings/unit_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/unit_settings.cpp @@ -27,7 +27,7 @@ public: std::string defaultSpeedUnitsValue = types::GetSpeedUnitsName(types::SpeedUnits::Knots); std::string defaultDistanceUnitsValue = - types::GetDistanceUnitsName(types::DistanceUnits::Kilometers); + types::GetDistanceUnitsName(types::DistanceUnits::Miles); boost::to_lower(defaultAccumulationUnitsValue); boost::to_lower(defaultEchoTopsUnitsValue); diff --git a/test/data b/test/data index 5076cbcd..51159935 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 5076cbcda30b029046d4fc859d5d91cc59dddc5b +Subproject commit 5115993596cfe6528b7a07c0b16dbd1ae16ce4df