All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MapDisplay.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2001-2009 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 terralib/qt/widgets/canvas/MapDisplay.cpp
22 
23  \brief A Qt4 widget to control the display of a set of layers.
24 */
25 
26 // TerraLib
27 #include "../../../common/STLUtils.h"
28 #include "../../../geometry/Coord2D.h"
29 #include "../../../geometry/Envelope.h"
30 #include "../../../maptools/AbstractLayer.h"
31 #include "../../../maptools/Utils.h"
32 #include "../../../qt/widgets/layer/explorer/AbstractTreeItem.h"
33 #include "../utils/ScopedCursor.h"
34 #include "Canvas.h"
35 #include "MapDisplay.h"
36 
37 // Qt
38 #include <QMimeData>
39 #include <QPaintDevice>
40 #include <QResizeEvent>
41 #include <QTimer>
42 
43 te::qt::widgets::MapDisplay::MapDisplay(const QSize& size, QWidget* parent, Qt::WindowFlags f)
44  : QWidget(parent, f),
45  te::map::MapDisplay(),
46  m_displayPixmap(new QPixmap(size)),
47  m_draftPixmap(new QPixmap(size)),
48  m_backgroundColor(Qt::white),
49  m_resizePolicy(te::qt::widgets::MapDisplay::Fixed),
50  m_timer(new QTimer(this)),
51  m_interval(200),
52  m_isDrawing(false)
53 {
54  m_timer->setSingleShot(true);
55  connect(m_timer, SIGNAL(timeout()), this, SLOT(onResizeTimeout()));
56 
58  m_draftPixmap->fill(Qt::transparent);
59 
60  resize(size);
61 }
62 
64 {
65  delete m_displayPixmap;
66  delete m_draftPixmap;
67 
68  std::map<te::map::AbstractLayer*, te::qt::widgets::Canvas*>::iterator it;
69  for(it = m_layerCanvasMap.begin(); it != m_layerCanvasMap.end(); ++it)
70  delete it->second;
71 
72  m_layerCanvasMap.clear();
73 }
74 
76 {
77  Qt::DropActions actions = e->dropAction();
78  if(actions != Qt::CopyAction)
79  return;
80 
81  const QMimeData* mime = e->mimeData();
82  QString s = mime->data("application/x-terralib;value=\"DraggedItems\"").constData();
83  if(s.isEmpty())
84  return;
85 
86  e->accept();
87  return;
88 }
89 
91 {
92  const QMimeData* mime = e->mimeData();
93  QString s = mime->data("application/x-terralib;value=\"DraggedItems\"").constData();
94  unsigned long v = s.toULongLong();
95  std::vector<te::qt::widgets::AbstractTreeItem*>* draggedItems = reinterpret_cast<std::vector<AbstractTreeItem*>*>(v);
96  te::qt::widgets::AbstractTreeItem* item = draggedItems->operator[](0);
98  changeData(al);
99 }
100 
102 {
103  // limpe todos os canvas antes usados
104  std::map<te::map::AbstractLayer*, te::qt::widgets::Canvas*>::iterator it;
105  for(it = m_layerCanvasMap.begin(); it != m_layerCanvasMap.end(); ++it)
106  {
107  te::map::Canvas* c = getCanvas(it->first);
108  delete c;
109  }
110  m_layerCanvasMap.clear();
111  m_srid = nsrid;
112 
113  if(al.get() == 0)
114  return;
115 
116  std::list<te::map::AbstractLayerPtr> vis, visibleLayers;
117  te::map::GetVisibleLayers(al, vis);
118  // remove folders
119  std::list<te::map::AbstractLayerPtr>::iterator vit;
120  for(vit = vis.begin(); vit != vis.end(); ++vit)
121  {
122  if((*vit)->getType() == "DATASETLAYER" ||
123  (*vit)->getType() == "QUERYLAYER" ||
124  (*vit)->getType() == "RASTERLAYER")
125  {
126  visibleLayers.push_front(*vit);
127  }
128  }
129 
130  setLayerList(visibleLayers);
131 
132  if(m_srid == TE_UNKNOWN_SRS)
133  {
134  // calcule SRID e extent
135  te::gm::Envelope envelope;
136 
137  std::list<te::map::AbstractLayerPtr>::iterator lit;
138  for(lit = visibleLayers.begin(); lit != visibleLayers.end(); ++lit)
139  {
140  te::gm::Envelope env = (*lit)->getExtent();
141 
142  int srid = (*lit)->getSRID();
143  if(m_srid <= 0)
144  m_srid = srid;
145  if(srid != m_srid)
146  env.transform(srid, m_srid);
147 
148  envelope.Union(env);
149  }
150  setExtent(envelope);
151  }
152 }
153 
155 {
156  te::map::MapDisplay::setExtent(e, doRefresh);
157 
158  std::map<te::map::AbstractLayer*, te::qt::widgets::Canvas*>::iterator it;
159  for(it = m_layerCanvasMap.begin(); it != m_layerCanvasMap.end(); ++it)
160  {
161  te::qt::widgets::Canvas* canvas = it->second;
162  canvas->calcAspectRatio(m_extent.m_llx, m_extent.m_lly, m_extent.m_urx, m_extent.m_ury, m_hAlign, m_vAlign);
163  canvas->setWindow(m_extent.m_llx, m_extent.m_lly, m_extent.m_urx, m_extent.m_ury);
164  canvas->clear();
165  e = m_extent;
166  }
167 
168  if(doRefresh)
169  refresh();
170 
171  emit extentChanged();
172 }
173 
175 {
176  ScopedCursor cursor(Qt::WaitCursor);
177 
178  m_isDrawing = true;
179 
180  // Cleaning...
181  m_displayPixmap->fill(m_backgroundColor);
182 
183  QPainter painter(m_displayPixmap);
184 
185  std::list<te::map::AbstractLayerPtr>::iterator it;
186 
187  for(it = m_layerList.begin(); it != m_layerList.end(); ++it) // for each layer
188  draw(it->get(), painter);
189 
190  m_isDrawing = false;
191 
192  update();
193 }
194 
196 {
197  return static_cast<unsigned int>(width());
198 }
199 
201 {
202  return static_cast<unsigned int>(height());
203 }
204 
206 {
207  return static_cast<double>(widthMM());
208 }
209 
211 {
212  return static_cast<double>(heightMM());
213 }
214 
215 void te::qt::widgets::MapDisplay::setSRID(const int& srid, bool doRefresh)
216 {
217  te::map::MapDisplay::setSRID(srid, doRefresh);
218  emit displaySridChanged();
219 }
220 
222 {
223  return m_displayPixmap;
224 }
225 
227 {
228  return m_draftPixmap;
229 }
230 
232 {
233  m_resizePolicy = policy;
234 }
235 
237 {
238  m_interval = msec;
239 }
240 
242 {
243  // Checking the visibility...
244  if(layer->getVisibility() == te::map::NOT_VISIBLE)
245  return;
246 
247  // Recursive draw
248  for(std::size_t i = 0; i < layer->getChildrenCount(); ++i)
249  draw(boost::dynamic_pointer_cast<te::map::AbstractLayer>(layer->getChild(i)).get(), painter);
250 
251  // Retrieves a canvas to current layer
252  te::qt::widgets::Canvas* canvas = getCanvas(layer);
253 
254  // Draw the current layer
255  layer->draw(canvas, m_extent, m_srid);
256 
257  // Compose the result
258  QPaintDevice* device = canvas->getDevice();
259 
260  if(device->devType() == QInternal::Pixmap)
261  painter.drawPixmap(0, 0, *static_cast<QPixmap*>(device));
262  else if(device->devType() == QInternal::Image)
263  painter.drawImage(0, 0, *static_cast<QImage*>(device));
264 }
265 
267 {
268  // Is there a canvas associated with the given layer?
269  std::map<te::map::AbstractLayer*, te::qt::widgets::Canvas*>::iterator it = m_layerCanvasMap.find(layer);
270  if(it != m_layerCanvasMap.end())
271  return it->second;
272 
273  // else, create one!
274  te::qt::widgets::Canvas* canvas = new te::qt::widgets::Canvas(m_displayPixmap->width(), m_displayPixmap->height(), type);
275  canvas->calcAspectRatio(m_extent.m_llx, m_extent.m_lly, m_extent.m_urx, m_extent.m_ury, m_hAlign, m_vAlign);
276  canvas->setWindow(m_extent.m_llx, m_extent.m_lly, m_extent.m_urx, m_extent.m_ury);
277  canvas->clear();
278 
279  m_layerCanvasMap[layer] = canvas;
280 
281  return canvas;
282 }
283 
285 {
286  std::map<te::map::AbstractLayer*, te::qt::widgets::Canvas*>::iterator it;
287  for(it = m_layerCanvasMap.begin(); it != m_layerCanvasMap.end(); ++it)
288  it->second->resize(m_displayPixmap->width(), m_displayPixmap->height());
289 }
290 
292 {
293  QPainter painter(this);
294  painter.drawPixmap(0, 0, *m_displayPixmap);
295 
296  emit displayPaintEvent(&painter);
297 
298  painter.drawPixmap(0, 0, *m_draftPixmap);
299 }
300 
302 {
303  QWidget::resizeEvent(e);
304 
305  if(m_interval == 0)
306  onResizeTimeout();
307  else
308  {
309  // Stores the old size
310  if(!m_oldSize.isValid())
311  e->oldSize().isValid() ? m_oldSize = e->oldSize() : m_oldSize = e->size();
312 
313  // Setups the timer controller
314  m_timer->start(m_interval);
315  }
316 }
317 
318 QPointF te::qt::widgets::MapDisplay::transform(const QPointF& p)
319 {
320  if(m_layerCanvasMap.empty())
321  return QPointF();
322 
323  te::qt::widgets::Canvas* canvas = m_layerCanvasMap.begin()->second;
324  if(canvas == 0)
325  return QPointF();
326 
327  return canvas->getMatrix().inverted().map(p);
328 }
329 
331 {
332  return m_backgroundColor;
333 }
334 
336 {
337  m_backgroundColor = color;
338 }
339 
341 {
342  return m_isDrawing;
343 }
344 
346 {
347  // Rebulding the map display pixmaps
348  delete m_displayPixmap;
349  m_displayPixmap = new QPixmap(size());
350  m_displayPixmap->fill(m_backgroundColor);
351 
352  delete m_draftPixmap;
353  m_draftPixmap = new QPixmap(size());
354  m_draftPixmap->fill(Qt::transparent);
355 
356  // Resizing all canvas
357  resizeAllCanvas();
358 
359  // Adjust the extent based on resize policy
360  adjustExtent(m_oldSize, size());
361 
362  // Invalidate old size
363  m_oldSize = QSize();
364 }
365 
366 void te::qt::widgets::MapDisplay::adjustExtent(const QSize& oldSize, const QSize& size)
367 {
368  if(!m_extent.isValid())
369  {
370  update();
371  return;
372  }
373 
374  te::gm::Envelope e = m_extent;
375  //if(m_resizePolicy == te::qt::widgets::MapDisplay::Fixed)
376  // setExtent(e);
377  if(m_resizePolicy == te::qt::widgets::MapDisplay::Fixed)
378  {
379  setExtent(e);
380  return;
381  }
382 
383  double widthW = e.m_urx - e.m_llx;
384  double heightW = e.m_ury - e.m_lly;
385 
386  double newWidthW = (size.width() * widthW) / oldSize.width();
387  double newHeightW = (size.height() * heightW) / oldSize.height();
388 
389  switch(m_resizePolicy)
390  {
392  {
393  e.m_urx = e.m_llx + newWidthW;
394  e.m_lly = e.m_ury - newHeightW;
395  }
396  break;
397 
399  {
400  te::gm::Coord2D center = e.getCenter();
401  e.m_llx = center.x - (newWidthW * 0.5);
402  e.m_urx = center.x + (newWidthW * 0.5);
403  e.m_lly = center.y - (newHeightW * 0.5);
404  e.m_ury = center.y + (newHeightW * 0.5);
405  }
406  break;
407 
408  default:
409  break;
410  }
411 
412  setExtent(e);
413 }
void clear()
It clears the canvas content and fills with the background color.
Definition: Canvas.cpp:222
A canvas built on top of Qt.
const TreeItemPtr & getChild(std::size_t i) const
It returns the n-th child.
Definition: TreeItem.cpp:75
unsigned int getWidth() const
It returns the MapDisplay current width in pixels.
Definition: MapDisplay.cpp:195
double y
y-coordinate.
Definition: Coord2D.h:87
std::size_t getChildrenCount() const
It returns the number of children of this node.
Definition: TreeItem.cpp:183
This is the base class for layers.
Definition: AbstractLayer.h:76
virtual void refresh()
It updates the contents in the map display.
Definition: MapDisplay.cpp:174
virtual void setBackgroundColor(const QColor &color)
Sets the map display background color.
Definition: MapDisplay.cpp:335
virtual te::qt::widgets::Canvas * getCanvas(te::map::AbstractLayer *layer, int type=QInternal::Pixmap)
It retrieves an associated canvas to the given layer.
Definition: MapDisplay.cpp:266
double x
x-coordinate.
Definition: Coord2D.h:86
double getWidthMM() const
It returns the MapDisplay current width in millimeters.
Definition: MapDisplay.cpp:205
double getHeightMM() const
It returns the MapDisplay current height in millimeters.
Definition: MapDisplay.cpp:210
virtual void paintEvent(QPaintEvent *e)
It assembles the final image and draws the widget.
Definition: MapDisplay.cpp:291
virtual void onResizeTimeout()
Definition: MapDisplay.cpp:345
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
The class that represents an item in a LayerTreeModel.
virtual void dragEnterEvent(QDragEnterEvent *)
Definition: MapDisplay.cpp:75
virtual void clear()=0
It clears the canvas content and fills with the background color.
virtual Visibility getVisibility() const
It returns the layer visibility.
A widget to control the display of a set of layers.
Definition: MapDisplay.h:65
A Qt4 widget to control the display of a set of layers.
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
QPixmap * m_displayPixmap
This pixmap will be the result of all canvas pixmap drawing, i. e., the result of drawing all visible...
Definition: MapDisplay.h:281
virtual void draw(Canvas *canvas, const te::gm::Envelope &bbox, int srid)=0
It draws the layer geographic objects in the given canvas using the informed SRS. ...
virtual void resizeAllCanvas()
It resizes all canvas of map display.
Definition: MapDisplay.cpp:284
void Union(const Envelope &rhs)
It updates the envelop with coordinates of another envelope.
Definition: Envelope.h:555
virtual te::map::AbstractLayerPtr getLayer() const =0
QMatrix getMatrix()
It returns the matrix.
Definition: Canvas.cpp:2123
virtual void setExtent(te::gm::Envelope &e, bool doRefresh=true)
It sets the world visible area and refreshes the contents in the map display.
Definition: MapDisplay.cpp:68
Coord2D getCenter() const
It returns the rectangle's center coordinate.
Definition: Envelope.cpp:49
MapDisplay()
It initializes a new MapDisplay.
Definition: MapDisplay.cpp:30
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
virtual QPointF transform(const QPointF &p)
Transforms the given point, in screen coordinates, to a point in world coordinates.
Definition: MapDisplay.cpp:318
virtual void setResizePolicy(const ResizePolicy &policy)
Sets the resize policy to this map display.
Definition: MapDisplay.cpp:231
QPaintDevice * getDevice() const
It returns the internal device used to draw geographical objects.
Definition: Canvas.cpp:2099
virtual void dropEvent(QDropEvent *)
Definition: MapDisplay.cpp:90
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:44
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
virtual void setSRID(const int &srid, bool doRefresh=true)
It sets a new Spatial Reference System to be used by the Map Display.
Definition: MapDisplay.cpp:78
virtual void setResizeInterval(int msec)
Sets the timeout interval in milliseconds to redraw on resize event.
Definition: MapDisplay.cpp:236
virtual void changeData(te::map::AbstractLayerPtr, int nsrid=TE_UNKNOWN_SRS)
Definition: MapDisplay.cpp:101
virtual void draw(te::map::AbstractLayer *layer, QPainter &painter)
It displays the given layer.
Definition: MapDisplay.cpp:241
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
A canvas built on top of Qt.
Definition: Canvas.h:54
ResizePolicy
Defines the resize policy for map display.
Definition: MapDisplay.h:76
A canvas is an abstraction of a drawing area.
Definition: Canvas.h:91
unsigned int getHeight() const
It returns the MapDisplay current height in pixels.
Definition: MapDisplay.cpp:200
virtual QPixmap * getDraftPixmap() const
It returns the map display draft pixmap.
Definition: MapDisplay.cpp:226
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
virtual void adjustExtent(const QSize &oldSize, const QSize &size)
It adjusts the map display extent based on resize policy.
Definition: MapDisplay.cpp:366
bool isDrawing() const
Returns if the map display is drawing.
Definition: MapDisplay.cpp:340
virtual void resizeEvent(QResizeEvent *e)
This event handler receives widget resize events wich are passed in the event parameter.
Definition: MapDisplay.cpp:301
QPixmap * m_draftPixmap
The draft pixmap can be used to draw some feedback on map display.
Definition: MapDisplay.h:282
virtual void setSRID(const int &srid, bool doRefresh=true)
It sets a new Spatial Reference System to be used by the Map Display.
Definition: MapDisplay.cpp:215
virtual QColor getBackgroundColor()
Gets the map display background color.
Definition: MapDisplay.cpp:330
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
void transform(int oldsrid, int newsrid)
It will transform the coordinates of the Envelope from the old SRS to the new one.
Definition: Envelope.cpp:90
QColor m_backgroundColor
Background color.
Definition: MapDisplay.h:283
virtual void setExtent(te::gm::Envelope &e, bool doRefresh=true)
It sets the world visible area and refreshes the contents in the map display.
Definition: MapDisplay.cpp:154
virtual ~MapDisplay()
Destructor.
Definition: MapDisplay.cpp:63
An object that when created shows a cursor during its scope.
Definition: ScopedCursor.h:48
QTimer * m_timer
Timer to execute redraw on resize action.
Definition: MapDisplay.h:286
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
virtual QPixmap * getDisplayPixmap() const
It returns the map display pixmap.
Definition: MapDisplay.cpp:221