TrajectoryItem.cpp
Go to the documentation of this file.
1 // TerraLib
2 #include "TrajectoryItem.h"
3 #include "AnimationScene.h"
4 #include "Animation.h"
5 #include "../canvas/MapDisplay.h"
6 #include "../canvas/Canvas.h"
7 
8 // Qt
9 #include <QtCore/QPropertyAnimation>
10 #include <QtGui/QPainter>
11 #include <QtCore/QVector>
12 #include <QtCore/QFile>
13 #include <QtCore/QMutex>
14 
15 
16 te::qt::widgets::TrajectoryItem::TrajectoryItem(const QString& title, const QString& id, te::qt::widgets::MapDisplay* display, const QString& file, const QSize& size)
17  : te::qt::widgets::AnimationItem(title, display),
18  m_iconFile(file),
19  m_iconSize(size),
20  m_doIconRotate(true),
21  m_drawTrail(true),
22  m_forwardColor(Qt::blue),
23  m_backwardColor(Qt::magenta),
24  m_lineWidth(2),
25  m_layerId(id)
26 {
27  if(m_iconSize.isValid() == false)
28  m_iconSize = QSize(20, 20);
29 
30  if(file.isEmpty() == false)
31  {
32  QFile f(file);
33  if(f.exists())
34  {
35  QPixmap p(file);
36  QPixmap pp(m_iconSize);
37  QPainter painter(&pp);
38  painter.drawPixmap(pp.rect(), p, p.rect());
39  painter.end();
40  setPixmap(pp);
41  }
42  }
43 
44  if(pixmap().isNull())
45  {
46  QPixmap pix(m_iconSize);
47  pix.fill(Qt::transparent);
48  QPainter painter(&pix);
49  QBrush b(Qt::red);
50  painter.setBrush(b);
51  QPen p(Qt::red);
52  painter.setPen(p);
53  painter.drawEllipse(QRect(1, 1, 18, 18));
54  painter.end();
55  setPixmap(pix);
56  }
57 }
58 
60 
61 void te::qt::widgets::TrajectoryItem::paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*)
62 {
63  m_posOld = m_pos;
64  m_pos = pos(); // icon position
65 
66  if(m_animationRoute.empty())
67  return;
68 
69  if(m_automaticPan)
70  {
72  double w = e.getWidth();
73  double h = e.getHeight();
74  QRectF r(e.getLowerLeftX(), e.getLowerLeftY(), w, h);
75  double dist = 200;
76  QRectF rm(e.getLowerLeftX()+w/dist, e.getLowerLeftY()+h/dist, w-2*w/dist, h-2*h/dist);
77  if(rm.contains(m_pos) == false)
78  {
79  w -= w/20;
80  h -= h/20;
81  QPointF c = r.center();
82  QPointF dif = m_pos - c;
83  double dw = fabs(dif.x());
84  double dh = fabs(dif.y());
85  double mw = 0;
86  double mh = 0;
87  if(dw >= w/2)
88  mw = (dw - w / 2) + w * m_panFactor;
89  if(dh >= h/2)
90  mh = (dh - h / 2) + h * m_panFactor;
91 
92  QPointF cc;
93  if(dif.x() >= 0 && dif.y() >= 0)
94  cc = c + QPointF(mw, mh);
95  else if(dif.x() >= 0 && dif.y() < 0)
96  cc = c + QPointF(mw, -mh);
97  else if(dif.x() < 0 && dif.y() >= 0)
98  cc = c + QPointF(-mw, mh);
99  else if(dif.x() < 0 && dif.y() < 0)
100  cc = c + QPointF(-mw, -mh);
101  r.moveCenter(cc);
102 
103  if(r.contains(m_pos) == false)
104  r.moveCenter(m_pos);
105 
106  e.m_llx = r.left();
107  e.m_lly = r.top();
108  e.m_urx = r.right();
109  e.m_ury = r.bottom();
110  m_display->setExtent(e);
111  return;
112  }
113  }
114 
115  unsigned int curTime = m_animation->currentTime();
116  if(m_curTimeDuration == curTime)
117  return;
118 
119  if(m_drawTrail)
120  {
121  bool erase = false;
122  if(m_animation->direction() == QAbstractAnimation::Forward)
123  {
124  if(curTime < m_curTimeDuration) // erase trail
125  erase = true;
126  }
127  else
128  {
129  if(curTime > m_curTimeDuration) // erase trail
130  erase = true;
131  }
132 
133  if(erase)
134  {
135  //if(m_erasePerfectly)
136  //{
137  // m_curTimeDuration = curTime;
138  // draw();
139  //}
140  //else
141  this->erase(curTime);
142  }
143  else
144  drawForward(curTime);
145  }
146 
147  m_display->update();
148 }
149 
151 {
153  {
154  size_t size = vec.count();
156  for (size_t i = 0; i < size; ++i)
157  line.setPoint(i, vec[(int)i].x(), vec[(int)i].y());
158  line.transform(m_display->getSRID());
159 
160  vec.clear();
161  for (size_t i = 0; i < size; ++i)
162  vec.push_back(QPointF(line.getPointN(i)->getX(), line.getPointN(i)->getY()));
163  }
164 }
165 
166 void te::qt::widgets::TrajectoryItem::drawForward(const unsigned int& curTime)
167 {
168  if(m_animationRoute.empty())
169  return;
170 
171  int indold = m_animation->getNextAnimationDataIndex((double)m_curTimeDuration / (double)m_duration);
172  int ind = m_animation->getNextAnimationDataIndex((double)curTime / (double)m_duration);
173  m_curTimeDuration = curTime;
174  if (ind == -1 || indold == -1)
175  return;
176 
177  QVector<QPointF> vec;
178 
179  if(indold == ind)
180  {
181  vec.push_back(m_posOld);
182  vec.push_back(m_pos);
183  }
184  else if(m_animation->direction() == QAbstractAnimation::Forward)
185  {
186  while(indold <= ind)
187  vec.push_back(m_animationRoute[indold++]);
188  if(vec.isEmpty() == false && vec.last() != m_pos)
189  vec.push_back(m_pos);
190  }
191  else
192  {
193  while(indold >= ind)
194  vec.push_back(m_animationRoute[indold--]);
195  if(vec.isEmpty() == false && vec.last() != m_pos)
196  vec.push_back(m_pos);
197  }
198 
199  size_t size = vec.count();
200  if (size > 1)
201  {
203 
204  QPolygonF polf(vec);
205  QPolygon pol = m_matrix.map(polf).toPolygon();
206 
207  QPen pen(Qt::NoBrush, 2);
208  QColor trailColor;
209  if(m_animation->direction() == QAbstractAnimation::Forward)
210  trailColor = m_forwardColor;
211  else
212  trailColor = m_backwardColor;
213  pen.setColor(trailColor);
214 
215  AnimationScene* as = (AnimationScene*)scene();
216  as->m_mutex.lock();
217  QPixmap* scenePixmap = as->m_trajectoryPixmap;
218  QPainter painter(scenePixmap);
219  painter.setPen(pen);
220  painter.setBrush(Qt::NoBrush);
221  painter.drawPolyline(pol);
222  painter.end();
223  as->m_mutex.unlock();
224  }
225 }
226 
227 void te::qt::widgets::TrajectoryItem::erase(const unsigned int& curTime)
228 {
229  if(m_animationRoute.empty())
230  return;
231 
232  int indold = m_animation->getNextAnimationDataIndex((double)m_curTimeDuration / (double)m_duration);
233  int ind = m_animation->getNextAnimationDataIndex((double)curTime / (double)m_duration);
234  m_curTimeDuration = curTime;
235  if (ind == -1 || indold == -1)
236  return;
237 
238  QVector<QPointF> vec;
239  if(indold == ind)
240  {
241  vec.push_back(m_posOld);
242  vec.push_back(m_pos);
243  }
244  else if(m_animation->direction() == QAbstractAnimation::Backward)
245  {
246  vec.push_back(m_posOld);
247  while(indold < ind)
248  vec.push_back(m_animationRoute[indold++]);
249  vec.push_back(m_pos);
250  }
251  else
252  {
253  vec.push_back(m_posOld);
254  while(indold > ind)
255  vec.push_back(m_animationRoute[indold--]);
256  vec.push_back(m_pos);
257  }
258 
259  size_t size = vec.count();
260 if (size > 1)
261 {
263 
264  QPolygonF polf(vec);
265  QPolygon pol = m_matrix.map(polf).toPolygon();
266 
267  QPen pen(Qt::NoBrush, 2);
268  QColor trailColor(Qt::white);
269  pen.setColor(trailColor);
270 
271  AnimationScene* as = (AnimationScene*)scene();
272  as->m_mutex.lock();
273  QPixmap* scenePixmap = as->m_trajectoryPixmap;
274  QPainter painter(scenePixmap);
275  painter.setPen(pen);
276  painter.setCompositionMode(QPainter::CompositionMode_DestinationOut);
277  painter.setBrush(Qt::NoBrush);
278  painter.drawPolyline(pol);
279  painter.end();
280  as->m_mutex.unlock();
281 }
282 }
283 
285 {
286  if (m_animationRoute.empty())
287  return;
288 
290  if (ind == -1)
291  return;
292 
293  int w = m_display->getDisplayPixmap()->width();
294  int h = m_display->getDisplayPixmap()->height();
295  te::qt::widgets::Canvas canvas(w, h);
297  canvas.calcAspectRatio(e.m_llx, e.m_lly, e.m_urx, e.m_ury);
298  canvas.setWindow(e.m_llx, e.m_lly, e.m_urx, e.m_ury);
299  m_matrix = canvas.getMatrix();
300 
301  int count = m_animationRoute.size();
302 
303  QVector<QPointF> vec;
304  if (m_animation->direction() == QAbstractAnimation::Forward)
305  {
306  if (ind > 0)
307  {
308  int i = 0;
309  while (i <= ind)
310  vec.push_back(m_animationRoute[i++]);
311  if (vec.isEmpty() == false && vec.last() != m_pos)
312  vec.push_back(m_pos);
313  }
314  }
315  else
316  {
317  int i = count - 1;
318  while (i >= ind)
319  vec.push_back(m_animationRoute[i--]);
320  if (m_curTimeDuration != m_duration)
321  {
322  if (vec.isEmpty() == false && vec.last() != m_pos)
323  vec.push_back(m_pos);
324  }
325  }
326 
327  size_t size = vec.count();
328  if (size > 1)
329  {
331 
332  QPolygonF polf(vec);
333  QPolygon pol = m_matrix.map(polf).toPolygon();
334 
335  QPen pen(Qt::NoBrush, 2);
336  QColor trailColor;
337  if (m_animation->direction() == QAbstractAnimation::Forward)
338  trailColor = m_forwardColor;
339  else
340  trailColor = m_backwardColor;
341 
342  pen.setColor(trailColor);
343 
344  AnimationScene* as = (AnimationScene*)scene();
345  as->m_mutex.lock();
346  QPixmap* scenePixmap = as->m_trajectoryPixmap;
347  QPainter painter(scenePixmap);
348  painter.setPen(pen);
349  painter.setBrush(Qt::NoBrush);
350  painter.drawPolyline(pol);
351  painter.end();
352  as->m_mutex.unlock();
353  }
354  m_display->update();
355 }
356 
358 {
359  QPoint pos = getPosInDeviceCoordinate();
360 
361  if (m_doIconRotate)
362  {
363  double xScale = -1.;
364  double yScale = -1.;
365  double angle = 0.;
367 
368  if (ind == -1)
369  return;
370 
371  QVector<QPointF> vec;
372  if (m_animation->direction() == QAbstractAnimation::Forward)
373  {
374  if (ind > 0)
375  {
376  vec.push_back(m_animationRoute[ind - 1]); // begin
377  vec.push_back(m_animationRoute[ind]); // end
379  }
380  }
381  else
382  {
383  if (ind < (m_animationRoute.count() - 1))
384  {
385  vec.push_back(m_animationRoute[ind]); // begin
386  vec.push_back(m_animationRoute[ind + 1]); // end
388  }
389  }
390  if (vec.isEmpty() == false)
391  {
392  double PI = 3.14159265;
393  QPointF p = vec[1] - vec[0]; // end - begin
394  if (p.x() > 0)
395  yScale = 1.;
396 
397  if (p.x() == 0)
398  {
399  if (p.y() >= 0)
400  angle = PI / 2;
401  else
402  angle = -PI / 2;
403  }
404  else if (p.y() == 0)
405  {
406  if (p.x() >= 0)
407  angle = 0;
408  else
409  angle = -PI;
410  }
411  else
412  {
413  angle = atan(p.y() / p.x());
414  if (p.x() < 0)
415  {
416  if (p.y() < 0)
417  angle -= PI;
418  else
419  angle += PI;
420  }
421  }
422  angle *= 180. / PI;
423  }
424 
425  painter->save();
426  painter->translate(pos);
427  painter->scale(xScale, yScale);
428  if (yScale == 1.)
429  angle = -angle;
430  painter->rotate(-angle);
431  painter->translate(-pos);
432  }
433 
434  QRect r = pixmap().rect();
435  r.moveCenter(pos);
436  QRect dr = m_display->rect();
437  if (dr.intersects(r))
438  {
439  if (m_opacity == 255)
440  painter->drawPixmap(r, pixmap());
441  else
442  {
443  QSize size = pixmap().size();
444  int width = size.width();
445  int height = size.height();
446  QImage ima = pixmap().toImage();
447 
448  if (ima.format() == QImage::Format_ARGB32)
449  {
450  for (int i = 0; i < height; ++i)
451  {
452  unsigned char* u = ima.scanLine(i);
453  for (int j = 0; j < width; ++j)
454  {
455  QRgb* v = (QRgb*)(u + (j << 2));
456  if (qAlpha(*v) < 50)
457  *v = qRgba(255, 255, 255, 0);
458  else
459  *v = qRgba(qRed(*v), qGreen(*v), qBlue(*v), m_opacity);
460  }
461  }
462  painter->drawImage(r, ima);
463  }
464  else
465  {
466  QImage img(size, QImage::Format_ARGB32);
467  for (int i = 0; i < height; ++i)
468  {
469  unsigned char* u = ima.scanLine(i);
470  unsigned char* uu = img.scanLine(i);
471 
472  for (int j = 0; j < width; ++j)
473  {
474  QRgb* v = (QRgb*)(u + (j << 2));
475  QRgb* uv = (QRgb*)(uu + (j << 2));
476  if (qAlpha(*v) < 50)
477  *uv = qRgba(255, 255, 255, 0);
478  else
479  *uv = qRgba(qRed(*v), qGreen(*v), qBlue(*v), m_opacity);
480  }
481  }
482  painter->drawImage(r, img);
483  }
484  }
485  }
486 
487  if (m_doIconRotate)
488  painter->restore();
489 }
bool m_doIconRotate
do automatic icon rotate
QPointF m_pos
The icon position.
void drawForward(const unsigned int &curTime)
Draw a piece of tracktrajectory trail. It draws from the previous time to the current time...
void transformToDisplayProjection(QVector< QPointF > &vec)
It transform coodinates to map display projection coodinates.
int getNextAnimationDataIndex(const double &trel)
It It gets the next animation data index. it is the end point, between two points of the trajectory...
Definition: Animation.cpp:179
TrajectoryItem(const QString &title, const QString &id, te::qt::widgets::MapDisplay *display, const QString &file, const QSize &size)
Constructor It constructs a Trajectory Icon Item.
void drawIcon(QPainter *painter)
draw tracktrajectory icon.
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
QPixmap * m_trajectoryPixmap
QPixmap where all the trajectory item are drawn.
double m_urx
Upper right corner x-coordinate.
std::unique_ptr< Point > getPointN(std::size_t i) const
It returns the specified point in this LineString.
const double & getLowerLeftY() const
It returns a constant refernce to the y coordinate of the lower left corner.
bool m_automaticPan
True if automatic pan over this item.
double getWidth() const
It returns the envelope width.
A widget to control the display of a set of layers.
void draw()
Draw the trajectory long trail. It draws the beginning until the current time. The beginning depends ...
te::qt::widgets::MapDisplay * m_display
Indicates where the icon item is displayed.
QColor m_backwardColor
The backward trail color.
Animation * m_animation
The animation this item.
QMatrix getMatrix()
It returns the matrix.
unsigned int line
void erase(const unsigned int &curTime)
erase a piece of tracktrajectory trail.
int b
Definition: TsRtree.cpp:32
void setWindow(const double &llx, const double &lly, const double &urx, const double &ury)
It sets the world (or window) coordinates area (supposing a cartesian reference system).
double m_llx
Lower left corner x-coordinate.
This file defines a class for a Animation Scene.
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
void setPoint(std::size_t i, const double &x, const double &y)
It sets the value of the specified point.
An Envelope defines a 2D rectangular region.
void calcAspectRatio(double &llx, double &lly, double &urx, double &ury, const te::map::AlignType hAlign=te::map::Center, const te::map::AlignType vAlign=te::map::Center)
It calculates the best aspect ratio for world (or window) coordinates area (supposing a cartesian ref...
QMutex m_mutex
To not use m_trajectoryPixmap simultaneously.
virtual int getSRID() const
It return the Spatial Reference System used by the Map Display.
URI C++ Library.
Definition: Attributes.h:37
QColor m_forwardColor
The forward trail color.
#define PI
virtual const te::gm::Envelope & getExtent() const
It returns the world extent showned by the MapDisplay.
te::gm::Polygon * p
unsigned int m_curTimeDuration
Current time (ms). Its value is between 0 and the total duration.
double m_lly
Lower left corner y-coordinate.
QPoint getPosInDeviceCoordinate()
It returns the Animation Item position in device coordinate.
This file defines a class for a Trajectory Animation.
double m_ury
Upper right corner y-coordinate.
This file defines a class for a Trajectory Item.
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
Paint a piece of trajectory trail.
const double & getLowerLeftX() const
It returns a constant reference to the x coordinate of the lower left corner.
An abstract class for Animation Item.
Definition: AnimationItem.h:64
virtual ~TrajectoryItem()
Destructor It destructs a Trajectory Icon Item.
double m_panFactor
the range is between 0.002 and 0.5
This class allows to add multiple trajectories and temporal image.
QMatrix m_matrix
The display transformation matrix.
QVector< QPointF > m_animationRoute
It contains only the portions to be animated.
virtual void setExtent(te::gm::Envelope &e, bool doRefresh=true)
It sets the world visible area and refreshes the contents in the map display.
double getHeight() const
It returns the envelope height.
int m_SRID
The input route srid.
file(WRITE ${CMAKE_BINARY_DIR}/config_qhelp.cmake"configure_file (${TERRALIB_ABSOLUTE_ROOT_DIR}/doc/qhelp/help.qhcp.in ${CMAKE_BINARY_DIR}/share/terraview/help/help.qhcp @ONLY)") add_custom_command(OUTPUT del_dir COMMAND $
unsigned int m_duration
The duration this item.
void transform(int srid)
It converts the coordinate values of the linestring to the new spatial reference system.
QPointF m_posOld
Auxiliar point.
virtual QPixmap * getDisplayPixmap() const
It returns the map display pixmap.
bool m_drawTrail
flag to draw trail