Blender.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/rp/Blender.cpp
22  \brief Blended pixel value calculation for two overlaped rasters.
23 */
24 
25 #include "Blender.h"
26 
27 #include "Macros.h"
28 #include "../geometry/LinearRing.h"
29 #include "../geometry/CircularString.h"
30 #include "../geometry/MultiPoint.h"
31 #include "../geometry/MultiLineString.h"
32 #include "../geometry/Point.h"
33 #include "../geometry/Coord2D.h"
34 #include "../geometry/CurvePolygon.h"
35 #include "../geometry/Envelope.h"
36 #include "../geometry/Enums.h"
37 #include "../raster/Raster.h"
38 #include "../raster/Grid.h"
39 #include "../raster/Band.h"
40 #include "../raster/BandProperty.h"
41 #include "../raster/Utils.h"
42 #include "../raster/SynchronizedRaster.h"
43 #include "../common/PlatformUtils.h"
44 #include "../common/MathUtils.h"
45 #include "../common/progress/TaskProgress.h"
46 
47 #include <boost/thread.hpp>
48 #include <boost/graph/graph_concepts.hpp>
49 #include <boost/scoped_ptr.hpp>
50 
51 #include <complex>
52 #include <limits>
53 #include <algorithm>
54 #include <memory>
55 
56 // Get the perpendicular distance from a point P(pX,pY) from a line defined
57 // by the points A(lineAX,lineAY) and B(lineBX,lineBY)
58 // Requires two previously declared variables aux1 and aux2
59 #define getPerpendicularDistance( pX, pY, lineAX, lineAY, lineBX, lineBY, aux1, aux2, perpDist ) \
60  aux1 = lineAX - lineBX; \
61  aux2 = lineAY - lineBY; \
62  if( aux1 == 0.0 ) \
63  { \
64  perpDist = std::abs( pX - lineAX ); \
65  } \
66  else if( aux2 == 0.0 ) \
67  { \
68  perpDist = std::abs( pY - lineAY ); \
69  } \
70  else \
71  { \
72  perpDist = \
73  std::abs( \
74  ( aux2 * pX ) - ( aux1 * pY ) + ( lineAX * lineBY ) - ( lineBX * lineAY ) \
75  ) \
76  / \
77  std::sqrt( ( aux1 * aux1 ) + ( aux2 * aux2 ) ); \
78  }
79 
80 namespace te
81 {
82  namespace rp
83  {
85  : m_returnValuePtr( nullptr ), m_abortValuePtr( nullptr ), m_sync1Ptr( nullptr ), m_sync2Ptr( nullptr ),
86  m_raster1BlocksInfosPtr( nullptr ), m_mutexPtr( nullptr ), m_blockProcessedSignalMutexPtr( nullptr ),
87  m_blockProcessedSignalPtr( nullptr ), m_runningThreadsCounterPtr( nullptr ),
88  m_blendMethod( te::rp::Blender::InvalidBlendMethod ),
89  m_interpMethod2( te::rst::NearestNeighbor ),
90  m_noDataValue( 0.0 ), m_forceRaster1NoDataValue( false ),
91  m_forceRaster2NoDataValue( false ),
92  m_maxRasterCachedBlocks( 0 ), m_useProgress( false )
93  {
94  }
95 
97  const BlendIntoRaster1ThreadParams& rhs )
98  {
99  operator=( rhs );
100  }
101 
103  default;
104 
106  const BlendIntoRaster1ThreadParams& rhs )
107  {
110  m_sync1Ptr = rhs.m_sync1Ptr;
111  m_sync2Ptr = rhs.m_sync2Ptr;
113  m_mutexPtr = rhs.m_mutexPtr;
130 
131  if( rhs.m_r1ValidDataDelimiterPtr.get() )
132  {
134  }
135  else
136  {
138  }
139 
140  if( rhs.m_r2ValidDataDelimiterPtr.get() )
141  {
143  }
144  else
145  {
147  }
148 
149  if( rhs.m_geomTransformationPtr.get() )
150  {
151  m_geomTransformationPtr.reset( rhs.m_geomTransformationPtr->clone() );
152  }
153  else
154  {
155  m_geomTransformationPtr.reset();
156  }
157 
158  return *this;
159  }
160 
161  // ----------------------------------------------------------------------
164  m_sumMethodImp_auxPoint(te::gm::Point(te::gm::PointType)),
165  m_maxMethodImp_auxPoint(te::gm::Point(te::gm::PointType)),
166  m_minMethodImp_auxPoint(te::gm::Point(te::gm::PointType))
167  {
168 
169 
170  initState();
171  }
172 
174  {
175  clear();
176  }
177 
179  const std::vector< unsigned int >& raster1Bands,
180  const te::rst::Raster& raster2,
181  const std::vector< unsigned int >& raster2Bands,
182  const BlendMethod& blendMethod,
183  const te::rst::Interpolator::Method& interpMethod1,
184  const te::rst::Interpolator::Method& interpMethod2,
185  const double& noDataValue,
186  const bool forceRaster1NoDataValue,
187  const bool forceRaster2NoDataValue,
188  const std::vector< double >& pixelOffsets1,
189  const std::vector< double >& pixelScales1,
190  const std::vector< double >& pixelOffsets2,
191  const std::vector< double >& pixelScales2,
192  te::gm::MultiPolygon const * const r1ValidDataDelimiterPtr,
193  te::gm::MultiPolygon const * const r2ValidDataDelimiterPtr,
194  const te::gm::GeometricTransformation& geomTransformation,
195  const unsigned int threadsNumber,
196  const bool enableProgressInterface )
197  {
200  "Invalid raster 1" );
203  "Invalid raster 2" );
204  TERP_TRUE_OR_RETURN_FALSE( raster1Bands.size() > 0,
205  "Invalid raster bands vector" );
206  TERP_TRUE_OR_RETURN_FALSE( raster1Bands.size() ==
207  raster2Bands.size(), "Invalid raster bands vector" );
208  TERP_TRUE_OR_RETURN_FALSE( pixelOffsets1.size() ==
209  raster1Bands.size(), "Invalid pixel offsets" );
210  TERP_TRUE_OR_RETURN_FALSE( pixelScales1.size() ==
211  raster1Bands.size(), "Invalid pixel scales" );
212  TERP_TRUE_OR_RETURN_FALSE( pixelOffsets2.size() ==
213  raster2Bands.size(), "Invalid pixel offsets" );
214  TERP_TRUE_OR_RETURN_FALSE( pixelScales2.size() ==
215  raster2Bands.size(), "Invalid pixel scales" );
216  TERP_TRUE_OR_RETURN_FALSE( ( r1ValidDataDelimiterPtr ?
217  ( r1ValidDataDelimiterPtr->getNumGeometries() > 0 ) : true ),
218  "Invalid geometry 1" )
219  TERP_TRUE_OR_RETURN_FALSE( ( r1ValidDataDelimiterPtr ?
220  r1ValidDataDelimiterPtr->isValid() : true ),
221  "Invalid geometry 1" )
222  TERP_TRUE_OR_RETURN_FALSE( ( r2ValidDataDelimiterPtr ?
223  ( r2ValidDataDelimiterPtr->getNumGeometries() > 0 ) : true ),
224  "Invalid geometry 2" )
225  TERP_TRUE_OR_RETURN_FALSE( ( r2ValidDataDelimiterPtr ?
226  r2ValidDataDelimiterPtr->isValid() : true ),
227  "Invalid geometry 2" )
228  TERP_TRUE_OR_RETURN_FALSE( geomTransformation.isValid(),
229  "Invalid transformation" );
230 
231  clear();
232 
233  // defining the input rasters
234 
235  m_raster1Ptr = &raster1;
236  m_raster2Ptr = &raster2;
237 
238  // Generating the valid data area points
239 
240  if( r1ValidDataDelimiterPtr )
241  {
242  m_r1ValidDataDelimiterPtr.reset( (te::gm::MultiPolygon*)r1ValidDataDelimiterPtr->clone() );
243  }
244  if( r2ValidDataDelimiterPtr )
245  {
246  m_r2ValidDataDelimiterPtr.reset( (te::gm::MultiPolygon*)r2ValidDataDelimiterPtr->clone() );
247  }
248 
249  // indexed under raster 1 lines/cols
250  std::unique_ptr< te::gm::MultiPolygon > indexedDelimiter1Ptr(
251  new te::gm::MultiPolygon( 0, te::gm::MultiPolygonType, 0, nullptr ) );
252 
253  if( r1ValidDataDelimiterPtr )
254  {
255  const te::rst::Grid& grid = (*raster1.getGrid());
256 
257  const std::size_t nGeoms = r1ValidDataDelimiterPtr->getNumGeometries();
258 
259  for( std::size_t geomIdx = 0 ; geomIdx < nGeoms ; ++geomIdx )
260  {
261  te::gm::Polygon const* geomPtr = dynamic_cast< te::gm::Polygon* >(
262  r1ValidDataDelimiterPtr->getGeometryN( geomIdx ) );
263  TERP_DEBUG_TRUE_OR_THROW( geomPtr, "Invalid geometry pointer" );
264 
265  const std::size_t nRings = geomPtr->getNumRings();
266 
267  te::gm::Polygon* outPolPtr = new te::gm::Polygon( 0, te::gm::PolygonType, 0, nullptr );
268 
269  for( std::size_t ringIdx = 0 ; ringIdx < nRings ; ++ringIdx )
270  {
271  te::gm::LinearRing const* inRingPtr = dynamic_cast< te::gm::LinearRing const* >(
272  geomPtr->getRingN( ringIdx ) );
273  assert( inRingPtr );
274 
275  const std::size_t nPoints = inRingPtr->getNPoints();
276  te::gm::Coord2D const * inCoordsPtr = inRingPtr->getCoordinates();
277  te::gm::Coord2D auxCoord;
278 
279  te::gm::LinearRing* outRingPtr = new te::gm::LinearRing( nPoints,
280  te::gm::LineStringType, 0, nullptr );
281 
282  for( std::size_t pIdx = 0 ; pIdx < nPoints ; ++pIdx )
283  {
284  grid.geoToGrid( inCoordsPtr[ pIdx ].x, inCoordsPtr[ pIdx ].y,
285  auxCoord.x, auxCoord.y );
286  outRingPtr->setPoint( pIdx, auxCoord.x, auxCoord.y );
287  }
288 
289  outPolPtr->add( outRingPtr );
290 
291  }
292 
293  indexedDelimiter1Ptr->add( outPolPtr );
294  }
295  }
296  else
297  {
298  te::gm::LinearRing* outRingPtr = new te::gm::LinearRing( 5,
299  te::gm::LineStringType, 0, nullptr );
300 
301  outRingPtr->setPoint( 0,
302  -0.5,
303  -0.5 );
304  outRingPtr->setPoint( 1,
305  ((double)raster1.getNumberOfColumns()) - 0.5,
306  -0.5 );
307  outRingPtr->setPoint( 2,
308  ((double)raster1.getNumberOfColumns()) - 0.5,
309  ((double)raster1.getNumberOfRows()) - 0.5 );
310  outRingPtr->setPoint( 3,
311  -0.5,
312  ((double)raster1.getNumberOfRows()) - 0.5 );
313  outRingPtr->setPoint( 4,
314  -0.5,
315  -0.5 );
316 
317  te::gm::Polygon* outPolPtr = new te::gm::Polygon( 0, te::gm::PolygonType, 0, nullptr );
318 
319  outPolPtr->add( outRingPtr );
320 
321  indexedDelimiter1Ptr->add( outPolPtr );
322  }
323 
324  TERP_TRUE_OR_RETURN_FALSE( indexedDelimiter1Ptr->isValid(),
325  "Invalid indexed geometry 1" );
326 
327  // indexed under raster 1 lines/cols
328  std::unique_ptr< te::gm::MultiPolygon > indexedDelimiter2Ptr(
329  new te::gm::MultiPolygon( 0, te::gm::MultiPolygonType, 0, nullptr ) );
330 
331  if( r2ValidDataDelimiterPtr )
332  {
333  const te::rst::Grid& grid = (*raster2.getGrid());
334 
335  const std::size_t nGeoms = r2ValidDataDelimiterPtr->getNumGeometries();
336 
337  for( std::size_t geomIdx = 0 ; geomIdx < nGeoms ; ++geomIdx )
338  {
339  te::gm::Polygon const* geomPtr = dynamic_cast< te::gm::Polygon* >(
340  r2ValidDataDelimiterPtr->getGeometryN( geomIdx ) );
341  TERP_DEBUG_TRUE_OR_THROW( geomPtr, "Invalid geometry pointer" );
342 
343  const std::size_t nRings = geomPtr->getNumRings();
344 
345  te::gm::Polygon* outPolPtr = new te::gm::Polygon( 0, te::gm::PolygonType, 0, nullptr );
346 
347  for( std::size_t ringIdx = 0 ; ringIdx < nRings ; ++ringIdx )
348  {
349  te::gm::LinearRing const* inRingPtr = dynamic_cast< te::gm::LinearRing const* >(
350  geomPtr->getRingN( ringIdx ) );
351  assert( inRingPtr );
352 
353  const std::size_t nPoints = inRingPtr->getNPoints();
354  te::gm::Coord2D const * inCoordsPtr = inRingPtr->getCoordinates();
355  te::gm::Coord2D auxCoord;
356  te::gm::Coord2D auxCoord2;
357 
358  te::gm::LinearRing* outRingPtr = new te::gm::LinearRing( nPoints,
359  te::gm::LineStringType, 0, nullptr );
360 
361  for( std::size_t pIdx = 0 ; pIdx < nPoints ; ++pIdx )
362  {
363  grid.geoToGrid( inCoordsPtr[ pIdx ].x, inCoordsPtr[ pIdx ].y,
364  auxCoord.x, auxCoord.y );
365  geomTransformation.inverseMap( auxCoord.x, auxCoord.y, auxCoord2.x, auxCoord2.y );
366  outRingPtr->setPoint( pIdx, auxCoord2.x, auxCoord2.y );
367  }
368 
369  outPolPtr->add( outRingPtr );
370  }
371 
372  indexedDelimiter2Ptr->add( outPolPtr );
373  }
374  }
375  else
376  {
377  te::gm::LinearRing* outRingPtr = new te::gm::LinearRing( 5,
378  te::gm::LineStringType, 0, nullptr );
379 
380  te::gm::Coord2D auxCoord;
381 
382  geomTransformation.inverseMap(
383  -0.5,
384  -0.5,
385  auxCoord.x, auxCoord.y );
386  outRingPtr->setPoint( 0, auxCoord.x, auxCoord.y );
387  outRingPtr->setPoint( 4, auxCoord.x, auxCoord.y );
388 
389  geomTransformation.inverseMap(
390  ((double)raster2.getNumberOfColumns()) - 0.5,
391  -0.5,
392  auxCoord.x, auxCoord.y );
393  outRingPtr->setPoint( 1, auxCoord.x, auxCoord.y );
394 
395  geomTransformation.inverseMap(
396  ((double)raster2.getNumberOfColumns()) - 0.5,
397  ((double)raster2.getNumberOfRows()) - 0.5,
398  auxCoord.x, auxCoord.y );
399  outRingPtr->setPoint( 2, auxCoord.x, auxCoord.y );
400 
401  geomTransformation.inverseMap(
402  -0.5,
403  ((double)raster2.getNumberOfRows()) - 0.5,
404  auxCoord.x, auxCoord.y );
405  outRingPtr->setPoint( 3, auxCoord.x, auxCoord.y );
406 
407  te::gm::Polygon* outPolPtr = new te::gm::Polygon( 0, te::gm::PolygonType, 0, nullptr );
408 
409  outPolPtr->add( outRingPtr );
410 
411  indexedDelimiter2Ptr->add( outPolPtr );
412  }
413 
414  TERP_TRUE_OR_RETURN_FALSE( indexedDelimiter2Ptr->isValid(),
415  "Invalid indexed geometry 1" );
416 
417  // Calculating the intersection (raster 1 lines/cols)
418 
419  try
420  {
421  m_intersectionPtr.reset( indexedDelimiter2Ptr->intersection(
422  indexedDelimiter1Ptr.get() ) );
423  }
424  catch( const std::exception& e )
425  {
426  TERP_LOG_AND_RETURN_FALSE( "Indexed geometry intersection:" +
427  std::string( e.what() ) );
428  }
429 
430  // Initializing the intersection tile indexer
431 
432  if( m_intersectionPtr.get() )
433  {
435  m_intersectionTileIndexers ), "Intersection tile indexers creation error" );
436  }
437 
438  // Extracting the intersection segments points
439 
440  if( m_intersectionPtr.get() )
441  {
442  std::size_t ringIdx = 0;
443  std::unique_ptr< te::gm::Geometry > ringIntersectionPtr;
444  std::size_t nPols = 0;
445  std::size_t polIdx = 0;
446 
447  nPols = indexedDelimiter2Ptr->getNumGeometries();
448  for( polIdx = 0 ; polIdx < nPols ; ++polIdx )
449  {
450  te::gm::Polygon const* polPtr = dynamic_cast< te::gm::Polygon* >(
451  indexedDelimiter2Ptr->getGeometryN( polIdx ) );
452 
453  if( polPtr )
454  {
455  for( ringIdx = 0 ; ringIdx < polPtr->getNumRings() ;
456  ++ringIdx )
457  {
458  ringIntersectionPtr.reset( indexedDelimiter1Ptr->intersection(
459  polPtr->getRingN( ringIdx ) ) );
460 
461  if( ringIntersectionPtr.get() != nullptr )
462  {
463  getSegments( ringIntersectionPtr.get(), m_r2IntersectionSegmentsPoints );
464  }
465  }
466  }
467  }
468 
469  nPols = indexedDelimiter1Ptr->getNumGeometries();
470  for( polIdx = 0 ; polIdx < nPols ; ++polIdx )
471  {
472  te::gm::Polygon const* polPtr = dynamic_cast< te::gm::Polygon* >(
473  indexedDelimiter1Ptr->getGeometryN( polIdx ) );
474 
475  if( polPtr )
476  {
477  for( ringIdx = 0 ; ringIdx < polPtr->getNumRings() ;
478  ++ringIdx )
479  {
480  ringIntersectionPtr.reset( indexedDelimiter2Ptr->intersection(
481  polPtr->getRingN( ringIdx ) ) );
482 
483  if( ringIntersectionPtr.get() != nullptr )
484  {
485  getSegments( ringIntersectionPtr.get(), m_r1IntersectionSegmentsPoints );
486  }
487  }
488  }
489  }
490 
491 /* std::cout << std::endl;
492  for( unsigned int idx = 0 ; idx < m_r1IntersectionSegmentsPoints.size() ; ++idx )
493  {
494  std::cout << std::endl << "m_r1IntersectionSegmentsPoints[" << idx << "]="
495  << m_r1IntersectionSegmentsPoints[ idx ].first.x
496  << " " << m_r1IntersectionSegmentsPoints[ idx ].first.y
497  << " " << m_r1IntersectionSegmentsPoints[ idx ].second.x
498  << " " << m_r1IntersectionSegmentsPoints[ idx ].second.y;
499  }
500  for( unsigned int idx = 0 ; idx < m_r2IntersectionSegmentsPoints.size() ; ++idx )
501  {
502  std::cout << std::endl << "m_r2IntersectionSegmentsPoints[" << idx << "]="
503  << m_r2IntersectionSegmentsPoints[ idx ].first.x
504  << " " << m_r2IntersectionSegmentsPoints[ idx ].first.y
505  << " " << m_r2IntersectionSegmentsPoints[ idx ].second.x
506  << " " << m_r2IntersectionSegmentsPoints[ idx ].second.y;
507  }
508  std::cout << std::endl; */
509 
512  }
513 
514  // defining the blending method
515 
516  switch( blendMethod )
517  {
518  case NoBlendMethod :
519  {
521  break;
522  }
524  {
525  if( ( m_intersectionPtr.get() != nullptr ) &&
528  {
530  }
531  else
532  {
534  }
535  break;
536  }
537  case SumMethod :
538  {
539  if( ( m_intersectionPtr.get() != nullptr ) &&
542  {
544  }
545  else
546  {
548  }
549  break;
550  }
551  case MaxMethod :
552  {
553  if( ( m_intersectionPtr.get() != nullptr ) &&
556  {
558  }
559  else
560  {
562  }
563  break;
564  }
565  case MinMethod :
566  {
567  if( ( m_intersectionPtr.get() != nullptr ) &&
570  {
572  }
573  else
574  {
576  }
577  break;
578  }
579  default :
580  {
581  TERP_LOG_AND_THROW( "Invalid blend method" );
582  break;
583  }
584  }
585 
586  // Defining the blending function pointers
587 
589 
590  // defining the geometric transformation
591 
592  m_geomTransformationPtr = geomTransformation.clone();
593 
594  // defining the interpolators
595 
596  if( forceRaster1NoDataValue )
597  {
598  std::vector< std::complex<double> > noDataValues1( raster1.getNumberOfBands(),
599  std::complex<double>( noDataValue, 0.0 ) );
600  m_interp1Ptr.reset( new te::rst::Interpolator( &raster1, interpMethod1,
601  noDataValues1 ) );
602  }
603  else
604  {
605  m_interp1Ptr.reset( new te::rst::Interpolator( &raster1, interpMethod1 ) );
606  }
607 
608  if( forceRaster2NoDataValue )
609  {
610  std::vector< std::complex<double> > noDataValues2( raster2.getNumberOfBands(),
611  std::complex<double>( noDataValue, 0.0 ) );
612  m_interp2Ptr.reset( new te::rst::Interpolator( &raster2, interpMethod2,
613  noDataValues2 ) );
614  }
615  else
616  {
617  m_interp2Ptr.reset( new te::rst::Interpolator( &raster2, interpMethod2 ) );
618  }
619 
620  m_interpMethod1 = interpMethod1;
621  m_interpMethod2 = interpMethod2;
622 
623  // defining dummy values
624 
625  m_forceRaster1NoDataValue = forceRaster1NoDataValue;
626  m_forceRaster2NoDataValue = forceRaster2NoDataValue;
627 
628  for( std::vector< unsigned int >::size_type rasterBandsIdx = 0 ;
629  rasterBandsIdx < raster1Bands.size() ; ++rasterBandsIdx )
630  {
631  TERP_TRUE_OR_RETURN_FALSE( raster1Bands[ rasterBandsIdx ] <
632  raster1.getNumberOfBands(), "Invalid band" );
633  TERP_TRUE_OR_RETURN_FALSE( raster2Bands[ rasterBandsIdx ] <
634  raster2.getNumberOfBands(), "Invalid band" );
635 
636  if( forceRaster1NoDataValue )
637  {
638  m_raster1NoDataValues.push_back( noDataValue );
639  }
640  else
641  {
642  m_raster1NoDataValues.push_back( raster1.getBand( raster1Bands[
643  rasterBandsIdx ] )->getProperty()->m_noDataValue );
644  }
645 
646  if( forceRaster2NoDataValue )
647  {
648  m_raster2NoDataValues.push_back( noDataValue );
649  }
650  else
651  {
652  m_raster2NoDataValues.push_back( raster2.getBand( raster2Bands[
653  rasterBandsIdx ] )->getProperty()->m_noDataValue );
654  }
655  }
656 
657  m_outputNoDataValue = noDataValue;
658 
659  // defining raster bands
660 
661  m_raster1Bands = raster1Bands;
662  m_raster2Bands = raster2Bands;
663 
664  // defining pixel offsets
665 
666  m_pixelOffsets1 = pixelOffsets1;
667  m_pixelScales1 = pixelScales1;
668 
669  m_pixelOffsets2 = pixelOffsets2;
670  m_pixelScales2 = pixelScales2;
671 
672  // threads
673 
674  if( threadsNumber == 0 )
675  {
677  }
678  else
679  {
680  m_threadsNumber = threadsNumber;
681  }
682 
683  // progress interface
684 
685  m_enableProgressInterface = enableProgressInterface;
686 
687  return true;
688  }
689 
691  {
695  m_threadsNumber = 0;
697  m_blendFuncPtr = nullptr;
698  m_raster1Ptr = nullptr;
699  m_raster2Ptr = nullptr;
702  m_geomTransformationPtr = nullptr;
706  }
707 
709  {
712  m_intersectionPtr.reset();
716  m_interp1Ptr.reset();
717  m_interp2Ptr.reset();
718  m_raster1Bands.clear();
719  m_raster2Bands.clear();
720  m_pixelOffsets1.clear();
721  m_pixelScales1.clear();
722  m_pixelOffsets2.clear();
723  m_pixelScales2.clear();
724  m_raster1NoDataValues.clear();
725  m_raster2NoDataValues.clear();
727 
728  initState();
729  }
730 
732  {
733  switch( blendMethod )
734  {
735  case NoBlendMethod :
736  {
738  break;
739  }
741  {
743  break;
744  }
745  case SumMethod :
746  {
748  break;
749  }
750  case MaxMethod :
751  {
753  break;
754  }
755  case MinMethod :
756  {
758  break;
759  }
760  default :
761  {
762  TERP_LOG_AND_THROW( "Invalid blend method" );
763  break;
764  }
765  }
766  }
767 
768  void Blender::noBlendMethodImp( const double& line, const double& col,
769  double* const values )
770  {
771  // Finding the point over the second raster
772 
775 
776  // Blending values
777 
780  {
781  m_interp1Ptr->getValue( col, line, m_noBlendMethodImp_cValue,
784 
785  if( m_noBlendMethodImp_Value == m_raster1NoDataValues[ m_noBlendMethodImp_BandIdx ] )
786  {
789  m_raster2Bands[ m_noBlendMethodImp_BandIdx ] );
791 
792  if( m_noBlendMethodImp_Value == m_raster2NoDataValues[ m_noBlendMethodImp_BandIdx ] )
793  {
795  }
796  else
797  {
798 
801 
803  }
804  }
805  else
806  {
807 
810 
812  }
813  }
814  }
815 
816  void Blender::euclideanDistanceMethodImp( const double& line, const double& col,
817  double* const values )
818  {
819  TERP_DEBUG_TRUE_OR_THROW( m_intersectionPtr.get(), "Invalid intersection pointer" );
820  TERP_DEBUG_TRUE_OR_THROW( m_r1IntersectionSegmentsPointsSize > 1, "Invalid intersection points" );
821  TERP_DEBUG_TRUE_OR_THROW( m_r2IntersectionSegmentsPointsSize > 1, "Invalid intersection points" );
822 
823  // Checking if it is inside the intersection
824 
827 
832  {
836  {
838  break;
839  }
840  }
841 
842  // Blending if the point is inside the intersection
843 
845  {
846  // Finding distances to both rasters valid area delimiters
847 
848  m_euclideanDistanceMethodImp_dist1 = std::numeric_limits<double>::max();
852  {
853 
855  col,
856  line,
858  m_r1IntersectionSegmentsPoints[ m_euclideanDistanceMethodImp_vecIdx ].first.y,
859  m_r1IntersectionSegmentsPoints[ m_euclideanDistanceMethodImp_vecIdx ].second.x,
860  m_r1IntersectionSegmentsPoints[ m_euclideanDistanceMethodImp_vecIdx ].second.y,
864 
866  {
868  }
869  }
870 
871  m_euclideanDistanceMethodImp_dist2 = std::numeric_limits<double>::max();
875  {
876 
878  col,
879  line,
881  m_r2IntersectionSegmentsPoints[ m_euclideanDistanceMethodImp_vecIdx ].first.y,
882  m_r2IntersectionSegmentsPoints[ m_euclideanDistanceMethodImp_vecIdx ].second.x,
883  m_r2IntersectionSegmentsPoints[ m_euclideanDistanceMethodImp_vecIdx ].second.y,
887 
889  {
891  }
892  }
893 
894  // Finding the point over the second raster
895 
898 
899  // Blending values
900 
903  {
904  m_interp1Ptr->getValue( col, line, m_euclideanDistanceMethodImp_cValue1,
908  m_raster2Bands[ m_euclideanDistanceMethodImp_BandIdx ] );
909 
911  {
913  {
915  }
916  else
917  {
919  (
921  *
923  )
924  +
925  m_pixelOffsets2[ m_euclideanDistanceMethodImp_BandIdx ];
926  }
927  }
928  else
929  {
931  {
933  (
935  *
937 
938  )
939  +
940  m_pixelOffsets1[ m_euclideanDistanceMethodImp_BandIdx ];
941  }
942  else
943  {
945  {
947  (
949  *
951  )
952  +
953  m_pixelOffsets1[ m_euclideanDistanceMethodImp_BandIdx ];
954  }
955  else if( m_euclideanDistanceMethodImp_dist1 == 0.0 )
956  {
958  (
960  *
962 
963  )
964  +
965  m_pixelOffsets2[ m_euclideanDistanceMethodImp_BandIdx ];
966  }
967  else
968  {
970  (
971  (
972  (
973  (
975  *
977 
978  )
979  +
980  m_pixelOffsets1[ m_euclideanDistanceMethodImp_BandIdx ]
981  )
982  *
984  )
985  +
986  (
987  (
988  (
990  *
992  )
993  +
994  m_pixelOffsets2[ m_euclideanDistanceMethodImp_BandIdx ]
995  )
996  *
998  )
999  )
1000  /
1001  (
1003  +
1005  );
1006  }
1007  }
1008  }
1009  }
1010  }
1011  else
1012  {
1013  noBlendMethodImp( line, col, values );
1014  }
1015  }
1016 
1017  void Blender::sumMethodImp( const double& line, const double& col,
1018  double* const values )
1019  {
1020  TERP_DEBUG_TRUE_OR_THROW( m_intersectionPtr.get(), "Invalid intersection pointer" );
1021  TERP_DEBUG_TRUE_OR_THROW( m_r1IntersectionSegmentsPointsSize > 1, "Invalid intersection points" );
1022  TERP_DEBUG_TRUE_OR_THROW( m_r2IntersectionSegmentsPointsSize > 1, "Invalid intersection points" );
1023 
1024  // Checking if it is inside the intersection
1025 
1027  m_sumMethodImp_auxPoint.setY( line );
1028 
1033  {
1037  {
1039  break;
1040  }
1041  }
1042 
1043  // Blending if the point is inside the intersection
1044 
1046  {
1047  // Finding the point over the second raster
1048 
1051 
1052  // Blending values
1053 
1056  {
1057  m_interp1Ptr->getValue( col, line, m_sumMethodImp_cValue1,
1061  m_raster2Bands[ m_sumMethodImp_BandIdx ] );
1062 
1064  {
1066  {
1068  }
1069  else
1070  {
1071  values[ m_sumMethodImp_BandIdx ] =
1072  (
1073  m_sumMethodImp_cValue2.real()
1074  *
1076  )
1077  +
1078  m_pixelOffsets2[ m_sumMethodImp_BandIdx ];
1079  }
1080  }
1081  else
1082  {
1084  {
1085  values[ m_sumMethodImp_BandIdx ] =
1086  (
1087  m_sumMethodImp_cValue1.real()
1088 
1089  *
1091  )
1092  +
1093  m_pixelOffsets1[ m_sumMethodImp_BandIdx ];
1094  }
1095  else
1096  {
1097  values[ m_sumMethodImp_BandIdx ] =
1098  (
1099  (
1100  m_sumMethodImp_cValue1.real()
1101  *
1103  )
1104  +
1105  m_pixelOffsets1[ m_sumMethodImp_BandIdx ]
1106  )
1107  +
1108  (
1109  (
1110  m_sumMethodImp_cValue2.real()
1111  *
1113  )
1114  +
1115  m_pixelOffsets2[ m_sumMethodImp_BandIdx ]
1116  );
1117  }
1118  }
1119  }
1120  }
1121  else
1122  {
1123  noBlendMethodImp( line, col, values );
1124  }
1125  }
1126 
1127  void Blender::maxMethodImp( const double& line, const double& col,
1128  double* const values )
1129  {
1130  TERP_DEBUG_TRUE_OR_THROW( m_intersectionPtr.get(), "Invalid intersection pointer" );
1131  TERP_DEBUG_TRUE_OR_THROW( m_r1IntersectionSegmentsPointsSize > 1, "Invalid intersection points" );
1132  TERP_DEBUG_TRUE_OR_THROW( m_r2IntersectionSegmentsPointsSize > 1, "Invalid intersection points" );
1133 
1134  // Checking if it is inside the intersection
1135 
1137  m_maxMethodImp_auxPoint.setY( line );
1138 
1143  {
1147  {
1149  break;
1150  }
1151  }
1152 
1153  // Blending if the point is inside the intersection
1154 
1156  {
1157  // Finding the point over the second raster
1158 
1161 
1162  // Blending values
1163 
1166  {
1167  m_interp1Ptr->getValue( col, line, m_maxMethodImp_cValue1,
1171  m_raster2Bands[ m_maxMethodImp_BandIdx ] );
1172 
1174  {
1176  {
1178  }
1179  else
1180  {
1181  values[ m_maxMethodImp_BandIdx ] =
1182  (
1183  m_maxMethodImp_cValue2.real()
1184  *
1186  )
1187  +
1188  m_pixelOffsets2[ m_maxMethodImp_BandIdx ];
1189  }
1190  }
1191  else
1192  {
1194  {
1195  values[ m_maxMethodImp_BandIdx ] =
1196  (
1197  m_maxMethodImp_cValue1.real()
1198 
1199  *
1201  )
1202  +
1203  m_pixelOffsets1[ m_maxMethodImp_BandIdx ];
1204  }
1205  else
1206  {
1207  values[ m_maxMethodImp_BandIdx ] =
1208  std::max(
1209  (
1210  (
1211  m_maxMethodImp_cValue1.real()
1212  *
1214  )
1215  +
1216  m_pixelOffsets1[ m_maxMethodImp_BandIdx ]
1217  )
1218  ,
1219  (
1220  (
1221  m_maxMethodImp_cValue2.real()
1222  *
1224  )
1225  +
1226  m_pixelOffsets2[ m_maxMethodImp_BandIdx ]
1227  )
1228  );
1229  }
1230  }
1231  }
1232  }
1233  else
1234  {
1235  noBlendMethodImp( line, col, values );
1236  }
1237  }
1238 
1239  void Blender::minMethodImp( const double& line, const double& col,
1240  double* const values )
1241  {
1242  TERP_DEBUG_TRUE_OR_THROW( m_intersectionPtr.get(), "Invalid intersection pointer" );
1243  TERP_DEBUG_TRUE_OR_THROW( m_r1IntersectionSegmentsPointsSize > 1, "Invalid intersection points" );
1244  TERP_DEBUG_TRUE_OR_THROW( m_r2IntersectionSegmentsPointsSize > 1, "Invalid intersection points" );
1245 
1246  // Checking if it is inside the intersection
1247 
1249  m_minMethodImp_auxPoint.setY( line );
1250 
1255  {
1259  {
1261  break;
1262  }
1263  }
1264 
1265  // Blending if the point is inside the intersection
1266 
1268  {
1269  // Finding the point over the second raster
1270 
1273 
1274  // Blending values
1275 
1278  {
1279  m_interp1Ptr->getValue( col, line, m_minMethodImp_cValue1,
1283  m_raster2Bands[ m_minMethodImp_BandIdx ] );
1284 
1286  {
1288  {
1290  }
1291  else
1292  {
1293  values[ m_minMethodImp_BandIdx ] =
1294  (
1295  m_minMethodImp_cValue2.real()
1296  *
1298  )
1299  +
1300  m_pixelOffsets2[ m_minMethodImp_BandIdx ];
1301  }
1302  }
1303  else
1304  {
1306  {
1307  values[ m_minMethodImp_BandIdx ] =
1308  (
1309  m_minMethodImp_cValue1.real()
1310 
1311  *
1313  )
1314  +
1315  m_pixelOffsets1[ m_minMethodImp_BandIdx ];
1316  }
1317  else
1318  {
1319  values[ m_minMethodImp_BandIdx ] =
1320  std::min(
1321  (
1322  (
1323  m_minMethodImp_cValue1.real()
1324  *
1326  )
1327  +
1328  m_pixelOffsets1[ m_minMethodImp_BandIdx ]
1329  )
1330  ,
1331  (
1332  (
1333  m_minMethodImp_cValue2.real()
1334  *
1336  )
1337  +
1338  m_pixelOffsets2[ m_minMethodImp_BandIdx ]
1339  )
1340  );
1341  }
1342  }
1343  }
1344  }
1345  else
1346  {
1347  noBlendMethodImp( line, col, values );
1348  }
1349  }
1350 
1352  {
1354  te::common::WAccess, "Invalid output raster access policy" );
1355 
1356  // Locating raster2 over the raster1
1357 
1358  unsigned int firstOutputRasterCol = 0;
1359  unsigned int lastOutputRasterRow = 0;
1360  unsigned int lastOutputRasterCol = 0;
1361  unsigned int firstOutputRasterRow = 0;
1362 
1363  {
1364  const double raster2LastRowIdx =
1365  (double)( m_raster2Ptr->getNumberOfRows() - 1 );
1366  const double raster2LastColIdx =
1367  (double)( m_raster2Ptr->getNumberOfColumns() - 1 );
1368  double raster2LLColOverRaster1 = 0;
1369  double raster2LLRowOverRaster1 = 0;
1370  double raster2LRColOverRaster1 = 0;
1371  double raster2LRRowOverRaster1 = 0;
1372  double raster2URColOverRaster1 = 0;
1373  double raster2URRowOverRaster1 = 0;
1374  double raster2ULColOverRaster1 = 0;
1375  double raster2ULRowOverRaster1 = 0;
1376 
1378  0.0,
1379  raster2LastRowIdx,
1380  raster2LLColOverRaster1,
1381  raster2LLRowOverRaster1);
1383  raster2LastColIdx,
1384  raster2LastRowIdx,
1385  raster2LRColOverRaster1,
1386  raster2LRRowOverRaster1);
1388  raster2LastColIdx,
1389  0.0,
1390  raster2URColOverRaster1,
1391  raster2URRowOverRaster1);
1393  0.0,
1394  0.0,
1395  raster2ULColOverRaster1,
1396  raster2ULRowOverRaster1);
1397 
1398  firstOutputRasterCol = (unsigned int)
1399  std::max( 0l,
1400  std::min( (long int)( m_raster1Ptr->getNumberOfColumns() - 1 ),
1401  te::common::Round< double, long int >(
1402  std::min( raster2LLColOverRaster1,
1403  std::min( raster2LRColOverRaster1,
1404  std::min( raster2URColOverRaster1,
1405  raster2ULColOverRaster1
1406  )
1407  )
1408  )
1409  )
1410  )
1411  );
1412 
1413  lastOutputRasterRow = (unsigned int)
1414  std::max( 0l,
1415  std::min( (long int)( m_raster1Ptr->getNumberOfRows() - 1 ),
1416  te::common::Round< double, long int >(
1417  std::max( raster2LLRowOverRaster1,
1418  std::max( raster2LRRowOverRaster1,
1419  std::max( raster2URRowOverRaster1,
1420  raster2ULRowOverRaster1
1421  )
1422  )
1423  )
1424  )
1425  )
1426  );
1427 
1428  lastOutputRasterCol = (unsigned int)
1429  std::max( 0l,
1430  std::min( (long int)( m_raster1Ptr->getNumberOfColumns() - 1 ),
1431  te::common::Round< double, long int >(
1432  std::max( raster2LLColOverRaster1,
1433  std::max( raster2LRColOverRaster1,
1434  std::max( raster2URColOverRaster1,
1435  raster2ULColOverRaster1
1436  )
1437  )
1438  )
1439  )
1440  )
1441  );
1442 
1443  firstOutputRasterRow = (unsigned int)
1444  std::max( 0l,
1445  std::min( (long int)( m_raster1Ptr->getNumberOfRows() - 1 ),
1446  te::common::Round< double, long int >(
1447  std::min( raster2LLRowOverRaster1,
1448  std::min( raster2LRRowOverRaster1,
1449  std::min( raster2URRowOverRaster1,
1450  raster2ULRowOverRaster1
1451  )
1452  )
1453  )
1454  )
1455  )
1456  );
1457 
1458  assert( firstOutputRasterCol >= 0 );
1459  assert( firstOutputRasterCol <=
1460  ( m_raster1Ptr->getNumberOfColumns() - 1 ) );
1461  assert( lastOutputRasterRow >= 0 );
1462  assert( lastOutputRasterRow <=
1463  ( m_raster1Ptr->getNumberOfRows() - 1 ) );
1464  assert( lastOutputRasterCol >= 0 );
1465  assert( lastOutputRasterCol <=
1466  ( m_raster1Ptr->getNumberOfColumns() - 1 ) );
1467  assert( firstOutputRasterRow >= 0 );
1468  assert( firstOutputRasterRow <=
1469  ( m_raster1Ptr->getNumberOfRows() - 1 ) );
1470  }
1471 
1472  // Discovering the raster 1 blocks we need to process
1473 
1474  std::vector< RasterBlockInfo > raster1BlocksInfos;
1475  bool allRaster1BandsWithSameBlocking = true;
1476 
1477  {
1478  const te::rst::Band& firstBand = *( m_raster1Ptr->getBand(
1479  m_raster1Bands[ 0 ] ) );
1480 
1481  for( unsigned int raster1BandsIdx = 0 ; raster1BandsIdx <
1482  m_raster1Bands.size() ; ++raster1BandsIdx )
1483  {
1484  const te::rst::Band& band = *( m_raster1Ptr->getBand(
1485  m_raster1Bands[ raster1BandsIdx ] ) );
1486 
1487  if(
1488  ( band.getProperty()->m_blkh != firstBand.getProperty()->m_blkh )
1489  ||
1490  ( band.getProperty()->m_blkw != firstBand.getProperty()->m_blkw )
1491  ||
1492  ( band.getProperty()->m_nblocksx != firstBand.getProperty()->m_nblocksx )
1493  ||
1494  ( band.getProperty()->m_nblocksy != firstBand.getProperty()->m_nblocksy )
1495  )
1496  {
1497  allRaster1BandsWithSameBlocking = false;
1498  break;
1499  }
1500  }
1501 
1502  unsigned int firstBlockX = firstOutputRasterCol /
1503  firstBand.getProperty()->m_blkw;
1504  unsigned int lastBlockX = lastOutputRasterCol /
1505  firstBand.getProperty()->m_blkw;
1506  unsigned int firstBlockY = firstOutputRasterRow /
1507  firstBand.getProperty()->m_blkh;
1508  unsigned int lastBlockY = lastOutputRasterRow /
1509  firstBand.getProperty()->m_blkh;
1510 
1511  for( unsigned int blkY = firstBlockY ; blkY <= lastBlockY ; ++blkY )
1512  {
1513  for( unsigned int blkX = firstBlockX ; blkX <= lastBlockX ; ++blkX )
1514  {
1515  raster1BlocksInfos.push_back( RasterBlockInfo() );
1516 
1517  RasterBlockInfo& rBInfo = raster1BlocksInfos.back();
1518 
1519  rBInfo.m_wasProcessed = false;
1520  rBInfo.m_blkX = blkX;
1521  rBInfo.m_blkY = blkY;
1522  rBInfo.m_blkTotalPixelsNumber = firstBand.getProperty()->m_blkh *
1523  firstBand.getProperty()->m_blkw;
1524 
1525  rBInfo.m_firstRasterRow2Process = blkY * firstBand.getProperty()->m_blkh;
1526  rBInfo.m_firstRasterRow2Process = std::max( firstOutputRasterRow,
1527  rBInfo.m_firstRasterRow2Process );
1528  rBInfo.m_firstRasterRow2Process = std::min( lastOutputRasterRow,
1529  rBInfo.m_firstRasterRow2Process );
1530 
1531  rBInfo.m_rasterRows2ProcessBound = ( blkY + 1 ) * firstBand.getProperty()->m_blkh;
1532  rBInfo.m_rasterRows2ProcessBound = std::max( firstOutputRasterRow,
1533  rBInfo.m_rasterRows2ProcessBound );
1534  rBInfo.m_rasterRows2ProcessBound = std::min( lastOutputRasterRow + 1,
1535  rBInfo.m_rasterRows2ProcessBound );
1536 
1537  rBInfo.m_firstRasterCol2Process = blkX * firstBand.getProperty()->m_blkw;
1538  rBInfo.m_firstRasterCol2Process = std::max( firstOutputRasterCol,
1539  rBInfo.m_firstRasterCol2Process );
1540  rBInfo.m_firstRasterCol2Process = std::min( lastOutputRasterCol,
1541  rBInfo.m_firstRasterCol2Process );
1542 
1543  rBInfo.m_rasterCols2ProcessBound = ( blkX + 1 ) * firstBand.getProperty()->m_blkw;
1544  rBInfo.m_rasterCols2ProcessBound = std::max( firstOutputRasterCol,
1545  rBInfo.m_rasterCols2ProcessBound );
1546  rBInfo.m_rasterCols2ProcessBound = std::min( lastOutputRasterCol + 1,
1547  rBInfo.m_rasterCols2ProcessBound );
1548  }
1549  }
1550  }
1551 
1552  // blending
1553 
1554  bool returnValue = true;
1555 
1556  {
1557  // Guessing memory resources
1558 
1559  const double totalPhysMem = (double)te::common::GetTotalPhysicalMemory();
1560  const double usedVMem = (double)te::common::GetUsedVirtualMemory();
1561  const double totalVMem = ( (double)te::common::GetTotalVirtualMemory() );
1562  const double maxVMem2Use = 0.75 * MIN( totalPhysMem, ( totalVMem - usedVMem ) );
1563 
1564  // Creating thread exec params
1565 
1566  bool abortValue = false;
1567  boost::mutex mutex;
1570  boost::mutex blockProcessedSignalMutex;
1571  boost::condition_variable blockProcessedSignal;
1572  unsigned int runningThreadsCounter = 0;
1573 
1574  BlendIntoRaster1ThreadParams auxThreadParams;
1575  auxThreadParams.m_returnValuePtr = &returnValue;
1576  auxThreadParams.m_abortValuePtr = &abortValue;
1577  auxThreadParams.m_sync1Ptr = &sync1;
1578  auxThreadParams.m_sync2Ptr = &sync2;
1579  auxThreadParams.m_raster1BlocksInfosPtr = &raster1BlocksInfos;
1580  auxThreadParams.m_mutexPtr = &mutex;
1581  auxThreadParams.m_blockProcessedSignalMutexPtr = &blockProcessedSignalMutex;
1582  auxThreadParams.m_blockProcessedSignalPtr = &blockProcessedSignal;
1583  auxThreadParams.m_runningThreadsCounterPtr = &runningThreadsCounter;
1584  auxThreadParams.m_raster1Bands = m_raster1Bands;
1585  auxThreadParams.m_raster2Bands = m_raster2Bands;
1586  auxThreadParams.m_blendMethod = m_blendMethod;
1587  auxThreadParams.m_interpMethod2 = m_interpMethod2;
1588  auxThreadParams.m_noDataValue = m_outputNoDataValue;
1591  auxThreadParams.m_pixelOffsets1 = m_pixelOffsets1;
1592  auxThreadParams.m_pixelScales1 = m_pixelScales1;
1593  auxThreadParams.m_pixelOffsets2 = m_pixelOffsets2;
1594  auxThreadParams.m_pixelScales2 = m_pixelScales2;
1595 
1596  std::vector< BlendIntoRaster1ThreadParams > allThreadsParams( m_threadsNumber,
1597  auxThreadParams );
1598 
1599  // creating threads
1600 
1601  if( ( m_threadsNumber == 1 ) || (!allRaster1BandsWithSameBlocking) )
1602  {
1603  runningThreadsCounter = 1;
1604  if( m_r1ValidDataDelimiterPtr.get() )
1605  {
1606  allThreadsParams[ 0 ].m_r1ValidDataDelimiterPtr.reset(
1608  }
1609  if( m_r2ValidDataDelimiterPtr.get() )
1610  {
1611  allThreadsParams[ 0 ].m_r2ValidDataDelimiterPtr.reset(
1613  }
1614  allThreadsParams[ 0 ].m_geomTransformationPtr.reset(
1616  allThreadsParams[ 0 ].m_maxRasterCachedBlocks = std::max( 1u,
1617  ((unsigned int)maxVMem2Use)
1618  / ((unsigned int)m_raster2Ptr->getBand( m_raster1Bands[ 0 ] )->getBlockSize() ) );
1619  allThreadsParams[ 0 ].m_useProgress = m_enableProgressInterface;
1620 
1621  blendIntoRaster1Thread( &( allThreadsParams[ 0 ] ) );
1622  }
1623  else
1624  {
1625  boost::thread_group threads;
1626  runningThreadsCounter = m_threadsNumber;
1627 
1628  for( unsigned int threadIdx = 0 ; threadIdx < m_threadsNumber ;
1629  ++threadIdx )
1630  {
1631  if( m_r1ValidDataDelimiterPtr.get() )
1632  {
1633  allThreadsParams[ threadIdx ].m_r1ValidDataDelimiterPtr.reset(
1635  }
1636  if( m_r2ValidDataDelimiterPtr.get() )
1637  {
1638  allThreadsParams[ threadIdx ].m_r2ValidDataDelimiterPtr.reset(
1640  }
1641  allThreadsParams[ threadIdx ].m_geomTransformationPtr.reset(
1643 
1644  allThreadsParams[ 0 ].m_maxRasterCachedBlocks = std::max( 1u,
1645  ((unsigned int)maxVMem2Use)
1646  /
1647  (
1648  ((unsigned int)m_raster2Ptr->getBand( m_raster1Bands[ 0 ] )->getBlockSize() )
1649  *
1650  m_threadsNumber
1651  ) );
1652 
1653  allThreadsParams[ threadIdx ].m_useProgress = false;
1654 
1655  threads.add_thread( new boost::thread( blendIntoRaster1Thread,
1656  &( allThreadsParams[ threadIdx ] ) ) );
1657  };
1658 
1659  // progress stuff
1660 
1661  std::unique_ptr< te::common::TaskProgress > progressPtr;
1663  {
1664  progressPtr.reset( new te::common::TaskProgress );
1665  progressPtr->setTotalSteps(static_cast<int>(raster1BlocksInfos.size()));
1666  progressPtr->setMessage( "Blending" );
1667 
1668  while( (!abortValue) && (runningThreadsCounter > 0 ) )
1669  {
1670  if( progressPtr->isActive() )
1671  {
1672  boost::unique_lock<boost::mutex> lock( blockProcessedSignalMutex );
1673  blockProcessedSignal.timed_wait( lock,
1674  boost::posix_time::seconds( 1 ) );
1675 
1676  int processedBlocksNmb = 0;
1677  for( unsigned int raster1BlocksInfosIdx = 0 ; raster1BlocksInfosIdx <
1678  raster1BlocksInfos.size() ; ++raster1BlocksInfosIdx )
1679  {
1680  if( raster1BlocksInfos[ raster1BlocksInfosIdx ].m_wasProcessed )
1681  {
1682  ++processedBlocksNmb;
1683  }
1684  }
1685 
1686  if( processedBlocksNmb != progressPtr->getCurrentStep() )
1687  {
1688  progressPtr->pulse();
1689  }
1690  }
1691  else
1692  {
1693  mutex.lock();
1694  abortValue = true;
1695  mutex.unlock();
1696  }
1697  }
1698  }
1699 
1700  // Joining threads
1701 
1702  threads.join_all();
1703  }
1704  }
1705 
1706  return returnValue;
1707  }
1708 
1710  {
1711  // Instantiating the local rasters instance
1712 
1713  te::rst::SynchronizedRaster raster1(static_cast<unsigned int>(paramsPtr->m_raster1Bands.size()),
1714  *( paramsPtr->m_sync1Ptr ) );
1716  *( paramsPtr->m_sync2Ptr ) );
1717 
1718  // Guessing the output raster channels ranges
1719 
1720  const std::vector< unsigned int >& raster1Bands =
1721  paramsPtr->m_raster1Bands;
1722  const unsigned int raster1BandsSize = static_cast<unsigned int>(raster1Bands.size());
1723 
1724  std::vector< double > raster1BandsRangeMin( raster1BandsSize, 0 );
1725  std::vector< double > raster1BandsRangeMax( raster1BandsSize, 0 );
1726 
1727  {
1728  for( unsigned int raster1BandsIdx = 0 ; raster1BandsIdx <
1729  raster1BandsSize ; ++raster1BandsIdx )
1730  {
1731  unsigned int bandIdx = raster1Bands[ raster1BandsIdx ];
1732 
1733  te::rst::GetDataTypeRanges( raster1.getBand( bandIdx )->getProperty()->m_type,
1734  raster1BandsRangeMin[ raster1BandsIdx ],
1735  raster1BandsRangeMax[ raster1BandsIdx ]);
1736  }
1737  }
1738 
1739  // instantiating the thread local blender instance
1740 
1741  paramsPtr->m_mutexPtr->lock();
1742  const unsigned int raster1BlocksInfosSize = static_cast<unsigned int>(paramsPtr->m_raster1BlocksInfosPtr->size());
1743  paramsPtr->m_mutexPtr->unlock();
1744 
1745  Blender blender;
1746 
1747  if( ! blender.initialize(
1748  raster1,
1749  paramsPtr->m_raster1Bands,
1750  raster2,
1751  paramsPtr->m_raster2Bands,
1752  paramsPtr->m_blendMethod,
1754  paramsPtr->m_interpMethod2,
1755  paramsPtr->m_noDataValue,
1756  paramsPtr->m_forceRaster1NoDataValue,
1757  paramsPtr->m_forceRaster2NoDataValue,
1758  paramsPtr->m_pixelOffsets1,
1759  paramsPtr->m_pixelScales1,
1760  paramsPtr->m_pixelOffsets2,
1761  paramsPtr->m_pixelScales2,
1762  paramsPtr->m_r1ValidDataDelimiterPtr.get(),
1763  paramsPtr->m_r2ValidDataDelimiterPtr.get(),
1764  *( paramsPtr->m_geomTransformationPtr ),
1765  1,
1766  false ) )
1767  {
1768  paramsPtr->m_mutexPtr->lock();
1769  *(paramsPtr->m_abortValuePtr) = true;
1770  *(paramsPtr->m_returnValuePtr) = false;
1771  --( *(paramsPtr->m_runningThreadsCounterPtr) );
1772  paramsPtr->m_mutexPtr->unlock();
1773  return;
1774  }
1775 
1776  // progress stuff
1777 
1778  std::unique_ptr< te::common::TaskProgress > progressPtr;
1779 
1780  if( paramsPtr->m_useProgress )
1781  {
1782  progressPtr.reset( new te::common::TaskProgress );
1783  progressPtr->setTotalSteps( raster1BlocksInfosSize );
1784  progressPtr->setMessage( "Blending" );
1785  }
1786 
1787  // loocking for the next raster block to blend
1788 
1789  boost::scoped_array< double > blendedValuesHandler( new double[ raster1BandsSize ] );
1790  double* blendedValuesHandlerPtr = blendedValuesHandler.get();
1791 
1792  const double noDataValue = paramsPtr->m_noDataValue;
1793 
1794  for( unsigned int raster1BlocksInfosIdx = 0 ; raster1BlocksInfosIdx <
1795  raster1BlocksInfosSize ; ++raster1BlocksInfosIdx )
1796  {
1797  paramsPtr->m_mutexPtr->lock();
1798 
1799  if( paramsPtr->m_raster1BlocksInfosPtr->operator[]( raster1BlocksInfosIdx ).m_wasProcessed )
1800  {
1801  paramsPtr->m_mutexPtr->unlock();
1802  }
1803  else
1804  {
1805  RasterBlockInfo& rBInfo = paramsPtr->m_raster1BlocksInfosPtr->operator[](
1806  raster1BlocksInfosIdx );
1807  rBInfo.m_wasProcessed = true;
1808  paramsPtr->m_mutexPtr->unlock();
1809 
1810  //blending block data
1811 
1812  unsigned int raster1Row = 0;
1813  unsigned int raster1Col = 0;
1814  unsigned int raster1BandsIdx = 0;
1815 
1816  for( raster1Row = rBInfo.m_firstRasterRow2Process ; raster1Row < rBInfo.m_rasterRows2ProcessBound ;
1817  ++raster1Row )
1818  {
1819  for( raster1Col = rBInfo.m_firstRasterCol2Process ; raster1Col < rBInfo.m_rasterCols2ProcessBound ;
1820  ++raster1Col )
1821  {
1822  blender.getBlendedValues( (double)raster1Row, (double)raster1Col,
1823  blendedValuesHandlerPtr );
1824 
1825  for( raster1BandsIdx = 0 ; raster1BandsIdx < raster1BandsSize ; ++raster1BandsIdx )
1826  {
1827  double& blendedValue = blendedValuesHandlerPtr[ raster1BandsIdx ];
1828 
1829  if( blendedValue != noDataValue )
1830  {
1831  blendedValue = std::max( blendedValue ,
1832  raster1BandsRangeMin[ raster1BandsIdx ] );
1833  blendedValue = std::min( blendedValue ,
1834  raster1BandsRangeMax[ raster1BandsIdx ] );
1835 
1836  raster1.setValue( raster1Col, raster1Row, blendedValue,
1837  raster1Bands[ raster1BandsIdx ] );
1838  }
1839  }
1840  }
1841  }
1842 
1843  // progress stuff
1844 
1845  if( paramsPtr->m_useProgress )
1846  {
1847  if( progressPtr->isActive() )
1848  {
1849  progressPtr->pulse();
1850  }
1851  else
1852  {
1853  paramsPtr->m_mutexPtr->lock();
1854  *(paramsPtr->m_abortValuePtr) = true;
1855  *(paramsPtr->m_returnValuePtr) = false;
1856  --( *(paramsPtr->m_runningThreadsCounterPtr) );
1857  paramsPtr->m_mutexPtr->unlock();
1858  return;
1859  }
1860  }
1861  else
1862  {
1863  // notifying the main thread with the block processed signal
1864 
1865  boost::lock_guard<boost::mutex> blockProcessedSignalLockGuard(
1866  *( paramsPtr->m_blockProcessedSignalMutexPtr) );
1867 
1868  paramsPtr->m_blockProcessedSignalPtr->notify_one();
1869  }
1870  }
1871 
1872  // do we must continue processing ?
1873 
1874  if( *(paramsPtr->m_abortValuePtr) )
1875  {
1876  break;
1877  }
1878  }
1879 
1880  paramsPtr->m_mutexPtr->lock();
1881  --( *(paramsPtr->m_runningThreadsCounterPtr) );
1882  paramsPtr->m_mutexPtr->unlock();
1883  }
1884 
1885  void Blender::getSegments( te::gm::Geometry const * const geometryPtr,
1886  std::vector< std::pair< te::gm::Coord2D, te::gm::Coord2D > >& segments ) const
1887  {
1888  if( dynamic_cast< te::gm::LineString const * >( geometryPtr ) )
1889  {
1890  te::gm::LineString const* castGeomPtr =
1891  dynamic_cast< te::gm::LineString const * >( geometryPtr );
1892 
1893  std::size_t nPoints = castGeomPtr->size();
1894  te::gm::Coord2D const* coodsPtr = castGeomPtr->getCoordinates();
1895 
1896  for( std::size_t pIdx = 1 ; pIdx < nPoints ; ++pIdx )
1897  {
1898  segments.push_back( std::pair< te::gm::Coord2D, te::gm::Coord2D >(
1899  coodsPtr[ pIdx - 1 ], coodsPtr[ pIdx ] ) );
1900  }
1901  }
1902  else if( dynamic_cast< te::gm::CircularString const * >( geometryPtr ) )
1903  {
1904  te::gm::CircularString const* castGeomPtr =
1905  dynamic_cast< te::gm::CircularString const * >( geometryPtr );
1906 
1907  std::size_t nPoints = castGeomPtr->size();
1908  const std::vector< te::gm::Coord2D >& coods = castGeomPtr->getCoordinates();
1909 
1910  for( std::size_t pIdx = 1 ; pIdx < nPoints ; ++pIdx )
1911  {
1912  segments.push_back( std::pair< te::gm::Coord2D, te::gm::Coord2D >(
1913  coods[ pIdx - 1 ], coods[ pIdx ] ) );
1914  }
1915  }
1916  else if( dynamic_cast< te::gm::CurvePolygon const * >( geometryPtr ) )
1917  {
1918  te::gm::CurvePolygon const * castGeomPtr =
1919  dynamic_cast< te::gm::CurvePolygon const * >( geometryPtr );
1920 
1921  std::size_t numGeoms = castGeomPtr->getNumRings();
1922 
1923  for( std::size_t gIdx = 0 ; gIdx < numGeoms ; ++gIdx )
1924  {
1925  getSegments( castGeomPtr->getRingN( gIdx ), segments );
1926  }
1927  }
1928  else if( dynamic_cast< te::gm::GeometryCollection const * >( geometryPtr ) )
1929  {
1930  te::gm::GeometryCollection const * castGeomPtr =
1931  dynamic_cast< te::gm::GeometryCollection const * >( geometryPtr );
1932 
1933  std::size_t numGeoms = castGeomPtr->getNumGeometries();
1934 
1935  for( std::size_t gIdx = 0 ; gIdx < numGeoms ; ++gIdx )
1936  {
1937  getSegments( castGeomPtr->getGeometryN( gIdx ), segments );
1938  }
1939  }
1940  }
1941 
1942  bool Blender::getTileIndexers( te::gm::Geometry const * const geometryPtr,
1943  boost::ptr_vector< te::rst::TileIndexer >& tileIndexers ) const
1944  {
1945  if( dynamic_cast< te::gm::Polygon const * >( geometryPtr ) )
1946  {
1947  te::gm::Polygon const * castGeomPtr =
1948  dynamic_cast< te::gm::Polygon const * >( geometryPtr );
1949 
1950  tileIndexers.push_back( new te::rst::TileIndexer( *castGeomPtr, 1.0 ) );
1951  }
1952  else if( dynamic_cast< te::gm::GeometryCollection const * >( geometryPtr ) )
1953  {
1954  te::gm::GeometryCollection const * castGeomPtr =
1955  dynamic_cast< te::gm::GeometryCollection const * >( geometryPtr );
1956 
1957  std::size_t numGeoms = castGeomPtr->getNumGeometries();
1958 
1959  for( std::size_t gIdx = 0 ; gIdx < numGeoms ; ++gIdx )
1960  {
1961  if( ! ( getTileIndexers( castGeomPtr->getGeometryN( gIdx ), tileIndexers ) ) )
1962  {
1963  return false;
1964  }
1965  }
1966  }
1967 
1968  return true;
1969  }
1970 
1971  } // end namespace rp
1972 } // end namespace te
1973 
std::unique_ptr< te::gm::GeometricTransformation > m_geomTransformationPtr
A transformation mapping raster 1 pixels ( te::gm::GTParameters::TiePoint::first ) to raster 2 pixels...
Definition: Blender.h:203
double m_euclideanDistanceMethodImp_aux1
Definition: Blender.h:269
te::rst::Interpolator::Method m_interpMethod1
The interpolation method to use when reading raster 1 data.
Definition: Blender.h:232
std::vector< std::pair< te::gm::Coord2D, te::gm::Coord2D > > m_r2IntersectionSegmentsPoints
A sub-set of the intersection polygon wich is part of raster 2 valid data polygon ( raster 1 indexed ...
Definition: Blender.h:229
std::size_t getNumRings() const
It returns the number of rings in this CurvePolygon.
Definition: CurvePolygon.h:153
void initState()
Reset the instance to its initial default state.
Definition: Blender.cpp:690
std::size_t getNumGeometries() const
It returns the number of geometries in this GeometryCollection.
std::size_t size() const
It returns the number of points (vertexes) in the geometry.
void add(Curve *ring)
It adds the ring to the curve polygon.
void push_back(Curve *ring)
It adds the curve to the curve polygon.
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
unsigned int band
te::gm::Point m_maxMethodImp_auxPoint
Definition: Blender.h:285
Near neighborhood interpolation method.
static void blendIntoRaster1Thread(BlendIntoRaster1ThreadParams *paramsPtr)
Thread entry for the method blendIntoRaster1.
Definition: Blender.cpp:1709
Polygon tile indexing class for optmized geometrical relational tests.
Definition: TileIndexer.h:54
Keep the maximum value of two overlapping pixels.
Definition: Blender.h:69
An adapter class to allow concurrent access to raster data by multiple threads.
TECOMMONEXPORT unsigned long long int GetTotalVirtualMemory()
Returns the amount of total virtual memory (bytes) that can be claimed by the current process (physic...
double y
y-coordinate.
Definition: Coord2D.h:114
unsigned long int m_maxRasterCachedBlocks
The maximum number of raster cache blocks.
Definition: Blender.h:204
TERASTEREXPORT void GetDataTypeRanges(const int &dataType, double &min, double &max)
Return the values range of a given data type.
bool * m_abortValuePtr
A pointer to the abort execution value.
Definition: Blender.h:182
std::vector< unsigned int > m_raster2Bands
Input raster 2 band indexes to use.
Definition: Blender.h:238
double m_euclideanDistanceMethodImp_Point2Col
Definition: Blender.h:261
void minMethodImp(const double &line1, const double &col1, double *const values)
Implementation for MinMethod.
Definition: Blender.cpp:1239
std::vector< RasterBlockInfo > * m_raster1BlocksInfosPtr
blocks to process.
Definition: Blender.h:185
The parameters passed to blendIntoRaster1Thread method.
Definition: Blender.h:177
bool m_useProgress
If enabled each thread will use its own progress interface, if false only a signal will be emitted on...
Definition: Blender.h:205
boost::condition_variable * m_blockProcessedSignalPtr
Signal used to update the main process progress update.
Definition: Blender.h:188
Coord2D * getCoordinates() const
It returns a pointer to the internal array of coordinates.
Definition: LineString.h:456
double m_euclideanDistanceMethodImp_currDist
Definition: Blender.h:265
double x
x-coordinate.
Definition: Coord2D.h:113
std::vector< double > m_pixelScales1
The values scale to be applied to raster 1 pixel values before the blended value calcule (one element...
Definition: Blender.h:198
Blended pixel value calculation for two overlaped rasters.
Definition: Blender.h:58
double m_sumMethodImp_Point2Col
Definition: Blender.h:277
std::vector< double > m_pixelOffsets1
The values offset to be applied to raster 1 pixel values before the blended value calcule (one elemen...
Definition: Blender.h:197
unsigned int m_minMethodImp_IntersectionTileIndexersIdx
Definition: Blender.h:301
std::vector< double > m_pixelScales2
The values scale to be applied to raster 2 pixel values before the blended value calcule (one element...
Definition: Blender.h:242
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
virtual bool isValid(const GTParameters &params) const =0
Verifies if the supplied parameters already has a valid transformation.
std::unique_ptr< te::gm::MultiPolygon > m_r2ValidDataDelimiterPtr
A pointer to a geometry (raster 2 world/projected coords) delimiting the raster region with valid dat...
Definition: Blender.h:202
int m_nblocksx
The number of blocks in x.
Definition: BandProperty.h:145
double m_sumMethodImp_Point2Line
Definition: Blender.h:276
std::complex< double > m_sumMethodImp_cValue2
Definition: Blender.h:279
te::rst::Raster const * m_raster2Ptr
Input raster 2.
Definition: Blender.h:223
double m_outputNoDataValue
The output raster no-data value.
Definition: Blender.h:234
te::gm::Point m_minMethodImp_auxPoint
Definition: Blender.h:295
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
std::complex< double > m_minMethodImp_cValue2
Definition: Blender.h:299
std::unique_ptr< te::gm::MultiPolygon > m_r1ValidDataDelimiterPtr
A pointer to a geometry (raster 1 world/projected coords) delimiting the raster region with valid dat...
Definition: Blender.h:201
Blended pixel value calculation for two overlaped rasters.
boost::mutex * m_mutexPtr
mutex pointer.
Definition: Blender.h:186
std::vector< double > m_raster2NoDataValues
Raster 2 no-data values (on value per band).
Definition: Blender.h:244
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
unsigned int m_maxMethodImp_BandIdx
Definition: Blender.h:290
#define MIN(a, b)
Macro that returns min between two values.
double m_minMethodImp_Point2Line
Definition: Blender.h:296
std::complex< double > m_maxMethodImp_cValue2
Definition: Blender.h:289
std::unique_ptr< te::rst::Interpolator > m_interp1Ptr
Raster 1 interpolator instance pointer.
Definition: Blender.h:235
unsigned int m_maxMethodImp_IntersectionTileIndexersIdx
Definition: Blender.h:291
std::unique_ptr< te::rst::Interpolator > m_interp2Ptr
Raster 2 interpolator instance pointer.
Definition: Blender.h:236
std::vector< unsigned int > m_raster2Bands
Input raster 2 band indexes to use (this vector has the same size as raster1Bands).
Definition: Blender.h:191
bool * m_returnValuePtr
A pointer to the threadreturn value.
Definition: Blender.h:181
void clear()
Clear all internal allocated resources.
Definition: Blender.cpp:708
unsigned int * m_runningThreadsCounterPtr
a pointer to the running threads counter.
Definition: Blender.h:189
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
An access synchronizer to be used in SynchronizedRaster raster instances.
2D Geometric transformation base class.
te::rst::RasterSynchronizer * m_sync2Ptr
Raster 1 syncronizer pointer.
Definition: Blender.h:184
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
Definition: BandProperty.h:136
std::size_t m_r1IntersectionSegmentsPointsSize
Size of m_r1IntersectionSegmentsPoints;.
Definition: Blender.h:228
std::complex< double > m_sumMethodImp_cValue1
Definition: Blender.h:278
InterpolationMethod
Allowed interpolation methods.
double m_euclideanDistanceMethodImp_dist2
Definition: Blender.h:267
No blending performed.
Definition: Blender.h:66
std::complex< double > m_noBlendMethodImp_cValue
Definition: Blender.h:254
double m_euclideanDistanceMethodImp_dist1
Definition: Blender.h:266
bool m_sumMethodImp_PointInsideIntersection
Definition: Blender.h:282
Raster block info.
Definition: Blender.h:162
void geoToGrid(const double &x, const double &y, double &col, double &row) const
Get the grid point associated to a spatial location.
double m_maxMethodImp_Point2Line
Definition: Blender.h:286
bool m_enableProgressInterface
Enable progress interface.
Definition: Blender.h:216
bool blendIntoRaster1()
Execute blending of the given input rasters and write the result into raster1.
Definition: Blender.cpp:1351
std::complex< double > m_maxMethodImp_cValue1
Definition: Blender.h:288
BlendIntoRaster1ThreadParams & operator=(const BlendIntoRaster1ThreadParams &rhs)
Definition: Blender.cpp:105
void setBlendFunctionPonter(const BlendMethod blendMethod)
Set the value of m_blendFuncPtr following the given blend method.
Definition: Blender.cpp:731
#define TERP_TRUE_OR_RETURN_FALSE(value, message)
Checks if value is true. For false values a warning message will be logged and a return of context wi...
Definition: Macros.h:185
unsigned int line
bool m_forceRaster1NoDataValue
Use noDataValue as the input raster 1 no-data value (The original rasters no-data values will be igno...
Definition: Blender.h:217
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
unsigned int m_minMethodImp_BandIdx
Definition: Blender.h:300
TECOMMONEXPORT unsigned int GetPhysProcNumber()
Returns the number of physical processors.
double m_euclideanDistanceMethodImp_aux2
Definition: Blender.h:270
std::vector< double > m_pixelOffsets1
The values offset to be applied to raster 1 pixel values before the blended value calcule (one elemen...
Definition: Blender.h:239
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
void setPoint(std::size_t i, const double &x, const double &y)
It sets the value of the specified point.
virtual bool isValid() const _NOEXCEPT_OP(false)
It tells if the geometry is well formed.
bool m_maxMethodImp_PointInsideIntersection
Definition: Blender.h:292
An abstract class for raster data strucutures.
std::size_t m_r2IntersectionSegmentsPointsSize
Size of m_r2IntersectionSegmentsPoints;.
Definition: Blender.h:230
te::rst::Raster * m_raster1Ptr
Input raster 1.
Definition: Blender.h:222
unsigned int getNumberOfRows() const
Returns the raster number of rows.
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
#define TERP_LOG_AND_THROW(message)
Logs a error message and throws.
Definition: Macros.h:139
Pixels will be summed inside the raster overlapped area.
Definition: Blender.h:68
unsigned int m_sumMethodImp_IntersectionTileIndexersIdx
Definition: Blender.h:281
Keep the minimum value of two overlapping pixels.
Definition: Blender.h:70
void euclideanDistanceMethodImp(const double &line1, const double &col1, double *const values)
Implementation for EuclideanDistanceMethod.
Definition: Blender.cpp:816
BandProperty * getProperty()
Returns the band property.
URI C++ Library.
Definition: Attributes.h:37
Invalid blending method.
Definition: Blender.h:65
boost::ptr_vector< te::rst::TileIndexer > m_intersectionTileIndexers
The Intersection geometry tile indexers( raster 1 indexed coods), one indexer for each intersection p...
Definition: Blender.h:245
std::vector< double > m_pixelOffsets2
The values offset to be applied to raster 2 pixel values before the blended value calcule (one elemen...
Definition: Blender.h:241
int m_blkw
Block width (pixels).
Definition: BandProperty.h:143
std::vector< double > m_raster1NoDataValues
Raster 1 no-data values (on value per band).
Definition: Blender.h:243
unsigned int m_rasterCols2ProcessBound
Definition: Blender.h:171
te::rst::RasterSynchronizer * m_sync1Ptr
Raster 1 syncronizer pointer.
Definition: Blender.h:183
void sumMethodImp(const double &line1, const double &col1, double *const values)
Implementation for SumMethod.
Definition: Blender.cpp:1017
void maxMethodImp(const double &line1, const double &col1, double *const values)
Implementation for MaxMethod.
Definition: Blender.cpp:1127
std::vector< double > m_pixelScales1
The values scale to be applied to raster 1 pixel values before the blended value calcule (one element...
Definition: Blender.h:240
bool m_forceRaster2NoDataValue
Use noDataValue as the input raster 2 no-data value (The original rasters no-data values will be igno...
Definition: Blender.h:218
std::size_t getNPoints() const
It returns the number of points (vertexes) in the linestring.
Definition: LineString.h:193
CurvePolygon is a planar surface defined by 1 exterior boundary and 0 or more interior boundaries...
Definition: CurvePolygon.h:57
void getBlendedValues(const double &line, const double &col, double *const values)
Blend a pixel value using the current parameters.
Definition: Blender.h:133
A raster band description.
double m_noBlendMethodImp_Point2Col
Definition: Blender.h:253
void getSegments(te::gm::Geometry const *const geometryPtr, std::vector< std::pair< te::gm::Coord2D, te::gm::Coord2D > > &segments) const
Extract segments from the given geometry.
Definition: Blender.cpp:1885
BlendFunctPtr m_blendFuncPtr
The current blend function.
Definition: Blender.h:221
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
Grid * getGrid()
It returns the raster grid.
std::unique_ptr< te::gm::MultiPolygon > m_r2ValidDataDelimiterPtr
A pointer to a geometry (raster 2 world/projected coords) delimiting the raster region with valid dat...
Definition: Blender.h:225
std::vector< unsigned int > m_raster1Bands
Input raster 1 band indexes to use.
Definition: Blender.h:237
std::size_t m_euclideanDistanceMethodImp_vecIdx
Definition: Blender.h:268
const std::vector< Coord2D > & getCoordinates() const
It returns a pointer to the internal array of coordinates.
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
virtual GeometricTransformation * clone() const =0
Creat a clone copy of this instance.
bool initialize(te::rst::Raster &raster1, const std::vector< unsigned int > &raster1Bands, const te::rst::Raster &raster2, const std::vector< unsigned int > &raster2Bands, const BlendMethod &blendMethod, const te::rst::Interpolator::Method &interpMethod1, const te::rst::Interpolator::Method &interpMethod2, const double &noDataValue, const bool forceRaster1NoDataValue, const bool forceRaster2NoDataValue, const std::vector< double > &pixelOffsets1, const std::vector< double > &pixelScales1, const std::vector< double > &pixelOffsets2, const std::vector< double > &pixelScales2, te::gm::MultiPolygon const *const r1ValidDataDelimiterPtr, te::gm::MultiPolygon const *const r2ValidDataDelimiterPtr, const te::gm::GeometricTransformation &geomTransformation, const unsigned int threadsNumber, const bool enableProgressInterface)
Inititate the blender instance.
Definition: Blender.cpp:178
std::complex< double > m_minMethodImp_cValue1
Definition: Blender.h:298
unsigned int m_blkTotalPixelsNumber
Definition: Blender.h:167
bool m_euclideanDistanceMethodImp_PointInsideIntersection
Definition: Blender.h:272
Geometry * getGeometryN(std::size_t i) const
It returns the n-th geometry in this GeometryCollection.
bool getTileIndexers(te::gm::Geometry const *const geometryPtr, boost::ptr_vector< te::rst::TileIndexer > &tileIndexers) const
Creater polygon tile indexers from the given geometry (only if it is a polygon or a collection of pol...
Definition: Blender.cpp:1942
TECOMMONEXPORT unsigned long long int GetTotalPhysicalMemory()
Returns the amount of total physical memory (bytes).
unsigned int m_euclideanDistanceMethodImp_BandIdx
Definition: Blender.h:264
#define TERP_LOG_AND_RETURN_FALSE(message)
Logs a warning message will and return false.
Definition: Macros.h:269
te::dt::AbstractData * clone() const
It clones the multi polygon.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
bool m_forceRaster1NoDataValue
Use noDataValue as the input rasters no-data value (The original rasters no-data values will be ignor...
Definition: Blender.h:195
#define getPerpendicularDistance(pX, pY, lineAX, lineAY, lineBX, lineBY, aux1, aux2, perpDist)
Definition: Blender.cpp:59
void setX(const double &x)
It sets the Point x-coordinate value.
Definition: Point.h:145
double m_noDataValue
The value returned where there is no pixel data bo blend.
Definition: Blender.h:194
unsigned int m_noBlendMethodImp_BandIdx
Definition: Blender.h:256
te::gm::Point m_sumMethodImp_auxPoint
Definition: Blender.h:275
virtual void directMap(const GTParameters &params, const double &pt1X, const double &pt1Y, double &pt2X, double &pt2Y) const =0
Direct mapping (from pt1 space into pt2 space).
te::gm::GeometricTransformation * m_geomTransformationPtr
A transformation mapping raster 1 pixels ( te::gm::GTParameters::TiePoint::first ) to raster 2 ( te::...
Definition: Blender.h:231
unsigned int m_rasterRows2ProcessBound
Definition: Blender.h:169
Euclidean distance method.
Definition: Blender.h:67
te::rst::Interpolator::Method m_interpMethod2
The interpolation method to use when reading raster 2 data.
Definition: Blender.h:233
double m_noBlendMethodImp_Point2Line
Definition: Blender.h:252
boost::mutex * m_blockProcessedSignalMutexPtr
Mutex used to update the main process progress update.
Definition: Blender.h:187
bool m_forceRaster2NoDataValue
Use noDataValue as the input rasters no-data value (The original rasters no-data values will be ignor...
Definition: Blender.h:196
double m_noBlendMethodImp_Value
Definition: Blender.h:255
BlendMethod m_blendMethod
The blend method to apply.
Definition: Blender.h:192
unsigned int m_sumMethodImp_BandIdx
Definition: Blender.h:280
std::vector< double > m_pixelOffsets2
The values offset to be applied to raster 2 pixel values before the blended value calcule (one elemen...
Definition: Blender.h:199
double m_maxMethodImp_Point2Col
Definition: Blender.h:287
unsigned int m_threadsNumber
The number of threads to use (0:automatic , 1:disabled, any other integer dictates the number of thre...
Definition: Blender.h:219
void setY(const double &y)
It sets the Point y-coordinate value.
Definition: Point.h:159
int m_blkh
Block height (pixels).
Definition: BandProperty.h:144
unsigned int m_firstRasterRow2Process
Definition: Blender.h:168
std::complex< double > m_euclideanDistanceMethodImp_cValue1
Definition: Blender.h:262
unsigned int m_euclideanDistanceMethodImp_IntersectionTileIndexersIdx
Definition: Blender.h:271
double m_euclideanDistanceMethodImp_Point2Line
Definition: Blender.h:260
#define TERP_DEBUG_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:400
TECOMMONEXPORT unsigned long long int GetUsedVirtualMemory()
Returns the amount of used virtual memory (bytes) for the current process (physical + swapped)...
It is a collection of other geometric objects.
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
BlendMethod m_blendMethod
The blend method to apply.
Definition: Blender.h:220
std::vector< unsigned int > m_raster1Bands
Input raster 1 band indexes to use.
Definition: Blender.h:190
std::unique_ptr< te::gm::Geometry > m_intersectionPtr
The Intersection geometry ( raster 1 indexed coods).
Definition: Blender.h:226
void noBlendMethodImp(const double &line1, const double &col1, double *const values)
Implementation for NoBlendMethod.
Definition: Blender.cpp:768
virtual int getBlockSize() const
It returns the number of bytes ocuppied by a data block.
te::gm::Point m_euclideanDistanceMethodImp_auxPoint
Definition: Blender.h:259
virtual void inverseMap(const GTParameters &params, const double &pt2X, const double &pt2Y, double &pt1X, double &pt1Y) const =0
Inverse mapping (from pt2 space into pt1 space).
unsigned int col
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:150
bool m_minMethodImp_PointInsideIntersection
Definition: Blender.h:302
std::complex< double > m_euclideanDistanceMethodImp_cValue2
Definition: Blender.h:263
CircularString is a curve with circular interpolation between points.
std::unique_ptr< te::gm::MultiPolygon > m_r1ValidDataDelimiterPtr
A pointer to a geometry (raster 1 world/projected coords) delimiting the raster region with valid dat...
Definition: Blender.h:224
std::vector< double > m_pixelScales2
The values scale to be applied to raster 2 pixel values before the blended value calcule (one element...
Definition: Blender.h:200
Curve * getRingN(std::size_t i) const
It returns the n-th ring for this curve polygon as a curve.
Definition: CurvePolygon.h:193
te::rst::Interpolator::Method m_interpMethod2
The interpolation method to use when reading raster 2 data.
Definition: Blender.h:193
std::size_t size() const
It returns the number of points (vertexes) in the geometry.
Definition: LineString.h:262
double m_minMethodImp_Point2Col
Definition: Blender.h:297
std::vector< std::pair< te::gm::Coord2D, te::gm::Coord2D > > m_r1IntersectionSegmentsPoints
A sub-set of the intersection polygon wich is part of raster 1 valid data polygon ( raster 1 indexed ...
Definition: Blender.h:227
unsigned int m_firstRasterCol2Process
Definition: Blender.h:170