All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Band.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008-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 terralib/raster/Band.cpp
22 
23  \brief It gives access to values in one band (dimension) of a raster.
24 */
25 
26 // TerraLib
27 #include "Band.h"
28 #include "BandProperty.h"
29 #include "Utils.h"
30 
31 // STL
32 #include <cassert>
33 #include <limits>
34 
35 te::rst::Band::Band(BandProperty* p, std::size_t idx)
36  : m_property(p),
37  m_idx(idx)
38 {
39 }
40 
42 {
43  delete m_property;
44 }
45 
47 {
48  if(this != &rhs)
49  {
50  delete m_property;
51 
52  m_property = rhs.m_property ? new BandProperty(*rhs.m_property) : 0;
53 
54  m_idx = rhs.m_idx;
55  }
56 
57  return *this;
58 }
59 
60 void te::rst::Band::getValue(unsigned int c, unsigned int r, std::complex<double>& value) const
61 {
62  double vr = 0.0;
63 
64  double vi = 0.0;
65 
66  getValue(c, r, vr);
67 
68  getIValue(c, r, vi);
69 
70  value = std::complex<double>(vr, vi);
71 }
72 
73 void te::rst::Band::setValue(unsigned int c, unsigned int r, const std::complex<double>& value)
74 {
75  setValue(c, r, value.real());
76 
77  setIValue(c, r, value.imag());
78 }
79 
80 std::complex<double> te::rst::Band::getMinValue(unsigned int rs, unsigned int cs, unsigned int rf, unsigned int cf) const
81 {
82  if ((rf == cf) && (rf == 0))
83  {
84  rf = getRaster()->getNumberOfRows() - 1;
85 
86  cf = getRaster()->getNumberOfColumns() - 1;
87  }
88 
89  std::complex<double> pixel;
90 
91  double min_img = std::numeric_limits<double>::max();
92  double min_real = std::numeric_limits<double>::max();
93 
94  for (unsigned r = rs; r <= rf; r++)
95  for (unsigned c = cs; c <= cf; c++)
96  {
97  getValue(c, r, pixel);
98 
99  if (pixel.real() < min_real)
100  min_real = pixel.real();
101 
102  if (pixel.imag() < min_img)
103  min_img = pixel.imag();
104  }
105 
106  return std::complex<double>(min_real, min_img);
107 }
108 
109 std::complex<double> te::rst::Band::getMaxValue(unsigned int rs, unsigned int cs, unsigned int rf, unsigned int cf) const
110 {
111  if ((rf == cf) && (rf == 0))
112  {
113  rf = getRaster()->getNumberOfRows() - 1;
114 
115  cf = getRaster()->getNumberOfColumns() - 1;
116  }
117 
118  std::complex<double> pixel;
119 
120  double max_img = -1.0 * std::numeric_limits<double>::max();
121  double max_real = -1.0 * std::numeric_limits<double>::max();
122 
123  for (unsigned r = rs; r <= rf; r++)
124  for (unsigned c = cs; c <= cf; c++)
125  {
126  getValue(c, r, pixel);
127 
128  if (pixel.real() > max_real)
129  max_real = pixel.real();
130 
131  if (pixel.imag() > max_img)
132  max_img = pixel.imag();
133  }
134 
135  return std::complex<double>(max_real, max_img);
136 }
137 
138 std::complex<double> te::rst::Band::getStdValue(unsigned int rs, unsigned int cs, unsigned int rf, unsigned int cf) const
139 {
140  if ((rf == cf) && (rf == 0))
141  {
142  rf = getRaster()->getNumberOfRows() - 1;
143 
144  cf = getRaster()->getNumberOfColumns() - 1;
145  }
146 
147  std::complex<double> pixel;
148 
149  std::complex<double> mean = getMeanValue(rs, cs, rf, cf);
150 
151  std::complex<double> diff;
152 
153  std::complex<double> sumDiffs(0.0, 0.0);
154 
155  unsigned n = (rf-rs+1) * (cf-cs+1) - 1;
156 
157  if (n == 0)
158  return std::complex<double> (1.0, 1.0);
159 
160  for (unsigned r = rs; r <= rf; r++)
161  for (unsigned c = cs; c <= cf; c++)
162  {
163  getValue(c, r, pixel);
164 
165  diff = pixel - mean;
166 
167  sumDiffs += diff * diff;
168  }
169 
170  return std::complex<double> (std::sqrt(sumDiffs.real() / n), std::sqrt(sumDiffs.imag() / n));
171 }
172 
173 std::complex<double> te::rst::Band::getMeanValue(unsigned int rs, unsigned int cs, unsigned int rf, unsigned int cf) const
174 {
175  if ((rf == cf) && (rf == 0))
176  {
177  rf = getRaster()->getNumberOfRows() - 1;
178 
179  cf = getRaster()->getNumberOfColumns() - 1;
180  }
181 
182  std::complex<double> pixel;
183 
184  std::complex<double> sumValue(0.0, 0.0);
185 
186  unsigned int n = (rf-rs+1) * (cf-cs+1);
187 
188  for (unsigned r = rs; r <= rf; r++)
189  for (unsigned c = cs; c <= cf; c++)
190  {
191  getValue(c, r, pixel);
192 
193  sumValue += pixel;
194  }
195 
196  if (n == 0)
197  return std::complex<double> (0.0, 0.0);
198 
199  return std::complex<double> (sumValue.real() / n, sumValue.imag() / n);
200 }
201 
202 std::map<double, unsigned> te::rst::Band::getHistogramR(unsigned int rs, unsigned int cs, unsigned int rf, unsigned int cf, unsigned int b) const
203 {
204  if ((rf == cf) && (rf == 0))
205  {
206  rf = getRaster()->getNumberOfRows() - 1;
207 
208  cf = getRaster()->getNumberOfColumns() - 1;
209  }
210 
211  std::map<double, unsigned> hist;
212 
213  double pixel;
214 
215  if (b == 0)
216  for (unsigned r = rs; r <= rf; r++)
217  for (unsigned c = cs; c <= cf; c++)
218  {
219  getValue(c, r, pixel);
220 
221  hist[pixel]++;
222  }
223  else
224  {
225 // find limits to divide into bins
226  double pmin = std::numeric_limits<double>::max();
227  double pmax = -1.0 * std::numeric_limits<double>::max();
228 
229  for (unsigned r = rs; r <= rf; r++)
230  for (unsigned c = cs; c <= cf; c++)
231  {
232  getValue(c, r, pixel);
233 
234  if (pixel > pmax)
235  pmax = pixel;
236 
237  if (pixel < pmin)
238  pmin = pixel;
239  }
240 
241 // create histogram with bins
242  double delta = (pmax * 1.000001 - pmin) / b;
243 
244  std::map<std::size_t, double> binsLocations;
245 
246  std::size_t location = 0;
247 
248  for (double bins = pmin; bins < pmax; bins += delta)
249  {
250  hist[bins] = 0;
251 
252  binsLocations[location++] = bins;
253  }
254 
255 // fill histogram
256  for (unsigned r = rs; r <= rf; r++)
257  for (unsigned c = cs; c <= cf; c++)
258  {
259  getValue(c, r, pixel);
260 
261  location = (std::size_t) ((pixel - pmin) / delta);
262 
263  hist[binsLocations[location]]++;
264  }
265 
266 // removing empty bins from histogram
267  for (double bins = pmin; bins < pmax; bins += delta)
268  if(hist[bins] == 0)
269  hist.erase(bins);
270 
271  }
272 
273  return hist;
274 }
275 
276 std::map<double, unsigned> te::rst::Band::getHistogramI(unsigned int rs, unsigned int cs, unsigned int rf, unsigned int cf, unsigned int b) const
277 {
278  if ((rf == cf) && (rf == 0))
279  {
280  rf = getRaster()->getNumberOfRows() - 1;
281 
282  cf = getRaster()->getNumberOfColumns() - 1;
283  }
284 
285  std::map<double, unsigned> hist;
286 
287  double pixel;
288 
289  if (b == 0)
290  for (unsigned r = rs; r <= rf; r++)
291  for (unsigned c = cs; c <= cf; c++)
292  {
293  getIValue(c, r, pixel);
294 
295  hist[pixel]++;
296  }
297  else
298  {
299 // find limits to divide into bins
300  double pmin = std::numeric_limits<double>::max();
301  double pmax = -1.0 * std::numeric_limits<double>::max();
302 
303  for (unsigned r = rs; r <= rf; r++)
304  for (unsigned c = cs; c <= cf; c++)
305  {
306  getIValue(c, r, pixel);
307 
308  if (pixel > pmax)
309  pmax = pixel;
310 
311  if (pixel < pmin)
312  pmin = pixel;
313  }
314 
315 // create histogram with bins
316  double delta = (pmax * 1.000001 - pmin) / b;
317 
318  std::map<std::size_t, double> binsLocations;
319 
320  std::size_t location = 0;
321 
322  for (double bins = pmin; bins < pmax; bins += delta)
323  {
324  hist[bins] = 0;
325 
326  binsLocations[location++] = bins;
327  }
328 
329 // fill histogram
330  for (unsigned r = rs; r <= rf; r++)
331  for (unsigned c = cs; c <= cf; c++)
332  {
333  getIValue(c, r, pixel);
334 
335  location = (std::size_t) ((pixel - pmin) / delta);
336 
337  hist[binsLocations[location]]++;
338  }
339 
340 // removing empty bins from histogram
341  for (double bins = pmin; bins < pmax; bins += delta)
342  if(hist[bins] == 0)
343  hist.erase(bins);
344 
345  }
346 
347  return hist;
348 }
349 
350 std::complex<double> te::rst::Band::getScaleValue() const
351 {
352  return m_property->m_valuesScale;
353 }
354 
355 void te::rst::Band::setScaleValue(const std::complex<double> s)
356 {
357  m_property->m_valuesScale = s;
358 }
359 
360 std::complex<double> te::rst::Band::getOffsetValue() const
361 {
362  return m_property->m_valuesOffset;
363 }
364 
365 void te::rst::Band::setOffsetValue(const std::complex<double> o)
366 {
367  m_property->m_valuesOffset = o;
368 }
369 
371 {
372  return m_property;
373 }
374 
376 {
377  return m_property;
378 }
379 
380 te::rst::Band& te::rst::Band::callOperator(std::complex<double>(*f)(std::complex<double>, std::complex<double>), te::rst::Band& rhs)
381 {
382  assert(getRaster()->getNumberOfRows() == rhs.getRaster()->getNumberOfRows());
383  assert(getRaster()->getNumberOfColumns() == rhs.getRaster()->getNumberOfColumns());
384  assert(getRaster()->getAccessPolicy() == te::common::RWAccess || getRaster()->getAccessPolicy() == te::common::WAccess);
385 
386  std::complex<double> lhsv, rhsv;
387 
388  std::vector<std::pair<unsigned, unsigned> > rcStPos, rcFPos;
389 
390  unsigned last_y;
391  unsigned last_x;
392  for (unsigned x = 0; x < (unsigned) getProperty()->m_nblocksx; x++)
393  {
394  for (unsigned y = 0; y < (unsigned) getProperty()->m_nblocksy; y++)
395  {
396  rcStPos.push_back(std::pair<unsigned, unsigned> (y * getProperty()->m_blkh, x * getProperty()->m_blkw));
397  last_y = (y + 1) * getProperty()->m_blkh;
398  last_x = (x + 1) * getProperty()->m_blkw;
399  if (last_y > getRaster()->getNumberOfRows())
400  last_y = getRaster()->getNumberOfRows();
401  if (last_x > getRaster()->getNumberOfColumns())
402  last_x = getRaster()->getNumberOfColumns();
403  rcFPos.push_back(std::pair<unsigned, unsigned> (last_y, last_x));
404  }
405  }
406 
407 // rasters without no data values
408  if (getProperty()->m_noDataValue == std::numeric_limits<double>::max())
409  {
410  for (unsigned i = 0; i < rcStPos.size(); i++)
411  {
412  for (unsigned r = rcStPos[i].first; r < rcFPos[i].first; r++)
413  for (unsigned c = rcStPos[i].second; c < rcFPos[i].second; c++)
414  {
415  getValue(c, r, lhsv);
416  rhs.getValue(c, r, rhsv);
417 
418  lhsv = f(lhsv, rhsv);
419  setValue(c, r, lhsv);
420  }
421  }
422  }
423 // rasters with no data values
424  else
425  {
426  for (unsigned i = 0; i < rcStPos.size(); i++)
427  {
428  for (unsigned r = rcStPos[i].first; r < rcFPos[i].first; r++)
429  for (unsigned c = rcStPos[i].second; c < rcFPos[i].second; c++)
430  {
431 // lhs data
432  getValue(c, r, lhsv);
433  if (lhsv.real() == getProperty()->m_noDataValue)
434  continue;
435 
436 // rhs data
437  rhs.getValue(c, r, rhsv);
438  if (rhsv.real() == rhs.getProperty()->m_noDataValue)
439  continue;
440 
441  lhsv = f(lhsv, rhsv);
442  setValue(c, r, lhsv);
443  }
444  }
445  }
446 
447  return *this;
448 }
449 
450 std::complex<double> plus(std::complex<double> lhs, std::complex<double> rhs)
451 {
452  return lhs + rhs;
453 }
454 
455 std::complex<double> minus(std::complex<double> lhs, std::complex<double> rhs)
456 {
457  return lhs - rhs;
458 }
459 
460 std::complex<double> times(std::complex<double> lhs, std::complex<double> rhs)
461 {
462  return lhs * rhs;
463 }
464 
465 std::complex<double> divide(std::complex<double> lhs, std::complex<double> rhs)
466 {
467  return lhs / rhs;
468 }
469 
471 {
472  return callOperator(plus, rhs);
473 }
474 
476 {
477  return callOperator(minus, rhs);
478 }
479 
481 {
482  return callOperator(times, rhs);
483 }
484 
486 {
487  return callOperator(divide, rhs);
488 }
489 
491 {
492  int blkw = m_property->m_blkw;
493 
494  int blkh = m_property->m_blkh;
495 
496  int pxlsize = GetPixelSize(m_property->getType());
497 
498  int blksize = blkw * blkh * pxlsize;
499 
500  return blksize;
501 }
502 
504  : m_property(0),
505  m_idx(rhs.m_idx)
506 {
507  m_property = rhs.m_property ? new BandProperty(*rhs.m_property) : 0;
508 }
509 
It gives access to values in one band (dimension) of a raster.
std::complex< double > getOffsetValue() const
It returns the offset values (real and imaginary) to be applied to the band.
Definition: Band.cpp:360
virtual std::map< double, unsigned > getHistogramR(unsigned int rs=0, unsigned int cs=0, unsigned int rf=0, unsigned int cf=0, unsigned int b=0) const
It computes and returns the histogram occurring values (real part) in a window of the band...
Definition: Band.cpp:202
std::complex< double > getScaleValue() const
It returns the scale values (real and imaginary) to be applied to the band.
Definition: Band.cpp:350
TERASTEREXPORT int GetPixelSize(int datatype)
Returns the byte size of a given datatype.
Definition: Utils.cpp:77
virtual Band & operator*=(Band &rhs)
It returns the band product (pixel by pixel).
Definition: Band.cpp:480
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Definition: Raster.cpp:208
It describes one band (or dimension) of a raster.
std::complex< double > plus(std::complex< double > lhs, std::complex< double > rhs)
Definition: Band.cpp:450
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
virtual std::complex< double > getMinValue(unsigned int rs=0, unsigned int cs=0, unsigned int rf=0, unsigned int cf=0) const
It computes and returns the minimum occurring value in a window of the band.
Definition: Band.cpp:80
std::complex< double > divide(std::complex< double > lhs, std::complex< double > rhs)
Definition: Band.cpp:465
Band(BandProperty *p, std::size_t idx)
Constructor.
Definition: Band.cpp:35
A raster band description.
Definition: Band.h:63
virtual Band & operator=(const Band &rhs)
Assignment operator.
Definition: Band.cpp:46
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
virtual Raster * getRaster() const =0
Returns the associated raster.
virtual std::complex< double > getMeanValue(unsigned int rs=0, unsigned int cs=0, unsigned int rf=0, unsigned int cf=0) const
It computes and returns the mean of the occurring values in a window of the band. ...
Definition: Band.cpp:173
virtual Band & operator-=(Band &rhs)
It returns the band subtraction (pixel by pixel).
Definition: Band.cpp:475
std::size_t m_idx
The band index.
Definition: Band.h:414
virtual Band & operator+=(Band &rhs)
It returns the band sum (pixel by pixel).
Definition: Band.cpp:470
void setScaleValue(const std::complex< double > s)
Sets the scale values (real and imaginary) to be applied to the band.
Definition: Band.cpp:355
virtual int getBlockSize() const
It returns the number of bytes ocuppied by a data block.
Definition: Band.cpp:490
std::complex< double > minus(std::complex< double > lhs, std::complex< double > rhs)
Definition: Band.cpp:455
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
Definition: Raster.cpp:213
A raster band description.
Definition: BandProperty.h:61
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits&lt;double&gt;::max().
Definition: BandProperty.h:136
std::complex< double > times(std::complex< double > lhs, std::complex< double > rhs)
Definition: Band.cpp:460
virtual ~Band()
Virtual destructor.
Definition: Band.cpp:41
Band & callOperator(std::complex< double >(*f)(std::complex< double >, std::complex< double >), Band &rhs)
It calls a parameter function f to apply in all pixels from two bands, e.g. pixel = f(lhs...
Definition: Band.cpp:380
BandProperty * getProperty()
Returns the band property.
Definition: Band.cpp:370
virtual Band & operator/=(Band &rhs)
It returns the band division (pixel by pixel).
Definition: Band.cpp:485
Utility functions for the raster module.
virtual std::map< double, unsigned > getHistogramI(unsigned int rs=0, unsigned int cs=0, unsigned int rf=0, unsigned int cf=0, unsigned int b=0) const
It computes and returns the histogram occurring values (imaginary part) in a window of the band...
Definition: Band.cpp:276
virtual std::complex< double > getMaxValue(unsigned int rs=0, unsigned int cs=0, unsigned int rf=0, unsigned int cf=0) const
It computes and returns the maximum occurring value in a window of the band.
Definition: Band.cpp:109
virtual std::complex< double > getStdValue(unsigned int rs=0, unsigned int cs=0, unsigned int rf=0, unsigned int cf=0) const
It computes and returns the standard deviation of the occurring values in a window of the band...
Definition: Band.cpp:138
BandProperty * m_property
The band information.
Definition: Band.h:413
void setOffsetValue(const std::complex< double > o)
Sets the offset values (real and imaginary) to be applied to the band.
Definition: Band.cpp:365