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