All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ColorBar.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/color/ColorBar.cpp
22 
23  \brief Implementation of the color bar concept.
24 */
25 
26 // TerraLib
27 #include "ColorBar.h"
28 
30  : m_barSize(0)
31 {
32 }
33 
35 {
36  RGBAColor c1(255, 0, 0, 255);
37  RGBAColor c2(255, 255, 255, 255);
38  m_colorMap[0.] = c1;
39  m_colorMap[1.] = c2;
40  m_barSize = size;
41 }
42 
43 te::color::ColorBar::ColorBar(const RGBAColor& colorBegin, const RGBAColor& colorEnd, int size)
44 {
45  m_colorMap[0.] = colorBegin;
46  m_colorMap[1.] = colorEnd;
47  m_barSize = size;
48 }
49 
51  : m_colorBarVec(rhs.m_colorBarVec), m_colorSliceVec(rhs.m_colorSliceVec),
52  m_name(rhs.m_name), m_barSize(rhs.m_barSize), m_colorMap(rhs.m_colorMap)
53 {
54 }
55 
57 {
58  if(this != &rhs)
59  {
60  m_colorBarVec = rhs.m_colorBarVec;
61  m_colorSliceVec = rhs.m_colorSliceVec;
62  m_name = rhs.m_name;
63  m_barSize = rhs.m_barSize;
64  m_colorMap = rhs.m_colorMap;
65  }
66 
67  return *this;
68 }
69 
71 {
72 }
73 
74 const std::string& te::color::ColorBar::getName() const
75 {
76  return m_name;
77 }
78 
79 void te::color::ColorBar::setName(const std::string& name)
80 {
81  m_name = name;
82 }
83 
84 const std::map<double, te::color::RGBAColor>& te::color::ColorBar::getColorMap() const
85 {
86  return m_colorMap;
87 }
88 
90 {
91  int i, p, pp, s;
92  double rd, gd, bd, ad;
93  RGBAColor c, cc, cor;
94  std::map<int, RGBAColor> colorMap;
95 
96  std::map<double, RGBAColor>::iterator iit;
97 
98  for(iit = m_colorMap.begin(); iit != m_colorMap.end(); ++iit)
99  {
100  p = (int)((*iit).first * (double)(m_barSize-1) + .5);
101  colorMap[p] = (*iit).second;
102  }
103 
104  s = 1;
105  std::map<int, RGBAColor>::iterator it = colorMap.begin();
106  while(it != colorMap.end())
107  {
108  p = it->first;
109  c = it->second;
110  if(s <= 0)
111  m_colorBarVec.pop_back();
112  m_colorBarVec.push_back(c);
113 
114  ++it;
115  if(it != colorMap.end())
116  {
117  pp = it->first;
118  cc = it->second;
119  s = pp - p - 1; // amount of colors to be generated
120  if(s >= 1)
121  {
122  rd = double(cc.getRed() - c.getRed()) / double(s + 1);
123  gd = double(cc.getGreen() - c.getGreen()) / double(s + 1);
124  bd = double(cc.getBlue() - c.getBlue()) / double(s + 1);
125  ad = double(cc.getAlpha() - c.getAlpha()) / double(s + 1);
126 
127  for(i = 1; i <= s; ++i)
128  {
129  int r = (int)(rd * (double)i + .5) + c.getRed();
130  int g = (int)(gd * (double)i + .5) + c.getGreen();
131  int b = (int)(bd * (double)i + .5) + c.getBlue();
132  int a = (int)(ad * (double)i + .5) + c.getAlpha();
133  cor.setColor(r, g, b, a);
134  m_colorBarVec.push_back(cor);
135  }
136  }
137  }
138  }
139  while((int)m_colorBarVec.size() < m_barSize)
140  m_colorBarVec.push_back(colorMap.rbegin()->second);
141 }
142 
143 const std::vector<te::color::RGBAColor>& te::color::ColorBar::getColorBar()
144 {
145  if(m_colorBarVec.empty())
146  generateColorBar();
147 
148  return m_colorBarVec;
149 }
150 
151 void te::color::ColorBar::generateSlices(const int& n) //private
152 {
153  int i, j;
154  RGBAColor c;
155  double d = (double)(m_barSize-1) / (double)(n-1);
156 
157  m_colorSliceVec.clear();
158 
159  for(i = 0; i < n; ++i)
160  {
161  j = (int)((double)i * d + .5);
162  c = m_colorBarVec[j];
163  m_colorSliceVec.push_back(c);
164  }
165 }
166 
167 const std::vector<te::color::RGBAColor>& te::color::ColorBar::getSlices(const int& n)
168 {
169  m_colorSliceVec.clear();
170 
171  if(n == 0)
172  return m_colorSliceVec;
173  if(n == 1)
174  {
175  m_colorSliceVec.push_back(m_colorMap.begin()->second);
176  return m_colorSliceVec;
177  }
178 
179  if(m_colorBarVec.empty())
180  generateColorBar();
181 
182  if((int)m_colorSliceVec.size() != n)
183  {
184  m_colorSliceVec.clear();
185  generateSlices(n);
186  }
187 
188  return m_colorSliceVec;
189 }
190 
192 {
193  if(m_colorBarVec.empty())
194  generateColorBar();
195 
196  int size = m_colorBarVec.size();
197  int mean = (int)((double)size / 2. + .5);
198 
199  return m_colorBarVec[mean];
200 }
201 
202 const std::vector<te::color::RGBAColor>& te::color::ColorBar::getLowerMeanSlices(const int& n)
203 {
204  if(m_colorBarVec.empty())
205  generateColorBar();
206 
207  int i, j;
208  RGBAColor c;
209  double d;
210 
211  if(n == 1)
212  d = 1;
213  else
214  d = ((double)(m_barSize-1) / (double)(n-1)) / 2.;
215 
216  m_colorSliceVec.clear();
217 
218  for(i = 0; i < n; ++i)
219  {
220  j = (int)((double)i * d + .5);
221  c = m_colorBarVec[j];
222  m_colorSliceVec.push_back(c);
223  }
224 
225  return m_colorSliceVec;
226 }
227 
228 const std::vector<te::color::RGBAColor>& te::color::ColorBar::getUpperMeanSlices(const int& n)
229 {
230  if(m_colorBarVec.empty())
231  generateColorBar();
232 
233  int i, j;
234  RGBAColor c;
235  double d = ((double)(m_barSize-1) / (double)(n-1)) / 2.;
236 
237  m_colorSliceVec.clear();
238 
239  double halfsize = (double)(m_barSize-1) / 2.;
240  int shift = (int)halfsize;
241 
242  for(i = 0; i < n; ++i)
243  {
244  j = ((int)((double)i * d + .5)) + shift;
245  c = m_colorBarVec[j];
246  m_colorSliceVec.push_back(c);
247  }
248 
249  return m_colorSliceVec;
250 }
251 
252 void te::color::ColorBar::setBarSize(const int& size)
253 {
254  m_colorBarVec.clear();
255  m_colorSliceVec.clear();
256  m_barSize = size;
257 }
258 
260 {
261  return m_barSize;
262 }
263 
264 void te::color::ColorBar::addColor(const RGBAColor& color, const double& ppos)
265 {
266  double p;
267  RGBAColor c;
268  std::map<double, RGBAColor>::iterator it = m_colorMap.find(ppos);
269  m_colorBarVec.clear();
270  m_colorSliceVec.clear();
271 
272  double pos = ppos;
273  if(pos > 1.)
274  pos = 1.;
275  else if(pos < 0.)
276  pos = 0.;
277 
278  if(it == m_colorMap.end())
279  m_colorMap[pos] = color;
280  else
281  {
282  c = (*it).second;
283  std::map<double, RGBAColor>::iterator itt = it;
284 
285  if(pos == 1.)
286  {
287  --itt;
288  p = (*itt).first;
289  p = pos - (pos - p) / 2.;
290  }
291  else if(pos == 0.)
292  {
293  ++itt;
294  p = (*itt).first;
295  p = pos + (p - pos) / 2.;
296  }
297 
298  m_colorMap.erase(it);
299  m_colorMap[p] = c;
300 
301  m_colorMap[pos] = color;
302  }
303 }
304 
306 {
307  std::map<double, RGBAColor>::iterator it;
308  RGBAColor c;
309  m_colorBarVec.clear();
310  m_colorSliceVec.clear();
311 
312  if(m_colorMap.size() > 2)
313  {
314  for(it = m_colorMap.begin(); it != m_colorMap.end(); ++it)
315  {
316  c = (*it).second;
317  if(c.getRed() == color.getRed() && c.getGreen() == color.getGreen() && c.getBlue() == color.getBlue() && c.getAlpha() == color.getAlpha())
318  {
319  m_colorMap.erase(it);
320  break;
321  }
322  }
323  }
324 }
325 
326 void te::color::ColorBar::remove(const int& index)
327 {
328  int i;
329  std::map<double, RGBAColor>::iterator it;
330  m_colorBarVec.clear();
331  m_colorSliceVec.clear();
332 
333  if(m_colorMap.size() > 2)
334  {
335  for(i = 0, it = m_colorMap.begin(); it != m_colorMap.end(); ++i, ++it)
336  {
337  if(i == index)
338  {
339  m_colorMap.erase(it);
340  break;
341  }
342  }
343  }
344 }
345 
346 void te::color::ColorBar::remove(const double& pos)
347 {
348  if(m_colorMap.size() == 2)
349  return;
350 
351  std::map<double, RGBAColor>::iterator it = m_colorMap.find(pos);
352 
353  if(it != m_colorMap.end())
354  {
355  m_colorBarVec.clear();
356  m_colorSliceVec.clear();
357  m_colorMap.erase(pos);
358  }
359 }
360 
362 {
363  int i;
364  std::map<double, RGBAColor>::reverse_iterator it;
365  m_colorBarVec.clear();
366  m_colorSliceVec.clear();
367 
368  if(m_colorMap.size() > 2)
369  {
370  for(i = 0, it = m_colorMap.rbegin(); it != m_colorMap.rend(); ++i, ++it)
371  {
372  if(i == index)
373  {
374  m_colorMap.erase(it->first);
375  break;
376  }
377  }
378  }
379 }
380 
381 void te::color::ColorBar::changeColor(const double& pos, const RGBAColor& color)
382 {
383  std::map<double, RGBAColor>::iterator it = m_colorMap.find(pos);
384  if(it != m_colorMap.end())
385  {
386  m_colorBarVec.clear();
387  m_colorSliceVec.clear();
388  it->second = color;
389  }
390 }
391 
392 void te::color::ColorBar::changeColor(const int& index, const RGBAColor& color)
393 {
394  int i;
395  std::map<double, RGBAColor>::iterator it;
396  m_colorBarVec.clear();
397  m_colorSliceVec.clear();
398 
399  for(i = 0, it = m_colorMap.begin(); it != m_colorMap.end(); ++i, ++it)
400  {
401  if(i == index)
402  {
403  it->second = color;
404  break;
405  }
406  }
407 }
408 
409 void te::color::ColorBar::move(const RGBAColor& color, const double& ppos)
410 {
411  double p, pp;
412  RGBAColor c;
413  std::map<double, RGBAColor>::iterator it;
414  m_colorBarVec.clear();
415  m_colorSliceVec.clear();
416 
417  double pos = ppos;
418  if(pos > 1.)
419  pos = 1.;
420  else if(pos < 0.)
421  pos = 0.;
422 
423  for(it = m_colorMap.begin(); it != m_colorMap.end(); ++it)
424  {
425  c = (*it).second;
426  if(c.getRed() == color.getRed() && c.getGreen() == color.getGreen() && c.getBlue() == color.getBlue() && c.getAlpha() == color.getAlpha())
427  break;
428  }
429 
430  if(it == m_colorMap.end()) // color not found
431  return;
432 
433  p = (*it).first;
434  if(p == 0. || p == 1.) // The first and last color can not be moved directly.
435  {
436  if(m_colorMap.size() == 2) // but if you have only two colors, makes the exchange
437  {
438  std::map<double, RGBAColor>::iterator itt = it;
439  if(p == 0.)
440  ++itt;
441  else
442  --itt;
443  (*it).second = (*itt).second;
444  (*itt).second = color;
445  }
446  return;
447  }
448 
449  m_colorMap.erase(it); // remove color
450 
451  it = m_colorMap.find(pos);
452 
453  if(it == m_colorMap.end()) // If there is no color at index pos
454  {
455  m_colorMap[pos] = color;
456  }
457  else
458  {
459  pp = p;
460  c = (*it).second;
461 
462  std::map<double, RGBAColor>::iterator itt = it;
463 
464  if(pp < pos)
465  {
466  --itt;
467  p = (*itt).first;
468  if(pp == p)
469  {
470  --itt;
471  p = (*itt).first;
472  }
473  p = pos - (pos - p) / 2.;
474  }
475  else
476  {
477  ++itt;
478  p = (*itt).first;
479  if(pp == p)
480  {
481  ++itt;
482  p = (*itt).first;
483  }
484  p = pos + (p - pos) / 2.;
485  }
486 
487  m_colorMap.erase(it);
488  m_colorMap[p] = c;
489  m_colorMap[pos] = color;
490  }
491 }
492 
493 int te::color::ColorBar::move(const int& index, const double& ppos)
494 {
495  int i;
496  double p, pp;
497  RGBAColor c, color;
498  std::map<double, RGBAColor>::iterator it;
499  m_colorBarVec.clear();
500  m_colorSliceVec.clear();
501 
502  if(index >= (int)m_colorMap.size())
503  return index;
504 
505  if(index == 0 || index == (int)(m_colorMap.size()-1))
506  return index;
507 
508  for(i = 0, it = m_colorMap.begin(); it != m_colorMap.end(); ++i, ++it)
509  if(i == index)
510  break;
511 
512  p = (*it).first;
513  pp = move(p, ppos);
514 
515  for(i = 0, it = m_colorMap.begin(); it != m_colorMap.end(); ++i, ++it)
516  if(it->first == pp)
517  break;
518 
519  return i;
520 }
521 
522 double te::color::ColorBar:: move(const double& p, const double& ppos)
523 {
524  std::map<double, RGBAColor>::iterator it = m_colorMap.find(p);
525  if(it == m_colorMap.end())
526  return p;
527 
528  double pp, d = 1. / (double)m_barSize;
529  double pos = ppos;
530  if(pos > 1.)
531  pos = 1.;
532  else if(pos < 0.)
533  pos = 0.;
534 
535  if(p == pos)
536  return pos;
537  if(p == 0. || p == 1.)
538  return ppos;
539 
540  std::map<double, RGBAColor>::iterator itp = m_colorMap.find(pos);
541 
542  m_colorBarVec.clear();
543  m_colorSliceVec.clear();
544 
545  RGBAColor c = it->second, cc;
546  m_colorMap.erase(p);
547 
548  if(itp == m_colorMap.end())
549  {
550  addColor(c, pos);
551  return pos;
552  }
553 
554  if(p > pos)
555  {
556  if(pos != 0.)
557  {
558  it = m_colorMap.begin();
559  pp = it->first;
560  while(it->first != pos)
561  {
562  pp = it->first;
563  ++it;
564  }
565  while(pos-d <= pp)
566  d /= 10.;
567  pos -= d;
568  m_colorMap[pos] = c;
569  return pos;
570  }
571  else
572  {
573  it = m_colorMap.begin();
574  cc = it->second;
575  ++it;
576  pp = it->first;
577  while(pos+d >= pp)
578  d /= 10.;
579  pos += d;
580  m_colorMap[0.] = c;
581  m_colorMap[pos] = cc;
582  return pos;
583  }
584  }
585  else
586  {
587  if(pos != 1.)
588  {
589  it = m_colorMap.begin();
590  while(it->first != pos)
591  ++it;
592  ++it;
593  pp = it->first;
594  while(pos+d >= pp)
595  d /= 10.;
596  pos += d;
597  m_colorMap[pos] = c;
598  return pos;
599  }
600  else
601  {
602  it = m_colorMap.end();
603  --it;
604  cc = it->second;
605  --it;
606  pp = it->first;
607  while(pos-d <= pp)
608  d /= 10.;
609  pos -= d;
610  m_colorMap[1.] = c;
611  m_colorMap[pos] = cc;
612  return pos;
613  }
614  }
615 }
616 
617 int te::color::ColorBar::moveReverse(const int& index, const double& ppos)
618 {
619  int i;
620  double p, pp;
621  RGBAColor c, color;
622  std::map<double, RGBAColor>::reverse_iterator it;
623  m_colorBarVec.clear();
624  m_colorSliceVec.clear();
625 
626  if(index >= (int)m_colorMap.size())
627  return index;
628 
629  for(i = 0, it = m_colorMap.rbegin(); it != m_colorMap.rend(); ++i, ++it)
630  if(i == index)
631  break;
632 
633  p = (*it).first;
634  pp = move(p, ppos);
635 
636  for(i = 0, it = m_colorMap.rbegin(); it != m_colorMap.rend(); ++i, ++it)
637  if(it->first == pp)
638  break;
639 
640  return i;
641 }
642 
void remove(const RGBAColor &color)
It removes a color in the color bar.
Definition: ColorBar.cpp:305
void generateSlices(const int &n)
It generates legend colors.
Definition: ColorBar.cpp:151
void setColor(const std::string &hexColor)
It sets the color using a two hexadecimal RGB-encoded color.
Definition: RGBAColor.h:329
int getRed() const
It returns the red component color value (a value from 0 to 255).
Definition: RGBAColor.h:295
~ColorBar()
Destructor.
Definition: ColorBar.cpp:70
const std::string & getName() const
It returns the color bar name.
Definition: ColorBar.cpp:74
const std::map< double, te::color::RGBAColor > & getColorMap() const
It gets color map.
Definition: ColorBar.cpp:84
int getBlue() const
It returns the blue component color value (a value from 0 to 255).
Definition: RGBAColor.h:305
void addColor(const RGBAColor &color, const double &pos)
It adds a color in the color bar.
Definition: ColorBar.cpp:264
const std::vector< te::color::RGBAColor > & getColorBar()
It generates color bar.
Definition: ColorBar.cpp:143
int getGreen() const
It returns the green component color value (a value from 0 to 255).
Definition: RGBAColor.h:300
void changeColor(const double &pos, const RGBAColor &color)
It moves a color to new posisiton.
Definition: ColorBar.cpp:381
te::color::ColorBar & operator=(const ColorBar &rhs)
Definition: ColorBar.cpp:56
void move(const RGBAColor &color, const double &pos)
It moves a color to new posisiton.
Definition: ColorBar.cpp:409
std::vector< RGBAColor > m_colorSliceVec
Color step vector.
Definition: ColorBar.h:291
const std::vector< te::color::RGBAColor > & getSlices(const int &n)
It generates color bar.
Definition: ColorBar.cpp:167
int moveReverse(const int &index, const double &pos)
It moves a color to new posisiton.
Definition: ColorBar.cpp:617
int m_barSize
Size of color bar (number of colors in the color bar).
Definition: ColorBar.h:293
ColorBar()
It initializes a new ColorBar(default constructor)
Definition: ColorBar.cpp:29
int getBarSize()
It returns number of colors in the color bar.
Definition: ColorBar.cpp:259
const std::vector< te::color::RGBAColor > & getUpperMeanSlices(const int &n)
Definition: ColorBar.cpp:228
int getAlpha() const
It returns the alpha component color value (a value from 0 to 255).
Definition: RGBAColor.h:310
const std::vector< te::color::RGBAColor > & getLowerMeanSlices(const int &n)
Definition: ColorBar.cpp:202
The concept of color bar.
void setName(const std::string &name)
It sets the color bar name and adjust its entry in the scheme group if needed.
Definition: ColorBar.cpp:79
void removeReverse(const int &index)
It removes a color in the color bar.
Definition: ColorBar.cpp:361
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
Definition: RGBAColor.h:57
void generateColorBar()
It generates bar colors.
Definition: ColorBar.cpp:89
std::vector< RGBAColor > m_colorBarVec
Color vector.
Definition: ColorBar.h:290
It models the concept of color bar.
Definition: ColorBar.h:49
void setBarSize(const int &size)
It sets number of colors in the color bar.
Definition: ColorBar.cpp:252
std::map< double, RGBAColor > m_colorMap
Color map.
Definition: ColorBar.h:294
std::string m_name
Color bar name.
Definition: ColorBar.h:292
const te::color::RGBAColor & getMeanSlice()
Definition: ColorBar.cpp:191