All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Utils.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2010-2013 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 Utils.cpp
22 
23  \brief This file contains a set of utility chart functions
24 */
25 
26 // TerraLib
27 #include "../../../color/RGBAColor.h"
28 #include "../../../common/progress/TaskProgress.h"
29 #include "../../../dataaccess/dataset/DataSet.h"
30 #include "../../../dataaccess/dataset/DataSetType.h"
31 #include "../../../dataaccess/dataset/ObjectId.h"
32 #include "../../../dataaccess/dataset/ObjectIdSet.h"
33 #include "../../../dataaccess/utils/Utils.h"
34 #include "../../../datatype.h"
35 #include "../../../raster.h"
36 #include "../../../maptools/ExternalGraphicRendererManager.h"
37 #include "../../../maptools/MarkRendererManager.h"
38 #include "../../../maptools/Utils.h"
39 #include "../../../se.h"
40 #include "../../../qt/widgets/Utils.h"
41 #include "Histogram.h"
42 #include "Scatter.h"
43 #include "Utils.h"
44 
45 //Boost
46 #include <boost/lexical_cast.hpp>
47 
48 //QT
49 #include <QPen>
50 
51 //STL
52 #include <memory>
53 
54 double getDouble(const std::string& value, std::vector<std::string>& sVector)
55 {
56  //verify if it exists
57  for(std::size_t i=0;i<sVector.size();++i)
58  {
59  if(value==sVector[i])
60  return (double)i;
61  }
62 
63  sVector.push_back(value);
64  return (double)sVector.size()-1;
65 }
66 
67 double getDouble(te::dt::DateTime* dateTime)
68 {
69  if(dateTime->getTypeCode() == te::dt::TIME_INSTANT)
70  {
71  std::auto_ptr<te::dt::TimeInstant> ti ((te::dt::TimeInstant*)dateTime);
72  boost::gregorian::date basedate(1400, 01, 01);
73  boost::gregorian::date_duration days = ti->getDate().getDate() - basedate;
74  long long int seconds = ti->getTime().getTimeDuration().total_seconds();
75  long long int dias = days.days();
76  double v = (double) dias * 86400 + seconds;
77  return v;
78  }
79  else if(dateTime->getTypeCode() == te::dt::DATE)
80  {
81  std::auto_ptr<te::dt::Date> d ((te::dt::Date*)dateTime);
82  boost::gregorian::date basedate(1400, 01, 01);
83  boost::gregorian::date_duration days = d->getDate() - basedate;
84  double v = days.days();
85  return v;
86  }
87  return 0.;
88 }
89 
90 double getDouble(te::da::DataSet* dataset, int propId)
91 {
92  double res = 0.;
93 
94  int propType = dataset->getPropertyDataType(propId);
95  switch (propType)
96  {
97  case(te::dt::INT16_TYPE):
98  res = dataset->getInt16(propId);
99  break;
100  case(te::dt::UINT16_TYPE):
101  res = dataset->getInt16(propId);
102  break;
103  case(te::dt::INT32_TYPE):
104  res = dataset->getInt32(propId);
105  break;
106  case(te::dt::UINT32_TYPE):
107  res = dataset->getInt32(propId);
108  break;
109  case(te::dt::INT64_TYPE):
110  res = dataset->getInt64(propId);
111  break;
112  case(te::dt::UINT64_TYPE):
113  res = dataset->getInt64(propId);
114  break;
115  case(te::dt::FLOAT_TYPE):
116  res = dataset->getFloat(propId);
117  break;
118  case(te::dt::NUMERIC_TYPE):
119  res = boost::lexical_cast<double>(dataset->getNumeric(propId));
120  break;
121  default:
122  res = dataset->getDouble(propId);
123  break;
124  }
125 
126  return res;
127 }
128 
129 void getObjectIds (te::da::DataSet* dataset, std::vector<std::size_t> pkeys, std::vector<te::da::ObjectId*>& valuesOIDs)
130 {
131  std::vector<size_t>::iterator it;
132  std::vector<std::string> propNames;
133 
134  for(it=pkeys.begin(); it!=pkeys.end(); ++it)
135  propNames.push_back(dataset->getPropertyName(*it));
136 
137  //The caller will take ownership of the generated pointers.
138  te::da::ObjectId* oid = te::da::GenerateOID(dataset, propNames);
139  valuesOIDs.push_back(oid);
140 }
141 
142 te::da::ObjectId* getObjectIds (te::da::DataSet* dataset, std::vector<std::size_t> pkeys)
143 {
144  std::vector<size_t>::iterator it;
145  std::vector<std::string> propNames;
146 
147  for(it=pkeys.begin(); it!=pkeys.end(); ++it)
148  propNames.push_back(dataset->getPropertyName(*it));
149 
150  //The caller will take ownership of the generated pointer.
151  te::da::ObjectId* oid = te::da::GenerateOID(dataset, propNames);
152  return oid;
153 }
154 
156 {
158 
159  std::vector<std::size_t> objIdIdx;
160  te::da::GetOIDPropertyPos(dataType, objIdIdx);
161 
162  std::map<double, std::vector<te::da::ObjectId*> > valuesIdsByinterval;
163  std::vector<te::da::ObjectId*> valuesOIds;
164 
165  std::size_t rpos = te::da::GetFirstPropertyPos(dataset, te::dt::RASTER_TYPE);
166  if(rpos != std::string::npos)
167  {
168  std::auto_ptr<te::rst::Raster> raster(dataset->getRaster(rpos));
169 
170  unsigned int nCol = raster->getNumberOfColumns();
171  unsigned int nLin = raster->getNumberOfRows();
172 
174  task.setTotalSteps(nCol * nLin);
175  task.setMessage("Scatter creation");
176 
177  for (unsigned int c=0; c < nCol; ++c)
178  {
179  if(!task.isActive())
180  {
181  break;
182  }
183  for (unsigned int r=0; r <nLin; ++r)
184  {
185  double val1, val2;
186 
187  raster->getValue(c, r, val1, propX);
188  raster->getValue(c, r, val2, propY);
189 
190  newScatter->addX(val1);
191  newScatter->addY(val2);
192 
193  task.pulse();
194  }
195  }
196  }
197  else
198  {
199  int xType = dataset->getPropertyDataType(propX);
200  int yType = dataset->getPropertyDataType(propY);
201 
203  task.setTotalSteps(dataset->getNumProperties());
204  task.setMessage("Scatter creation");
205 
206  while(dataset->moveNext())
207  {
208 
209  if(!task.isActive())
210  {
211  break;
212  }
213 
214  double x_doubleValue = 0.;
215  double y_doubleValue = 0.;
216 
217  if((xType >= te::dt::INT16_TYPE && xType <= te::dt::UINT64_TYPE) ||
218  xType == te::dt::FLOAT_TYPE || xType == te::dt::DOUBLE_TYPE ||
219  xType == te::dt::NUMERIC_TYPE)
220  {
221  if(dataset->isNull(propX))
222  continue;
223 
224  x_doubleValue = getDouble(dataset, propX);
225  }
226  else if(xType == te::dt::DATETIME_TYPE)
227  {
228  if(dataset->isNull(propX))
229  continue;
230 
231  std::auto_ptr<te::dt::DateTime> dateTime = dataset->getDateTime(propX);
232  x_doubleValue = getDouble(dateTime.get());
233  }
234 
235  //======treat the Y value
236  if((yType >= te::dt::INT16_TYPE && yType <= te::dt::UINT64_TYPE) ||
237  yType == te::dt::FLOAT_TYPE || yType == te::dt::DOUBLE_TYPE ||
238  yType == te::dt::NUMERIC_TYPE)
239  {
240  if(dataset->isNull(propY))
241  continue;
242  y_doubleValue = getDouble(dataset, propY);
243  }
244  else if(yType == te::dt::DATETIME_TYPE)
245  {
246  if(dataset->isNull(propY))
247  continue;
248 
249  std::auto_ptr<te::dt::DateTime> dateTime = dataset->getDateTime(propY);
250  y_doubleValue = getDouble(dateTime.get());
251  }
252 
253  //insert values into the vectors
254  newScatter->addData(x_doubleValue, y_doubleValue, getObjectIds(dataset, objIdIdx));
255  task.pulse();
256  } //end of the data set
257  }
258  newScatter->calculateMinMaxValues();
259  return newScatter;
260 }
261 
263 {
264 
266 
267  std::size_t rpos = te::da::GetFirstPropertyPos(dataset, te::dt::RASTER_TYPE);
268  std::vector<std::size_t> objIdIdx;
269  te::da::GetOIDPropertyPos(dataType, objIdIdx);
270 
271  if(rpos != std::string::npos)
272  {
273  std::auto_ptr<te::rst::Raster> rstptr = dataset->getRaster(rpos);
274  std::map<double, unsigned int> values = rstptr->getBand(propId)->getHistogramR(0, 0, 0, 0, slices);
275 
276  for(std::map<double, unsigned int>::iterator it = values.begin(); it != values.end(); ++it)
277  {
278  newHistogram->insert(std::make_pair(new te::dt::Double(it->first), it->second));
279  }
280  }
281  else
282  {
283 
284  int propType = dataset->getPropertyDataType(propId);
285  newHistogram->setType(propType);
286 
287  //The vector containing the frequency of each interval, will be used to every property type
288  std::vector< unsigned int> values;
289 
290  if((propType >= te::dt::INT16_TYPE && propType <= te::dt::UINT64_TYPE) ||
291  propType == te::dt::FLOAT_TYPE || propType == te::dt::DOUBLE_TYPE || propType == te::dt::NUMERIC_TYPE)
292  {
293 
294  std::map<double, std::vector<te::da::ObjectId*> > intervalToOIds;
295  std::vector<te::da::ObjectId*> valuesOIds;
296 
297  double interval, minValue, maxValue;
298  minValue = std::numeric_limits<double>::max();
299  maxValue = -std::numeric_limits<double>::max();
300 
301  std::vector<double> intervals;
302 
304  task.setMessage("Histogram creation");
305  task.setTotalSteps((dataset->getNumProperties()) * 2);
306 
307  //Calculating the minimum and maximum values of the given property and adjusting the Histogram's interval.
308  while(dataset->moveNext())
309  {
310 
311  if(!task.isActive())
312  {
313  break;
314  }
315 
316  //calculate range
317  if(minValue > getDouble(dataset, propId))
318  minValue = getDouble(dataset, propId);
319  if(maxValue < getDouble(dataset, propId))
320  maxValue = getDouble(dataset, propId);
321 
322  task.pulse();
323  }
324 
325  //Adjusting the interval to the user-defined number of slices.
326  interval = maxValue - minValue;
327  newHistogram->setInterval(interval/slices);
328 
329  //Adjusting the histogram's intervals
330  for (double i = minValue; i <(maxValue+newHistogram->getInterval()); i+=newHistogram->getInterval())
331  {
332  intervals.push_back(i);
333  intervalToOIds.insert(std::make_pair(i, valuesOIds));
334  }
335 
336  values.resize(intervals.size(), 0);
337 
338  dataset->moveBeforeFirst();
339 
340  //Adjusting the Histogram's values
341  while(dataset->moveNext())
342  {
343 
344  if(!task.isActive())
345  {
346  break;
347  }
348 
349  double currentValue = getDouble(dataset, propId);
350 
351  for (unsigned int i= 0; i<intervals.size(); ++i)
352  {
353  if((currentValue >= intervals[i]) && (currentValue <= intervals[i+1]))
354  {
355  values[i] = values[i]+1;
356  getObjectIds(dataset, objIdIdx, intervalToOIds.at(intervals[i]));
357  break;
358  }
359 
360  }
361  task.pulse();
362  }
363 
364  //With both the intervals and values ready, the map can be populated
365  for (unsigned int i= 0; i<intervals.size(); ++i)
366  {
367  te::dt::Double* data = new te::dt::Double(intervals[i]);
368  newHistogram->insert(std::make_pair(data, values[i]), intervalToOIds.at(intervals[i]));
369  }
370 
371  newHistogram->setMinValue(minValue);
372  dataset->moveBeforeFirst();
373 
374  }
375  }
376 
377  return newHistogram;
378 }
379 
381 {
383 
384  std::size_t rpos = te::da::GetFirstPropertyPos(dataset, te::dt::RASTER_TYPE);
385  std::vector<std::size_t> objIdIdx;
386  te::da::GetOIDPropertyPos(dataType, objIdIdx);
387 
389  task.setMessage("Histogram creation");
390 
391 
392  if(rpos != std::string::npos)
393  {
394  std::auto_ptr<te::rst::Raster> rstptr = dataset->getRaster(rpos);
395  std::map<double, unsigned int> values = rstptr->getBand(propId)->getHistogramR();
396 
397  for(std::map<double, unsigned int>::iterator it = values.begin(); it != values.end(); ++it)
398  {
399  task.pulse();
400  newHistogram->insert(std::make_pair(new te::dt::Double(it->first), it->second));
401  }
402  }
403  else
404  {
405  int propType = dataset->getPropertyDataType(propId);
406 
407  newHistogram->setType(propType);
408 
409  //The vector containing the frequency of each interval, will be used to every property type
410  std::vector< unsigned int> values;
411 
412  if(propType == te::dt::DATETIME_TYPE || propType == te::dt::STRING_TYPE)
413  {
414 
415  std::set <std::string> intervals;
416  std::set <std::string>::iterator intervalsIt;
417  std::map<std::string, std::vector<te::da::ObjectId*> > valuesIdsByinterval;
418  std::vector<te::da::ObjectId*> valuesOIds;
419 
420  //Adjusting the histogram's intervals
421  while(dataset->moveNext())
422  {
423 
424  if(!task.isActive())
425  {
426  break;
427  }
428 
429  std::string interval = dataset->getString(propId);
430 
431  //Every unique string will be an interval
432  intervals.insert(interval);
433  task.pulse();
434  }
435 
436  for (intervalsIt = intervals.begin(); intervalsIt != intervals.end(); ++intervalsIt)
437  {
438  valuesIdsByinterval.insert(make_pair((*intervalsIt), valuesOIds));
439  }
440 
441  values.resize(intervals.size(), 0);
442  dataset->moveBeforeFirst();
443  newHistogram->setStringInterval(intervals);
444 
445  //Adjusting the Histogram's values
446  while(dataset->moveNext())
447  {
448 
449  if(!task.isActive())
450  {
451  break;
452  }
453 
454  std::string currentValue = dataset->getString(propId);
455  int i;
456 
457  for ( i= 0, intervalsIt = intervals.begin(); intervalsIt != intervals.end(); ++intervalsIt,++i)
458  {
459  if(currentValue == *intervalsIt)
460  {
461  values[i] = values[i]+1;
462  getObjectIds(dataset, objIdIdx, valuesIdsByinterval.at(*intervalsIt));
463  break;
464  }
465  }
466  task.pulse();
467  }
468 
469  //With both the intervals and values ready, the map can be populated
470  int i;
471  for (i= 0, intervalsIt = intervals.begin(); intervalsIt != intervals.end(); ++intervalsIt,++i)
472  {
473  te::dt::String* data = new te::dt::String(*intervalsIt);
474  newHistogram->insert(std::make_pair(data, values[i]), valuesIdsByinterval.at(*intervalsIt));
475  }
476 
477  dataset->moveBeforeFirst();
478  }
479  }
480  return newHistogram;
481 }
482 
483 QwtText* te::qt::widgets::Terralib2Qwt(const std::string& text)
484 {
485  QwtText* result = new QwtText(text.c_str());
486  result->setBackgroundBrush(QBrush(QColor(0, 255, 0)));
487  result->setBorderPen(QPen(Qt::red, 3, Qt::SolidLine));
488  return result;
489 }
490 
491 QwtText* te::qt::widgets::Terralib2Qwt(const std::string& text, te::color::RGBAColor* color,
492  te::se::Font* font, te::se::Fill* backFill,
493  te::se::Stroke* backStroke)
494 {
495  QwtText* result = new QwtText(QString(text.c_str()));
496 
497  return result;
498 }
499 
501 {
502  //Default symbol used in case the Graphic is not completely populated.
503  QwtSymbol* symbol = new QwtSymbol( QwtSymbol::Ellipse, QBrush( Qt::yellow ), QPen( Qt::red, 2 ), QSize( 8, 8 ));
504 
505  //Default size and width for the symbols
506  size_t height = 8, width = 8;
507 
508  //Adjusting the size if the user changed it
509  if(graphic->getSize())
510  {
511  height = te::map::GetInt(graphic->getSize());
512  width = height;
513  }
514 
515  /*Image that will be used to generate the symbol's pixmap,
516  it can be either from a mark or from an external graphic, whichever is valid.
517  */
518  te::color::RGBAColor** image;
519 
520  if(!graphic->getMarks().empty())
521  {
522  image = te::map::MarkRendererManager::getInstance().render(graphic->getMarks()[0], height);
523  }
524  else
525  {
526  image = te::map::ExternalGraphicRendererManager::getInstance().render(graphic->getExternalGraphics()[0], height, width);
527  }
528 
529  QImage* qimg = te::qt::widgets::GetImage(image, height, width);
530  QPixmap pixmap;
531  pixmap = QPixmap::fromImage(*qimg);
532 
533  //Adjusting the symbol
534  symbol->setPixmap(pixmap);
535  symbol->setSize(width, height);
536 
537  delete image;
538  delete qimg;
539 
540  return symbol;
541 }
virtual std::string getPropertyName(std::size_t i) const =0
It returns the property name at position pos.
virtual double getDouble(std::size_t i) const =0
Method for retrieving a double attribute value.
bool isActive() const
Verify if the task is active.
TEQTWIDGETSEXPORT Histogram * createHistogram(te::da::DataSet *dataset, te::da::DataSetType *dataType, int propId, int slices)
Histogram Creator.
Definition: Utils.cpp:262
double & getInterval()
It returns the histogram&#39;s interval. Will be invalid if the histogram was created based on string int...
Definition: Histogram.cpp:93
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
TEMAPEXPORT int GetInt(const te::se::ParameterValue *param)
Gets the parameter value as integer.
Definition: Utils.cpp:122
virtual std::auto_ptr< te::rst::Raster > getRaster(std::size_t i) const =0
Method for retrieving a raster attribute value.
virtual float getFloat(std::size_t i) const =0
Method for retrieving a float attribute value.
A class to represent a Histogram.
Definition: Histogram.h:56
void setTotalSteps(int value)
Set the task total stepes.
void getObjectIds(te::da::DataSet *dataset, std::vector< std::size_t > pkeys, std::vector< te::da::ObjectId * > &valuesOIDs)
Definition: Utils.cpp:129
virtual std::auto_ptr< te::dt::DateTime > getDateTime(std::size_t i) const =0
Method for retrieving a date and time attribute value.
virtual boost::int32_t getInt32(std::size_t i) const =0
Method for retrieving a 32-bit integer attribute value (4 bytes long).
void setType(int new_type)
It sets the histogram&#39;s type.
Definition: Histogram.cpp:58
virtual std::string getString(std::size_t i) const =0
Method for retrieving a string value attribute.
A template for atomic data types (integers, floats, strings and others).
Definition: SimpleData.h:59
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
virtual std::string getNumeric(std::size_t i) const =0
Method for retrieving a numeric attribute value.
A class to represent a histogram.
virtual bool isNull(std::size_t i) const =0
It checks if the attribute value is NULL.
A base class for date data types.
Definition: Date.h:53
virtual boost::int16_t getInt16(std::size_t i) const =0
Method for retrieving a 16-bit integer attribute value (2 bytes long).
void setStringInterval(std::set< std::string > new_Interval)
It sets the histogram&#39;s string set of intervals.
Definition: Histogram.cpp:108
TEDATAACCESSEXPORT ObjectId * GenerateOID(DataSet *dataset, const std::vector< std::string > &names)
Definition: Utils.cpp:393
A class to represent a scatter.
Definition: Scatter.h:51
Utility functions for the data access module.
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
void addY(double &yValue)
It adds a new value to the vector containing the Y axis values.
Definition: Scatter.cpp:151
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
Definition: RGBAColor.h:57
SimpleData< std::string, STRING_TYPE > String
Definition: SimpleData.h:229
TEDATAACCESSEXPORT void GetOIDPropertyPos(const DataSetType *type, std::vector< std::size_t > &ppos)
Definition: Utils.cpp:351
A Font specifies the text font to use in a text symbolizer.
Definition: Font.h:63
virtual int getPropertyDataType(std::size_t i) const =0
It returns the underlying data type of the property at position pos.
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: Utils.cpp:428
virtual boost::int64_t getInt64(std::size_t i) const =0
Method for retrieving a 64-bit integer attribute value (8 bytes long).
A class to represent a scatter.
void calculateMinMaxValues()
Calculates the minimum and maximum values for both the X and Y axis.
Definition: Scatter.cpp:53
virtual bool moveBeforeFirst()=0
It moves the internal pointer to a position before the first item in the collection.
This class represents an unique id for a data set element.
Definition: ObjectId.h:47
TEQTWIDGETSEXPORT Scatter * createScatter(te::da::DataSet *dataset, te::da::DataSetType *dataType, int propX, int propY)
Scatter Creator.
Definition: Utils.cpp:155
TEQTWIDGETSEXPORT QwtText * Terralib2Qwt(const std::string &title)
Definition: Utils.cpp:483
void insert(std::pair< te::dt::AbstractData *, unsigned int > new_value, std::vector< te::da::ObjectId * > valuesOIds)
It adds a new value to the map containing the histogram values.
Definition: Histogram.cpp:113
A class that models the description of a dataset.
Definition: DataSetType.h:72
void setMinValue(double new_minValue)
It sets the histogram&#39;s minimum value.
Definition: Histogram.cpp:88
A class to represent time instant.
Definition: TimeInstant.h:55
const ParameterValue * getSize() const
Definition: Graphic.cpp:120
void setInterval(double new_Interval)
It sets the histogram&#39;s interval.
Definition: Histogram.cpp:98
void addData(double &xValue, double &yValue, te::da::ObjectId *oid)
It adds the x and Y axis values to the scatter&#39;s vectors and the associeted objectId to the scatter&#39;s...
Definition: Scatter.cpp:156
double getDouble(const std::string &value, std::vector< std::string > &sVector)
Definition: Utils.cpp:54
void setMessage(const std::string &message)
Set the task message.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
void addX(double &xValue)
It adds a new value to the vector containing the X axis values.
Definition: Scatter.cpp:146
const std::vector< ExternalGraphic * > getExternalGraphics() const
Definition: Graphic.cpp:76
SimpleData< double, DOUBLE_TYPE > Double
Definition: SimpleData.h:227
static MarkRendererManager & getInstance()
It returns a reference to the singleton instance.
A Graphic is a graphic symbol with an inherent shape, color(s), and possibly size.
Definition: Graphic.h:66
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:111
int getTypeCode() const
It returns the data type code associated to date and time values: DATETIME_TYPE.
Definition: DateTime.h:103
const std::vector< Mark * > getMarks() const
Definition: Graphic.cpp:98
TEQTWIDGETSEXPORT QImage * GetImage(te::color::RGBAColor **img, int width, int height)
It creates a QImage from an RGBA color array.
Definition: Utils.cpp:63