BandIterator.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 terralib/raster/BandIterator.h
22 
23  \brief It implements an iterator to "navigate" over a single band (const or not const).
24 */
25 
26 #ifndef __TERRALIB_RASTER_INTERNAL_BANDITERATOR_H
27 #define __TERRALIB_RASTER_INTERNAL_BANDITERATOR_H
28 
29 // Terralib
30 #include "Band.h"
31 #include "BandProperty.h"
32 #include "BlockUtils.h"
33 
34 // Boost
35 #include <boost/dynamic_bitset.hpp>
36 
37 namespace te
38 {
39  namespace rst
40  {
41 // Forward declaration.
42  class Band;
43 
44  /*!
45  \class AbstractBandIterator
46 
47  \brief This class implements an abstract iterator to "navigate" over a single band.
48 
49  We provide an efficient method to obtain all values in a raster, without regard
50  to their locations. The implementation navigates through the blocks of the image.
51 
52  \ingroup rst
53 
54  \sa te::rst::Band
55  */
56  template<class T> class AbstractBandIterator
57  {
58  public:
59 
60  /*! \brief Constructor. */
62 
63  /*!
64  \brief Constructor.
65 
66  \param b The band to iterate.
67  */
69 
70  /*!
71  \brief Copy constructor.
72 
73  \param rhs The right-hand-side copy used to copy from.
74  */
76 
77  /*! \brief Destructor. */
79 
80  /*! \brief Returns the value in current position (column, row) from iterator. */
81  virtual const T operator*() const = 0;
82 
83  /*! \brief Returns the current row in iterator. */
84  unsigned int getRow() const;
85 
86  /*! \brief Returns the current column in iterator. */
87  unsigned int getColumn() const;
88 
89  /*! \brief Advances to the next position. */
90  virtual void operator++();
91 
92  /*! \brief Returns to the previous position. */
93  void operator--();
94 
95  /*!
96  \brief Assignment operator.
97 
98  \param rhs The right-hand-side copy used to copy from.
99 
100  \return A reference to this object.
101  */
103 
104  /*!
105  \brief Difference operator.
106 
107  \param rhs The right-hand side to compare.
108 
109  \return Returns true if the iterators are at different positions, or false otherwise.
110  */
111  bool operator!=(const AbstractBandIterator& rhs) const;
112 
113  /*! \brief Replaces the current bufferized block values. */
114  virtual void replaceBlock() = 0;
115 
116  protected:
117 
118  int m_blkw; //!< The internal block width.
119  int m_blkh; //!< The internal block height.
120  int m_npxlsblk; //!< The maximum number of pixels inside the block.
121  int m_nblocksx; //!< The number of blocks in X direction.
122  int m_nblocksy; //!< The number of blocks in Y direction.
123  int m_i; //!< The actual position inside the block.
124  int m_blkx; //!< The position in X of the current block.
125  int m_blky; //!< The position in Y of the current block.
126  int m_lastblksize; //!< The number of pixels inside the last block.
127  int m_blksize; //!< The block size of the band.
128  T* m_blk; //!< Internal block.
129  te::rst::GetBufferValueFPtr m_getBuff; //!< A pointer to a function that helps to extract a double or complex value from a specific buffer data type (char, int16, int32, float, ...).
130  te::rst::GetBufferValueFPtr m_getBuffI; //!< A pointer to a function that helps to extract the imaginary part value from a specific buffer data type (cint16, cint32, cfloat, cdouble).
131  te::rst::SetBufferValueFPtr m_setBuff; //!< A pointer to a function that helps to insert a double or complex value into a specific buffer data type (char, int16, int32, float, ...).
132  te::rst::SetBufferValueFPtr m_setBuffI; //!< A pointer to a function that helps to insert the imaginary part value into a specific buffer data type (cint16, cint32, cfloat, cdouble).
133 
134  };
135 
136  /*!
137  \class BandIterator
138 
139  \brief This class implements an iterator to "navigate" over a single band.
140 
141  We provide an efficient method to obtain all values in a raster, without regard
142  to their locations. The implementation navigates through the blocks of the image.
143 
144  \ingroup rst
145 
146  \sa te::rst::Band
147  */
148  template<class T> class BandIterator : public te::rst::AbstractBandIterator<T>
149  {
150  public:
151 
152  /*! \brief Constructor. */
153  BandIterator();
154 
155  /*!
156  \brief Constructor.
157 
158  \param b The band to iterate.
159  */
160  BandIterator(Band* b);
161 
162  /*!
163  \brief Copy constructor.
164 
165  \param rhs The right-hand-side copy used to copy from.
166  */
167  BandIterator(const BandIterator& rhs);
168 
169  /*! \brief Returns the value in current position (column, row) from iterator. */
170  T operator*();
171 
172  /*! \brief Returns the value in current position (column, row) from iterator. */
173  const T operator*() const;
174 
175  /*!
176  \brief Assignment operator.
177 
178  \param rhs The right-hand-side copy used to copy from.
179 
180  \return A reference to this object.
181  */
182  BandIterator& operator=(const BandIterator& rhs);
183 
184  /*! \brief Returns an iterator referring to the first value of the band.*/
185  static BandIterator begin(Band* b);
186 
187  /*! \brief Returns an iterator referring to after the end of the iterator. */
188  static BandIterator end(Band* b);
189 
190  /*! \brief Replaces the current bufferized block values. */
191  void replaceBlock();
192 
193  protected:
194 
195  Band* m_band; //!< The band from where to get the values.
196 
197  };
198 
199  /*!
200  \class ConstBandIterator
201 
202  \brief This class implements an iterator to "navigate" over a single band (const).
203 
204  We provide an efficient method to obtain all values in a raster, without regard
205  to their locations. The implementation navigates through the blocks of the image.
206 
207  \ingroup rst
208 
209  \sa te::rst::Band
210  */
211  template<class T> class ConstBandIterator : public te::rst::AbstractBandIterator<T>
212  {
213  public:
214 
215  /*! \brief Constructor. */
217 
218  /*!
219  \brief Constructor.
220 
221  \param b The band to iterate.
222  */
223  ConstBandIterator(const Band* b);
224 
225  /*!
226  \brief Copy constructor.
227 
228  \param rhs The right-hand-side copy used to copy from.
229  */
231 
232  /*! \brief Returns the value in current position (column, row) from iterator. */
233  const T operator*() const;
234 
235  /*!
236  \brief Assignment operator.
237 
238  \param rhs The right-hand-side copy used to copy from.
239 
240  \return A reference to this object.
241  */
243 
244  /*! \brief Returns an iterator referring to the first value of the band.*/
245  static ConstBandIterator begin(const Band* b);
246 
247  /*! \brief Returns an iterator referring to after the end of the iterator. */
248  static ConstBandIterator end(const Band* b);
249 
250  /*! \brief Replaces the current bufferized block values. */
251  void replaceBlock();
252 
253  protected:
254 
255  const Band* m_band; //!< The band from where to get the values.
256  };
257 
258  /*!
259  \class BandIteratorWithMask
260 
261  \brief This class implements an iterator to "navigate" over a single band, with a spatial restriction given by a mask.
262 
263  We provide an efficient method to obtain all values in a raster, without regard
264  to their locations. The implementation navigates through the blocks of the image.
265  The mask is a 1bit raster where the pixels with value 0 are not returned by the
266  iterator, and pixels with value 1 are returned.
267 
268  \ingroup rst
269 
270  \sa te::rst::Band
271  */
272  template<class T> class BandIteratorWithMask : public te::rst::BandIterator<T>
273  {
274  public:
275 
276  /*! \brief Constructor. */
278 
279  /*!
280  \brief Constructor.
281 
282  \param b The band to iterate.
283  \param m The raster with the mask.
284  */
286 
287  /*!
288  \brief Copy constructor.
289 
290  \param rhs The right-hand-side copy used to copy from.
291  */
293 
294  void operator++();
295 
296  void operator--();
297 
298  /*!
299  \brief Assignment operator.
300 
301  \param rhs The right-hand-side copy used to copy from.
302 
303  \return A reference to this object.
304  */
306 
307  /*! \brief Returns an iterator with the mask referring to the first value of the band.*/
308  static BandIteratorWithMask begin(Band* b, Raster* m);
309 
310  /*! \brief Returns an iterator with the mask referring to after the end of the iterator. */
311  static BandIteratorWithMask end(Band* b, Raster* m);
312 
313  protected:
314  boost::dynamic_bitset<> m_mask; //!< The internal mask of bits, one bit per pixel.
315  unsigned int m_masksize; //!< The size of the mask (rows * columns of the mask raster).
316  unsigned int m_currentpixelindex; //!< The index of the current pixel location.
317 
318  };
319 
320 // Abstract Band Iterator implementation
322  : m_blkw(-1),
323  m_blkh(-1),
324  m_npxlsblk(-1),
325  m_nblocksx(-1),
326  m_nblocksy(-1),
327  m_i(-1),
328  m_blkx(-1),
329  m_blky(-1),
330  m_lastblksize(-1),
331  m_blksize(-1),
332  m_blk(0),
333  m_getBuff(0),
334  m_getBuffI(0),
335  m_setBuff(0),
336  m_setBuffI(0)
337  {
338  }
339 
341  : m_blkw(b->getProperty()->m_blkw),
342  m_blkh(b->getProperty()->m_blkh),
343  m_npxlsblk(m_blkw * m_blkh),
344  m_nblocksx(b->getProperty()->m_nblocksx),
345  m_nblocksy(b->getProperty()->m_nblocksy),
346  m_i(0),
347  m_blkx(0),
348  m_blky(0),
349  m_blksize(b->getBlockSize()),
350  m_getBuff(0),
351  m_getBuffI(0),
352  m_setBuff(0),
353  m_setBuffI(0)
354  {
357 
358  m_blk = new T[m_blksize];
359 
361  }
362 
364  : m_blkw(rhs.m_blkw),
365  m_blkh(rhs.m_blkh),
366  m_npxlsblk(rhs.m_npxlsblk),
367  m_nblocksx(rhs.m_nblocksx),
368  m_nblocksy(rhs.m_nblocksy),
369  m_i(rhs.m_i),
370  m_blkx(rhs.m_blkx),
371  m_blky(rhs.m_blky),
372  m_lastblksize(rhs.m_lastblksize),
373  m_blksize(rhs.m_blksize),
374  m_getBuff(rhs.m_getBuff),
375  m_getBuffI(rhs.m_getBuffI),
376  m_setBuff(rhs.m_setBuff),
377  m_setBuffI(rhs.m_setBuffI)
378  {
379  if (m_blksize > 0)
380  m_blk = new T[m_blksize];
381  }
382 
384  {
385  if (m_blksize > 0)
386  delete [] m_blk;
387  }
388 
389  template<class T> unsigned int te::rst::AbstractBandIterator<T>::getRow() const
390  {
391  return m_blky * m_blkh + (m_i - (m_i % m_blkw)) / m_blkw;
392  }
393 
394  template<class T> unsigned int te::rst::AbstractBandIterator<T>::getColumn() const
395  {
396  return m_blkx * m_blkw + m_i % m_blkw;
397  }
398 
400  {
401  m_i++;
402 
403  if(m_i < m_npxlsblk)
404  return;
405 
406  m_i = 0;
407 
408  m_blkx++;
409 
410  if(m_blkx < m_nblocksx)
411  {
412  replaceBlock();
413 
414  return;
415  }
416 
417  m_blkx = 0;
418 
419  m_blky++;
420 
421  if(m_blky < m_nblocksy)
422  replaceBlock();
423 
424  if((m_blkx == m_nblocksx - 1) && (m_blky == m_nblocksy - 1))
425  m_npxlsblk = m_lastblksize;
426  }
427 
429  {
430  m_i--;
431 
432  if(m_i >= 0)
433  return;
434 
435  m_i = m_npxlsblk - 1;
436 
437  m_blkx--;
438 
439  if(m_blkx >= 0)
440  {
441  replaceBlock();
442 
443  return;
444  }
445 
446  m_blkx = m_nblocksx - 1;
447 
448  m_blky--;
449 
450  if(m_blky >= 0)
451  replaceBlock();
452  else
453  m_blky = m_nblocksy;
454  }
455 
457  {
458  if (this != &rhs)
459  {
460  m_blkw = rhs.m_blkw;
461  m_blkh = rhs.m_blkh;
462  m_npxlsblk = rhs.m_npxlsblk;
463  m_nblocksx = rhs.m_nblocksx;
464  m_nblocksy = rhs.m_nblocksy;
465  m_i = rhs.m_i;
466  m_blkx = rhs.m_blkx;
467  m_blky = rhs.m_blky;
468  m_lastblksize = rhs.m_lastblksize;
469 
470  delete [] m_blk;
471  m_blk = new T[rhs.m_blksize];
472  }
473 
474  return *this;
475  }
476 
478  {
479  return (m_blky != rhs.m_blky);
480  }
481 
482 // Band Iterator implementation
484  : te::rst::AbstractBandIterator<T>(),
485  m_band(0)
486  {
487  }
488 
490  : te::rst::AbstractBandIterator<T>(b),
491  m_band(b)
492  {
493  if (this->m_blksize > 0)
494  this->replaceBlock();
495  }
496 
498  : te::rst::AbstractBandIterator<T>(rhs),
499  m_band(rhs.m_band)
500  {
501  if (this->m_blksize > 0)
502  this->replaceBlock();
503  }
504 
506  {
507  double value;
508 
509  this->m_getBuff(this->m_i, this->m_blk, &value);
510 
511  return (T) value;
512  }
513 
514  template<class T> const T te::rst::BandIterator<T>::operator*() const
515  {
516  double value;
517 
518  this->m_getBuff(this->m_i, this->m_blk, &value);
519 
520  return (T) value;
521  }
522 
524  {
526 
527  m_band = rhs.m_band;
528 
529  return *this;
530  }
531 
533  {
534  return te::rst::BandIterator<T>(b);
535  }
536 
538  {
540 
541  it.m_blky = b->getProperty()->m_nblocksy;
542 
543  return it;
544  }
545 
546  template<class T> void te::rst::BandIterator<T>::replaceBlock()
547  {
548  m_band->read(this->m_blkx, this->m_blky, this->m_blk);
549  }
550 
551 // Const Band Iterator implementation
553  : te::rst::AbstractBandIterator<T>(),
554  m_band(0)
555  {
556  }
557 
559  : te::rst::AbstractBandIterator<T>(b), // (te::rst::Band*)(b) ?
560  m_band(b)
561  {
562  if (this->m_blksize > 0)
563  this->replaceBlock();
564  }
565 
567  : te::rst::AbstractBandIterator<T>(rhs),
568  m_band(rhs.m_band)
569  {
570  if (this->m_blksize > 0)
571  this->replaceBlock();
572  }
573 
574  template<class T> const T te::rst::ConstBandIterator<T>::operator*() const
575  {
576  double value;
577 
578  this->m_getBuff(this->m_i, this->m_blk, &value);
579 
580  return (T) value;
581  }
582 
584  {
586 
587  m_band = rhs.m_band;
588 
589  return *this;
590  }
591 
593  {
595  }
596 
598  {
600 
601  it.m_blky = b->getProperty()->m_nblocksy;
602 
603  return it;
604  }
605 
607  {
608  m_band->read(this->m_blkx, this->m_blky, this->m_blk);
609  }
610 
611 // Band Iterator With Mask implementation
613  : te::rst::BandIterator<T>(),
614  m_mask(0),
615  m_masksize(0),
616  m_currentpixelindex(0)
617  {
618  }
619 
621  : te::rst::BandIterator<T>(b),
622  m_mask(0),
623  m_currentpixelindex(0)
624  {
625 // fill bitset maks with raster values
628 
630  m_mask.resize(m_masksize);
631 
632  unsigned int i = 0;
633  while(it != itend)
634  {
635  m_mask[i++] = *it;
636 
637  ++it;
638  }
639 
640 // to avoid the first position be outside the mask
641  if (!m_mask[0])
642  operator++();
643  }
644 
646  : te::rst::BandIterator<T>(rhs),
647  m_mask(rhs.m_mask)
648  {
649  }
650 
652  {
653  do
654  {
656 
657  m_currentpixelindex++;
658 
659  if (m_currentpixelindex >= m_masksize)
660  break;
661  }
662  while (m_mask[m_currentpixelindex] == 0);
663  }
664 
666  {
667  do
668  {
670 
671  m_currentpixelindex--;
672 
673  if (m_currentpixelindex < 0)
674  break;
675  }
676  while (m_mask[m_currentpixelindex] == 0);
677  }
678 
680  {
682 
683  m_currentpixelindex = rhs.m_currentpixelindex;
684  m_masksize = rhs.m_masksize;
685  m_mask = rhs.m_mask;
686 
687  return *this;
688  }
689 
691  {
693  }
694 
696  {
698 
699  it.m_blky = b->getProperty()->m_nblocksy;
700 
701  return it;
702  }
703 
704  } // end namespace rst
705 } // end namespace te
706 
707 #endif // __TERRALIB_RASTER_INTERNAL_BANDITERATOR_H
te::rst::GetBufferValueFPtr m_getBuff
A pointer to a function that helps to extract a double or complex value from a specific buffer data t...
Definition: BandIterator.h:129
This class implements an iterator to "navigate" over a single band, with a spatial restriction given ...
Definition: BandIterator.h:272
unsigned int getRow() const
Returns the current row in iterator.
Definition: BandIterator.h:389
int m_nblocksy
The number of blocks in Y direction.
Definition: BandIterator.h:122
int m_blky
The position in Y of the current block.
Definition: BandIterator.h:125
te::rst::GetBufferValueFPtr m_getBuffI
A pointer to a function that helps to extract the imaginary part value from a specific buffer data ty...
Definition: BandIterator.h:130
It describes one band (or dimension) of a raster.
unsigned int getColumn() const
Returns the current column in iterator.
Definition: BandIterator.h:394
virtual void replaceBlock()=0
Replaces the current bufferized block values.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
const Band * m_band
The band from where to get the values.
Definition: BandIterator.h:255
int m_i
The actual position inside the block.
Definition: BandIterator.h:123
int m_nblocksy
The number of blocks in y.
Definition: BandProperty.h:146
bool operator!=(const AbstractBandIterator &rhs) const
Difference operator.
Definition: BandIterator.h:477
Band * m_band
The band from where to get the values.
Definition: BandIterator.h:195
te::rst::SetBufferValueFPtr m_setBuffI
A pointer to a function that helps to insert the imaginary part value into a specific buffer data typ...
Definition: BandIterator.h:132
void operator--()
Returns to the previous position.
Definition: BandIterator.h:428
BandIteratorWithMask & operator=(const BandIteratorWithMask &rhs)
Assignment operator.
Definition: BandIterator.h:679
ConstBandIterator()
Constructor.
Definition: BandIterator.h:552
void(* SetBufferValueFPtr)(int index, void *buffer, const double *value)
The type of function used to extract data from a buffer.
Definition: BlockUtils.h:40
~AbstractBandIterator()
Destructor.
Definition: BandIterator.h:383
int m_blksize
The block size of the band.
Definition: BandIterator.h:127
This class implements an iterator to "navigate" over a single band (const).
Definition: BandIterator.h:211
static BandIterator begin(Band *b)
Returns an iterator referring to the first value of the band.
Definition: BandIterator.h:532
static ConstBandIterator begin(const Band *b)
Returns an iterator referring to the first value of the band.
Definition: BandIterator.h:592
Utility functions for dealing with raster data blocks.
boost::dynamic_bitset m_mask
The internal mask of bits, one bit per pixel.
Definition: BandIterator.h:314
T * m_blk
Internal block.
Definition: BandIterator.h:128
This class implements an abstract iterator to "navigate" over a single band.
Definition: BandIterator.h:56
static BandIteratorWithMask end(Band *b, Raster *m)
Returns an iterator with the mask referring to after the end of the iterator.
Definition: BandIterator.h:695
void(* GetBufferValueFPtr)(int index, void *buffer, double *value)
The type of function used to extract data from a buffer.
Definition: BlockUtils.h:37
int m_blkx
The position in X of the current block.
Definition: BandIterator.h:124
int m_blkw
The internal block width.
Definition: BandIterator.h:118
T operator*()
Returns the value in current position (column, row) from iterator.
Definition: BandIterator.h:505
BandProperty * getProperty()
Returns the band property.
An abstract class for raster data strucutures.
Definition: Raster.h:71
unsigned int getNumberOfRows() const
Returns the raster number of rows.
void replaceBlock()
Replaces the current bufferized block values.
Definition: BandIterator.h:546
TERASTEREXPORT void SetBlockFunctions(GetBufferValueFPtr *gb, GetBufferValueFPtr *gbi, SetBufferValueFPtr *sb, SetBufferValueFPtr *sbi, int type)
Sets the pointers to functions that helps to extract a double or complex value from a specific buffer...
URI C++ Library.
int m_npxlsblk
The maximum number of pixels inside the block.
Definition: BandIterator.h:120
It gives access to values in one band (dimension) of a raster.
A raster band description.
Definition: Band.h:63
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
const T operator*() const
Returns the value in current position (column, row) from iterator.
Definition: BandIterator.h:574
BandIterator()
Constructor.
Definition: BandIterator.h:483
int m_blkh
The internal block height.
Definition: BandIterator.h:119
AbstractBandIterator()
Constructor.
Definition: BandIterator.h:321
te::rst::SetBufferValueFPtr m_setBuff
A pointer to a function that helps to insert a double or complex value into a specific buffer data ty...
Definition: BandIterator.h:131
AbstractBandIterator & operator=(const AbstractBandIterator &rhs)
Assignment operator.
Definition: BandIterator.h:456
virtual const T operator*() const =0
Returns the value in current position (column, row) from iterator.
This class implements an iterator to "navigate" over a single band.
Definition: BandIterator.h:148
int m_lastblksize
The number of pixels inside the last block.
Definition: BandIterator.h:126
BandIterator & operator=(const BandIterator &rhs)
Assignment operator.
Definition: BandIterator.h:523
void replaceBlock()
Replaces the current bufferized block values.
Definition: BandIterator.h:606
virtual Raster * getRaster() const =0
Returns the associated raster.
virtual void operator++()
Advances to the next position.
Definition: BandIterator.h:399
unsigned int m_currentpixelindex
The index of the current pixel location.
Definition: BandIterator.h:316
static BandIteratorWithMask begin(Band *b, Raster *m)
Returns an iterator with the mask referring to the first value of the band.
Definition: BandIterator.h:690
int getType() const
It returns the data type of the elements in the band.
Definition: BandProperty.h:113
static BandIterator end(Band *b)
Returns an iterator referring to after the end of the iterator.
Definition: BandIterator.h:537
int m_nblocksx
The number of blocks in X direction.
Definition: BandIterator.h:121
ConstBandIterator & operator=(const ConstBandIterator &rhs)
Assignment operator.
Definition: BandIterator.h:583
BandIteratorWithMask()
Constructor.
Definition: BandIterator.h:612
void operator++()
Advances to the next position.
Definition: BandIterator.h:651
unsigned int m_masksize
The size of the mask (rows * columns of the mask raster).
Definition: BandIterator.h:315
static ConstBandIterator end(const Band *b)
Returns an iterator referring to after the end of the iterator.
Definition: BandIterator.h:597