ExpansibleRaster.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/memory/ExpansibleRaster.cpp
22 
23  \brief A raster (stored in memory and eventually swapped to disk) where it is possible to dynamically add lines/columns/bands.
24 */
25 
26 // TerraLib
27 #include "../core/translator/Translator.h"
28 #include "../common/PlatformUtils.h"
29 #include "../geometry/Envelope.h"
30 #include "../raster/Utils.h"
31 #include "../raster/BlockUtils.h"
32 #include "../raster/Interpolator.h"
33 #include "Exception.h"
34 #include "ExpansibleRaster.h"
35 
36 
37 #ifndef TLINTERNAL_EXPANSIBLERASTER_MAXDISKFILESSIZE
38  #define TLINTERNAL_EXPANSIBLERASTER_MAXDISKFILESSIZE 2147483648ul
39 #endif
40 
42 
44 : te::rst::Raster( rhs )
45 {
47 
48  for( unsigned int bandsIdx = 0 ; bandsIdx < rhs.getNumberOfBands() ;
49  ++bandsIdx )
50  {
51  m_bands.push_back( new te::mem::ExpansibleBand( *m_blocksManagerPtr, *this,
52  *(rhs.getBand( bandsIdx )->getProperty()) , bandsIdx ) );
53  }
54 
56 }
57 
59 : te::rst::Raster( rhs )
60 {
61  ExpansibleRaster const* rhsPtr = dynamic_cast< ExpansibleRaster const* >( &rhs );
62  if( rhsPtr == nullptr )
63  {
64  throw te::mem::Exception( "Invalid constructor call" );
65  }
66 
68 
69  for( unsigned int bandsIdx = 0 ; bandsIdx < rhsPtr->getNumberOfBands() ;
70  ++bandsIdx )
71  {
72  m_bands.push_back( new te::mem::ExpansibleBand( *m_blocksManagerPtr, *this,
73  *(rhsPtr->getBand( bandsIdx )->getProperty()) , bandsIdx ) );
74  }
75 
77 }
78 
80 : te::rst::Raster( grid, p )
81 {
82 }
83 
84 te::mem::ExpansibleRaster::ExpansibleRaster( const unsigned char maxMemPercentUsed,
85  te::rst::Grid* grid,
86  const std::vector<te::rst::BandProperty*> bandsProperties )
87  : te::rst::Raster( grid, te::common::RWAccess )
88 {
89  // Finding the global block dimensions
90 
91  unsigned int maxBlockSizeBytes = 0;
92  std::vector< unsigned int> numbersOfBlocksX;
93  std::vector< unsigned int> numbersOfBlocksY;
94  std::vector< unsigned int> blocksSizesBytes;
95 
96  {
97  for( unsigned int bandIdx = 0 ; bandIdx < bandsProperties.size() ; ++bandIdx )
98  {
99  // Making all bands blocking equal
100  bandsProperties[ bandIdx ]->m_nblocksx = bandsProperties[ 0 ]->m_nblocksx;
101  bandsProperties[ bandIdx ]->m_nblocksy = bandsProperties[ 0 ]->m_nblocksy;
102  bandsProperties[ bandIdx ]->m_blkw = bandsProperties[ 0 ]->m_blkw;
103  bandsProperties[ bandIdx ]->m_blkh = bandsProperties[ 0 ]->m_blkh;
104  bandsProperties[ bandIdx ]->m_nblocksx = (int)std::ceil(
105  ((double)grid->getNumberOfColumns()) /
106  ((double)bandsProperties[ bandIdx ]->m_blkw) );
107  bandsProperties[ bandIdx ]->m_nblocksy = (int)std::ceil(
108  ((double)grid->getNumberOfRows()) /
109  ((double)bandsProperties[ bandIdx ]->m_blkh) );
110 
111  const unsigned int blockSizeBytes = (unsigned int)(
112  bandsProperties[ bandIdx ]->m_blkw *
113  bandsProperties[ bandIdx ]->m_blkh *
114  te::rst::GetPixelSize( bandsProperties[ bandIdx ]->m_type ) );
115 
116  if( maxBlockSizeBytes < blockSizeBytes )
117  maxBlockSizeBytes = blockSizeBytes;
118 
119  numbersOfBlocksX.push_back( (unsigned int)bandsProperties[ bandIdx ]->m_nblocksx );
120  numbersOfBlocksY.push_back( (unsigned int)bandsProperties[ bandIdx ]->m_nblocksy );
121  blocksSizesBytes.push_back( blockSizeBytes );
122  }
123  }
124 
125  const double totalPhysMem = (double)te::common::GetTotalPhysicalMemory();
126  const double usedVMem = (double)te::common::GetUsedVirtualMemory();
127  const double totalVMem = ( (double)te::common::GetTotalVirtualMemory() );
128  const double freeVMem = ( ((double)maxMemPercentUsed) / 100.0 ) *
129  std::min( totalPhysMem, ( totalVMem - usedVMem ) );
130  const unsigned int maxNumberOfBlocks = (unsigned int)
131  std::max( 1.0, std::ceil( freeVMem / ((double)maxBlockSizeBytes) ) );
132 
134  if( ! m_blocksManagerPtr->initialize( maxNumberOfBlocks, numbersOfBlocksX,
135  numbersOfBlocksY, blocksSizesBytes,
137  throw Exception(TE_TR("Cannot initialize the blocks menager") );
138 
139  for( unsigned int bandsIdx = 0 ; bandsIdx < bandsProperties.size() ;
140  ++bandsIdx )
141  {
142  m_bands.push_back( new te::mem::ExpansibleBand( *m_blocksManagerPtr, *this,
143  *(bandsProperties[ bandsIdx ]) , bandsIdx ) );
144  delete ( bandsProperties[ bandsIdx ] );
145  }
146 }
147 
149  const std::vector<te::rst::BandProperty*> bandsProperties,
150  const unsigned int maxNumberOfRAMBlocks )
151  : te::rst::Raster( grid, te::common::RWAccess )
152 {
153  // Finding the global block dimensions
154 
155  std::vector< unsigned int> numbersOfBlocksX;
156  std::vector< unsigned int> numbersOfBlocksY;
157  std::vector< unsigned int> blocksSizesBytes;
158 
159  {
160  for( unsigned int bandIdx = 0 ; bandIdx < bandsProperties.size() ; ++bandIdx )
161  {
162  // Making all bands blocking equal
163  bandsProperties[ bandIdx ]->m_nblocksx = bandsProperties[ 0 ]->m_nblocksx;
164  bandsProperties[ bandIdx ]->m_nblocksy = bandsProperties[ 0 ]->m_nblocksy;
165  bandsProperties[ bandIdx ]->m_blkw = bandsProperties[ 0 ]->m_blkw;
166  bandsProperties[ bandIdx ]->m_blkh = bandsProperties[ 0 ]->m_blkh;
167  bandsProperties[ bandIdx ]->m_nblocksx = (int)std::ceil(
168  ((double)grid->getNumberOfColumns()) /
169  ((double)bandsProperties[ bandIdx ]->m_blkw) );
170  bandsProperties[ bandIdx ]->m_nblocksy = (int)std::ceil(
171  ((double)grid->getNumberOfRows()) /
172  ((double)bandsProperties[ bandIdx ]->m_blkh) );
173 
174  const unsigned int blockSizeBytes = (unsigned int)(
175  bandsProperties[ bandIdx ]->m_blkw *
176  bandsProperties[ bandIdx ]->m_blkh *
177  te::rst::GetPixelSize( bandsProperties[ bandIdx ]->m_type ) );
178 
179  numbersOfBlocksX.push_back( (unsigned int)bandsProperties[ bandIdx ]->m_nblocksx );
180  numbersOfBlocksY.push_back( (unsigned int)bandsProperties[ bandIdx ]->m_nblocksy );
181  blocksSizesBytes.push_back( blockSizeBytes );
182  }
183  }
184 
186  if( ! m_blocksManagerPtr->initialize( maxNumberOfRAMBlocks, numbersOfBlocksX,
187  numbersOfBlocksY, blocksSizesBytes,
189  throw Exception(TE_TR("Cannot initialize the blocks menager") );
190 
191  for( unsigned int bandsIdx = 0 ; bandsIdx < bandsProperties.size() ;
192  ++bandsIdx )
193  {
194  m_bands.push_back( new te::mem::ExpansibleBand( *m_blocksManagerPtr, *this,
195  *(bandsProperties[ bandsIdx ]) , bandsIdx ) );
196  delete ( bandsProperties[ bandsIdx ] );
197  }
198 }
199 
201 {
202  free();
203 }
204 
205 void te::mem::ExpansibleRaster::open(const std::map<std::string, std::string>& /*rinfo*/,
207 {
208 }
209 
210 std::map<std::string, std::string> te::mem::ExpansibleRaster::getInfo() const
211 {
212  return std::map<std::string, std::string>();
213 }
214 
216 {
217  const std::size_t nBands = m_bands.size();
218  std::size_t bandIdx = 0;
219 
220  std::vector<te::rst::BandProperty*> bandsProperties;
221  for( bandIdx = 0 ; bandIdx < nBands ; ++bandIdx )
222  {
223  bandsProperties.push_back( new te::rst::BandProperty(
224  *(m_bands[ bandIdx ]->getProperty() ) ) );
225  }
226 
227  std::unique_ptr< ExpansibleRaster > rasterPtr( new ExpansibleRaster(
228  new te::rst::Grid( *m_grid ), bandsProperties,
229  m_blocksManagerPtr->getMaxNumberOfRAMBlocks() ) );
230 
231  int nblcksX = 0;
232  int nblkksY = 0;
233  int blkXIdx = 0;
234  int blkYIdx = 0;
235 
236  for ( bandIdx = 0; bandIdx < nBands; ++bandIdx )
237  {
238  te::rst::Band& inBand = *m_bands[ bandIdx ];
239  te::rst::Band& outBand = *rasterPtr->m_bands[ bandIdx ];
240  nblcksX = inBand.getProperty()->m_nblocksx;
241  nblkksY = inBand.getProperty()->m_nblocksy;
242 
243  for( blkXIdx = 0; blkXIdx < nblcksX; ++blkXIdx )
244  {
245  for( blkYIdx = 0; blkYIdx < nblkksY; ++blkYIdx )
246  {
247  outBand.write( blkXIdx, blkYIdx, inBand.read( blkXIdx, blkYIdx ) );
248  }
249  }
250  }
251 
252  return rasterPtr.release();
253 }
254 
255 bool te::mem::ExpansibleRaster::createMultiResolution( const unsigned int levels,
256  const te::rst::InterpolationMethod interpMethod )
257 {
258  m_multiResRasters.clear();
259 
260  for( unsigned int level = 1 ; level < levels ; ++level )
261  {
262  std::unique_ptr< te::rst::Grid > gridPtr( new te::rst::Grid(
263  getGrid()->getNumberOfColumns() / ( 2 * level ),
264  getGrid()->getNumberOfRows() / ( 2 * level ),
265  new te::gm::Envelope( *(getGrid()->getExtent()) ), getSRID() ) );
266 
267  std::vector<te::rst::BandProperty*> bandsProperties;
268 
269  for( unsigned int bandIdx = 0 ; bandIdx < getNumberOfBands() ; ++bandIdx )
270  {
271  bandsProperties.push_back( new te::rst::BandProperty( *( getBand( bandIdx
272  )->getProperty() ) ) );
273 
274  bandsProperties[ bandIdx ]->m_blkw = std::max( 1,
275  bandsProperties[ bandIdx ]->m_blkw / (int)( 2 * level ) );
276  bandsProperties[ bandIdx ]->m_blkh = std::max( 1,
277  bandsProperties[ bandIdx ]->m_blkh / (int)( 2 * level ) );
278  bandsProperties[ bandIdx ]->m_nblocksx = (int)std::ceil(
279  ((double)gridPtr->getNumberOfColumns()) /
280  ((double)bandsProperties[ bandIdx ]->m_blkw) );
281  bandsProperties[ bandIdx ]->m_nblocksy = (int)std::ceil(
282  ((double)gridPtr->getNumberOfRows()) /
283  ((double)bandsProperties[ bandIdx ]->m_blkh) );
284  }
285 
286  boost::shared_ptr< ExpansibleRaster > outRasterPtr;
287  try
288  {
289  outRasterPtr.reset( new ExpansibleRaster( gridPtr.release(), bandsProperties,
290  m_blocksManagerPtr->getMaxNumberOfRAMBlocks() ) );
291  }
292  catch( te::common::Exception& )
293  {
294  m_multiResRasters.clear();
295  return false;
296  }
297 
298  // data interpolation
299 
300  const double scaleFactorX = ((double)getNumberOfColumns()) /
301  ((double)outRasterPtr->getNumberOfColumns());
302  const double scaleFactorY = ((double)getNumberOfRows()) /
303  ((double)outRasterPtr->getNumberOfRows());
304  const unsigned int outBandsNumber = static_cast<unsigned int>(getNumberOfBands());
305  const unsigned int outColsNumber = outRasterPtr->getNumberOfColumns();
306  const unsigned int outRowsNumber = outRasterPtr->getNumberOfRows();
307  te::rst::Interpolator interp( this, interpMethod );
308  unsigned int outBandIdx = 0;
309  unsigned int outCol = 0;
310  unsigned int outRow = 0;
311  double inRow = 0;
312  double inCol = 0;
313  std::complex<double> value;
314 
315  for( outBandIdx = 0 ; outBandIdx < outBandsNumber ; ++outBandIdx )
316  {
317  te::rst::Band& outBand = (*(outRasterPtr->getBand( outBandIdx )));
318 
319  for( outRow = 0 ; outRow < outRowsNumber ; ++outRow )
320  {
321  inRow = scaleFactorY * ((double)outRow);
322 
323  for( outCol = 0 ; outCol < outColsNumber ; ++outCol )
324  {
325  inCol = scaleFactorX * ((double)outCol);
326  interp.getValue( inCol, inRow, value, outBandIdx );
327  outBand.setValue( outCol, outRow, value );
328  }
329  }
330  }
331 
332  m_multiResRasters.push_back( outRasterPtr );
333  }
334 
335  return true;
336 }
337 
339 {
340  m_multiResRasters.clear();
341  return true;
342 }
343 
345 {
346  return static_cast<unsigned int>(m_multiResRasters.empty() ? 0 : (m_multiResRasters.size() + 1));
347 }
348 
350 {
351  if( m_multiResRasters.empty() )
352  {
353  return nullptr;
354  }
355  else
356  {
357  if( level == 0 )
358  {
359  return new ExpansibleRaster( *this );
360  }
361  else
362  {
363  if( ( level - 1 ) < m_multiResRasters.size() )
364  {
365  return new ExpansibleRaster( *( m_multiResRasters[ level - 1 ].get() ) );
366  }
367  else
368  {
369  return nullptr;
370  }
371  }
372  }
373 }
374 
375 bool te::mem::ExpansibleRaster::addTopLines( const unsigned int number )
376 {
377  if( m_bands.empty() ) return false;
378 
379  if( number )
380  {
381  const unsigned int blockExpansionSize = (unsigned int)std::ceil(
382  ((double)number) / ((double)m_bands[ 0 ]->getProperty()->m_blkh) );
383 
384  std::vector< ExpansibleBandBlocksManager::BlockIndex3D > addedBlocksCoords;
385 
386  for( unsigned int bandsIdx = 0 ; bandsIdx < m_bands.size() ; ++bandsIdx )
387  {
388  std::vector< ExpansibleBandBlocksManager::BlockIndex3D > bandAddedBlocksCoords;
389  if( ! m_blocksManagerPtr->addTopBlocks( blockExpansionSize, bandsIdx,
390  bandAddedBlocksCoords ) )
391  return false;
392 
393  addedBlocksCoords.insert( addedBlocksCoords.end(), bandAddedBlocksCoords.begin(),
394  bandAddedBlocksCoords.end() );
395 
396  m_bands[ bandsIdx ]->getProperty()->m_nblocksy += blockExpansionSize;
397  }
398 
399  dummyFillBlocks( addedBlocksCoords );
400 
401  const unsigned int newLinesNumber =
402  ((unsigned int)m_bands[ 0 ]->getProperty()->m_blkh) *
403  ((unsigned int)m_bands[ 0 ]->getProperty()->m_nblocksy );
404  const unsigned int newColsNumber =
405  ((unsigned int)m_bands[ 0 ]->getProperty()->m_blkw) *
406  ((unsigned int)m_bands[ 0 ]->getProperty()->m_nblocksx );
407 
408  const double addedLinesNumber = (double)( blockExpansionSize *
409  ((unsigned int)m_bands[ 0 ]->getProperty()->m_blkh) );
410 
411  te::gm::Coord2D newULC(
413  m_grid->getExtent()->getUpperRightY() + ( addedLinesNumber *
414  m_grid->getResolutionY() ) );
415 
416  te::rst::Grid* newGridPtr( new te::rst::Grid( newColsNumber,
417  newLinesNumber, m_grid->getResolutionX(), m_grid->getResolutionY(),
418  &newULC, m_grid->getSRID() ) );
419  delete( m_grid );
420  m_grid = newGridPtr;
421  }
422 
423  return true;
424 }
425 
426 bool te::mem::ExpansibleRaster::addBottomLines( const unsigned int number )
427 {
428  if( m_bands.empty() ) return false;
429 
430  if( number )
431  {
432  const unsigned int currExtraLines =
433  ( (unsigned int)( m_bands[ 0 ]->getProperty()->m_blkh *
434  m_bands[ 0 ]->getProperty()->m_nblocksy ) ) -
436 
437  te::gm::Coord2D uLC(
440 
441  if( currExtraLines < number )
442  {
443  const unsigned int blockExpansionSize = (unsigned int)std::ceil(
444  ((double)number) / ((double)m_bands[ 0 ]->getProperty()->m_blkh) );
445 
446  std::vector< ExpansibleBandBlocksManager::BlockIndex3D > addedBlocksCoords;
447 
448  for( unsigned int bandsIdx = 0 ; bandsIdx < m_bands.size() ; ++bandsIdx )
449  {
450  std::vector< ExpansibleBandBlocksManager::BlockIndex3D > bandAddedBlocksCoords;
451  if( ! m_blocksManagerPtr->addBottomBlocks( blockExpansionSize, bandsIdx,
452  bandAddedBlocksCoords ) )
453  return false;
454 
455  addedBlocksCoords.insert( addedBlocksCoords.end(), bandAddedBlocksCoords.begin(),
456  bandAddedBlocksCoords.end() );
457 
458  m_bands[ bandsIdx ]->getProperty()->m_nblocksy += blockExpansionSize;
459  }
460 
461  dummyFillBlocks( addedBlocksCoords );
462 
463  const unsigned int newLinesNumber =
464  ((unsigned int)m_bands[ 0 ]->getProperty()->m_blkh) *
465  ((unsigned int)m_bands[ 0 ]->getProperty()->m_nblocksy );
466  const unsigned int newColsNumber =
467  ((unsigned int)m_bands[ 0 ]->getProperty()->m_blkw) *
468  ((unsigned int)m_bands[ 0 ]->getProperty()->m_nblocksx );
469 
470  te::rst::Grid* newGridPtr( new te::rst::Grid( newColsNumber,
471  newLinesNumber, m_grid->getResolutionX(), m_grid->getResolutionY(),
472  &uLC, m_grid->getSRID() ) );
473  delete( m_grid );
474  m_grid = newGridPtr;
475  }
476  else
477  {
478  te::rst::Grid* newGridPtr( new te::rst::Grid(
480  m_grid->getNumberOfRows() + number,
482  &uLC, m_grid->getSRID() ) );
483  delete( m_grid );
484  m_grid = newGridPtr;
485  }
486  }
487 
488  return true;
489 }
490 
491 bool te::mem::ExpansibleRaster::addLeftColumns( const unsigned int number )
492 {
493  if( m_bands.empty() ) return false;
494 
495  if( number )
496  {
497  const unsigned int oldColsNumber =
498  ((unsigned int)m_bands[ 0 ]->getProperty()->m_blkw) *
499  ((unsigned int)m_bands[ 0 ]->getProperty()->m_nblocksx );
500 
501  const unsigned int blockExpansionSize = (unsigned int)std::ceil(
502  ((double)number) / ((double)m_bands[ 0 ]->getProperty()->m_blkw) );
503 
504  std::vector< ExpansibleBandBlocksManager::BlockIndex3D > addedBlocksCoords;
505 
506  for( unsigned int bandsIdx = 0 ; bandsIdx < m_bands.size() ; ++bandsIdx )
507  {
508  std::vector< ExpansibleBandBlocksManager::BlockIndex3D > bandAddedBlocksCoords;
509  if( ! m_blocksManagerPtr->addLeftBlocks( blockExpansionSize, bandsIdx,
510  bandAddedBlocksCoords ) )
511  return false;
512 
513  addedBlocksCoords.insert( addedBlocksCoords.end(), bandAddedBlocksCoords.begin(),
514  bandAddedBlocksCoords.end() );
515 
516  m_bands[ bandsIdx ]->getProperty()->m_nblocksx += blockExpansionSize;
517  }
518 
519  dummyFillBlocks( addedBlocksCoords );
520 
521  const unsigned int newLinesNumber =
522  ((unsigned int)m_bands[ 0 ]->getProperty()->m_blkh) *
523  ((unsigned int)m_bands[ 0 ]->getProperty()->m_nblocksy );
524  const unsigned int newColsNumber =
525  ((unsigned int)m_bands[ 0 ]->getProperty()->m_blkw) *
526  ((unsigned int)m_bands[ 0 ]->getProperty()->m_nblocksx );
527 
528  const double addedColsNumber = (double)( newColsNumber - oldColsNumber );
529 
530  te::gm::Coord2D newULC(
531  m_grid->getExtent()->getLowerLeftX() - ( addedColsNumber *
532  m_grid->getResolutionX() ),
534 
535  te::rst::Grid* newGridPtr( new te::rst::Grid( newColsNumber,
536  newLinesNumber, m_grid->getResolutionX(), m_grid->getResolutionY(),
537  &newULC, m_grid->getSRID() ) );
538  delete( m_grid );
539  m_grid = newGridPtr;
540  }
541 
542  return true;
543 }
544 
545 bool te::mem::ExpansibleRaster::addRightColumns( const unsigned int number )
546 {
547  if( m_bands.empty() ) return false;
548 
549  if( number )
550  {
551  const unsigned int currExtraCols =
552  ( (unsigned int)( m_bands[ 0 ]->getProperty()->m_blkw *
553  m_bands[ 0 ]->getProperty()->m_nblocksx ) ) -
555 
556  te::gm::Coord2D uLC(
559 
560  if( currExtraCols < number )
561  {
562  const unsigned int blockExpansionSize = (unsigned int)std::ceil(
563  ((double)number) / ((double)m_bands[ 0 ]->getProperty()->m_blkw) );
564 
565  std::vector< ExpansibleBandBlocksManager::BlockIndex3D > addedBlocksCoords;
566 
567  for( unsigned int bandsIdx = 0 ; bandsIdx < m_bands.size() ; ++bandsIdx )
568  {
569  std::vector< ExpansibleBandBlocksManager::BlockIndex3D > bandAddedBlocksCoords;
570  if( ! m_blocksManagerPtr->addRightBlocks( blockExpansionSize, bandsIdx,
571  bandAddedBlocksCoords ) )
572  return false;
573 
574  addedBlocksCoords.insert( addedBlocksCoords.end(), bandAddedBlocksCoords.begin(),
575  bandAddedBlocksCoords.end() );
576 
577  m_bands[ bandsIdx ]->getProperty()->m_nblocksx += blockExpansionSize;
578  }
579 
580  dummyFillBlocks( addedBlocksCoords );
581 
582  const unsigned int newLinesNumber =
583  ((unsigned int)m_bands[ 0 ]->getProperty()->m_blkh) *
584  ((unsigned int)m_bands[ 0 ]->getProperty()->m_nblocksy );
585  const unsigned int newColsNumber =
586  ((unsigned int)m_bands[ 0 ]->getProperty()->m_blkw) *
587  ((unsigned int)m_bands[ 0 ]->getProperty()->m_nblocksx );
588 
589  te::rst::Grid* newGridPtr( new te::rst::Grid( newColsNumber,
590  newLinesNumber, m_grid->getResolutionX(), m_grid->getResolutionY(),
591  &uLC, m_grid->getSRID() ) );
592  delete( m_grid );
593  m_grid = newGridPtr;
594  }
595  else
596  {
597  te::rst::Grid* newGridPtr( new te::rst::Grid(
598  m_grid->getNumberOfColumns() + number,
601  &uLC, m_grid->getSRID() ) );
602  delete( m_grid );
603  m_grid = newGridPtr;
604  }
605  }
606 
607  return true;
608 }
609 
610 bool te::mem::ExpansibleRaster::addTopBands( const unsigned int number )
611 {
612  if( m_bands.empty() ) return false;
613 
614  if( number )
615  {
616  std::vector< ExpansibleBandBlocksManager::BlockIndex3D > addedBlocksCoords;
617 
618  if( ! m_blocksManagerPtr->addTopBands( number, addedBlocksCoords ) )
619  return false;
620 
621  m_bands.insert( m_bands.begin(), number, nullptr );
622  for( unsigned int bIdx = 0 ; bIdx < m_bands.size() ; ++bIdx )
623  {
624  if( m_bands[ bIdx ] )
625  {
626  te::mem::ExpansibleBand* oldBandPtr = m_bands[ bIdx ];
627  m_bands[ bIdx ] = new te::mem::ExpansibleBand( *m_blocksManagerPtr, *this,
628  *( oldBandPtr->getProperty() ), bIdx );
629  delete( oldBandPtr );
630  }
631  else
632  {
633  m_bands[ bIdx ] = new te::mem::ExpansibleBand( *m_blocksManagerPtr, *this,
634  *( m_bands[ number ]->getProperty() ), bIdx );
635  }
636  }
637 
638  dummyFillBlocks( addedBlocksCoords );
639  }
640 
641  return true;
642 }
643 
644 bool te::mem::ExpansibleRaster::addBottomBands( const unsigned int number )
645 {
646  if( m_bands.empty() ) return false;
647 
648  if( number )
649  {
650  std::vector< ExpansibleBandBlocksManager::BlockIndex3D > addedBlocksCoords;
651 
652  if( ! m_blocksManagerPtr->addBottomBands( number, addedBlocksCoords ) )
653  return false;
654 
655  unsigned int lastBandIdx = (unsigned int)m_bands.size() - 1;
656  m_bands.insert( m_bands.end(), number, nullptr );
657  for( unsigned int bIdx = lastBandIdx + 1 ; bIdx < m_bands.size() ; ++bIdx )
658  {
659  m_bands[ bIdx ] = new te::mem::ExpansibleBand( *m_blocksManagerPtr, *this,
660  *( m_bands[ lastBandIdx ]->getProperty() ), bIdx );
661  }
662 
663  dummyFillBlocks( addedBlocksCoords );
664  }
665 
666  return true;
667 }
668 
670 {
671  if( m_bands.size() > 0 )
672  {
673  for( unsigned int bandsIdx = 0 ; bandsIdx < m_bands.size() ; ++bandsIdx )
674  delete (m_bands[ bandsIdx ]);
675  m_bands.clear();
676  }
677 
678  m_blocksManagerPtr.reset();
679 
680  m_multiResRasters.clear();
681 }
682 
684 {
685  for( unsigned int bandsIdx = 0 ; bandsIdx < m_bands.size() ;
686  ++bandsIdx )
687  {
688  te::mem::ExpansibleBand& band = *( m_bands[ bandsIdx ] );
689 
690  te::rst::GetBufferValueFPtr gb = nullptr;
691  te::rst::GetBufferValueFPtr gbi = nullptr;
692  te::rst::SetBufferValueFPtr sb = nullptr;
693  te::rst::SetBufferValueFPtr sbi = nullptr;
694  te::rst::SetBlockFunctions( &gb, &gbi, &sb, &sbi, band.getProperty()->m_type );
695 
696  const int elementsNumber = band.getProperty()->m_blkh *
697  band.getProperty()->m_blkw;
698  double* noDataValuePtr = &( band.getProperty()->m_noDataValue );
699  const unsigned int nBlocksX = band.getProperty()->m_nblocksx;
700  const unsigned int nBlocksY = band.getProperty()->m_nblocksy;
701  unsigned int blockXIdx = 0;
702  unsigned int blockYIdx = 0;
703  int eIdx = 0;
704  void* blockPtr = nullptr;
705 
706  for( blockXIdx = 0 ; blockXIdx < nBlocksX ; ++blockXIdx )
707  {
708  for( blockYIdx = 0 ; blockYIdx < nBlocksY ; ++blockYIdx )
709  {
710  blockPtr = m_blocksManagerPtr->getBlockPointer( bandsIdx, blockXIdx,
711  blockYIdx );
712  assert( blockPtr );
713 
714  for( eIdx = 0 ; eIdx < elementsNumber ; ++eIdx )
715  sb( eIdx, blockPtr, noDataValuePtr );
716  }
717  }
718  }
719 }
720 
722  const std::vector< ExpansibleBandBlocksManager::BlockIndex3D >& blocksCoords )
723 {
724  for( unsigned int coodsIdx = 0 ; coodsIdx < blocksCoords.size() ;
725  ++coodsIdx )
726  {
727  const ExpansibleBandBlocksManager::BlockIndex3D& block3DIdx = blocksCoords[ coodsIdx ];
728 
729  assert( block3DIdx.m_dim0Index < m_bands.size() );
730  te::mem::ExpansibleBand& band = *( m_bands[ block3DIdx.m_dim0Index ] );
731 
732  te::rst::GetBufferValueFPtr gb = nullptr;
733  te::rst::GetBufferValueFPtr gbi = nullptr;
734  te::rst::SetBufferValueFPtr sb = nullptr;
735  te::rst::SetBufferValueFPtr sbi = nullptr;
736 
737  te::rst::SetBlockFunctions( &gb, &gbi, &sb, &sbi, band.getProperty()->m_type );
738 
739  void* blockPtr = m_blocksManagerPtr->getBlockPointer( block3DIdx.m_dim0Index,
740  block3DIdx.m_dim2Index, block3DIdx.m_dim1Index );
741 
742  const int elementsNumber = band.getProperty()->m_blkh *
743  band.getProperty()->m_blkw;
744 
745  double* noDataValuePtr = &( band.getProperty()->m_noDataValue );
746 
747  for( int eIdx = 0 ; eIdx < elementsNumber ; ++eIdx )
748  sb( eIdx, blockPtr, noDataValuePtr );
749  }
750 }
751 
752 
753 
A raster (stored in memory and eventually swapped to disk) where it is possible to dynamically add li...
unsigned int getNumberOfRows() const
Returns the grid number of rows.
te::gm::Envelope * getExtent()
Returns the geographic extension of the raster data.
bool addTopLines(const unsigned int number)
New lines will be added at the top of the raster (before the first line).
std::vector< ExpansibleBand * > m_bands
Internal raster bands.
unsigned int band
A raster class for memory.
TECOMMONEXPORT unsigned long long int GetTotalVirtualMemory()
Returns the amount of total virtual memory (bytes) that can be claimed by the current process (physic...
bool createMultiResolution(const unsigned int levels, const te::rst::InterpolationMethod interpMethod)
Create a sub-sampled multi-resolution pyramid.
A raster band description.
Definition: BandProperty.h:61
int getSRID() const
Returns the grid spatial reference system identifier.
Base exception class for plugin module.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
int m_nblocksx
The number of blocks in x.
Definition: BandProperty.h:145
void dummyFillBlocks(const std::vector< ExpansibleBandBlocksManager::BlockIndex3D > &blocksCoords)
Fill the required blocks with dummy values.
It interpolates one pixel based on a selected algorithm. Methods currently available are Nearest Neig...
Definition: Interpolator.h:55
int m_nblocksy
The number of blocks in y.
Definition: BandProperty.h:146
An exception class for the TerraLib In-Memory Data Access driver.
void dummyFillAllBlocks()
Fill all blocks with dummy values.
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
std::vector< boost::shared_ptr< ExpansibleRaster > > m_multiResRasters
Pointer to Multi-resolution versions of this raster instance.
void getValue(const double &c, const double &r, std::complex< double > &v, const std::size_t &b)
Get the interpolated value at specific band.
Definition: Interpolator.h:93
int m_type
The data type of the elements in the band ( See te::dt namespace basic data types for reference )...
Definition: BandProperty.h:133
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
Definition: BandProperty.h:136
const double & getUpperRightY() const
It returns a constant refernce to the x coordinate of the upper right corner.
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
std::size_t getNumberOfBands() const
Returns the number of bands (dimension of cells attribute values) in the raster.
InterpolationMethod
Allowed interpolation methods.
void(* SetBufferValueFPtr)(int index, void *buffer, const double *value)
The type of function used to extract data from a buffer.
Definition: BlockUtils.h:40
double getResolutionY() const
Returns the grid vertical (y-axis) resolution.
Grid * m_grid
The spatial support for raster data.
void open(const std::map< std::string, std::string > &rinfo, te::common::AccessPolicy p=te::common::RAccess)
Opens a raster.
AccessPolicy
Supported data access policies (can be used as bitfield).
void(* GetBufferValueFPtr)(int index, void *buffer, double *value)
The type of function used to extract data from a buffer.
Definition: BlockUtils.h:37
An Envelope defines a 2D rectangular region.
void free()
Free all allocated internal resources and go back to the initial state.
An abstract class for raster data strucutures.
bool addRightColumns(const unsigned int number)
New columns will be added at the right of the raster (after the last column).
unsigned int getNumberOfRows() const
Returns the raster number of rows.
std::map< std::string, std::string > getInfo() const
It returns additional information about the raster.
RAM cached and tiled raster band blocks manager.
BandProperty * getProperty()
Returns the band property.
URI C++ Library.
Definition: Attributes.h:37
int m_blkw
Block width (pixels).
Definition: BandProperty.h:143
bool addBottomBands(const unsigned int number)
New bands will be added at the bottom of the raster (after de the last band).
unsigned int getNumberOfColumns() const
Returns the grid number of columns.
double getResolutionX() const
Returns the grid horizontal (x-axis) resolution.
virtual void write(int x, int y, void *buffer)=0
It writes a data block from the specified buffer.
te::rst::Raster * getMultiResLevel(const unsigned int level) const
Returns the required level of a multi-resolution pyramid or NULL if that level does not exists...
te::gm::Polygon * p
bool addBottomLines(const unsigned int number)
New lines will be added at the bottom of the raster (after de the last line).
A base class for values that can be retrieved from the data access module.
Definition: AbstractData.h:57
A raster band description.
Grid * getGrid()
It returns the raster grid.
unsigned int getMultiResLevelsCount() const
Returns the current number of multi-resolution pyramid levels.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
TERASTEREXPORT int GetPixelSize(int datatype)
Returns the byte size of a given datatype.
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
TECOMMONEXPORT unsigned long long int GetTotalPhysicalMemory()
Returns the amount of total physical memory (bytes).
virtual void read(int x, int y, void *buffer) const =0
It reads a data block to the specified buffer.
int getSRID() const
Returns the raster spatial reference system identifier.
boost::shared_ptr< ExpansibleBandBlocksManager > m_blocksManagerPtr
Internal blocks manager.
bool removeMultiResolution()
Remove/Destroy a sub-sampled multi-resolution pyramid, if there is one.
A raster (stored in memory and eventually swapped to disk) where it is possible to dynamically add li...
const double & getLowerLeftX() const
It returns a constant reference to the x coordinate of the lower left corner.
te::gm::Envelope * getExtent()
Returns the geographic extension of the grid.
te::dt::AbstractData * clone() const
It returns a clone of this object.
Expansible raster band.
const te::rst::Band * getBand(std::size_t i) const
Returns the raster i-th band.
int m_blkh
Block height (pixels).
Definition: BandProperty.h:144
TECOMMONEXPORT unsigned long long int GetUsedVirtualMemory()
Returns the amount of used virtual memory (bytes) for the current process (physical + swapped)...
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
bool addLeftColumns(const unsigned int number)
New columns will be added at the left of the raster (before the first column).
bool addTopBands(const unsigned int number)
New bands will be added at the top of the raster (before the first band).
#define TLINTERNAL_EXPANSIBLERASTER_MAXDISKFILESSIZE
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...
Definition: BlockUtils.cpp:295