mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-11-01 14:00:06 +00:00
Merge pull request #397 from AdenKoperczak/speed_up_geolines
Speed up geolines by avoiding iterative finds
This commit is contained in:
commit
e641c0b0e5
3 changed files with 55 additions and 52 deletions
|
|
@ -50,6 +50,7 @@ struct GeoLineDrawItem : types::EventHandler
|
||||||
units::angle::degrees<float> angle_ {};
|
units::angle::degrees<float> angle_ {};
|
||||||
std::string hoverText_ {};
|
std::string hoverText_ {};
|
||||||
GeoLines::HoverCallback hoverCallback_ {nullptr};
|
GeoLines::HoverCallback hoverCallback_ {nullptr};
|
||||||
|
size_t lineIndex_ {0};
|
||||||
};
|
};
|
||||||
|
|
||||||
class GeoLines::Impl
|
class GeoLines::Impl
|
||||||
|
|
@ -87,10 +88,10 @@ public:
|
||||||
void UpdateBuffers();
|
void UpdateBuffers();
|
||||||
void UpdateModifiedLineBuffers();
|
void UpdateModifiedLineBuffers();
|
||||||
void UpdateSingleBuffer(const std::shared_ptr<GeoLineDrawItem>& di,
|
void UpdateSingleBuffer(const std::shared_ptr<GeoLineDrawItem>& di,
|
||||||
std::size_t lineIndex,
|
|
||||||
std::vector<float>& linesBuffer,
|
std::vector<float>& linesBuffer,
|
||||||
std::vector<GLint>& integerBuffer,
|
std::vector<GLint>& integerBuffer,
|
||||||
std::vector<LineHoverEntry>& hoverLines);
|
std::unordered_map<std::shared_ptr<GeoLineDrawItem>,
|
||||||
|
LineHoverEntry>& hoverLines);
|
||||||
|
|
||||||
std::shared_ptr<GlContext> context_;
|
std::shared_ptr<GlContext> context_;
|
||||||
|
|
||||||
|
|
@ -112,8 +113,10 @@ public:
|
||||||
std::vector<float> newLinesBuffer_ {};
|
std::vector<float> newLinesBuffer_ {};
|
||||||
std::vector<GLint> newIntegerBuffer_ {};
|
std::vector<GLint> newIntegerBuffer_ {};
|
||||||
|
|
||||||
std::vector<LineHoverEntry> currentHoverLines_ {};
|
std::unordered_map<std::shared_ptr<GeoLineDrawItem>, LineHoverEntry>
|
||||||
std::vector<LineHoverEntry> newHoverLines_ {};
|
currentHoverLines_ {};
|
||||||
|
std::unordered_map<std::shared_ptr<GeoLineDrawItem>, LineHoverEntry>
|
||||||
|
newHoverLines_ {};
|
||||||
|
|
||||||
std::shared_ptr<ShaderProgram> shaderProgram_;
|
std::shared_ptr<ShaderProgram> shaderProgram_;
|
||||||
GLint uMVPMatrixLocation_;
|
GLint uMVPMatrixLocation_;
|
||||||
|
|
@ -323,7 +326,9 @@ void GeoLines::StartLines()
|
||||||
|
|
||||||
std::shared_ptr<GeoLineDrawItem> GeoLines::AddLine()
|
std::shared_ptr<GeoLineDrawItem> GeoLines::AddLine()
|
||||||
{
|
{
|
||||||
return p->newLineList_.emplace_back(std::make_shared<GeoLineDrawItem>());
|
auto& di = p->newLineList_.emplace_back(std::make_shared<GeoLineDrawItem>());
|
||||||
|
di->lineIndex_ = p->newLineList_.size() - 1;
|
||||||
|
return di;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeoLines::SetLineLocation(const std::shared_ptr<GeoLineDrawItem>& di,
|
void GeoLines::SetLineLocation(const std::shared_ptr<GeoLineDrawItem>& di,
|
||||||
|
|
@ -470,7 +475,7 @@ void GeoLines::Impl::UpdateBuffers()
|
||||||
|
|
||||||
// Update line buffer
|
// Update line buffer
|
||||||
UpdateSingleBuffer(
|
UpdateSingleBuffer(
|
||||||
di, i, newLinesBuffer_, newIntegerBuffer_, newHoverLines_);
|
di, newLinesBuffer_, newIntegerBuffer_, newHoverLines_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// All lines have been updated
|
// All lines have been updated
|
||||||
|
|
@ -488,23 +493,15 @@ void GeoLines::Impl::UpdateModifiedLineBuffers()
|
||||||
// Update buffers for modified lines
|
// Update buffers for modified lines
|
||||||
for (auto& di : dirtyLines_)
|
for (auto& di : dirtyLines_)
|
||||||
{
|
{
|
||||||
// Find modified line in the current list
|
// Check if modified line is in the current list
|
||||||
auto it =
|
if (di->lineIndex_ >= currentLineList_.size() ||
|
||||||
std::find(currentLineList_.cbegin(), currentLineList_.cend(), di);
|
currentLineList_[di->lineIndex_] != di)
|
||||||
|
|
||||||
// Ignore invalid lines
|
|
||||||
if (it == currentLineList_.cend())
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lineIndex = std::distance(currentLineList_.cbegin(), it);
|
UpdateSingleBuffer(
|
||||||
|
di, currentLinesBuffer_, currentIntegerBuffer_, currentHoverLines_);
|
||||||
UpdateSingleBuffer(di,
|
|
||||||
lineIndex,
|
|
||||||
currentLinesBuffer_,
|
|
||||||
currentIntegerBuffer_,
|
|
||||||
currentHoverLines_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear list of modified lines
|
// Clear list of modified lines
|
||||||
|
|
@ -517,10 +514,10 @@ void GeoLines::Impl::UpdateModifiedLineBuffers()
|
||||||
|
|
||||||
void GeoLines::Impl::UpdateSingleBuffer(
|
void GeoLines::Impl::UpdateSingleBuffer(
|
||||||
const std::shared_ptr<GeoLineDrawItem>& di,
|
const std::shared_ptr<GeoLineDrawItem>& di,
|
||||||
std::size_t lineIndex,
|
|
||||||
std::vector<float>& lineBuffer,
|
std::vector<float>& lineBuffer,
|
||||||
std::vector<GLint>& integerBuffer,
|
std::vector<GLint>& integerBuffer,
|
||||||
std::vector<LineHoverEntry>& hoverLines)
|
std::unordered_map<std::shared_ptr<GeoLineDrawItem>, LineHoverEntry>&
|
||||||
|
hoverLines)
|
||||||
{
|
{
|
||||||
// Threshold value
|
// Threshold value
|
||||||
units::length::nautical_miles<double> threshold = di->threshold_;
|
units::length::nautical_miles<double> threshold = di->threshold_;
|
||||||
|
|
@ -588,10 +585,10 @@ void GeoLines::Impl::UpdateSingleBuffer(
|
||||||
|
|
||||||
// Buffer position data
|
// Buffer position data
|
||||||
auto lineBufferPosition = lineBuffer.end();
|
auto lineBufferPosition = lineBuffer.end();
|
||||||
auto lineBufferOffset = lineIndex * kLineBufferLength_;
|
auto lineBufferOffset = di->lineIndex_ * kLineBufferLength_;
|
||||||
|
|
||||||
auto integerBufferPosition = integerBuffer.end();
|
auto integerBufferPosition = integerBuffer.end();
|
||||||
auto integerBufferOffset = lineIndex * kIntegerBufferLength_;
|
auto integerBufferOffset = di->lineIndex_ * kIntegerBufferLength_;
|
||||||
|
|
||||||
if (lineBufferOffset < lineBuffer.size())
|
if (lineBufferOffset < lineBuffer.size())
|
||||||
{
|
{
|
||||||
|
|
@ -620,9 +617,7 @@ void GeoLines::Impl::UpdateSingleBuffer(
|
||||||
std::copy(integerData.begin(), integerData.end(), integerBufferPosition);
|
std::copy(integerData.begin(), integerData.end(), integerBufferPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto hoverIt = std::find_if(hoverLines.begin(),
|
auto hoverIt = hoverLines.find(di);
|
||||||
hoverLines.end(),
|
|
||||||
[&di](auto& entry) { return entry.di_ == di; });
|
|
||||||
|
|
||||||
if (di->visible_ && (!di->hoverText_.empty() ||
|
if (di->visible_ && (!di->hoverText_.empty() ||
|
||||||
di->hoverCallback_ != nullptr || di->event_ != nullptr))
|
di->hoverCallback_ != nullptr || di->event_ != nullptr))
|
||||||
|
|
@ -644,17 +639,23 @@ void GeoLines::Impl::UpdateSingleBuffer(
|
||||||
|
|
||||||
if (hoverIt == hoverLines.end())
|
if (hoverIt == hoverLines.end())
|
||||||
{
|
{
|
||||||
hoverLines.emplace_back(
|
hoverLines.emplace(di,
|
||||||
LineHoverEntry {di, sc1, sc2, otl, otr, obl, obr});
|
LineHoverEntry {.di_ = di,
|
||||||
|
.p1_ = sc1,
|
||||||
|
.p2_ = sc2,
|
||||||
|
.otl_ = otl,
|
||||||
|
.otr_ = otr,
|
||||||
|
.obl_ = obl,
|
||||||
|
.obr_ = obr});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hoverIt->p1_ = sc1;
|
hoverIt->second.p1_ = sc1;
|
||||||
hoverIt->p2_ = sc2;
|
hoverIt->second.p2_ = sc2;
|
||||||
hoverIt->otl_ = otl;
|
hoverIt->second.otl_ = otl;
|
||||||
hoverIt->otr_ = otr;
|
hoverIt->second.otr_ = otr;
|
||||||
hoverIt->obl_ = obl;
|
hoverIt->second.obl_ = obl;
|
||||||
hoverIt->obr_ = obr;
|
hoverIt->second.obr_ = obr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (hoverIt != hoverLines.end())
|
else if (hoverIt != hoverLines.end())
|
||||||
|
|
@ -726,10 +727,12 @@ bool GeoLines::RunMousePicking(
|
||||||
// For each pickable line
|
// For each pickable line
|
||||||
auto it = std::find_if(
|
auto it = std::find_if(
|
||||||
std::execution::par_unseq,
|
std::execution::par_unseq,
|
||||||
p->currentHoverLines_.rbegin(),
|
p->currentHoverLines_.cbegin(),
|
||||||
p->currentHoverLines_.rend(),
|
p->currentHoverLines_.cend(),
|
||||||
[&mapDistance, &selectedTime, &mapMatrix, &mouseCoords](const auto& line)
|
[&mapDistance, &selectedTime, &mapMatrix, &mouseCoords](
|
||||||
|
const auto& lineIt)
|
||||||
{
|
{
|
||||||
|
const auto& line = lineIt.second;
|
||||||
if ((
|
if ((
|
||||||
// Placefile is thresholded
|
// Placefile is thresholded
|
||||||
mapDistance > units::length::meters<double> {0.0} &&
|
mapDistance > units::length::meters<double> {0.0} &&
|
||||||
|
|
@ -785,24 +788,24 @@ bool GeoLines::RunMousePicking(
|
||||||
return util::maplibre::IsPointInPolygon({tl, bl, br, tr}, mouseCoords);
|
return util::maplibre::IsPointInPolygon({tl, bl, br, tr}, mouseCoords);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (it != p->currentHoverLines_.crend())
|
if (it != p->currentHoverLines_.cend())
|
||||||
{
|
{
|
||||||
itemPicked = true;
|
itemPicked = true;
|
||||||
|
|
||||||
if (!it->di_->hoverText_.empty())
|
if (!it->second.di_->hoverText_.empty())
|
||||||
{
|
{
|
||||||
// Show tooltip
|
// Show tooltip
|
||||||
util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos);
|
util::tooltip::Show(it->second.di_->hoverText_, mouseGlobalPos);
|
||||||
}
|
}
|
||||||
else if (it->di_->hoverCallback_ != nullptr)
|
else if (it->second.di_->hoverCallback_ != nullptr)
|
||||||
{
|
{
|
||||||
it->di_->hoverCallback_(it->di_, mouseGlobalPos);
|
it->second.di_->hoverCallback_(it->second.di_, mouseGlobalPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it->di_->event_ != nullptr)
|
if (it->second.di_->event_ != nullptr)
|
||||||
{
|
{
|
||||||
// Register event handler
|
// Register event handler
|
||||||
eventHandler = it->di_;
|
eventHandler = it->second.di_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,8 @@ struct GeoLineDrawItem;
|
||||||
class GeoLines : public DrawItem
|
class GeoLines : public DrawItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::function<void(std::shared_ptr<GeoLineDrawItem>&,
|
using HoverCallback = std::function<void(
|
||||||
const QPointF&)>
|
const std::shared_ptr<GeoLineDrawItem>&, const QPointF&)>;
|
||||||
HoverCallback;
|
|
||||||
|
|
||||||
explicit GeoLines(std::shared_ptr<GlContext> context);
|
explicit GeoLines(std::shared_ptr<GlContext> context);
|
||||||
~GeoLines();
|
~GeoLines();
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,8 @@ public:
|
||||||
void ConnectSignals();
|
void ConnectSignals();
|
||||||
void HandleGeoLinesEvent(std::weak_ptr<gl::draw::GeoLineDrawItem>& di,
|
void HandleGeoLinesEvent(std::weak_ptr<gl::draw::GeoLineDrawItem>& di,
|
||||||
QEvent* ev);
|
QEvent* ev);
|
||||||
void HandleGeoLinesHover(std::shared_ptr<gl::draw::GeoLineDrawItem>& di,
|
void
|
||||||
|
HandleGeoLinesHover(const std::shared_ptr<gl::draw::GeoLineDrawItem>& di,
|
||||||
const QPointF& mouseGlobalPos);
|
const QPointF& mouseGlobalPos);
|
||||||
void ScheduleRefresh();
|
void ScheduleRefresh();
|
||||||
|
|
||||||
|
|
@ -720,7 +721,7 @@ void AlertLayer::Impl::HandleGeoLinesEvent(
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlertLayer::Impl::HandleGeoLinesHover(
|
void AlertLayer::Impl::HandleGeoLinesHover(
|
||||||
std::shared_ptr<gl::draw::GeoLineDrawItem>& di,
|
const std::shared_ptr<gl::draw::GeoLineDrawItem>& di,
|
||||||
const QPointF& mouseGlobalPos)
|
const QPointF& mouseGlobalPos)
|
||||||
{
|
{
|
||||||
if (di != lastHoverDi_)
|
if (di != lastHoverDi_)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue