mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 20:50:06 +00:00
Find nearest radar site
This commit is contained in:
parent
b739aad4bb
commit
4a31cf6d3e
3 changed files with 91 additions and 4 deletions
|
|
@ -8,6 +8,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <boost/json.hpp>
|
#include <boost/json.hpp>
|
||||||
|
#include <GeographicLib/Geodesic.hpp>
|
||||||
|
|
||||||
namespace scwx
|
namespace scwx
|
||||||
{
|
{
|
||||||
|
|
@ -30,6 +31,9 @@ static std::unordered_map<std::string, std::shared_ptr<RadarSite>>
|
||||||
static std::unordered_map<std::string, std::string> siteIdMap_;
|
static std::unordered_map<std::string, std::string> siteIdMap_;
|
||||||
static std::shared_mutex siteMutex_;
|
static std::shared_mutex siteMutex_;
|
||||||
|
|
||||||
|
static GeographicLib::Geodesic geodesic_ {GeographicLib::Constants::WGS84_a(),
|
||||||
|
GeographicLib::Constants::WGS84_f()};
|
||||||
|
|
||||||
static bool ValidateJsonEntry(const boost::json::object& o);
|
static bool ValidateJsonEntry(const boost::json::object& o);
|
||||||
|
|
||||||
class RadarSiteImpl
|
class RadarSiteImpl
|
||||||
|
|
@ -162,6 +166,44 @@ std::vector<std::shared_ptr<RadarSite>> RadarSite::GetAll()
|
||||||
return radarSites;
|
return radarSites;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<RadarSite> RadarSite::FindNearest(
|
||||||
|
double latitude, double longitude, std::optional<std::string> type)
|
||||||
|
{
|
||||||
|
std::shared_lock lock(siteMutex_);
|
||||||
|
|
||||||
|
double distanceInMeters;
|
||||||
|
|
||||||
|
std::shared_ptr<RadarSite> nearestRadarSite = nullptr;
|
||||||
|
double nearestDistance = 0.0;
|
||||||
|
|
||||||
|
for (const auto& site : radarSiteMap_)
|
||||||
|
{
|
||||||
|
auto& radarSite = site.second;
|
||||||
|
|
||||||
|
// If the type filter doesn't match, skip
|
||||||
|
if (type.has_value() && radarSite->type() != type)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate distance to radar site
|
||||||
|
geodesic_.Inverse(latitude,
|
||||||
|
longitude,
|
||||||
|
radarSite->latitude(),
|
||||||
|
radarSite->longitude(),
|
||||||
|
distanceInMeters);
|
||||||
|
|
||||||
|
// If the radar site is the closer, record it as the closest
|
||||||
|
if (nearestRadarSite == nullptr || distanceInMeters < nearestDistance)
|
||||||
|
{
|
||||||
|
nearestRadarSite = radarSite;
|
||||||
|
nearestDistance = distanceInMeters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nearestRadarSite;
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetRadarIdFromSiteId(const std::string& siteId)
|
std::string GetRadarIdFromSiteId(const std::string& siteId)
|
||||||
{
|
{
|
||||||
std::shared_lock lock(siteMutex_);
|
std::shared_lock lock(siteMutex_);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -38,6 +39,20 @@ public:
|
||||||
static std::shared_ptr<RadarSite> Get(const std::string& id);
|
static std::shared_ptr<RadarSite> Get(const std::string& id);
|
||||||
static std::vector<std::shared_ptr<RadarSite>> GetAll();
|
static std::vector<std::shared_ptr<RadarSite>> GetAll();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the nearest radar site to the supplied location.
|
||||||
|
*
|
||||||
|
* @param latitude Latitude in degrees
|
||||||
|
* @param longitude Longitude in degrees
|
||||||
|
* @param type Restrict results to optional radar type
|
||||||
|
*
|
||||||
|
* @return Nearest radar site
|
||||||
|
*/
|
||||||
|
static std::shared_ptr<RadarSite>
|
||||||
|
FindNearest(double latitude,
|
||||||
|
double longitude,
|
||||||
|
std::optional<std::string> type = std::nullopt);
|
||||||
|
|
||||||
static void Initialize();
|
static void Initialize();
|
||||||
static size_t ReadConfig(const std::string& path);
|
static size_t ReadConfig(const std::string& path);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,23 @@ namespace config
|
||||||
static const std::string DEFAULT_RADAR_SITE_FILE =
|
static const std::string DEFAULT_RADAR_SITE_FILE =
|
||||||
":/res/config/radar_sites.json";
|
":/res/config/radar_sites.json";
|
||||||
|
|
||||||
TEST(RadarSite, DefaultConfig)
|
class RadarSiteTest : public testing::Test
|
||||||
{
|
{
|
||||||
size_t numSites = RadarSite::ReadConfig(DEFAULT_RADAR_SITE_FILE);
|
protected:
|
||||||
|
static size_t numSites_;
|
||||||
|
|
||||||
ASSERT_GT(numSites, 0);
|
static void SetUpTestSuite()
|
||||||
EXPECT_EQ(numSites, 204);
|
{
|
||||||
|
numSites_ = RadarSite::ReadConfig(DEFAULT_RADAR_SITE_FILE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t RadarSiteTest::numSites_ {0u};
|
||||||
|
|
||||||
|
TEST_F(RadarSiteTest, DefaultConfig)
|
||||||
|
{
|
||||||
|
ASSERT_GT(numSites_, 0);
|
||||||
|
EXPECT_EQ(numSites_, 204);
|
||||||
|
|
||||||
std::shared_ptr<RadarSite> radarSite = RadarSite::Get("KLSX");
|
std::shared_ptr<RadarSite> radarSite = RadarSite::Get("KLSX");
|
||||||
|
|
||||||
|
|
@ -31,6 +42,25 @@ TEST(RadarSite, DefaultConfig)
|
||||||
EXPECT_DOUBLE_EQ(radarSite->longitude(), -90.682877);
|
EXPECT_DOUBLE_EQ(radarSite->longitude(), -90.682877);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(RadarSiteTest, FindNearest)
|
||||||
|
{
|
||||||
|
ASSERT_GT(numSites_, 0);
|
||||||
|
|
||||||
|
std::shared_ptr<RadarSite> nearest1 =
|
||||||
|
RadarSite::FindNearest(46.591111, -112.020278); // Helena, MT
|
||||||
|
std::shared_ptr<RadarSite> nearest2 =
|
||||||
|
RadarSite::FindNearest(28.54, -81.38); // Orlando, FL
|
||||||
|
std::shared_ptr<RadarSite> nearest3 =
|
||||||
|
RadarSite::FindNearest(38.627222, -90.197778, "wsr88d"); // St Louis, MO
|
||||||
|
std::shared_ptr<RadarSite> nearest4 =
|
||||||
|
RadarSite::FindNearest(38.627222, -90.197778, "tdwr"); // St Louis, MO
|
||||||
|
|
||||||
|
EXPECT_EQ(nearest1->id(), "KTFX");
|
||||||
|
EXPECT_EQ(nearest2->id(), "TMCO");
|
||||||
|
EXPECT_EQ(nearest3->id(), "KLSX");
|
||||||
|
EXPECT_EQ(nearest4->id(), "TSTL");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace config
|
} // namespace config
|
||||||
} // namespace qt
|
} // namespace qt
|
||||||
} // namespace scwx
|
} // namespace scwx
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue