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