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) 2008-2013 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of TerraView - A GIS Application.
4 
5  TerraView is free software: you can redistribute it and/or modify
6  it under the terms of the GNU 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  TerraView 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 General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with TerraLib Code Editor. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@dpi.inpe.br>.
18  */
19 
20 /*!
21  \file terralib/qt/af/connectors/MapDisplay.cpp
22 
23  \brief A connector of the te::qt::widgets::MapDisplay class to the Application Framework.
24 */
25 
26 // TerraLib
27 #include "../../../dataaccess/dataset/DataSet.h"
28 #include "../../../dataaccess/dataset/ObjectId.h"
29 #include "../../../dataaccess/dataset/ObjectIdSet.h"
30 #include "../../../dataaccess/utils/Utils.h"
31 #include "../../../geometry/Geometry.h"
32 #include "../../../geometry/Envelope.h"
33 #include "../../../geometry/Utils.h"
34 #include "../../../maptools/Utils.h"
35 #include "../../../srs/Config.h"
36 #include "../../widgets/canvas/Canvas.h"
37 #include "../../widgets/canvas/EyeBirdMapDisplayWidget.h"
38 #include "../../widgets/canvas/MapDisplay.h"
39 #include "../../widgets/canvas/ZoomInMapDisplayWidget.h"
40 #include "../../widgets/tools/AbstractTool.h"
41 #include "../../widgets/tools/ZoomWheel.h"
42 #include "../../widgets/tools/CoordTracking.h"
43 #include "../../widgets/Utils.h"
44 #include "../events/LayerEvents.h"
45 #include "../events/MapEvents.h"
46 #include "../events/ProjectEvents.h"
47 #include "../events/ToolEvents.h"
48 #include "../ApplicationController.h"
49 #include "../Project.h"
50 #include "../Utils.h"
51 #include "MapDisplay.h"
52 
53 // Qt
54 #include <QtGui/QContextMenuEvent>
55 #include <QtGui/QMessageBox>
56 
57 // STL
58 #include <cassert>
59 #include <memory>
60 #include <utility>
61 
63  : QObject(display),
64  m_display(display),
65  m_tool(0),
66  m_menu(0),
67  m_currentExtentIndex(-1),
68  m_extentStackMaxSize(5),
69  m_zoomInDisplay(0),
70  m_eyeBirdDisplay(0)
71 {
72  // CoordTracking tool
74  connect(coordTracking, SIGNAL(coordTracked(QPointF&)), SLOT(onCoordTracked(QPointF&)));
75  m_display->installEventFilter(coordTracking);
76 
77  // Zoom Wheel tool
78  m_display->installEventFilter(new te::qt::widgets::ZoomWheel(m_display, 2.0, this));
79 
80  // Signals & slots
81  connect(m_display, SIGNAL(drawLayersFinished(const QMap<QString, QString>&)), SLOT(onDrawLayersFinished(const QMap<QString, QString>&)));
82  connect(m_display, SIGNAL(extentChanged()), SLOT(onExtentChanged()));
83 
84  // Gets the popup menu
86 
87  // To show popup menu
88  m_display->installEventFilter(this);
89 
90  // Config the default SRS
91  m_display->setSRID(ApplicationController::getInstance().getDefaultSRID(), false);
92 
93  // Getting default display color
95 }
96 
98 {
99  delete m_tool;
100 }
101 
103 {
104  return m_display;
105 }
106 
108 {
109  m_zoomInDisplay = display;
110 }
111 
113 {
114  m_eyeBirdDisplay = display;
115 }
116 
117 bool te::qt::af::MapDisplay::eventFilter(QObject* /*watched*/, QEvent* e)
118 {
119  switch(e->type())
120  {
121  case QEvent::ContextMenu:
122  if(m_menu)
123  m_menu->exec(static_cast<QContextMenuEvent*>(e)->globalPos());
124  break;
125 
126  default:
127  break;
128  }
129 
130  return false;
131 }
132 
133 void te::qt::af::MapDisplay::draw(const std::list<te::map::AbstractLayerPtr>& layers)
134 {
135  if(layers.empty())
136  {
137  clear();
138  return;
139  }
140 
141  std::list<te::map::AbstractLayerPtr> visibleLayers;
142  te::map::GetVisibleLayers(layers, visibleLayers);
143 
144  configSRS(visibleLayers);
145 
146  if(!m_display->getExtent().isValid())
147  {
148  te::gm::Envelope displayExtent = te::map::GetExtent(layers, m_display->getSRID(), true);
149  m_display->setExtent(displayExtent, false);
150  }
151 
152  m_display->setLayerList(layers);
153 
154  m_display->refresh();
155 
156  if(m_zoomInDisplay)
157  m_zoomInDisplay->setList(visibleLayers, m_display->getSRID());
158 
159  if(m_eyeBirdDisplay)
160  m_eyeBirdDisplay->setList(visibleLayers, m_display->getSRID());
161 
162 }
163 
165 {
166  std::list<te::map::AbstractLayerPtr> empty;
167  m_display->setLayerList(empty);
168  m_display->refresh();
169 }
170 
172 {
173  delete m_tool;
174  m_tool = tool;
175 
176  m_display->installEventFilter(m_tool);
177 }
178 
180 {
181  if(m_extentStack.empty())
182  return;
183 
184  if(m_currentExtentIndex < static_cast<int>(m_extentStack.size() - 1))
185  {
186  m_currentExtentIndex += 1;
187  m_display->setExtent(m_extentStack[m_currentExtentIndex]);
188  }
189 
190  emit hasNextExtent(m_currentExtentIndex < static_cast<int>(m_extentStack.size() - 1));
191  emit hasPreviousExtent(m_currentExtentIndex > 0);
192 }
193 
195 {
196  if(m_extentStack.empty())
197  return;
198 
199  if(m_currentExtentIndex > 0)
200  {
201  m_currentExtentIndex -= 1;
202  m_display->setExtent(m_extentStack[m_currentExtentIndex]);
203  }
204 
205  emit hasNextExtent(m_currentExtentIndex < static_cast<int>(m_extentStack.size() - 1));
206  emit hasPreviousExtent(m_currentExtentIndex > 0);
207 }
208 
209 void te::qt::af::MapDisplay::fit(const std::list<te::map::AbstractLayerPtr>& layers)
210 {
211  std::list<te::map::AbstractLayerPtr> visibleLayers;
212  te::map::GetVisibleLayers(layers, visibleLayers);
213 
214  configSRS(visibleLayers);
215 
216  te::gm::Envelope displayExtent = te::map::GetExtent(layers, m_display->getSRID(), true);
217 
218  m_display->setExtent(displayExtent, false);
219 
220  m_display->setLayerList(layers);
221 
222  m_display->refresh();
223 
224  if(m_zoomInDisplay)
225  m_zoomInDisplay->setList(visibleLayers, m_display->getSRID());
226 
227  if(m_eyeBirdDisplay)
228  m_eyeBirdDisplay->setList(visibleLayers, m_display->getSRID());
229 }
230 
231 void te::qt::af::MapDisplay::onCoordTracked(QPointF& coordinate)
232 {
233  te::qt::af::evt::CoordinateTracked e(coordinate.x(), coordinate.y());
235 
236  if(m_zoomInDisplay)
237  m_zoomInDisplay->drawCursorPosition(static_cast<double>(coordinate.x()), static_cast<double>(coordinate.ry()));
238 }
239 
240 void te::qt::af::MapDisplay::onDrawLayersFinished(const QMap<QString, QString>& /*errors*/)
241 {
242  // Stores the clean pixmap!
243  m_lastDisplayContent = QPixmap(*m_display->getDisplayPixmap());
244 
245  // Draw the layers selection
246  drawLayersSelection(ApplicationController::getInstance().getProject()->getSingleLayers());
247 }
248 
250 {
251  switch(e->m_id)
252  {
254  clear();
255  break;
256 
258  {
259  QPixmap* content = m_display->getDisplayPixmap();
260  content->fill(Qt::transparent);
261 
262  QPainter painter(content);
263  painter.drawPixmap(0, 0, m_lastDisplayContent);
264  painter.end();
265 
266  drawLayersSelection(ApplicationController::getInstance().getProject()->getSingleLayers());
267  }
268  break;
269 
271  {
273  drawDataSet(highlightEvent->m_dataset, highlightEvent->m_layer->getSRID(), highlightEvent->m_color);
274  m_display->repaint();
275  }
276  break;
277 
279  {
280  // TODO
281  }
282  break;
283 
286  {
287  draw(ApplicationController::getInstance().getProject()->getVisibleSingleLayers());
288  }
289  break;
290 
292  {
293  te::qt::af::evt::MapColorChanged* mapColorChanged = static_cast<te::qt::af::evt::MapColorChanged*>(e);
294  m_display->setBackgroundColor(mapColorChanged->m_color);
295  m_display->refresh();
296  }
297  break;
298 
299  default:
300  return;
301  }
302 }
303 
304 void te::qt::af::MapDisplay::drawLayersSelection(const std::list<te::map::AbstractLayerPtr>& layers)
305 {
306  if(layers.empty())
307  return;
308 
309  std::list<te::map::AbstractLayerPtr>::const_iterator it;
310  for(it = layers.begin(); it != layers.end(); ++it)
311  drawLayerSelection(*it);
312 
313  m_display->repaint();
314 }
315 
317 {
318  assert(layer.get());
319 
320  if(layer->getVisibility() != te::map::VISIBLE)
321  return;
322 
323  std::auto_ptr<te::da::DataSetType> dsType = layer->getSchema();
324 
325  if(!dsType->hasGeom())
326  return;
327 
328  const te::da::ObjectIdSet* oids = layer->getSelected();
329  if(oids == 0 || oids->size() == 0)
330  return;
331 
332  try
333  {
334  std::size_t maxOids = 4000;
335 
336  if(oids->size() <= maxOids)
337  {
338  // Try to retrieve the layer selection
339  std::auto_ptr<te::da::DataSet> selected(layer->getData(oids));
340 
341  drawDataSet(selected.get(), layer->getSRID(), ApplicationController::getInstance().getSelectionColor());
342 
343  return;
344  }
345 
346  // The batch of oids
347  std::auto_ptr<te::da::ObjectIdSet> oidsBatch(new te::da::ObjectIdSet(*oids, false));
348 
349  // Count the all oids
350  std::size_t nOids = 0;
351 
352  // Count the processed oids
353  std::size_t nProcessedOids = 0;
354 
355  std::set<te::da::ObjectId*, te::common::LessCmp<te::da::ObjectId*> >::const_iterator it;
356  for(it = oids->begin(); it != oids->end(); ++it)
357  {
358  oidsBatch->add((*it)->clone());
359 
360  ++nOids;
361  ++nProcessedOids;
362 
363  if(nProcessedOids == maxOids || nOids == oids->size())
364  {
365  // Try to retrieve the layer selection batch
366  std::auto_ptr<te::da::DataSet> selected(layer->getData(oidsBatch.get()));
367 
368  drawDataSet(selected.get(), layer->getSRID(), ApplicationController::getInstance().getSelectionColor());
369 
370  // Prepares to next batch
371  oidsBatch->clear();
372  nProcessedOids = 0;
373  }
374  }
375  }
376  catch(std::exception& e)
377  {
378  QMessageBox::critical(m_display, tr("Error"), QString(tr("The layer selection cannot be drawn. Details:") + " %1.").arg(e.what()));
379  return;
380  }
381 }
382 
383 void te::qt::af::MapDisplay::drawDataSet(te::da::DataSet* dataset, int srid, const QColor& color)
384 {
385  assert(dataset);
386  assert(color.isValid());
387 
388  if(srid == TE_UNKNOWN_SRS && m_display->getSRID() != TE_UNKNOWN_SRS)
389  return;
390 
391  bool needRemap = false;
392 
393  if((srid != TE_UNKNOWN_SRS) && (m_display->getSRID() != TE_UNKNOWN_SRS) && (srid != m_display->getSRID()))
394  needRemap = true;
395 
396  std::size_t gpos = te::da::GetFirstPropertyPos(dataset, te::dt::GEOMETRY_TYPE);
397 
398  QPixmap* content = m_display->getDisplayPixmap();
399 
400  const te::gm::Envelope& displayExtent = m_display->getExtent();
401 
402  te::qt::widgets::Canvas canvas(content);
403  canvas.setWindow(displayExtent.m_llx, displayExtent.m_lly, displayExtent.m_urx, displayExtent.m_ury);
404 
406 
407  dataset->moveBeforeFirst();
408 
409  while(dataset->moveNext())
410  {
411  std::auto_ptr<te::gm::Geometry> g(dataset->getGeometry(gpos));
412 
413  if(needRemap)
414  {
415  g->setSRID(srid);
416  g->transform(m_display->getSRID());
417  }
418 
419  if(currentGeomType != g->getGeomTypeId())
420  {
421  currentGeomType = g->getGeomTypeId();
422  te::qt::widgets::Config2DrawLayerSelection(&canvas, color, currentGeomType);
423  }
424 
425  canvas.draw(g.get());
426  }
427 }
428 
430 {
431  if(!m_extentStack.empty() && m_display->getExtent().equals(m_extentStack[m_currentExtentIndex]))
432  return;
433 
434  if(m_currentExtentIndex != m_extentStackMaxSize)
435  {
436  m_extentStack.push_back(m_display->getExtent());
437  m_currentExtentIndex += 1;
438  }
439  else
440  {
441  m_extentStack.erase(m_extentStack.begin());
442  m_extentStack.push_back(m_display->getExtent());
443  m_currentExtentIndex = m_extentStackMaxSize;
444  }
445 
446  emit hasNextExtent(m_currentExtentIndex < static_cast<int>(m_extentStack.size() - 1));
447  emit hasPreviousExtent(m_currentExtentIndex > 0);
448 }
449 
450 void te::qt::af::MapDisplay::configSRS(const std::list<te::map::AbstractLayerPtr>& layers)
451 {
452  if(layers.size() == 1 && (*layers.begin())->getSRID() == TE_UNKNOWN_SRS && m_display->getSRID() != TE_UNKNOWN_SRS)
453  {
454  const te::map::AbstractLayerPtr& layer = *layers.begin();
455 
456  m_display->setSRID(TE_UNKNOWN_SRS, false);
457 
458  std::pair<int, std::string> srid(layer->getSRID(), "EPSG");
459  te::qt::af::evt::MapSRIDChanged mapSRIDChanged(srid);
461  }
462  else if(m_display->getSRID() == TE_UNKNOWN_SRS)
463  {
464  std::list<te::map::AbstractLayerPtr>::const_iterator it;
465 
466  for(it = layers.begin(); it != layers.end(); ++it)
467  {
468  const te::map::AbstractLayerPtr& layer = *it;
469 
470  if(layer->getSRID() == TE_UNKNOWN_SRS)
471  continue;
472 
473  m_display->setSRID(layer->getSRID(), false);
474 
475  std::pair<int, std::string> srid(layer->getSRID(), "EPSG");
476  te::qt::af::evt::MapSRIDChanged mapSRIDChanged(srid);
478 
479  break;
480  }
481  }
482 }
A connector of the te::qt::widgets::MapDisplay class to the Application Framework.
QMenu * findMenu(const QString &id) const
Returns the menu registered with key id.
This class represents a set of unique ids created in the same context. i.e. from the same data set...
Definition: ObjectIdSet.h:53
void drawLayerSelection(te::map::AbstractLayerPtr layer)
Definition: MapDisplay.cpp:316
void clear()
It clears the map display.
Definition: MapDisplay.cpp:164
QColor getSelectionColor() const
Returns the application selection color.
This event signals that the color of the map display changed.
Definition: MapEvents.h:73
void fit(const std::list< te::map::AbstractLayerPtr > &layers)
Definition: MapDisplay.cpp:209
void onDrawLayersFinished(const QMap< QString, QString > &errors)
Definition: MapDisplay.cpp:240
void setZoomInDisplay(te::qt::widgets::ZoomInMapDisplayWidget *display)
Definition: MapDisplay.cpp:107
QMenu * m_menu
The map display popup menu.
Definition: MapDisplay.h:159
This event signals that the srid of the map display changed.
Definition: MapEvents.h:52
virtual void setBackgroundColor(const QColor &color)
Sets the map display background color.
Definition: MapDisplay.cpp:325
This class defines an interface for objects that can receive application events and respond to them...
Definition: AbstractTool.h:62
virtual bool moveNext()=0
It moves the internal pointer to the next item of the collection.
This class implements a concrete tool to geographic zoom operation using the mouse wheel...
Definition: ZoomWheel.h:49
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:72
void configSRS(const std::list< te::map::AbstractLayerPtr > &layers)
Definition: MapDisplay.cpp:450
void draw(const std::list< te::map::AbstractLayerPtr > &layers)
It draws the given layer list.
Definition: MapDisplay.cpp:133
static ApplicationController & getInstance()
It gives access to the controller singleton.
TEMAPEXPORT te::gm::Envelope GetExtent(const std::list< te::map::AbstractLayerPtr > &layers, int srid, bool onlyVisibles)
It calculates the extent of the given layers in the given SRID.
Definition: Utils.cpp:326
void onCoordTracked(QPointF &coordinate)
Definition: MapDisplay.cpp:231
QColor m_color
The color used to highlight.
Definition: LayerEvents.h:213
te::qt::widgets::MapDisplay * getDisplay()
Definition: MapDisplay.cpp:102
TEQTAFEXPORT QColor GetDefaultDisplayColorFromSettings()
Definition: Utils.cpp:603
This event indicates that the objects of the given layer must be highlighted.
Definition: LayerEvents.h:194
te::qt::widgets::MapDisplay * m_display
Pointer to a component te::qt::widgets::MapDisplay.
Definition: MapDisplay.h:157
void draw(const te::gm::Geometry *geom)
It draws the geometry on canvas.
Definition: Canvas.cpp:296
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
te::da::DataSet * m_dataset
The dataset that represents the objects that must be highlighted.
Definition: LayerEvents.h:212
std::size_t size() const
It returns the object id set size.
This class defines the map display ZoomIn, this component is only a specific map that shows the curre...
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
~MapDisplay()
destructor.
Definition: MapDisplay.cpp:97
A canvas built on top of Qt.
Definition: Canvas.h:54
void drawDataSet(te::da::DataSet *dataset, int srid, const QColor &color)
Definition: MapDisplay.cpp:383
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: Utils.cpp:428
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
Definition: Enums.h:41
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
std::set< ObjectId *, te::common::LessCmp< ObjectId * > >::const_iterator begin() const
Returns an iterator for the object ids in container.
std::set< ObjectId *, te::common::LessCmp< ObjectId * > >::const_iterator end() const
Returns an iterator for the object ids in container.
int m_id
Identifier.
Definition: Event.h:70
virtual bool moveBeforeFirst()=0
It moves the internal pointer to a position before the first item in the collection.
void setCurrentTool(te::qt::widgets::AbstractTool *tool)
Updates the current tool being used on te::qt::widgets::MapDisplay.
Definition: MapDisplay.cpp:171
void drawLayersSelection(const std::list< te::map::AbstractLayerPtr > &layers)
Definition: MapDisplay.cpp:304
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
bool eventFilter(QObject *watched, QEvent *e)
Definition: MapDisplay.cpp:117
te::map::AbstractLayerPtr m_layer
The layer whose objects must be highlighted.
Definition: LayerEvents.h:211
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
A base class for application events.
Definition: Event.h:59
This class implements a concrete tool to geographic coordinate tracking on mouse move operation...
Definition: CoordTracking.h:52
MapDisplay(te::qt::widgets::MapDisplay *display)
Constructor.
Definition: MapDisplay.cpp:62
TEQTWIDGETSEXPORT void Config2DrawLayerSelection(te::map::Canvas *canvas, const QColor &selectionColor, const te::gm::GeomType &type)
It configs (i.e. prepares) the given canvas to draw a layer selection.
Definition: Utils.cpp:264
void setEyeBirdDisplay(te::qt::widgets::EyeBirdMapDisplayWidget *display)
Definition: MapDisplay.cpp:112
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
virtual std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const =0
Method for retrieving a geometric attribute value.
This class defines the map display EyeBird, this component is only a specific map that shows the orig...
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
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:111
void broadcast(te::qt::af::evt::Event *evt)
Send events in broadcast for all registered components.
Signals a mouse moved over the current display.
Definition: ToolEvents.h:78
void onApplicationTriggered(te::qt::af::evt::Event *e)
Listener to the application framewrork events.
Definition: MapDisplay.cpp:249