All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Info.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/tools/Info.cpp
22 
23  \brief This class implements a concrete tool to get informations about a specified feature using pointing operation.
24 */
25 
26 // TerraLib
27 #include "../../../common/STLUtils.h"
28 #include "../../../dataaccess/dataset/DataSet.h"
29 #include "../../../dataaccess/dataset/DataSetType.h"
30 #include "../../../dataaccess/utils/Utils.h"
31 #include "../../../geometry/Coord2D.h"
32 #include "../../../geometry/Envelope.h"
33 #include "../../../geometry/Geometry.h"
34 #include "../../../geometry/GeometryProperty.h"
35 #include "../../../geometry/Point.h"
36 #include "../../../geometry/Utils.h"
37 #include "../../../maptools/MarkRendererManager.h"
38 #include "../../../raster/Raster.h"
39 #include "../../../raster/RasterProperty.h"
40 #include "../../../raster/Utils.h"
41 #include "../../../se/Fill.h"
42 #include "../../../se/Stroke.h"
43 #include "../../../se/Mark.h"
44 #include "../../../se/Utils.h"
45 #include "../../../srs/Config.h"
46 #include "../canvas/Canvas.h"
47 #include "../canvas/MapDisplay.h"
48 #include "Info.h"
49 
50 // Qt
51 #include <QtCore/QPointF>
52 #include <QtCore/QString>
53 #include <QtCore/QStringList>
54 #include <QtGui/QMessageBox>
55 #include <QtGui/QMouseEvent>
56 
57 // STL
58 #include <cassert>
59 #include <memory>
60 
61 te::qt::widgets::Info::Info(te::qt::widgets::MapDisplay* display, const QCursor& cursor, const std::list<te::map::AbstractLayerPtr>& layers, QObject* parent)
62  : AbstractTool(display, parent),
63  m_layers(layers),
64  m_infoWidget(new QTreeWidget(display))
65 {
66  setCursor(cursor);
67 
68  // Setup the widget that will be used to show the informations
69  m_infoWidget->setWindowTitle(tr("Information"));
70  m_infoWidget->setWindowFlags(Qt::Tool);
71  m_infoWidget->setAlternatingRowColors(true);
72  m_infoWidget->setMinimumSize(300, 300);
73  m_infoWidget->setColumnCount(2);
74 
75  QStringList labels;
76  labels << tr("Property") << tr("Value");
77  m_infoWidget->setHeaderLabels(labels);
78 }
79 
81 {
82  QPixmap* draft = m_display->getDraftPixmap();
83  draft->fill(Qt::transparent);
84 
85  m_infoWidget->close();
86 
87  delete m_infoWidget;
88 }
89 
91 {
92  if(e->button() != Qt::LeftButton)
93  return false;
94 
95  if(m_layers.empty())
96  return false;
97 
98  QPointF pixelOffset(4.0, 4.0);
99  QRectF rect = QRectF(e->posF() - pixelOffset, e->posF() + pixelOffset);
100 
101  // Converts rect boundary to world coordinates
102  QPointF ll(rect.left(), rect.bottom());
103  QPointF ur(rect.right(), rect.top());
104  ll = m_display->transform(ll);
105  ur = m_display->transform(ur);
106 
107  // Bulding the query box
108  te::gm::Envelope envelope(ll.x(), ll.y(), ur.x(), ur.y());
109 
110  // Clear draft!
111  QPixmap* draft = m_display->getDraftPixmap();
112  draft->fill(Qt::transparent);
113 
114  // Clear info widget!
115  m_infoWidget->clear();
116 
117  // For each layer, get info!
118  std::list<te::map::AbstractLayerPtr>::const_iterator it;
119  for(it = m_layers.begin(); it != m_layers.end(); ++it)
120  getInfo(*it, envelope);
121 
122  if(m_infoWidget->topLevelItemCount() > 0)
123  {
124  m_infoWidget->expandAll();
125  m_infoWidget->resizeColumnToContents(0);
126  m_infoWidget->show();
127  }
128  else
129  m_infoWidget->hide();
130 
131  m_display->repaint();
132 
133  return true;
134 }
135 
136 void te::qt::widgets::Info::setLayers(const std::list<te::map::AbstractLayerPtr>& layers)
137 {
138  m_layers = layers;
139 }
140 
142 {
143  if(layer->getVisibility() != te::map::VISIBLE)
144  return;
145 
146  bool needRemap = false;
147  te::gm::Envelope reprojectedEnvelope(e);
148 
149  if((layer->getSRID() != TE_UNKNOWN_SRS) &&
150  (m_display->getSRID() != TE_UNKNOWN_SRS) &&
151  (layer->getSRID() != m_display->getSRID()))
152  {
153  needRemap = true;
154  reprojectedEnvelope.transform(m_display->getSRID(), layer->getSRID());
155  }
156 
157  if(!reprojectedEnvelope.within(layer->getExtent()))
158  return;
159 
160  // The Layer item
161  QTreeWidgetItem* layerItem = new QTreeWidgetItem;
162  layerItem->setIcon(0, QIcon::fromTheme("layer"));
163  layerItem->setText(0, tr("Layer"));
164  layerItem->setText(1, layer->getTitle().c_str());
165 
166  try
167  {
168  // Gets the Layer Schema
169  std::auto_ptr<const te::map::LayerSchema> ls(layer->getSchema());
170 
171  if(ls->hasGeom())
172  {
173  // Retrieves the data from layer
175 
176  std::auto_ptr<te::da::DataSet> dataset(layer->getData(gp->getName(), &reprojectedEnvelope, te::gm::INTERSECTS).release());
177  getGeometryInfo(layerItem, dataset.get(), reprojectedEnvelope, layer->getSRID(), needRemap);
178  }
179 
180  if(ls->hasRaster())
181  {
182  // Retrieves the data from layer
184 
185  std::auto_ptr<te::da::DataSet> dataset(layer->getData(rp->getName(), &reprojectedEnvelope, te::gm::INTERSECTS).release());
186 
187  if(!dataset->moveNext())
188  return;
189 
190  std::size_t rpos = te::da::GetFirstPropertyPos(dataset.get(), te::dt::RASTER_TYPE);
191  assert(rpos != std::string::npos);
192 
193  std::auto_ptr<te::rst::Raster> raster(dataset->getRaster(rpos));
194  assert(raster.get());
195 
196  getRasterInfo(layerItem, raster.get(), reprojectedEnvelope, layer->getSRID(), needRemap);
197  }
198 
199  layerItem->childCount() != 0 ? m_infoWidget->addTopLevelItem(layerItem) : delete layerItem;
200  }
201  catch(...)
202  {
203  delete layerItem;
204  // TODO: catch the exceptions...
205  }
206 }
207 
208 void te::qt::widgets::Info::getGeometryInfo(QTreeWidgetItem* layerItem, te::da::DataSet* dataset, const te::gm::Envelope& e, int srid, bool needRemap)
209 {
210  // Generates a geometry from the given extent. It will be used to refine the results
211  std::auto_ptr<te::gm::Geometry> geometryFromEnvelope(te::gm::GetGeomFromEnvelope(&e, srid));
212 
213  // The restriction point. It will be used to refine the results
214  te::gm::Coord2D center = e.getCenter();
215  te::gm::Point point(center.x, center.y, srid);
216 
217  // For while, using the first geometry property
218  std::size_t gpos = te::da::GetFirstPropertyPos(dataset, te::dt::GEOMETRY_TYPE);
219 
220  while(dataset->moveNext())
221  {
222  std::auto_ptr<te::gm::Geometry> g(dataset->getGeometry(gpos));
223 
224  if(g->contains(&point) || g->crosses(geometryFromEnvelope.get()) || geometryFromEnvelope->contains(g.get()))
225  {
226  // Feature found! Building the list of property values...
227  for(std::size_t i = 0; i < dataset->getNumProperties(); ++i)
228  {
229  if(dataset->getPropertyDataType(i) == te::dt::RASTER_TYPE)
230  continue;
231 
232  QTreeWidgetItem* propertyItem = new QTreeWidgetItem(layerItem);
233  propertyItem->setText(0, dataset->getPropertyName(i).c_str());
234 
235  if(dataset->getPropertyDataType(i) == te::dt::GEOMETRY_TYPE)
236  propertyItem->setIcon(0, QIcon::fromTheme("geometry"));
237 
238  if(!dataset->isNull(i))
239  propertyItem->setText(1, dataset->getAsString(i, 3).c_str());
240  else
241  propertyItem->setText(1, "");
242  }
243 
244  if(needRemap)
245  {
246  g->setSRID(srid);
247  g->transform(m_display->getSRID());
248  }
249 
250  drawGeometry(g.get()); // to show feedback!
251 
252  break;
253  }
254  }
255 }
256 
257 void te::qt::widgets::Info::getRasterInfo(QTreeWidgetItem* layerItem, te::rst::Raster* raster, const te::gm::Envelope& e, int /*srid*/, bool /*needRemap*/)
258 {
259  te::gm::Coord2D center = e.getCenter();
260  te::gm::Coord2D coord = raster->getGrid()->geoToGrid(center.x, center.y);
261 
262  int x = te::rst::Round(coord.x);
263  int y = te::rst::Round(coord.y);
264 
265  if((x < 0 && x >= static_cast<int>(raster->getNumberOfColumns())) ||
266  (y < 0 && y >= static_cast<int>(raster->getNumberOfRows())))
267  return;
268 
269  // Raster location informations
270  QTreeWidgetItem* lineItem = new QTreeWidgetItem(layerItem);
271  lineItem->setText(0, tr("Line"));
272  lineItem->setText(1, QString::number(y));
273 
274  QTreeWidgetItem* columnItem = new QTreeWidgetItem(layerItem);
275  columnItem->setText(0, tr("Column"));
276  columnItem->setText(1, QString::number(x));
277 
278  QTreeWidgetItem* coordXItem = new QTreeWidgetItem(layerItem);
279  coordXItem->setText(0, tr("Coordinate X"));
280  coordXItem->setText(1, QString::number(center.x));
281 
282  QTreeWidgetItem* coordYItem = new QTreeWidgetItem(layerItem);
283  coordYItem->setText(0, tr("Coordinate Y"));
284  coordYItem->setText(1, QString::number(center.y));
285 
286  // Raster value informations for each band
287  double value = 0.0;
288  for(std::size_t b = 0; b < raster->getNumberOfBands(); ++b)
289  {
290  raster->getValue(x, y, value, b);
291 
292  QTreeWidgetItem* bandValueItem = new QTreeWidgetItem(layerItem);
293  bandValueItem->setIcon(0, QIcon::fromTheme("channel-gray"));
294  bandValueItem->setText(0, tr("Band") + " " + QString::number(b));
295  bandValueItem->setText(1, QString::number(value));
296  }
297 }
298 
300 {
301  QPixmap* draft = m_display->getDraftPixmap();
302 
303  const te::gm::Envelope& displayExtent = m_display->getExtent();
304 
305  Canvas canvas(draft);
306  canvas.setWindow(displayExtent.m_llx, displayExtent.m_lly, displayExtent.m_urx, displayExtent.m_ury);
307  canvas.setRenderHint(QPainter::Antialiasing, true);
308 
309  switch(g->getGeomTypeId())
310  {
311  case te::gm::PolygonType:
319  {
320  canvas.setPolygonContourWidth(2);
321  canvas.setPolygonContourColor(te::color::RGBAColor(255, 0, 0, 128));
322  canvas.setPolygonFillColor(te::color::RGBAColor(255, 255, 255, 128));
323  }
324  break;
325 
334  {
335  canvas.setLineColor(te::color::RGBAColor(255, 0, 0, 128));
336  canvas.setLineWidth(6);
337  }
338  break;
339 
340  case te::gm::PointType:
341  case te::gm::PointZType:
342  case te::gm::PointMType:
343  case te::gm::PointZMType:
348  {
349  std::size_t size = 24;
350 
351  te::se::Stroke* stroke = te::se::CreateStroke("#FF0000", "2","0.5");
352  te::se::Fill* fill = te::se::CreateFill("#FFFFFF", "0.5");
353  te::se::Mark* mark = te::se::CreateMark("square", stroke, fill);
354 
356 
358  canvas.setPointPattern(rgba, size, size);
359 
360  te::common::Free(rgba, size);
361  delete mark;
362  }
363  break;
364 
365  default:
366  return;
367  }
368 
369  canvas.draw(g);
370 }
virtual std::string getPropertyName(std::size_t i) const =0
It returns the property name at position pos.
void setPolygonContourColor(const te::color::RGBAColor &color)
It sets the pen color used to draw the boundary of polygon geometries.
Definition: Canvas.cpp:1862
TESEEXPORT Fill * CreateFill(const std::string &color, const std::string &opacity)
Creates a fill.
Definition: Utils.cpp:107
void setLayers(const std::list< te::map::AbstractLayerPtr > &layers)
Definition: Info.cpp:136
TEGEOMEXPORT Geometry * GetGeomFromEnvelope(const Envelope *const e, int srid)
It creates a Geometry (a polygon) from the given envelope.
Definition: Utils.cpp:35
virtual std::size_t getNumProperties() const =0
It returns the number of properties that composes an item of the dataset.
A Fill specifies the pattern for filling an area geometry.
Definition: Fill.h:59
TERASTEREXPORT int Round(double val)
Round a double value to a integer value.
Definition: Utils.cpp:295
TEDATAACCESSEXPORT te::rst::RasterProperty * GetFirstRasterProperty(const DataSetType *dt)
Definition: Utils.cpp:518
void setLineColor(const te::color::RGBAColor &color)
It sets the pen color used to draw line geometries.
Definition: Canvas.cpp:1620
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Definition: Raster.cpp:208
void setPointPattern(te::color::RGBAColor **pattern, int ncols, int nrows)
It sets the point pattern.
Definition: Canvas.cpp:1565
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:504
virtual std::string getAsString(std::size_t i, int precision=0) const
Method for retrieving a data value as a string plain representation.
Definition: DataSet.cpp:218
This class implements a concrete tool to get informations about a specified feature using pointing op...
void setLineWidth(int w)
It sets the line width.
Definition: Canvas.cpp:1725
void getInfo(const te::map::AbstractLayerPtr &layer, const te::gm::Envelope &e)
Definition: Info.cpp:141
QTreeWidget * m_infoWidget
Widget used to show the informations.
Definition: Info.h:127
double y
y-coordinate.
Definition: Coord2D.h:87
Grid * getGrid()
It returns the raster grid.
Definition: Raster.cpp:94
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.
A Stroke specifies the appearance of a linear geometry.
Definition: Stroke.h:67
const std::string & getName() const
It returns the property name.
Definition: Property.h:126
~Info()
Destructor.
Definition: Info.cpp:80
virtual bool isNull(std::size_t i) const =0
It checks if the attribute value is NULL.
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:72
TESEEXPORT Mark * CreateMark(const std::string &wellKnownName, Stroke *stroke, Fill *fill)
Creates a mark.
Definition: Utils.cpp:128
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
virtual void getValue(unsigned int c, unsigned int r, double &value, std::size_t b=0) const
Returns the attribute value of a band of a cell.
Definition: Raster.cpp:228
void setPolygonFillColor(const te::color::RGBAColor &color)
It sets the color used to fill the draw of polygon geometries.
Definition: Canvas.cpp:1732
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
#define TE_TRANSPARENT
For an RGBA color this is the value of the alpha-channel for totally transparent. ...
Definition: Config.h:46
virtual void setCursor(const QCursor &cursor)
void draw(const te::gm::Geometry *geom)
It draws the geometry on canvas.
Definition: Canvas.cpp:296
void getRasterInfo(QTreeWidgetItem *layerItem, te::rst::Raster *raster, const te::gm::Envelope &e, int srid, bool needRemap)
Definition: Info.cpp:257
TESEEXPORT Stroke * CreateStroke(const std::string &color, const std::string &width)
Creates a stroke.
Definition: Utils.cpp:52
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
void drawGeometry(te::gm::Geometry *g)
Definition: Info.cpp:299
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
Definition: RGBAColor.h:57
A canvas built on top of Qt.
Definition: Canvas.h:54
virtual int getPropertyDataType(std::size_t i) const =0
It returns the underlying data type of the property at position pos.
A point with x and y coordinate values.
Definition: Point.h:50
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: Utils.cpp:428
Info(MapDisplay *display, const QCursor &cursor, const std::list< te::map::AbstractLayerPtr > &layers, QObject *parent=0)
It constructs a info tool associated with the given map display.
Definition: Info.cpp:61
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
GeomType getGeomTypeId() const
It returns the geometry subclass type identifier.
Definition: Geometry.h:178
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
Definition: Raster.cpp:213
Coord2D getCenter() const
It returns the rectangle&#39;s center coordinate.
Definition: Envelope.cpp:48
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
void setRenderHint(QPainter::RenderHint hint, bool on=true)
Sets the given render hint on the canvas painter if on is true; otherwise clears the render hint...
Definition: Canvas.cpp:2128
void Free(std::vector< T * > *v)
This function can be applied to a pointer to a vector of pointers.
Definition: STLUtils.h:131
void setPolygonContourWidth(int w)
It sets the polygon contour width.
Definition: Canvas.cpp:1919
void getGeometryInfo(QTreeWidgetItem *layerItem, te::da::DataSet *dataset, const te::gm::Envelope &e, int srid, bool needRemap)
Definition: Info.cpp:208
Raster property.
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
An abstract class for raster data strucutures.
Definition: Raster.h:70
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
bool within(const Envelope &rhs) const
It returns true if this envelope is &quot;spatially within&quot; the rhs envelope.
Definition: Envelope.h:527
static MarkRendererManager & getInstance()
It returns a reference to the singleton instance.
double x
x-coordinate.
Definition: Coord2D.h:86
virtual std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const =0
Method for retrieving a geometric attribute value.
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
void geoToGrid(const double &x, const double &y, double &col, double &row) const
Get the grid point associated to a spatial location.
Definition: Grid.cpp:308
Geometric property.
void setPointColor(const te::color::RGBAColor &color)
It sets the point drawing color.
Definition: Canvas.cpp:1530
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:111
bool mouseReleaseEvent(QMouseEvent *e)
Definition: Info.cpp:90
A Mark specifies a geometric shape and applies coloring to it.
Definition: Mark.h:84