mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 13:30:06 +00:00
Finish windowed load. Not all polygon updates are shown on the map.
This commit is contained in:
parent
33e18765b7
commit
1a1c668d62
3 changed files with 65 additions and 62 deletions
|
|
@ -10,6 +10,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <ranges>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
|
@ -148,9 +149,8 @@ public:
|
||||||
|
|
||||||
std::mutex archiveMutex_ {};
|
std::mutex archiveMutex_ {};
|
||||||
std::list<std::chrono::sys_days> archiveDates_ {};
|
std::list<std::chrono::sys_days> archiveDates_ {};
|
||||||
std::map<std::chrono::sys_days,
|
|
||||||
std::vector<std::shared_ptr<awips::TextProductFile>>>
|
std::mutex unloadedProductMapMutex_ {};
|
||||||
archiveMap_;
|
|
||||||
std::map<std::chrono::sys_days,
|
std::map<std::chrono::sys_days,
|
||||||
boost::container::stable_vector<scwx::types::iem::AfosEntry>>
|
boost::container::stable_vector<scwx::types::iem::AfosEntry>>
|
||||||
unloadedProductMap_;
|
unloadedProductMap_;
|
||||||
|
|
@ -248,6 +248,9 @@ void TextEventManager::SelectTime(
|
||||||
date < p->archiveLimit_;
|
date < p->archiveLimit_;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
std::unique_lock lock {p->archiveMutex_};
|
||||||
|
|
||||||
|
p->UpdateArchiveDates(dates);
|
||||||
p->ListArchives(dates);
|
p->ListArchives(dates);
|
||||||
p->LoadArchives(dateTime);
|
p->LoadArchives(dateTime);
|
||||||
}
|
}
|
||||||
|
|
@ -334,18 +337,12 @@ void TextEventManager::Impl::HandleMessage(
|
||||||
void TextEventManager::Impl::ListArchives(
|
void TextEventManager::Impl::ListArchives(
|
||||||
ranges::any_view<std::chrono::sys_days> dates)
|
ranges::any_view<std::chrono::sys_days> dates)
|
||||||
{
|
{
|
||||||
std::unique_lock lock {archiveMutex_};
|
|
||||||
|
|
||||||
UpdateArchiveDates(dates);
|
|
||||||
|
|
||||||
// Don't reload data that has already been loaded
|
// Don't reload data that has already been loaded
|
||||||
ranges::any_view<std::chrono::sys_days> filteredDates =
|
ranges::any_view<std::chrono::sys_days> filteredDates =
|
||||||
dates |
|
dates |
|
||||||
ranges::views::filter([this](const auto& date)
|
ranges::views::filter([this](const auto& date)
|
||||||
{ return !unloadedProductMap_.contains(date); });
|
{ return !unloadedProductMap_.contains(date); });
|
||||||
|
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
const auto dv = ranges::to<std::vector>(filteredDates);
|
const auto dv = ranges::to<std::vector>(filteredDates);
|
||||||
|
|
||||||
std::for_each(
|
std::for_each(
|
||||||
|
|
@ -359,14 +356,15 @@ void TextEventManager::Impl::ListArchives(
|
||||||
auto productEntries =
|
auto productEntries =
|
||||||
iemApiProvider_->ListTextProducts(dateArray, {}, kPils_);
|
iemApiProvider_->ListTextProducts(dateArray, {}, kPils_);
|
||||||
|
|
||||||
std::unique_lock lock {archiveMutex_};
|
std::unique_lock lock {unloadedProductMapMutex_};
|
||||||
|
|
||||||
if (productEntries.has_value())
|
if (productEntries.has_value())
|
||||||
{
|
{
|
||||||
unloadedProductMap_.try_emplace(
|
unloadedProductMap_.try_emplace(
|
||||||
date,
|
date,
|
||||||
{std::make_move_iterator(productEntries.value().begin()),
|
boost::container::stable_vector<scwx::types::iem::AfosEntry> {
|
||||||
std::make_move_iterator(productEntries.value().end())});
|
std::make_move_iterator(productEntries.value().begin()),
|
||||||
|
std::make_move_iterator(productEntries.value().end())});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -409,9 +407,7 @@ void TextEventManager::Impl::LoadArchives(
|
||||||
df::format(kDateFormat, (dateTime + loadWindow.second.second))});
|
df::format(kDateFormat, (dateTime + loadWindow.second.second))});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<scwx::types::iem::AfosEntry> loadList {};
|
std::vector<scwx::types::iem::AfosEntry> loadListEntries {};
|
||||||
|
|
||||||
std::unique_lock lock {archiveMutex_};
|
|
||||||
|
|
||||||
for (auto date : boost::irange(startDate, endDate))
|
for (auto date : boost::irange(startDate, endDate))
|
||||||
{
|
{
|
||||||
|
|
@ -441,7 +437,7 @@ void TextEventManager::Impl::LoadArchives(
|
||||||
if (windowStart <= productId && productId <= windowEnd)
|
if (windowStart <= productId && productId <= windowEnd)
|
||||||
{
|
{
|
||||||
// Product matches, move it to the load list
|
// Product matches, move it to the load list
|
||||||
loadList.emplace_back(std::move(*it));
|
loadListEntries.emplace_back(std::move(*it));
|
||||||
it = mapIt->second.erase(it);
|
it = mapIt->second.erase(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -453,33 +449,21 @@ void TextEventManager::Impl::LoadArchives(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (productIds.has_value())
|
// Load the load list
|
||||||
|
auto loadView = loadListEntries |
|
||||||
|
std::ranges::views::transform([](const auto& entry)
|
||||||
|
{ return entry.productId_; });
|
||||||
|
auto products = iemApiProvider_->LoadTextProducts(loadView);
|
||||||
|
|
||||||
|
// Process loaded products
|
||||||
|
for (auto& product : products)
|
||||||
{
|
{
|
||||||
logger_->debug("Loading {} products", productIds.value().size());
|
const auto& messages = product->messages();
|
||||||
|
|
||||||
// Load listed products
|
for (auto& message : messages)
|
||||||
auto products = iemApiProvider_->LoadTextProducts(productIds.value());
|
|
||||||
|
|
||||||
for (auto& product : products)
|
|
||||||
{
|
{
|
||||||
const auto& messages = product->messages();
|
HandleMessage(message);
|
||||||
|
|
||||||
for (auto& message : messages)
|
|
||||||
{
|
|
||||||
HandleMessage(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lock.lock();
|
|
||||||
|
|
||||||
for (const auto& date : dates)
|
|
||||||
{
|
|
||||||
archiveMap_[date];
|
|
||||||
|
|
||||||
// TODO: Store the products in the archive
|
|
||||||
}
|
|
||||||
|
|
||||||
lock.unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <scwx/awips/text_product_file.hpp>
|
#include <scwx/awips/text_product_file.hpp>
|
||||||
|
#include <scwx/network/cpr.hpp>
|
||||||
#include <scwx/types/iem_types.hpp>
|
#include <scwx/types/iem_types.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <ranges>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <boost/outcome/result.hpp>
|
#include <boost/outcome/result.hpp>
|
||||||
|
#include <cpr/cpr.h>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
|
|
@ -47,12 +51,41 @@ public:
|
||||||
ranges::any_view<std::string_view> ccccs = {},
|
ranges::any_view<std::string_view> ccccs = {},
|
||||||
ranges::any_view<std::string_view> pils = {});
|
ranges::any_view<std::string_view> pils = {});
|
||||||
|
|
||||||
|
template<std::ranges::forward_range Range>
|
||||||
|
requires std::same_as<std::ranges::range_value_t<Range>, std::string>
|
||||||
static std::vector<std::shared_ptr<awips::TextProductFile>>
|
static std::vector<std::shared_ptr<awips::TextProductFile>>
|
||||||
LoadTextProducts(const std::vector<std::string>& textProducts);
|
LoadTextProducts(const Range& textProducts)
|
||||||
|
{
|
||||||
|
auto parameters = cpr::Parameters {{"nolimit", "true"}};
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, cpr::AsyncResponse>> asyncResponses {};
|
||||||
|
asyncResponses.reserve(textProducts.size());
|
||||||
|
|
||||||
|
const std::string endpointUrl = kBaseUrl_ + kNwsTextProductEndpoint_;
|
||||||
|
|
||||||
|
for (const auto& productId : textProducts)
|
||||||
|
{
|
||||||
|
asyncResponses.emplace_back(
|
||||||
|
productId,
|
||||||
|
cpr::GetAsync(cpr::Url {endpointUrl + productId},
|
||||||
|
network::cpr::GetHeader(),
|
||||||
|
parameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProcessTextProductResponses(asyncResponses);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
std::unique_ptr<Impl> p;
|
std::unique_ptr<Impl> p;
|
||||||
|
|
||||||
|
static const std::string kBaseUrl_;
|
||||||
|
static const std::string kListNwsTextProductsEndpoint_;
|
||||||
|
static const std::string kNwsTextProductEndpoint_;
|
||||||
|
|
||||||
|
static std::vector<std::shared_ptr<awips::TextProductFile>>
|
||||||
|
ProcessTextProductResponses(
|
||||||
|
std::vector<std::pair<std::string, cpr::AsyncResponse>>& asyncResponses);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace scwx::provider
|
} // namespace scwx::provider
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
#include <scwx/provider/iem_api_provider.hpp>
|
#include <scwx/provider/iem_api_provider.hpp>
|
||||||
#include <scwx/network/cpr.hpp>
|
|
||||||
#include <scwx/util/json.hpp>
|
#include <scwx/util/json.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
#include <boost/json.hpp>
|
#include <boost/json.hpp>
|
||||||
#include <cpr/cpr.h>
|
#include <cpr/cpr.h>
|
||||||
|
#include <range/v3/iterator/operations.hpp>
|
||||||
#include <range/v3/range/conversion.hpp>
|
#include <range/v3/range/conversion.hpp>
|
||||||
#include <range/v3/view/cartesian_product.hpp>
|
#include <range/v3/view/cartesian_product.hpp>
|
||||||
#include <range/v3/view/single.hpp>
|
#include <range/v3/view/single.hpp>
|
||||||
|
|
@ -19,10 +19,12 @@ namespace scwx::provider
|
||||||
static const std::string logPrefix_ = "scwx::provider::iem_api_provider";
|
static const std::string logPrefix_ = "scwx::provider::iem_api_provider";
|
||||||
static const auto logger_ = util::Logger::Create(logPrefix_);
|
static const auto logger_ = util::Logger::Create(logPrefix_);
|
||||||
|
|
||||||
static const std::string kBaseUrl_ = "https://mesonet.agron.iastate.edu/api/1";
|
const std::string IemApiProvider::kBaseUrl_ =
|
||||||
|
"https://mesonet.agron.iastate.edu/api/1";
|
||||||
|
|
||||||
static const std::string kListNwsTextProductsEndpoint_ = "/nws/afos/list.json";
|
const std::string IemApiProvider::kListNwsTextProductsEndpoint_ =
|
||||||
static const std::string kNwsTextProductEndpoint_ = "/nwstext/";
|
"/nws/afos/list.json";
|
||||||
|
const std::string IemApiProvider::kNwsTextProductEndpoint_ = "/nwstext/";
|
||||||
|
|
||||||
class IemApiProvider::Impl
|
class IemApiProvider::Impl
|
||||||
{
|
{
|
||||||
|
|
@ -199,25 +201,9 @@ IemApiProvider::ListTextProducts(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<awips::TextProductFile>>
|
std::vector<std::shared_ptr<awips::TextProductFile>>
|
||||||
IemApiProvider::LoadTextProducts(const std::vector<std::string>& textProducts)
|
IemApiProvider::ProcessTextProductResponses(
|
||||||
|
std::vector<std::pair<std::string, cpr::AsyncResponse>>& asyncResponses)
|
||||||
{
|
{
|
||||||
auto parameters = cpr::Parameters {{"nolimit", "true"}};
|
|
||||||
|
|
||||||
std::vector<std::pair<const std::string&, cpr::AsyncResponse>>
|
|
||||||
asyncResponses {};
|
|
||||||
asyncResponses.reserve(textProducts.size());
|
|
||||||
|
|
||||||
const std::string endpointUrl = kBaseUrl_ + kNwsTextProductEndpoint_;
|
|
||||||
|
|
||||||
for (auto& productId : textProducts)
|
|
||||||
{
|
|
||||||
asyncResponses.emplace_back(
|
|
||||||
productId,
|
|
||||||
cpr::GetAsync(cpr::Url {endpointUrl + productId},
|
|
||||||
network::cpr::GetHeader(),
|
|
||||||
parameters));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<awips::TextProductFile>> textProductFiles;
|
std::vector<std::shared_ptr<awips::TextProductFile>> textProductFiles;
|
||||||
|
|
||||||
for (auto& asyncResponse : asyncResponses)
|
for (auto& asyncResponse : asyncResponses)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue