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 slice = (max - min)/double(nSteps);
112 
113  for(int i = 0; i < nSteps; ++i)
114  {
115  if (i == 0)
116  min = te::map::AdjustToPrecision(min, precision, true);
117  else
118  min = min + double(i) * slice;
119 
120  if (i == nSteps - 1)
121  max = te::map::AdjustToPrecision(max, precision, false);
122  else
123  max = min + double(i + 1) * slice;
124 
125  te::se::Rule* ruleItem = new te::se::Rule;
126  std::string ruleName = "[" + te::common::Convert2String(min, precision) + ", " + te::common::Convert2String(max, precision) + "[";
127  std::string* ruleNamePtr = new std::string(ruleName);
128  ruleItem->setName(ruleNamePtr);
129  ruleItem->setFilter(te::fe::CreateFilterByStep(attrName, te::common::Convert2String(min, precision), te::common::Convert2String(max, precision)));
130 
131  rules.push_back(ruleItem);
132  }
133  }
134 
135  /*!
136  \brief It groups the values defined by a range of iterators using the quantil algorithm.
137 
138  \param begin The iterator associated to the first element value.
139  \param end The iterator associated to the last element value.
140  \param nSteps The number of steps.
141  \param rules The container of rules items.
142  \param precision The precision to be used in the conversion of the values.
143  \param countElements The flag indicating if the counting of elements must be done.
144 
145  \output The groups will be stored in the container of legend items.
146  */
147  template<class iterator>
148  void GroupingByQuantil(std::string attrName, iterator begin, iterator end, int nSteps, std::vector<te::se::Rule*>& rules,
149  int precision = 0)
150  {
151  sort(begin, end);
152 
153  int size = static_cast<int>(end - begin);
154  double steps = (double)size / (double)nSteps;
155 
156  std::vector< std::pair<std::string, std::string> > pairMinMax;
157 
158  int n = 0;
159  iterator it = begin;
160  while(it < end)
161  {
162  std::string minValue = te::common::Convert2String(*it, precision);
163  std::string maxValue = "";
164 
165  int p = (int)(steps * (double)++n + .5);
166 
167  it = begin + p;
168  if(it < end)
169  maxValue = te::common::Convert2String(*it, precision);
170  else
171  maxValue = te::common::Convert2String(*(it - 1), precision);
172 
173  std::pair<std::string, std::string> pair(minValue, maxValue);
174 
175  pairMinMax.push_back(pair);
176  }
177 
178  if(end-begin > 1)
179  {
180  double min = (*begin);
181  double max = (*(end-1));
182 
183  min = te::map::AdjustToPrecision(min, precision, true);
184  pairMinMax[0].first = te::common::Convert2String(min, precision);
185 
186  max = te::map::AdjustToPrecision(max, precision, false);
187  pairMinMax[pairMinMax.size() - 1].second = te::common::Convert2String(max, precision);
188  }
189 
190  for (std::size_t t = 0; t < pairMinMax.size(); ++t)
191  {
192  te::se::Rule* ruleItem = new te::se::Rule;
193  std::string ruleName = "[" + pairMinMax[t].first + ", " + pairMinMax[t].second + "[";
194  std::string* ruleNamePtr = new std::string(ruleName);
195  ruleItem->setName(ruleNamePtr);
196  ruleItem->setFilter(te::fe::CreateFilterByStep(attrName, pairMinMax[t].first, pairMinMax[t].second));
197 
198  rules.push_back(ruleItem);
199  }
200  }
201 
202  /*!
203  \brief It groups the values defined by a range of iterators using the standard deviation algorithm.
204 
205  \param begin The iterator associated to the first element value.
206  \param end The iterator associated to the last element value.
207  \param nDevs The number of deviations.
208  \param rules The container of rules items.
209  \param rmean The mean value.
210  \param precision The precision to be used in the conversion of the values.
211  \param countElements The flag indicating if the counting of elements must be done.
212 
213  \output The groups will be stored in the container of legend items.
214  */
215  template<class iterator>
216  void GroupingByStdDeviation(std::string attrName, iterator begin, iterator end, double nDevs, std::vector<te::se::Rule*>& rules,
217  std::string& meanTitle, int precision = 0)
218  {
219  // Compute min, max and mean
220  double min = std::numeric_limits<double>::max();
221  double max = -std::numeric_limits<double>::max();
222  long double sum = 0.;
223  long double sm2 = 0.;
224 
225  iterator it = begin;
226  while (it < end)
227  {
228  min = MIN(min, *it);
229  max = MAX(max, *it);
230  sum += (*it);
231  sm2 += ((*it) * (*it));
232  ++it;
233  }
234 
235  double count = (double)(end - begin);
236  double mean = (double)(sum / count);
237  long double var = (sm2 / count) - (mean * mean);
238  double stdDev = sqrt(var);
239 
240  double slice = stdDev * nDevs;
241 
242  std::vector<te::se::Rule*> aux;
243 
244  std::string strMean = te::common::Convert2String(mean, precision);
245 
246  double val = mean;
247  while (val - slice > min - slice)
248  {
249  te::se::Rule* ruleItem = new te::se::Rule;
250 
251  double v = val - slice;
252  std::string ruleName = "[" + te::common::Convert2String(v, precision) + ", " + te::common::Convert2String(val, precision) + "[";
253  std::string* ruleNamePtr = new std::string(ruleName);
254  ruleItem->setName(ruleNamePtr);
255  ruleItem->setFilter(te::fe::CreateFilterByStep(attrName, te::common::Convert2String(v, precision), te::common::Convert2String(val, precision)));
256 
257  aux.push_back(ruleItem);
258 
259  val = v;
260  }
261 
262  std::vector<te::se::Rule*>::reverse_iterator sit;
263  for (sit = aux.rbegin(); sit != aux.rend(); ++sit)
264  rules.push_back(*sit);
265 
266  meanTitle = TE_TR("Mean - ") + strMean;
267 
268  te::se::Rule* ruleItemMean = new te::se::Rule;
269  std::string* ruleNamePtr = new std::string(meanTitle);
270  ruleItemMean->setName(ruleNamePtr);
271  ruleItemMean->setFilter(te::fe::CreateFilterByStep(attrName, te::common::Convert2String(mean, precision), te::common::Convert2String(mean, precision)));
272  rules.push_back(ruleItemMean);
273 
274  val = mean;
275  while (val + slice < max + slice)
276  {
277  te::se::Rule* ruleItem = new te::se::Rule;
278 
279  double v = val + slice;
280  std::string ruleName = "[" + te::common::Convert2String(v, precision) + ", " + te::common::Convert2String(val, precision) + "[";
281  std::string* ruleNamePtr = new std::string(ruleName);
282  ruleItem->setName(ruleNamePtr);
283  ruleItem->setFilter(te::fe::CreateFilterByStep(attrName, te::common::Convert2String(v, precision), te::common::Convert2String(val, precision)));
284 
285  aux.push_back(ruleItem);
286 
287  val = v;
288  }
289  }
290  } // end namespace map
291 } // end namespace te
292 
293 #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.
void setName(std::string *name)
Definition: Rule.cpp:58
TEMAPEXPORT double AdjustToPrecision(double val, int precision, bool reduce=false)
It adjusts a value to the precision specified.
#define MIN(a, b)
Macro that returns min between two values.
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. ...
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.
void setFilter(te::fe::Filter *f)
Definition: Rule.cpp:91
#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.
TEFEEXPORT te::fe::Filter * CreateFilterByStep(const std::string &attrName, const std::string &minValue, const std::string &maxValue)
URI C++ Library.
Definition: Attributes.h:37
te::gm::Polygon * p
A Rule is used to attach property/scale conditions to and group the individual symbols used for rende...
Definition: Rule.h:76
#define TEMAPEXPORT
You can use this macro in order to export/import classes and functions from this module.
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...