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 }
62 
63 void te::qt::widgets::TrajectoryItem::paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*)
64 {
65  m_posOld = m_pos;
66  m_pos = pos(); // icon position
67 
68  if(m_animationRoute.empty())
69  return;
70 
71  if(m_automaticPan)
72  {
73  te::gm::Envelope e = m_display->getExtent();
74  double w = e.getWidth();
75  double h = e.getHeight();
76  QRectF r(e.getLowerLeftX(), e.getLowerLeftY(), w, h);
77  double dist = 200;
78  QRectF rm(e.getLowerLeftX()+w/dist, e.getLowerLeftY()+h/dist, w-2*w/dist, h-2*h/dist);
79  if(rm.contains(m_pos) == false)
80  {
81  w -= w/20;
82  h -= h/20;
83  QPointF c = r.center();
84  QPointF dif = m_pos - c;
85  double dw = fabs(dif.x());
86  double dh = fabs(dif.y());
87  double mw = 0;
88  double mh = 0;
89  if(dw >= w/2)
90  mw = (dw - w / 2) + w * m_panFactor;
91  if(dh >= h/2)
92  mh = (dh - h / 2) + h * m_panFactor;
93 
94  QPointF cc;
95  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  else if(dif.x() < 0 && dif.y() < 0)
102  cc = c + QPointF(-mw, -mh);
103  r.moveCenter(cc);
104 
105  if(r.contains(m_pos) == false)
106  r.moveCenter(m_pos);
107 
108  e.m_llx = r.left();
109  e.m_lly = r.top();
110  e.m_urx = r.right();
111  e.m_ury = r.bottom();
112  m_display->setExtent(e);
113  return;
114  }
115  }
116 
117  unsigned int curTime = m_animation->currentTime();
118  if(m_curTimeDuration == curTime)
119  return;
120 
121  if(m_drawTrail)
122  {
123  bool erase = false;
124  if(m_animation->direction() == QAbstractAnimation::Forward)
125  {
126  if(curTime < m_curTimeDuration) // erase trail
127  erase = true;
128  }
129  else
130  {
131  if(curTime > m_curTimeDuration) // erase trail
132  erase = true;
133  }
134 
135  if(erase)
136  {
137  //if(m_erasePerfectly)
138  //{
139  // m_curTimeDuration = curTime;
140  // draw();
141  //}
142  //else
143  this->erase(curTime);
144  }
145  else
146  drawForward(curTime);
147  }
148 
149  m_display->update();
150 }
151 
153 {
154  if (m_display->getSRID() != TE_UNKNOWN_SRS && m_display->getSRID() != m_SRID)
155  {
156  size_t size = vec.count();
157  te::gm::LineString line(size, te::gm::LineStringType, m_SRID);
158  for (size_t i = 0; i < size; ++i)
159  line.setPoint(i, vec[(int)i].x(), vec[(int)i].y());
160  line.transform(m_display->getSRID());
161 
162  vec.clear();
163  for (size_t i = 0; i < size; ++i)
164  vec.push_back(QPointF(line.getPointN(i)->getX(), line.getPointN(i)->getY()));
165  }
166 }
167 
168 void te::qt::widgets::TrajectoryItem::drawForward(const unsigned int& curTime)
169 {
170  if(m_animationRoute.empty())
171  return;
172 
173  int indold = m_animation->getAnimationDataIndex((double)m_curTimeDuration / (double)m_duration);
174  int ind = m_animation->getAnimationDataIndex((double)curTime / (double)m_duration);
175  m_curTimeDuration = curTime;
176  if (ind == -1 || indold == -1)
177  return;
178 
179  QVector<QPointF> vec;
180 
181  if(indold == ind)
182  {
183  vec.push_back(m_posOld);
184  vec.push_back(m_pos);
185  }
186  else if(m_animation->direction() == QAbstractAnimation::Forward)
187  {
188  while(indold <= ind)
189  vec.push_back(m_animationRoute[indold++]);
190  if(vec.isEmpty() == false && vec.last() != m_pos)
191  vec.push_back(m_pos);
192  }
193  else
194  {
195  while(indold >= ind)
196  vec.push_back(m_animationRoute[indold--]);
197  if(vec.isEmpty() == false && vec.last() != m_pos)
198  vec.push_back(m_pos);
199  }
200 
201  size_t size = vec.count();
202  if (size > 1)
203  {
204  transformToDisplayProjection(vec);
205 
206  QPolygonF polf(vec);
207  QPolygon pol = m_matrix.map(polf).toPolygon();
208 
209  QPen pen(Qt::NoBrush, 2);
210  QColor trailColor;
211  if(m_animation->direction() == QAbstractAnimation::Forward)
212  trailColor = m_forwardColor;
213  else
214  trailColor = m_backwardColor;
215  pen.setColor(trailColor);
216 
217  AnimationScene* as = (AnimationScene*)scene();
218  as->m_mutex.lock();
219  QPixmap* scenePixmap = as->m_trajectoryPixmap;
220  QPainter painter(scenePixmap);
221  painter.setPen(pen);
222  painter.setBrush(Qt::NoBrush);
223  painter.drawPolyline(pol);
224  painter.end();
225  as->m_mutex.unlock();
226  }
227 }
228 
229 void te::qt::widgets::TrajectoryItem::erase(const unsigned int& curTime)
230 {
231  if(m_animationRoute.empty())
232  return;
233 
234  int indold = m_animation->getAnimationDataIndex((double)m_curTimeDuration / (double)m_duration);
235  int ind = m_animation->getAnimationDataIndex((double)curTime / (double)m_duration);
236  m_curTimeDuration = curTime;
237  if (ind == -1 || indold == -1)
238  return;
239 
240  QVector<QPointF> vec;
241  if(indold == ind)
242  {
243  vec.push_back(m_posOld);
244  vec.push_back(m_pos);
245  }
246  else if(m_animation->direction() == QAbstractAnimation::Backward)
247  {
248  vec.push_back(m_posOld);
249  while(indold < ind)
250  vec.push_back(m_animationRoute[indold++]);
251  vec.push_back(m_pos);
252  }
253  else
254  {
255  vec.push_back(m_posOld);
256  while(indold > ind)
257  vec.push_back(m_animationRoute[indold--]);
258  vec.push_back(m_pos);
259  }
260 
261  size_t size = vec.count();
262 if (size > 1)
263 {
264  transformToDisplayProjection(vec);
265 
266  QPolygonF polf(vec);
267  QPolygon pol = m_matrix.map(polf).toPolygon();
268 
269  QPen pen(Qt::NoBrush, 2);
270  QColor trailColor(Qt::white);
271  pen.setColor(trailColor);
272 
273  AnimationScene* as = (AnimationScene*)scene();
274  as->m_mutex.lock();
275  QPixmap* scenePixmap = as->m_trajectoryPixmap;
276  QPainter painter(scenePixmap);
277  painter.setPen(pen);
278  painter.setCompositionMode(QPainter::CompositionMode_DestinationOut);
279  painter.setBrush(Qt::NoBrush);
280  painter.drawPolyline(pol);
281  painter.end();
282  as->m_mutex.unlock();
283 }
284 }
285 
287 {
288  if (m_animationRoute.empty())
289  return;
290 
291  int ind = m_animation->getAnimationDataIndex((double)m_curTimeDuration / (double)m_duration);
292  if (ind == -1)
293  return;
294 
295  int w = m_display->getDisplayPixmap()->width();
296  int h = m_display->getDisplayPixmap()->height();
297  te::qt::widgets::Canvas canvas(w, h);
298  te::gm::Envelope e = m_display->getExtent();
299  canvas.calcAspectRatio(e.m_llx, e.m_lly, e.m_urx, e.m_ury);
300  canvas.setWindow(e.m_llx, e.m_lly, e.m_urx, e.m_ury);
301  m_matrix = canvas.getMatrix();
302 
303  int count = m_animationRoute.size();
304 
305  QVector<QPointF> vec;
306  if (m_animation->direction() == QAbstractAnimation::Forward)
307  {
308  if (ind > 0)
309  {
310  int i = 0;
311  while (i <= ind)
312  vec.push_back(m_animationRoute[i++]);
313  if (vec.isEmpty() == false && vec.last() != m_pos)
314  vec.push_back(m_pos);
315  }
316  }
317  else
318  {
319  int i = count - 1;
320  while (i >= ind)
321  vec.push_back(m_animationRoute[i--]);
322  if (m_curTimeDuration != m_duration)
323  {
324  if (vec.isEmpty() == false && vec.last() != m_pos)
325  vec.push_back(m_pos);
326  }
327  }
328 
329  size_t size = vec.count();
330  if (size > 1)
331  {
332  transformToDisplayProjection(vec);
333 
334  QPolygonF polf(vec);
335  QPolygon pol = m_matrix.map(polf).toPolygon();
336 
337  QPen pen(Qt::NoBrush, 2);
338  QColor trailColor;
339  if (m_animation->direction() == QAbstractAnimation::Forward)
340  trailColor = m_forwardColor;
341  else
342  trailColor = m_backwardColor;
343 
344  pen.setColor(trailColor);
345 
346  AnimationScene* as = (AnimationScene*)scene();
347  as->m_mutex.lock();
348  QPixmap* scenePixmap = as->m_trajectoryPixmap;
349  QPainter painter(scenePixmap);
350  painter.setPen(pen);
351  painter.setBrush(Qt::NoBrush);
352  painter.drawPolyline(pol);
353  painter.end();
354  as->m_mutex.unlock();
355  }
356  m_display->update();
357 }
358 
360 {
361  QPoint pos = getPosInDeviceCoordinate();
362 
363  if (m_doIconRotate)
364  {
365  double xScale = -1.;
366  double yScale = -1.;
367  double angle = 0.;
368  int ind = m_animation->getAnimationDataIndex((double)m_curTimeDuration / (double)m_duration);
369 
370  if (ind == -1)
371  return;
372 
373  QVector<QPointF> vec;
374  if (m_animation->direction() == QAbstractAnimation::Forward)
375  {
376  if (ind > 0)
377  {
378  vec.push_back(m_animationRoute[ind - 1]); // begin
379  vec.push_back(m_animationRoute[ind]); // end
380  transformToDisplayProjection(vec);
381  }
382  }
383  else
384  {
385  if (ind < (m_animationRoute.count() - 1))
386  {
387  vec.push_back(m_animationRoute[ind]); // begin
388  vec.push_back(m_animationRoute[ind + 1]); // end
389  transformToDisplayProjection(vec);
390  }
391  }
392  if (vec.isEmpty() == false)
393  {
394  double PI = 3.14159265;
395  QPointF p = vec[1] - vec[0]; // end - begin
396  if (p.x() > 0)
397  yScale = 1.;
398 
399  if (p.x() == 0)
400  {
401  if (p.y() >= 0)
402  angle = PI / 2;
403  else
404  angle = -PI / 2;
405  }
406  else if (p.y() == 0)
407  {
408  if (p.x() >= 0)
409  angle = 0;
410  else
411  angle = -PI;
412  }
413  else
414  {
415  angle = atan(p.y() / p.x());
416  if (p.x() < 0)
417  {
418  if (p.y() < 0)
419  angle -= PI;
420  else
421  angle += PI;
422  }
423  }
424  angle *= 180. / PI;
425  }
426 
427  painter->save();
428  painter->translate(pos);
429  painter->scale(xScale, yScale);
430  if (yScale == 1.)
431  angle = -angle;
432  painter->rotate(-angle);
433  painter->translate(-pos);
434  }
435 
436  QRect r = pixmap().rect();
437  r.moveCenter(pos);
438  QRect dr = m_display->rect();
439  if (dr.intersects(r))
440  {
441  if (m_opacity == 255)
442  painter->drawPixmap(r, pixmap());
443  else
444  {
445  QSize size = pixmap().size();
446  int width = size.width();
447  int height = size.height();
448  QImage ima = pixmap().toImage();
449 
450  if (ima.format() == QImage::Format_ARGB32)
451  {
452  for (int i = 0; i < height; ++i)
453  {
454  unsigned char* u = ima.scanLine(i);
455  for (int j = 0; j < width; ++j)
456  {
457  QRgb* v = (QRgb*)(u + (j << 2));
458  if (qAlpha(*v) < 50)
459  *v = qRgba(255, 255, 255, 0);
460  else
461  *v = qRgba(qRed(*v), qGreen(*v), qBlue(*v), m_opacity);
462  }
463  }
464  painter->drawImage(r, ima);
465  }
466  else
467  {
468  QImage img(size, QImage::Format_ARGB32);
469  for (int i = 0; i < height; ++i)
470  {
471  unsigned char* u = ima.scanLine(i);
472  unsigned char* uu = img.scanLine(i);
473 
474  for (int j = 0; j < width; ++j)
475  {
476  QRgb* v = (QRgb*)(u + (j << 2));
477  QRgb* uv = (QRgb*)(uu + (j << 2));
478  if (qAlpha(*v) < 50)
479  *uv = qRgba(255, 255, 255, 0);
480  else
481  *uv = qRgba(qRed(*v), qGreen(*v), qBlue(*v), m_opacity);
482  }
483  }
484  painter->drawImage(r, img);
485  }
486  }
487  }
488 
489  if (m_doIconRotate)
490  painter->restore();
491 }
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.
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 PI
Definition: Canvas.h:29
QPixmap * m_trajectoryPixmap
QPixmap where all the trajectory item are drawn.
Point * getPointN(std::size_t i) const
It returns the specified point in this LineString.
Definition: LineString.cpp:323
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
const double & getLowerLeftY() const
It returns a constant refernce to the y coordinate of the lower left corner.
Definition: Envelope.h:400
double getWidth() const
It returns the envelope width.
Definition: Envelope.h:443
A widget to control the display of a set of layers.
Definition: MapDisplay.h:66
void draw()
Draw the trajectory long trail. It draws the beginning until the current time. The beginning depends ...
QMatrix getMatrix()
It returns the matrix.
Definition: Canvas.cpp:2123
void erase(const unsigned int &curTime)
erase a piece of tracktrajectory trail.
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).
Definition: Canvas.cpp:147
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
This file defines a class for a Animation Scene.
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
const double & getY() const
It returns the Point y-coordinate value.
Definition: Point.h:150
void setPoint(std::size_t i, const double &x, const double &y)
It sets the value of the specified point.
Definition: LineString.cpp:353
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:41
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...
Definition: Canvas.cpp:160
QMutex m_mutex
To not use m_trajectoryPixmap simultaneously.
URI C++ Library.
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
A canvas built on top of Qt.
Definition: Canvas.h:54
This file defines a class for a Trajectory Animation.
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
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.
Definition: Envelope.h:390
An abstract class for Animation Item.
Definition: AnimationItem.h:62
virtual ~TrajectoryItem()
Destructor It destructs a Trajectory Icon Item.
This class allows to add multiple trajectories and temporal image.
double getHeight() const
It returns the envelope height.
Definition: Envelope.h:448
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:136
void transform(int srid)
It converts the coordinate values of the linestring to the new spatial reference system.
Definition: LineString.cpp:181