mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-02 11:39:14 +01:00
feat(editor): the terrain model asks again for what it didn't get, can be stopped and says when the place is outside Poland
This commit is contained in:
@@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@@ -33,6 +34,12 @@ char const *const cache_folder{"editor/cache/nmt/grid1/"};
|
|||||||
int constexpr worker_count{2}; // the service is quick, but isn't to be hammered
|
int constexpr worker_count{2}; // the service is quick, but isn't to be hammered
|
||||||
int constexpr border{1}; // pixels of the neighbouring squares fetched around a square, so the heights interpolate across its edges
|
int constexpr border{1}; // pixels of the neighbouring squares fetched around a square, so the heights interpolate across its edges
|
||||||
float constexpr no_data{-1000.f}; // the model gives far lower values outside of the country
|
float constexpr no_data{-1000.f}; // the model gives far lower values outside of the country
|
||||||
|
double constexpr retry_after{15.0}; // s, a square the service didn't give is asked for again
|
||||||
|
|
||||||
|
double seconds()
|
||||||
|
{
|
||||||
|
return std::chrono::duration<double>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||||
|
}
|
||||||
|
|
||||||
// the name of the model among the names the capabilities of the service list: the first which says it's a terrain model
|
// the name of the model among the names the capabilities of the service list: the first which says it's a terrain model
|
||||||
std::string coverage_of(std::string const &Capabilities)
|
std::string coverage_of(std::string const &Capabilities)
|
||||||
@@ -231,12 +238,17 @@ bool editor_nmt::request(glm::dvec2 const &Min, glm::dvec2 const &Max)
|
|||||||
auto const low{key_of(m_east - Max.x, m_north + Min.y)};
|
auto const low{key_of(m_east - Max.x, m_north + Min.y)};
|
||||||
auto const high{key_of(m_east - Min.x, m_north + Max.y)};
|
auto const high{key_of(m_east - Min.x, m_north + Max.y)};
|
||||||
auto const middle{key_of(m_east - 0.5 * (Min.x + Max.x), m_north + 0.5 * (Min.y + Max.y))};
|
auto const middle{key_of(m_east - 0.5 * (Min.x + Max.x), m_north + 0.5 * (Min.y + Max.y))};
|
||||||
|
auto const now{seconds()};
|
||||||
for (auto e = low.first; e <= high.first; ++e)
|
for (auto e = low.first; e <= high.first; ++e)
|
||||||
for (auto n = low.second; n <= high.second; ++n)
|
for (auto n = low.second; n <= high.second; ++n)
|
||||||
{
|
{
|
||||||
key const square{e, n};
|
key const square{e, n};
|
||||||
if (m_squares.contains(square))
|
if (auto const found{m_squares.find(square)}; found != m_squares.end())
|
||||||
continue;
|
{
|
||||||
|
if (false == found->second->failed || found->second->outside || now - found->second->failed_at < retry_after)
|
||||||
|
continue;
|
||||||
|
m_squares.erase(found);
|
||||||
|
}
|
||||||
all = false;
|
all = false;
|
||||||
if (false == m_queued.contains(square))
|
if (false == m_queued.contains(square))
|
||||||
wanted.push_back(square);
|
wanted.push_back(square);
|
||||||
@@ -265,10 +277,52 @@ std::size_t editor_nmt::waiting() const
|
|||||||
return m_queued.size();
|
return m_queued.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string editor_nmt::error() const
|
bool editor_nmt::retrying(glm::dvec2 const &Min, glm::dvec2 const &Max) const
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock{m_mutex};
|
std::lock_guard<std::mutex> lock{m_mutex};
|
||||||
return m_error;
|
auto const low{key_of(m_east - Max.x, m_north + Min.y)};
|
||||||
|
auto const high{key_of(m_east - Min.x, m_north + Max.y)};
|
||||||
|
for (auto e = low.first; e <= high.first; ++e)
|
||||||
|
for (auto n = low.second; n <= high.second; ++n)
|
||||||
|
if (auto const found{m_squares.find({e, n})}; found != m_squares.end() && found->second->failed && false == found->second->outside)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_nmt::retry()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock{m_mutex};
|
||||||
|
std::erase_if(m_squares, [](auto const &Square) { return Square.second->failed && false == Square.second->outside; });
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_nmt::cancel()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock{m_mutex};
|
||||||
|
for (auto const &square : m_queue)
|
||||||
|
m_queued.erase(square);
|
||||||
|
m_queue.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string editor_nmt::error(bool *Again) const
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock{m_mutex};
|
||||||
|
std::string result;
|
||||||
|
bool outside{false};
|
||||||
|
if (Again != nullptr)
|
||||||
|
*Again = false;
|
||||||
|
for (auto const &[key, square] : m_squares)
|
||||||
|
{
|
||||||
|
if (false == square->failed)
|
||||||
|
continue;
|
||||||
|
if (Again != nullptr && false == square->outside)
|
||||||
|
*Again = true;
|
||||||
|
if (result.empty() || (square->outside && false == outside))
|
||||||
|
{
|
||||||
|
result = square->error;
|
||||||
|
outside = square->outside;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void editor_nmt::clear()
|
void editor_nmt::clear()
|
||||||
@@ -300,7 +354,6 @@ void editor_nmt::work()
|
|||||||
continue; // cleared meanwhile
|
continue; // cleared meanwhile
|
||||||
m_queued.erase(square);
|
m_queued.erase(square);
|
||||||
m_squares[square] = std::move(fetched);
|
m_squares[square] = std::move(fetched);
|
||||||
m_error = error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -324,6 +377,8 @@ std::shared_ptr<editor_nmt::square const> editor_nmt::fetch(key const &Key, std:
|
|||||||
{
|
{
|
||||||
Error = STRN("This build can't fetch from the internet");
|
Error = STRN("This build can't fetch from the internet");
|
||||||
result->failed = true;
|
result->failed = true;
|
||||||
|
result->outside = true;
|
||||||
|
result->error = Error;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
editor_http::client client;
|
editor_http::client client;
|
||||||
@@ -365,10 +420,18 @@ std::shared_ptr<editor_nmt::square const> editor_nmt::fetch(key const &Key, std:
|
|||||||
}
|
}
|
||||||
if (stop())
|
if (stop())
|
||||||
break;
|
break;
|
||||||
|
if (std::string const text(data.begin(), data.end()); text.find("outside requested coverage") != std::string::npos)
|
||||||
|
{
|
||||||
|
Error = STRN("The place lies outside of the terrain model of Poland: check the location of the scenery");
|
||||||
|
result->outside = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (Error.empty())
|
if (Error.empty())
|
||||||
Error = STRN("The service gave no terrain model");
|
Error = STRN("The service gave no terrain model");
|
||||||
}
|
}
|
||||||
WriteLog("Editor: NMT square " + std::to_string(Key.first) + "," + std::to_string(Key.second) + " not fetched: " + Error, logtype::generic);
|
WriteLog("Editor: NMT square " + std::to_string(Key.first) + "," + std::to_string(Key.second) + " not fetched: " + Error, logtype::generic);
|
||||||
result->failed = true;
|
result->failed = true;
|
||||||
|
result->error = Error;
|
||||||
|
result->failed_at = seconds();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,8 +46,15 @@ class editor_nmt
|
|||||||
bool request(glm::dvec2 const &Min, glm::dvec2 const &Max);
|
bool request(glm::dvec2 const &Min, glm::dvec2 const &Max);
|
||||||
// squares asked for and not in yet
|
// squares asked for and not in yet
|
||||||
std::size_t waiting() const;
|
std::size_t waiting() const;
|
||||||
// what the last fetch said went wrong, empty when it went right
|
// a square under the rectangle the service didn't give, which is asked for again after a while
|
||||||
std::string error() const;
|
bool retrying(glm::dvec2 const &Min, glm::dvec2 const &Max) const;
|
||||||
|
// the squares the service didn't give asked for again at once
|
||||||
|
void retry();
|
||||||
|
// the squares waiting aren't fetched; those in stay
|
||||||
|
void cancel();
|
||||||
|
// why squares in memory have no data, empty when all came; a place outside of the model is told first. Again: whether
|
||||||
|
// some of them are asked for again
|
||||||
|
std::string error(bool *Again = nullptr) const;
|
||||||
// the squares dropped from the memory, and those waiting; the files on the disk stay
|
// the squares dropped from the memory, and those waiting; the files on the disk stay
|
||||||
void clear();
|
void clear();
|
||||||
// whether this build can fetch from the service at all
|
// whether this build can fetch from the service at all
|
||||||
@@ -67,6 +74,9 @@ class editor_nmt
|
|||||||
int height{0};
|
int height{0};
|
||||||
std::vector<float> heights; // rows from the north, columns from the west
|
std::vector<float> heights; // rows from the north, columns from the west
|
||||||
bool failed{false}; // the service gave nothing usable: the square has no data
|
bool failed{false}; // the service gave nothing usable: the square has no data
|
||||||
|
bool outside{false}; // failed for it lies outside of the model: asked again, it gives nothing either
|
||||||
|
double failed_at{0.0}; // s
|
||||||
|
std::string error;
|
||||||
};
|
};
|
||||||
|
|
||||||
key key_of(double const East, double const North) const;
|
key key_of(double const East, double const North) const;
|
||||||
@@ -80,7 +90,6 @@ class editor_nmt
|
|||||||
std::set<key> m_queued;
|
std::set<key> m_queued;
|
||||||
std::map<key, std::shared_ptr<square const>> m_squares;
|
std::map<key, std::shared_ptr<square const>> m_squares;
|
||||||
std::string m_coverage; // the name of the model in the service, read from its capabilities once
|
std::string m_coverage; // the name of the model in the service, read from its capabilities once
|
||||||
std::string m_error;
|
|
||||||
double m_north{0.0};
|
double m_north{0.0};
|
||||||
double m_east{0.0};
|
double m_east{0.0};
|
||||||
bool m_stop{false};
|
bool m_stop{false};
|
||||||
|
|||||||
Reference in New Issue
Block a user