hivemind 1.0.0
Loading...
Searching...
No Matches
map_viewer.cpp
Go to the documentation of this file.
1#include "gui/map_viewer.h"
2
3#include "gui/main_window.h"
4
5#include <QPainter>
6#include <QRandomGenerator>
7#include <QTimer>
8
9namespace Gui
10{
11
12 MapViewer::MapViewer(QWidget* parent)
13 : QWidget(parent), m_WaitingForData(true),
14 m_WaitingForDataTimer(new QTimer(this)), m_LoaderAngle(0),
15 m_LoaderSize(100), m_LoaderSpeed(180.0f), m_LoaderSpan(270.0f),
16 m_LoaderThickness(8), m_StartX{}, m_StartY{}, m_Size{},
17 m_ActiveAgentId{}, m_TimeStamp{}
18 {
19 setObjectName("MapViewer");
20
21 connect(m_WaitingForDataTimer, &QTimer::timeout, this, [this]() {
22 qint64 elapsedMilliseconds = m_WaitingForDataElapsedTimer.elapsed();
23 float deltaTimeSeconds =
24 static_cast<float>(elapsedMilliseconds) / 1000.0f;
25 m_LoaderAngle -= m_LoaderSpeed * deltaTimeSeconds;
27 update();
28 });
29
30 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
32
35 }
36
37 void
38 MapViewer::paintEvent(QPaintEvent* event)
39 {
40 QPainter painter(this);
41
42 if (m_WaitingForData) {
43 DrawLoader(painter);
44 return;
45 }
46
47 QByteArray mapData = MapManagement::MapManager::GetData();
48 if (!mapData.isEmpty()) {
49 int pixmapResolution{
51 };
52 QPixmap pixmap(pixmapResolution, pixmapResolution);
53 pixmap.loadFromData(mapData);
54 painter.drawPixmap(m_StartX, m_StartY,
55 pixmap.scaled(m_Size, m_Size));
56 }
57
58 DrawRoutes(painter);
59 DrawKeyframes(painter);
60 }
61
62 void
63 MapViewer::resizeEvent(QResizeEvent* event)
64 {
66 }
67
68 void
69 MapViewer::mousePressEvent(QMouseEvent* event)
70 {
71 event->ignore();
72
73 // Only respond to left mouse button clicks
74 if (event->button() != Qt::LeftButton) {
75 return;
76 }
77
78 // Ignore clicks if they are outside the rendering area
79 int x = static_cast<int>(event->position().x());
80 int y = static_cast<int>(event->position().y());
81 bool contained = (x >= m_StartX && x < (m_StartX + m_Size) &&
82 y >= m_StartY && y < (m_StartY + m_Size));
83 if (!contained) {
84 return;
85 }
86
87 // Relative coordinates of mouse click within the rendering area
88 float xRel{ static_cast<float>(x - m_StartX) };
89 float yRel{ static_cast<float>(y - m_StartY) };
90
91 float size{ static_cast<float>(
93
94 // Find relative coordinate within scenario space
95 xRel = xRel * size / static_cast<float>(m_Size);
96 yRel = yRel * size / static_cast<float>(m_Size);
97 Core::CartesianCoordinate symmetricPosition{
99 { xRel, yRel, 0 })
100 };
101
103 symmetricPosition);
105 newKeyframe);
106 }
107
108 void
110 {
111 int maxWidth = width();
112 int maxHeight = height();
113
114 m_Size = std::min(maxWidth, maxHeight);
115 int marginX = maxWidth - m_Size;
116 int marginY = maxHeight - m_Size;
117
118 m_StartX = marginX / 2;
119 m_StartY = marginY / 2;
120 }
121
122 void
124 {
125 m_WaitingForData = true;
126 m_WaitingForDataTimer->start(16);
127 setCursor(Qt::WaitCursor);
128 update();
129 }
130
131 void
133 {
134 m_WaitingForData = false;
135 m_WaitingForDataTimer->stop();
136 setCursor(Qt::ArrowCursor);
137 update();
138 }
139
140 void
141 MapViewer::DrawKeyframes(QPainter& painter)
142 {
143 int radius = 8;
144 int scenarioSize{ CoordinateConverter::CoordConv::GetSize() };
145 auto keyframes =
147 for (const Core::Keyframe& keyframe : keyframes) {
148 Core::CartesianCoordinate keyframePositionAsymmetric{
150 keyframe.Position)
151 };
152 int x{ static_cast<int>(
153 keyframePositionAsymmetric.X / scenarioSize * m_Size +
154 m_StartX - static_cast<float>(radius) / 2.0f) };
155 int y{ static_cast<int>(
156 keyframePositionAsymmetric.Y / scenarioSize * m_Size +
157 m_StartY - static_cast<float>(radius) / 2.0f) };
158
159 auto agent = std::find_if(m_Agents.first, m_Agents.second,
160 [&](const Core::Agent& agent) {
161 return agent.Id == keyframe.AgentId;
162 });
163 QColor color(Qt::magenta);
164 if (agent != m_Agents.second) {
165 color = QColor(QString::fromStdString(agent->Color));
166 }
167
168 painter.setPen(Qt::black);
169 painter.setBrush({ color });
170 painter.drawEllipse(x, y, radius, radius);
171 }
172 }
173
174 void
175 MapViewer::DrawRoutes(QPainter& painter)
176 {
177 QPen pen(Qt::red, 2);
178 painter.setPen(pen);
179 painter.setRenderHint(QPainter::Antialiasing);
180
181 for (auto iter = m_Routes.first; iter != m_Routes.second; ++iter) {
182 int agentId = iter->first;
183 auto route = iter->second;
184 for (int j = 0; j < route.size(); j++) {
185 for (int k = 0; k < route[j].size() - 1; k++) {
186 Core::CartesianCoordinate asymmetricA =
188 route[j][k]);
189 Core::CartesianCoordinate asymmetricB =
191 route[j][k + 1]);
192
193 int x1{ static_cast<int>(
194 asymmetricA.X /
196 m_StartX) };
197 int y1{ static_cast<int>(
198 asymmetricA.Y /
200 m_StartY) };
201 int x2{ static_cast<int>(
202 asymmetricB.X /
204 m_StartX) };
205 int y2{ static_cast<int>(
206 asymmetricB.Y /
208 m_StartY) };
209
210 auto agent = std::find_if(m_Agents.first, m_Agents.second,
211 [&](const Core::Agent& agent) {
212 return agent.Id == agentId;
213 });
214 QColor color(Qt::magenta);
215 if (agent != m_Agents.second) {
216 color = QColor(QString::fromStdString(agent->Color));
217 }
218
219 painter.setPen({ color, 2 });
220 painter.drawLine(x1, y1, x2, y2);
221 }
222 }
223 }
224 }
225
226 void
227 MapViewer::DrawLoader(QPainter& painter) const
228 {
229 QColor hivemindOrange(227, 118, 39);
230 QPen pen(hivemindOrange, m_LoaderThickness, Qt::SolidLine,
231 Qt::RoundCap);
232 painter.setPen(pen);
233 painter.setRenderHint(QPainter::Antialiasing);
234
235 int x{ m_StartX + (m_Size - m_LoaderSize) / 2 };
236 int y{ m_StartY + (m_Size - m_LoaderSize) / 2 };
237
238 QRectF rectangle(x, y, m_LoaderSize, m_LoaderSize);
239
240 // Multiply angles by 16 because Qt's angles are specified 1/16th of a
241 // degree
242 int spanAngle = static_cast<int>(m_LoaderSpan) * 16;
243 int startAngle = static_cast<int>(m_LoaderAngle) * 16;
244 painter.drawArc(rectangle, startAngle, spanAngle);
245 }
246
247 void
249 std::pair<CompileScenario::Scenario::RouteMap::iterator,
250 CompileScenario::Scenario::RouteMap::iterator>
251 routes)
252 {
253 m_Routes = routes;
254 update();
255 }
256
257 void
258 MapViewer::UpdateAgents(std::pair<std::vector<Core::Agent>::iterator,
259 std::vector<Core::Agent>::iterator>
260 agents)
261 {
262 m_Agents = agents;
263 update();
264 }
265
266} // namespace Gui
static Core::CartesianCoordinate SymmetricToAsymmetric(Core::CartesianCoordinate symmetric)
Function used to convert a coordinate in a symmetric coordinate system to a coordinate in an asymmetr...
static Core::CartesianCoordinate AsymmetricToSymmetric(Core::CartesianCoordinate asymmetric)
Function used to convert a coordinate in an asymmetric cooridnate system to a coordinate in a symmetr...
void UpdateRoutes(std::pair< CompileScenario::Scenario::RouteMap::iterator, CompileScenario::Scenario::RouteMap::iterator > routes)
Definition: map_viewer.cpp:248
void DrawLoader(QPainter &painter) const
Definition: map_viewer.cpp:227
std::pair< CompileScenario::Scenario::RouteMap::iterator, CompileScenario::Scenario::RouteMap::iterator > m_Routes
Definition: map_viewer.h:77
MapViewer(QWidget *parent=nullptr)
Definition: map_viewer.cpp:12
void resizeEvent(QResizeEvent *event) override
Definition: map_viewer.cpp:63
float m_LoaderAngle
Definition: map_viewer.h:66
void WaitForData()
Definition: map_viewer.cpp:123
int m_ActiveAgentId
Definition: map_viewer.h:79
float m_TimeStamp
Definition: map_viewer.h:80
void UpdateRenderingArea()
Definition: map_viewer.cpp:109
void UpdateAgents(std::pair< std::vector< Core::Agent >::iterator, std::vector< Core::Agent >::iterator > agents)
Definition: map_viewer.cpp:258
void DrawKeyframes(QPainter &painter)
Definition: map_viewer.cpp:141
QTimer * m_WaitingForDataTimer
Definition: map_viewer.h:64
float m_LoaderSpan
Definition: map_viewer.h:69
void DrawRoutes(QPainter &painter)
Definition: map_viewer.cpp:175
QElapsedTimer m_WaitingForDataElapsedTimer
Definition: map_viewer.h:65
void DataReceived()
Definition: map_viewer.cpp:132
std::pair< std::vector< Core::Agent >::iterator, std::vector< Core::Agent >::iterator > m_Agents
Definition: map_viewer.h:74
bool m_WaitingForData
Definition: map_viewer.h:63
void mousePressEvent(QMouseEvent *event) override
Definition: map_viewer.cpp:69
float m_LoaderSpeed
Definition: map_viewer.h:68
void paintEvent(QPaintEvent *event) override
Definition: map_viewer.cpp:38
int m_LoaderThickness
Definition: map_viewer.h:70
static KeyframeManager & Instance()
Returns the singleton instance of the KeyframeManager.
std::vector< Core::Keyframe > & GetKeyframes()
Returns a reference to the list of keyframes.
void AddKeyframe(int agentId, float timeStamp, float x, float y, float z)
Adds a keyframe to the keyframe list using x, y, and z coordinates.
static int GetImageResolution()
Definition: map_manager.h:55
static QByteArray & GetData()
Returns the map data as a byte array.
Definition: map_manager.h:49
Definition: action.h:6
std::string Color
Definition: types.h:94
A structure that represents a cartesian coordinate.
Definition: types.h:12
A structure representing an agent's position in cartesian space at a given point in time.
Definition: types.h:69