GroupingAlgorithms.h
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 GroupingAlgorithms.h
22 
23  \brief This file contains functions containing the algorithms for grouping values.
24 */
25 
26 #ifndef __TERRALIB_MAPTOOLS_INTERNAL_GROUPINGALGORITHMS_H
27 #define __TERRALIB_MAPTOOLS_INTERNAL_GROUPINGALGORITHMS_H
28 
29 // TerraLib
30 #include "Config.h"
31 #include "../core/translator/Translator.h"
32 #include "../common/StringUtils.h"
33 #include "../fe/Utils.h"
34 #include "../se/Description.h"
35 #include "../se/Rule.h"
36 
37 // STL
38 #include <string>
39 #include <vector>
40 
41 #include <cmath>
42 #include <stdlib.h>
43 
44 
45 #ifndef MIN
46 #define MIN(a,b) ( (a<b) ? a : b ) //!< Macro that returns min between two values
47 #endif
48 
49 #ifndef MAX
50 #define MAX(a,b) ( (a>b) ? a : b ) //!< Macro that returns max between two values
51 #endif
52 
53 
54 namespace te
55 {
56  namespace map
57  {
58  /*!
59  \brief It groups the values using the unique value algorithm.
60 
61  \param attrName The attribute name used do create the group.
62  \param inputValues The data to be grouped by unique values.
63  \param dataType The data type of the values.
64  \param rules The container of rules items where the groups will be placed.
65  \precision The precision to be used in the conversion of the values.
66 
67  \output The groups will be stored in the container of legend items.
68  */
69  TEMAPEXPORT void GroupingByUniqueValues(std::string attrName, std::vector<std::string>& inputValues, int dataType,
70  std::vector<te::se::Rule*>& rules, int precision);
71 
72  /*!
73  \brief It adjusts a value to the precision specified
74 
75  \param value The value to be adjusted.
76  \param precision The precision the given value must be adjusted to.
77  \param reduce Flag indicating if the value must be added or subtracted to the value represented by the precision.
78 
79  \output The value adjusted to the precision specified.
80  */
81  TEMAPEXPORT double AdjustToPrecision(double val, int precision, bool reduce = false);
82 
83  /*!
84  \brief It groups the values defined by a range of iterators using the equal steps algorithm.
85 
86  \param begin The iterator associated to the first element value.
87  \param end The iterator associated to the last element value.
88  \param nSteps The number of steps.
89  \param rules The container of rules items.
90  \param precision The precision to be used in the conversion of the values.
91  \param countElements The flag indicating if the counting of elements must be done.
92 
93  \output The groups will be stored in the container of legend items.
94  */
95  template<class iterator>
96  void GroupingByEqualSteps(std::string attrName, iterator begin, iterator end, int nSteps, std::vector<te::se::Rule*>& rules,
97  int precision = 0)
98  {
99  double min = std::numeric_limits<double>::max();
100  double max = -std::numeric_limits<double>::max();
101 
102  iterator it = begin;
103 
104  while(it < end)
105  {
106  min = MIN(min, *it);
107  max = MAX(max, *it);
108  ++it;
109  }
110 
111  double min_slice, max_slice;
112 
113  double slice = (max - min)/double(nSteps);
114 
115  for(int i = 0; i < nSteps; ++i)
116  {
117  if (i == 0)
118  min_slice = te::map::AdjustToPrecision(min, precision, true);
119  else
120  min_slice = min + double(i) * slice;
121 
122  if (i == nSteps - 1)
123  max_slice = te::map::AdjustToPrecision(max, precision, false);
124  else
125  max_slice = min + double(i + 1) * slice;
126 
127  te::se::Rule* ruleItem = new te::se::Rule;
128  std::string ruleName = "[" + te::common::Convert2String(min_slice, precision) + ", " + te::common::Convert2String(max_slice, precision) + "]";
129  std::string* ruleNamePtr = new std::string(ruleName);
130  ruleItem->setName(ruleNamePtr);
131  ruleItem->setFilter(te::fe::CreateFilterByStep(attrName, te::common::Convert2String(min_slice, precision), te::common::Convert2String(max_slice, precision)));
132 
133  rules.push_back(ruleItem);
134  }
135  }
136 
137  /*!
138  \brief It groups the values defined by a range of iterators using the quantil algorithm.
139 
140  \param begin The iterator associated to the first element value.
141  \param end The iterator associated to the last element value.
142  \param nSteps The number of steps.
143  \param rules The container of rules items.
144  \param precision The precision to be used in the conversion of the values.
145  \param countElements The flag indicating if the counting of elements must be done.
146 
147  \output The groups will be stored in the container of legend items.
148  */
149  template<class iterator>
150  void GroupingByQuantil(std::string attrName, iterator begin, iterator end, int nSteps, std::vector<te::se::Rule*>& rules,
151  int precision = 0)
152  {
153  sort(begin, end);
154 
155  int size = static_cast<int>(end - begin);
156  double steps = (double)size / (double)nSteps;
157 
158  std::vector< std::pair<std::string, std::string> > pairMinMax;
159 
160  int n = 0;
161  iterator it = begin;
162  while(it < end)
163  {
164  std::string minValue = te::common::Convert2String(*it, precision);
165  std::string maxValue = "";
166 
167  int p = (int)(steps * (double)++n + .5);
168 
169  it = begin + p;
170  if(it < end)
171  maxValue = te::common::Convert2String(*it, precision);
172  else
173  maxValue = te::common::Convert2String(*(it - 1), precision);
174 
175  std::pair<std::string, std::string> pair(minValue, maxValue);
176 
177  pairMinMax.push_back(pair);
178  }
179 
180  if(end-begin > 1)
181  {
182  double min = (*begin);
183  double max = (*(end-1));
184 
185  min = te::map::AdjustToPrecision(min, precision, true);
186  pairMinMax[0].first = te::common::Convert2String(min, precision);
187 
188  max = te::map::AdjustToPrecision(max, precision, false);
189  pairMinMax[pairMinMax.size() - 1].second = te::common::Convert2String(max, precision);
190  }
191 
192  for (std::size_t t = 0; t < pairMinMax.size(); ++t)
193  {
194  te::se::Rule* ruleItem = new te::se::Rule;
195  std::string ruleName = "[" + pairMinMax[t].first + ", " + pairMinMax[t].second + "[";
196  std::string* ruleNamePtr = new std::string(ruleName);
197  ruleItem->setName(ruleNamePtr);
198  ruleItem->setFilter(te::fe::CreateFilterByStep(attrName, pairMinMax[t].first, pairMinMax[t].second));
199 
200  rules.push_back(ruleItem);
201  }
202  }
203 
204  /*!
205  \brief It groups the values defined by a range of iterators using the standard deviation algorithm.
206 
207  \param begin The iterator associated to the first element value.
208  \param end The iterator associated to the last element value.
209  \param nDevs The number of deviations.
210  \param rules The container of rules items.
211  \param rmean The mean value.
212  \param precision The precision to be used in the conversion of the values.
213  \param countElements The flag indicating if the counting of elements must be done.
214 
215  \output The groups will be stored in the container of legend items.
216  */
217  template<class iterator>
218  void GroupingByStdDeviation(std::string attrName, iterator begin, iterator end, double nDevs, std::vector<te::se::Rule*>& rules,
219  std::string& meanTitle, int precision = 0)
220  {
221  // Compute min, max and mean
222  double min = std::numeric_limits<double>::max();
223  double max = -std::numeric_limits<double>::max();
224  long double sum = 0.;
225  long double sm2 = 0.;
226 
227  iterator it = begin;
228  while (it < end)
229  {
230  min = MIN(min, *it);
231  max = MAX(max, *it);
232  sum += (*it);
233  sm2 += ((*it) * (*it));
234  ++it;
235  }
236 
237  double count = (double)(end - begin);
238  double mean = (double)(sum / count);
239  long double var = (sm2 / count) - (mean * mean);
240  double stdDev = sqrt(var);
241 
242  double slice = stdDev * nDevs;
243 
244  std::vector<te::se::Rule*> aux;
245 
246  std::string strMean = te::common::Convert2String(mean, precision);
247 
248  double val = mean;
249  while (val - slice > min - slice)
250  {
251  te::se::Rule* ruleItem = new te::se::Rule;
252 
253  double v = val - slice;
254  std::string ruleName = "[" + te::common::Convert2String(v, precision) + ", " + te::common::Convert2String(val, precision) + "[";
255  std::string* ruleNamePtr = new std::string(ruleName);
256  ruleItem->setName(ruleNamePtr);
257  ruleItem->setFilter(te::fe::CreateFilterByStep(attrName, te::common::Convert2String(v, precision), te::common::Convert2String(val, precision)));
258 
259  aux.push_back(ruleItem);
260 
261  val = v;
262  }
263 
264  std::vector<te::se::Rule*>::reverse_iterator sit;
265  for (sit = aux.rbegin(); sit != aux.rend(); ++sit)
266  rules.push_back(*sit);
267 
268  meanTitle = TE_TR("Mean - ") + strMean;
269 
270  te::se::Rule* ruleItemMean = new te::se::Rule;
271  std::string* ruleNamePtr = new std::string(meanTitle);
272  ruleItemMean->setName(ruleNamePtr);
273  ruleItemMean->setFilter(te::fe::CreateFilterByStep(attrName, te::common::Convert2String(mean, precision), te::common::Convert2String(mean, precision)));
274  rules.push_back(ruleItemMean);
275 
276  val = mean;
277  while (val + slice < max + slice)
278  {
279  te::se::Rule* ruleItem = new te::se::Rule;
280 
281  double v = val + slice;
282  std::string ruleName = "[" + te::common::Convert2String(v, precision) + ", " + te::common::Convert2String(val, precision) + "[";
283  std::string* ruleNamePtr = new std::string(ruleName);
284  ruleItem->setName(ruleNamePtr);
285  ruleItem->setFilter(te::fe::CreateFilterByStep(attrName, te::common::Convert2String(v, precision), te::common::Convert2String(val, precision)));
286 
287  aux.push_back(ruleItem);
288 
289  val = v;
290  }
291  }
292  } // end namespace map
293 } // end namespace te
294 
295 #endif //__TERRALIB_MAPTOOLS_INTERNAL_GROUPINGALGORITHMS_H
TEMAPEXPORT void GroupingByUniqueValues(std::string attrName, std::vector< std::string > &inputValues, int dataType, std::vector< te::se::Rule *> &rules, int precision)
It groups the values using the unique value algorithm.
TEFEEXPORT te::fe::Filter * CreateFilterByStep(const std::string &attrName, const std::string &minValue, const std::string &maxValue)
void setName(std::string *name)
#define MIN(a, b)
Macro that returns min between two values.
void setFilter(te::fe::Filter *f)
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
#define MAX(a, b)
Macro that returns max between two values.
TEMAPEXPORT double AdjustToPrecision(double val, int precision, bool reduce=false)
It adjusts a value to the precision specified.
void GroupingByQuantil(std::string attrName, iterator begin, iterator end, int nSteps, std::vector< te::se::Rule *> &rules, int precision=0)
It groups the values defined by a range of iterators using the quantil algorithm. ...
TerraLib.
#define TEMAPEXPORT
You can use this macro in order to export/import classes and functions from this module.
Definition: Config.h:60
void GroupingByEqualSteps(std::string attrName, iterator begin, iterator end, int nSteps, std::vector< te::se::Rule *> &rules, int precision=0)
It groups the values defined by a range of iterators using the equal steps algorithm.
A Rule is used to attach property/scale conditions to and group the individual symbols used for rende...
Definition: Rule.h:76
std::string Convert2String(boost::int16_t value)
It converts a short integer value to a string.
Definition: StringUtils.h:56
void GroupingByStdDeviation(std::string attrName, iterator begin, iterator end, double nDevs, std::vector< te::se::Rule *> &rules, std::string &meanTitle, int precision=0)
It groups the values defined by a range of iterators using the standard deviation algorithm...