All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MapItem.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2014-2014 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file MapItem.cpp
22 
23  \brief
24 
25  \ingroup layout
26 */
27 
28 // TerraLib
29 #include "MapItem.h"
30 #include "Context.h"
31 #include "AbstractScene.h"
32 #include "ItemModelObservable.h"
33 #include "ItemObserver.h"
34 #include "ItemController.h"
35 #include "../../../color/RGBAColor.h"
36 #include "../../../../qt/widgets/Utils.h"
37 #include "../../../../geometry/Envelope.h"
38 #include "../../../../common/STLUtils.h"
39 #include "../../../../qt/widgets/canvas/Canvas.h"
40 #include "../../../../dataaccess/utils/Utils.h"
41 #include "../../../../dataaccess/dataset/ObjectIdSet.h"
42 #include "../../../../qt/widgets/canvas/MultiThreadMapDisplay.h"
43 #include "../../../../common/TreeItem.h"
44 #include "../../../../srs/Converter.h"
45 #include "../../../../qt/widgets/tools/ZoomWheel.h"
46 #include "../../../../maptools/Utils.h"
47 #include "MapController.h"
48 #include "../../../../qt/widgets/tools/Pan.h"
49 #include "../../../../qt/widgets/tools/ZoomArea.h"
50 #include "../../../../qt/widgets/tools/ZoomClick.h"
51 #include "LayoutConfig.h"
52 #include "ItemUtils.h"
53 
54 // STL
55 #include <vector>
56 #include <memory>
57 
58 // Qt
59 #include <QCursor>
60 #include <QPixmap>
61 #include <QMessageBox>
62 #include <QWidget>
63 #include <QDropEvent>
64 #include <QBoxLayout>
65 #include <QGroupBox>
66 #include <QVBoxLayout>
67 #include <QLabel>
68 #include <QPointer>
69 #include <QDebug>
70 #include <QApplication>
71 #include <QGraphicsSceneMouseEvent>
72 #include <QStyleOptionGraphicsItem>
73 #include <QEvent>
74 
76  QGraphicsProxyWidget(0),
77  ItemObserver(controller, o),
78  m_mapDisplay(0),
79  m_grabbedByWidget(false),
80  m_treeItem(0),
81  m_tool(0)
82 {
83  this->setFlags(QGraphicsItem::ItemIsMovable
84  | QGraphicsItem::ItemIsSelectable
85  | QGraphicsItem::ItemSendsGeometryChanges
86  | QGraphicsItem::ItemIgnoresTransformations);
87 
88  setAcceptDrops(true);
89 
90  Utils* utils = Context::getInstance()->getUtils();
91  te::gm::Envelope box = utils->viewportBox(m_model->getBox());
92 
94  m_mapDisplay->setAcceptDrops(true);
97  m_mapDisplay->setMouseTracking(true);
98 
99  connect(m_mapDisplay,SIGNAL(drawLayersFinished(const QMap<QString, QString>&)),
100  this,SLOT(onDrawLayersFinished(const QMap<QString, QString>&)));
101 
103  m_mapDisplay->installEventFilter(zoom);
104 
105  setWidget(m_mapDisplay);
106 
107  QGraphicsItem* item = this;
109 
110  m_mapDisplay->show();
111 }
112 
114 {
115  if(m_tool)
116  {
117  delete m_tool;
118  m_tool = 0;
119  }
120 
121  if(m_mapDisplay)
122  {
123  setWidget(0);
124  delete m_mapDisplay;
125  m_mapDisplay = 0;
126  }
127 }
128 
130 {
131  if(!m_model)
132  return;
133 
134  te::color::RGBAColor** rgba = context.getPixmap();
135 
136  if(!rgba)
137  return;
138 
139  Utils* utils = Context::getInstance()->getUtils();
140 
141  if(!utils)
142  return;
143 
144  te::gm::Envelope box = utils->viewportBox(m_model->getBox());
145 
146  if(!box.isValid())
147  return;
148 
149  QPixmap pixmap;
150  QImage* img = 0;
151 
152  if(rgba)
153  {
154  img = te::qt::widgets::GetImage(rgba, box.getWidth(), box.getHeight());
155  pixmap = QPixmap::fromImage(*img);
156  }
157 
158  te::common::Free(rgba, box.getHeight());
159  if(img)
160  delete img;
161 
162  setPixmap(pixmap);
163  update();
164 }
165 
166 void te::layout::MapItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget /*= 0 */ )
167 {
168  QGraphicsProxyWidget::paint(painter, option, widget);
169 
170  if(!m_pixmap.isNull())
171  {
172  QRectF boundRect;
173  boundRect = boundingRect();
174 
175  painter->save();
176  painter->translate( -boundRect.bottomLeft().x(), -boundRect.topRight().y() );
177  painter->drawPixmap(boundRect, m_pixmap, QRectF( 0, 0, m_pixmap.width(), m_pixmap.height() ));
178  painter->restore();
179  }
180 
181  //Draw Selection
182  if (option->state & QStyle::State_Selected)
183  {
184  drawSelection(painter);
185  }
186 }
187 
188 void te::layout::MapItem::drawSelection( QPainter* painter)
189 {
190  if(!painter)
191  {
192  return;
193  }
194 
195  qreal penWidth = painter->pen().widthF();
196 
197  const qreal adj = penWidth / 2;
198  const QColor fgcolor(255,255,255);
199  const QColor backgroundColor(0,0,0);
200 
201  painter->setPen(QPen(backgroundColor, 0, Qt::SolidLine));
202  painter->setBrush(Qt::NoBrush);
203  painter->drawRect(boundingRect().adjusted(adj, adj, -adj, -adj));
204 
205  painter->setPen(QPen(fgcolor, 0, Qt::DashLine));
206  painter->setBrush(Qt::NoBrush);
207  painter->drawRect(boundingRect().adjusted(adj, adj, -adj, -adj));
208 }
209 
210 void te::layout::MapItem::dropEvent( QGraphicsSceneDragDropEvent * event )
211 {
212  //Copy the map from layer tree
213  Qt::DropActions actions = event->dropAction();
214  if(actions != Qt::CopyAction)
215  return;
216 
217  getMimeData(event->mimeData());
218 
219  QDropEvent dropEvent(QPoint(event->pos().x(), event->pos().y()), event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
220  QApplication::sendEvent(m_mapDisplay, &dropEvent);
221  event->setAccepted(dropEvent.isAccepted());
222 }
223 
224 void te::layout::MapItem::dragEnterEvent( QGraphicsSceneDragDropEvent * event )
225 {
226  //Copy the map from layer tree
227  Qt::DropActions actions = event->dropAction();
228  if(actions != Qt::CopyAction)
229  return;
230 
231  event->acceptProposedAction();
232 }
233 
234 void te::layout::MapItem::dragLeaveEvent( QGraphicsSceneDragDropEvent * event )
235 {
236 }
237 
238 void te::layout::MapItem::dragMoveEvent( QGraphicsSceneDragDropEvent * event )
239 {
240 
241 }
242 
243 void te::layout::MapItem::setPixmap( const QPixmap& pixmap )
244 {
245  m_pixmap = pixmap;
246 
247  if(m_pixmap.isNull())
248  return;
249 
250  Utils* utils = Context::getInstance()->getUtils();
251  QPointF point = pos();
252 
253  ItemModelObservable* model = (ItemModelObservable*)m_controller->getModel();
254  te::gm::Envelope box = model->getBox();
255 
256  //If you modify the boundingRect value, you need to inform Graphics View about it by calling QGraphicsItem::prepareGeometryChange();
257  QGraphicsObject::prepareGeometryChange();
258  setRect(QRectF(0, 0, box.getWidth(), box.getHeight()));
259  update();
260 }
261 
262 void te::layout::MapItem::setRect( QRectF rect )
263 {
264  if (rect.isEmpty() && !rect.isNull())
265  return;
266 
267  m_rect = rect;
268  update(rect);
269 }
270 
272 {
273  QPointF posF = scenePos();
274  qreal valuex = posF.x();
275  qreal valuey = posF.y();
276 
277  te::gm::Coord2D coordinate;
278  coordinate.x = valuex;
279  coordinate.y = valuey;
280 
281  return coordinate;
282 }
283 
284 void te::layout::MapItem::setPos( const QPointF &pos )
285 {
286  QGraphicsItem::setPos(pos);
287 
288  refresh();
289 }
290 
291 void te::layout::MapItem::mouseMoveEvent( QGraphicsSceneMouseEvent * event )
292 {
294  {
295  clearCurrentTool();
296  QGraphicsItem::mouseMoveEvent(event);
297  }
298  else
299  {
300  QMouseEvent mouseEvent(QEvent::MouseMove,QPoint(event->pos().x(), event->pos().y()),
301  event->button(),event->buttons(), event->modifiers());
302  QApplication::sendEvent(m_mapDisplay, &mouseEvent);
303  event->setAccepted(mouseEvent.isAccepted());
304  }
305 }
306 
307 void te::layout::MapItem::mousePressEvent( QGraphicsSceneMouseEvent * event )
308 {
310  {
311  clearCurrentTool();
312  QGraphicsItem::mousePressEvent(event);
313  }
314  else
315  {
316  QMouseEvent mouseEvent(QEvent::MouseButtonPress,QPoint(event->pos().x(), event->pos().y()),
317  event->button(),event->buttons(), event->modifiers());
318  QApplication::sendEvent(m_mapDisplay, &mouseEvent);
319  event->setAccepted(mouseEvent.isAccepted());
320  }
321 }
322 
323 void te::layout::MapItem::mouseReleaseEvent( QGraphicsSceneMouseEvent * event )
324 {
326  {
327  clearCurrentTool();
328  QGraphicsItem::mouseReleaseEvent(event);
329  }
330  else
331  {
332  QMouseEvent mouseEvent(QEvent::MouseButtonRelease,QPoint(event->pos().x(), event->pos().y()),
333  event->button(),event->buttons(), event->modifiers());
334  QApplication::sendEvent(m_mapDisplay, &mouseEvent);
335  event->setAccepted(mouseEvent.isAccepted());
336  }
337 
338  refresh();
339 }
340 
341 void te::layout::MapItem::resizeEvent( QGraphicsSceneResizeEvent * event )
342 {
343  QGraphicsProxyWidget::resizeEvent(event);
344 }
345 
346 void te::layout::MapItem::getMimeData( const QMimeData* mime )
347 {
348  QString s = mime->data("application/x-terralib;value=\"DraggedItems\"").constData();
349  unsigned long v = s.toULongLong();
350  std::vector<te::qt::widgets::AbstractTreeItem*>* draggedItems = reinterpret_cast<std::vector<te::qt::widgets::AbstractTreeItem*>*>(v);
351 
352  if(draggedItems->empty())
353  return;
354 
355  m_treeItem = draggedItems->operator[](0);
356 }
357 
358 std::list<te::map::AbstractLayerPtr> te::layout::MapItem::getVisibleLayers()
359 {
360  std::list<te::map::AbstractLayerPtr> visibleLayers;
361 
362  if(!m_treeItem)
363  return visibleLayers;
364 
365  te::map::AbstractLayerPtr al = m_treeItem->getLayer();
366 
367  if(al.get() == 0)
368  return visibleLayers;
369 
370  std::list<te::map::AbstractLayerPtr> vis;
371  te::map::GetVisibleLayers(al, vis);
372  // remove folders
373  std::list<te::map::AbstractLayerPtr>::iterator vit;
374  for(vit = vis.begin(); vit != vis.end(); ++vit)
375  {
376  if((*vit)->getType() == "DATASETLAYER" ||
377  (*vit)->getType() == "QUERYLAYER" ||
378  (*vit)->getType() == "RASTERLAYER")
379  {
380  visibleLayers.push_front(*vit);
381  }
382  }
383 
384  return visibleLayers;
385 }
386 
388 {
390 
391  if(!m_treeItem)
392  return layer;
393 
394  layer = m_treeItem->getLayer();
395 
396  return layer;
397 }
398 
399 void te::layout::MapItem::onDrawLayersFinished( const QMap<QString, QString>& errors )
400 {
401  if(!errors.empty())
402  return;
403 
404  te::map::AbstractLayerPtr layer = getLayer();
405 
406  if(!m_controller)
407  return;
408 
409  MapController* controller = dynamic_cast<MapController*>(m_controller);
410  if(controller)
411  {
412  bool result = controller->refreshLayer(layer);
413  if(result)
414  {
415  redraw();
416  }
417  }
418 }
419 
421 {
422  QGraphicsItem::setZValue(z);
423  setZValueItem(z);
424 
425 }
426 
428 {
429  return QGraphicsItem::zValue();
430 }
431 
433 {
434  if(m_tool)
435  {
436  m_mapDisplay->removeEventFilter(m_tool);
437  delete m_tool;
438  m_tool = 0;
439  }
440 
441  m_tool = tool;
442 
443  m_mapDisplay->installEventFilter(m_tool);
444 }
445 
447 {
448  if(m_tool)
449  {
450  m_mapDisplay->removeEventFilter(m_tool);
451 
452  delete m_tool;
453  m_tool = 0;
454  }
455 
456  setCursor(Qt::ArrowCursor);
457 }
458 
460 {
461  if(mode == TypeMapPan)
462  {
463  te::qt::widgets::Pan* pan = new te::qt::widgets::Pan(m_mapDisplay, Qt::OpenHandCursor, Qt::ClosedHandCursor);
464  setCurrentTool(pan);
465  }
466  if(mode == TypeMapZoomIn)
467  {
468  //Zoom In
469  std::string icon_path_zoom_area = LAYOUT_IMAGES_PNG"/layout-map-zoom-in";
470  QCursor zoomAreaCursor(QIcon::fromTheme(icon_path_zoom_area.c_str()).pixmap(QSize(10,10)));
471  te::qt::widgets::ZoomArea* zoomArea = new te::qt::widgets::ZoomArea(m_mapDisplay, zoomAreaCursor);
472  setCurrentTool(zoomArea);
473  }
474  if(mode == TypeMapZoomOut)
475  {
476  //Zoom Out
477  std::string icon_path_zoom_out = LAYOUT_IMAGES_PNG"/layout-map-zoom-out";
478  QCursor zoomOutCursor(QIcon::fromTheme(icon_path_zoom_out.c_str()).pixmap(QSize(10,10)));
479  te::qt::widgets::ZoomClick* zoomOut = new te::qt::widgets::ZoomClick(m_mapDisplay, zoomOutCursor, 2.0, te::qt::widgets::Zoom::Out);
480  setCurrentTool(zoomOut);
481  }
482 }
virtual void updateObserver(ContextItem context)
Definition: MapItem.cpp:129
virtual ~MapItem()
Definition: MapItem.cpp:113
virtual void getMimeData(const QMimeData *mime)
Definition: MapItem.cpp:346
double y
y-coordinate.
Definition: Coord2D.h:87
void onDrawLayersFinished(const QMap< QString, QString > &errors)
Definition: MapItem.cpp:399
te::layout::Observable * m_model
Definition: ItemObserver.h:82
virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event)
Definition: MapItem.cpp:224
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
Definition: MapItem.cpp:291
virtual void setBackgroundColor(const QColor &color)
Sets the map display background color.
Definition: MapDisplay.cpp:335
double x
x-coordinate.
Definition: Coord2D.h:86
This class implements a concrete tool to geographic zoom in operation using a boundary rectangle...
Definition: ZoomArea.h:49
virtual void changeCurrentTool(LayoutMode mode)
Definition: MapItem.cpp:459
virtual te::gm::Envelope getBox()=0
virtual void drawSelection(QPainter *painter)
Definition: MapItem.cpp:188
virtual void setRect(QRectF rect)
Definition: MapItem.cpp:262
double getWidth() const
It returns the envelope width.
Definition: Envelope.h:443
virtual void setPos(const QPointF &pos)
Definition: MapItem.cpp:284
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
void setPixmap(const QPixmap &pixmap)
Definition: MapItem.cpp:243
This class defines an interface for objects that can receive application events and respond to them...
Definition: AbstractTool.h:62
LayoutMode
Enum LayoutMode. This is the enumeration of the components types.
Definition: EnumMode.h:38
virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
Definition: MapItem.cpp:234
void setZValue(qreal z)
Definition: MapItem.cpp:420
te::color::RGBAColor ** getPixmap()
Definition: ContextItem.cpp:82
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0)
Definition: MapItem.cpp:166
void Free(std::vector< T * > *v)
This function can be applied to a pointer to a vector of pointers.
Definition: STLUtils.h:131
This class implements a concrete tool to geographic pan operation.
Definition: Pan.h:49
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
virtual void insertItem(ItemObserver *item)=0
virtual void setResizeInterval(int msec)
Sets the timeout interval in milliseconds to redraw on resize event.
Definition: MapDisplay.cpp:236
void setCurrentTool(te::qt::widgets::AbstractTool *tool)
Definition: MapItem.cpp:432
Utils * getUtils()
Definition: Context.cpp:126
virtual void dropEvent(QGraphicsSceneDragDropEvent *event)
Definition: MapItem.cpp:210
This class implements a concrete tool to geographic zoom operation using the mouse click...
Definition: ZoomClick.h:49
virtual te::gm::Envelope viewportBox(te::gm::Envelope box)
Definition: Utils.cpp:164
std::list< te::map::AbstractLayerPtr > getVisibleLayers()
Definition: MapItem.cpp:358
virtual te::gm::Coord2D getPosition()
Definition: MapItem.cpp:271
virtual void resizeEvent(QGraphicsSceneResizeEvent *event)
Definition: MapItem.cpp:341
void clearCurrentTool()
Definition: MapItem.cpp:446
TEQTWIDGETSEXPORT QImage * GetImage(te::color::RGBAColor **img, int width, int height)
It creates a QImage from an RGBA color array.
Definition: Utils.cpp:63
This class implements a concrete tool to geographic zoom operation using the mouse wheel...
Definition: ZoomWheel.h:49
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
Definition: RGBAColor.h:57
TELAYOUTEXPORT bool isCurrentMapTools()
Definition: ItemUtils.cpp:169
AbstractScene * getScene()
Definition: Context.cpp:61
virtual te::gm::Envelope getBox()
virtual int getZValueItem()
Definition: MapItem.cpp:427
te::map::AbstractLayerPtr getLayer()
Definition: MapItem.cpp:387
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
Definition: MapItem.cpp:323
static Context * getInstance()
This function is called to create an instance of the class.
Definition: Context.cpp:46
virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event)
Definition: MapItem.cpp:238
virtual bool refreshLayer(te::map::AbstractLayerPtr layer)
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
double getHeight() const
It returns the envelope height.
Definition: Envelope.h:448
bool isValid() const
It tells if the rectangle is valid or not.
Definition: Envelope.h:438
A multi thread Qt4 widget to control the display of a set of layers.
MapItem(ItemController *controller, Observable *o)
Definition: MapItem.cpp:75
TEMAPEXPORT void GetVisibleLayers(const std::list< te::map::AbstractLayerPtr > &layers, std::list< te::map::AbstractLayerPtr > &visibleLayers)
It gets the visible layers of the given layer list.
Definition: Utils.cpp:248
te::qt::widgets::MultiThreadMapDisplay * m_mapDisplay
Definition: MapItem.h:116
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event)
Definition: MapItem.cpp:307