GeoMosaic.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/GeoMosaic.cpp
22  \brief Create a mosaic from a set of geo-referenced rasters.
23 */
24 
25 #include "GeoMosaic.h"
26 
27 #include "Macros.h"
28 #include "Functions.h"
29 #include "../raster/Interpolator.h"
30 #include "../raster/Enums.h"
31 #include "../raster/RasterFactory.h"
32 #include "../raster/Grid.h"
33 #include "../raster/Band.h"
34 #include "../raster/BandProperty.h"
35 #include "../raster/PositionIterator.h"
36 #include "../raster/Utils.h"
37 #include "../memory/CachedRaster.h"
38 #include "../geometry/Envelope.h"
39 #include "../geometry/GTFactory.h"
40 #include "../geometry/Polygon.h"
41 #include "../geometry/LinearRing.h"
42 #include "../geometry/MultiPolygon.h"
43 #include "../srs/Converter.h"
44 #include "../common/progress/TaskProgress.h"
45 #include "../common/MathUtils.h"
46 
47 #include <boost/shared_array.hpp>
48 #include <boost/filesystem.hpp>
49 #include <boost/lexical_cast.hpp>
50 
51 #include <climits>
52 #include <cfloat>
53 #include <cmath>
54 #include <memory>
55 #include <cstdio>
56 
57 namespace te
58 {
59  namespace rp
60  {
61 
63  {
64  reset();
65  }
66 
68  {
69  reset();
70  operator=( other );
71  }
72 
74  {
75  reset();
76  }
77 
79  {
80  m_feederRasterPtr = nullptr;
81  m_inputRastersBands.clear();
83  m_noDataValue = 0.0;
86  m_autoEqualize = true;
87  m_useRasterCache = true;
88  m_enableProgress = false;
89  m_enableMultiThread = true;
90  }
91 
93  const GeoMosaic::InputParameters& params )
94  {
95  reset();
96 
100  m_noDataValue = params.m_noDataValue;
102  m_blendMethod = params.m_blendMethod;
107 
108  return *this;
109  }
110 
112  {
113  return new InputParameters( *this );
114  }
115 
117  {
118  reset();
119  }
120 
122  {
123  reset();
124  operator=( other );
125  }
126 
128  {
129  reset();
130  }
131 
133  {
134  m_rType.clear();
135  m_rInfo.clear();
136  m_outputRasterPtr.reset();
137  }
138 
140  const GeoMosaic::OutputParameters& params )
141  {
142  reset();
143 
144  m_rType = params.m_rType;
145  m_rInfo = params.m_rInfo;
146  m_outputRasterPtr.reset();;
147 
148  return *this;
149  }
150 
152  {
153  return new OutputParameters( *this );
154  }
155 
157  {
158  reset();
159  }
160 
161  GeoMosaic::~GeoMosaic() = default;
162 
164  _NOEXCEPT_OP(false)
165  {
166  if( ! m_isInitialized ) return false;
167 
168  GeoMosaic::OutputParameters* outParamsPtr = dynamic_cast<
169  GeoMosaic::OutputParameters* >( &outputParams );
170  TERP_TRUE_OR_THROW( outParamsPtr, "Invalid paramters" );
171 
173 
174  // progress
175 
176  std::unique_ptr< te::common::TaskProgress > progressPtr;
178  {
179  progressPtr.reset( new te::common::TaskProgress );
180 
181  progressPtr->setTotalSteps( static_cast<int>(2 + m_inputParameters.m_feederRasterPtr->getObjsCount()) );
182 
183  progressPtr->setMessage( "Mosaic" );
184  }
185 
186  // First pass: getting global mosaic info
187 
188  double mosaicXResolution = 0.0;
189  double mosaicYResolution = 0.0;
190  double mosaicLLX = DBL_MAX; // world coords
191  double mosaicLLY = DBL_MAX; // world coords
192  double mosaicURX = -1.0 * DBL_MAX; // world coords
193  double mosaicURY = -1.0 * DBL_MAX; // world coords
194  int mosaicSRID = 0;
195  te::rst::BandProperty mosaicBaseBandProperties( 0, 0, "" );
196  std::vector< te::gm::Polygon > rastersBBoxes; // all rasters bounding boxes (under the first raster world coords.
197 
198  {
199  te::rst::Raster const* inputRasterPtr = nullptr;
200  unsigned int inputRasterIdx = 0;
201  std::unique_ptr< te::gm::Polygon > rasterExtentPolPtr;
202 
204  while( ( inputRasterPtr = m_inputParameters.m_feederRasterPtr->getCurrentObj() ) )
205  {
208  inputRasterPtr->getAccessPolicy() & te::common::RAccess,
209  "Invalid raster" );
210 
211  // checking the input bands
212 
213  for( std::vector< unsigned int >::size_type inputRastersBandsIdx = 0 ;
214  inputRastersBandsIdx <
215  m_inputParameters.m_inputRastersBands[ inputRasterIdx ].size() ;
216  ++inputRastersBandsIdx )
217  {
218  const unsigned int& currBand =
219  m_inputParameters.m_inputRastersBands[ inputRasterIdx ][ inputRastersBandsIdx ];
220 
221  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( currBand < inputRasterPtr->getNumberOfBands(),
222  "Invalid band" )
223  }
224 
225  // Defining the base mosaic info
226 
227  if( inputRasterIdx == 0 )
228  {
229  mosaicXResolution = inputRasterPtr->getGrid()->getResolutionX();
230  mosaicYResolution = inputRasterPtr->getGrid()->getResolutionY();
231  mosaicSRID = inputRasterPtr->getGrid()->getSRID();
232  mosaicBaseBandProperties = *inputRasterPtr->getBand(
233  m_inputParameters.m_inputRastersBands[ inputRasterIdx ][ 0 ] )->getProperty();
234  }
235 
236  rasterExtentPolPtr.reset( static_cast<te::gm::Polygon*>(te::gm::GetGeomFromEnvelope(
237  inputRasterPtr->getGrid()->getExtent(), inputRasterPtr->getGrid()->getSRID() ) ) );
238 
239  if( mosaicSRID != inputRasterPtr->getGrid()->getSRID() )
240  {
241  rasterExtentPolPtr->transform( mosaicSRID );
242  }
243 
244  rastersBBoxes.push_back( *rasterExtentPolPtr );
245 
246  // expanding mosaic area
247 
248  mosaicLLX = std::min( mosaicLLX, rasterExtentPolPtr->getMBR()->getLowerLeftX() );
249  mosaicLLY = std::min( mosaicLLY, rasterExtentPolPtr->getMBR()->getLowerLeftY() );
250 
251  mosaicURX = std::max( mosaicURX, rasterExtentPolPtr->getMBR()->getUpperRightX() );
252  mosaicURY = std::max( mosaicURY, rasterExtentPolPtr->getMBR()->getUpperRightY() );
253 
254  // move to the next raster
255 
257  }
258  }
259 
261  {
262  progressPtr->pulse();
263  if( ! progressPtr->isActive() ) return false;
264  }
265 
266  // creating the output raster
267 
268  te::rst::Raster* outputRasterPtr = nullptr;
269  std::vector< double > mosaicBandsRangeMin;
270  std::vector< double > mosaicBandsRangeMax;
271 
272  {
273  mosaicBandsRangeMin.resize(
274  m_inputParameters.m_inputRastersBands[ 0 ].size(), 0 );
275  mosaicBandsRangeMax.resize(
276  m_inputParameters.m_inputRastersBands[ 0 ].size(), 0 );
277 
278  std::vector< te::rst::BandProperty* > bandsProperties;
279  for( std::vector< unsigned int >::size_type bandIdx = 0 ; bandIdx <
280  m_inputParameters.m_inputRastersBands[ 0 ].size() ; ++bandIdx )
281  {
282  bandsProperties.push_back( new te::rst::BandProperty( mosaicBaseBandProperties ) );
283  bandsProperties[ bandIdx ]->m_colorInterp = te::rst::GrayIdxCInt;
284  bandsProperties[ bandIdx ]->m_noDataValue = m_inputParameters.m_noDataValue;
285 
286  te::rst::GetDataTypeRanges( bandsProperties[ bandIdx ]->m_type,
287  mosaicBandsRangeMin[ bandIdx ],
288  mosaicBandsRangeMax[ bandIdx ]);
289  }
290 
291  te::rst::Grid* outputGrid = new te::rst::Grid( mosaicXResolution,
292  mosaicYResolution, new te::gm::Envelope( mosaicLLX, mosaicLLY, mosaicURX,
293  mosaicURY ), mosaicSRID );
294 
295  outParamsPtr->m_outputRasterPtr.reset(
297  outParamsPtr->m_rType,
298  outputGrid,
299  bandsProperties,
300  outParamsPtr->m_rInfo,
301  nullptr,
302  nullptr ) );
304  "Output raster creation error" );
305 
306  outputRasterPtr = outParamsPtr->m_outputRasterPtr.get();
307  }
308 
309  std::unique_ptr< te::mem::CachedRaster > outputCachedRasterInstancePtr;
310 
312  {
313  outputCachedRasterInstancePtr.reset( new te::mem::CachedRaster(
314  *(outParamsPtr->m_outputRasterPtr.get()), 20, 0 ) );
315 
316  outputRasterPtr = outputCachedRasterInstancePtr.get();
317  }
318 
319  // fill output with no data values
320 
321  {
322  const unsigned int nBands = static_cast<unsigned int>(outputRasterPtr->getNumberOfBands());
323  const unsigned int nRows = outputRasterPtr->getNumberOfRows();
324  const unsigned int nCols = outputRasterPtr->getNumberOfColumns();
325  unsigned int col = 0;
326  unsigned int row = 0;
327  unsigned int bandIdx = 0;
328 
329  for( bandIdx = 0 ; bandIdx < nBands ; ++bandIdx )
330  {
331  te::rst::Band& outBand = ( *( outputRasterPtr->getBand( bandIdx ) ) );
332 
333  for( row = 0 ; row < nRows ; ++row )
334  {
335  for( col = 0 ; col < nCols ; ++col )
336  {
337  outBand.setValue( col, row, m_inputParameters.m_noDataValue );
338  }
339  }
340  }
341  }
342 
344  {
345  progressPtr->pulse();
346  if( ! progressPtr->isActive() ) return false;
347  }
348 
349  // Copying the first image data to the output mosaic
350  // and find the base mosaic mean and offset values
351 
352  std::vector< double > mosaicTargetMeans( outputRasterPtr->getNumberOfBands(), 0 );
353  std::vector< double > mosaicTargetVariances( outputRasterPtr->getNumberOfBands(), 0 );
354 
355  {
357 
358  te::rst::Raster const* inputRasterPtr =
360  TERP_DEBUG_TRUE_OR_RETURN_FALSE( inputRasterPtr, "Invalid raster pointer" );
361 
362  double inXStartGeo = 0;
363  double inYStartGeo = 0;
364  inputRasterPtr->getGrid()->gridToGeo( 0.0, 0.0, inXStartGeo, inYStartGeo );
365 
366  double outFirstRowDouble = 0;
367  double outFirstColDouble = 0;
368  outputRasterPtr->getGrid()->geoToGrid( inXStartGeo, inYStartGeo,
369  outFirstColDouble, outFirstRowDouble );
370 
371  const double outRowsBoundDouble = outFirstRowDouble +
372  static_cast<double>( inputRasterPtr->getNumberOfRows() );
373  const double outColsBoundDouble = outFirstColDouble +
374  static_cast<double>( inputRasterPtr->getNumberOfColumns() );
375 
376  const unsigned int outFirstRow = static_cast<unsigned int>(std::max( 0u,
377  te::common::Round< double, unsigned int >( outFirstRowDouble ) ) );
378  const unsigned int outFirstCol = static_cast<unsigned int>(std::max( 0u,
379  te::common::Round< double, unsigned int >( outFirstColDouble ) ) );
380 
381  const unsigned int outRowsBound = static_cast<unsigned int>(std::min(
382  te::common::Round< double, unsigned int >( outRowsBoundDouble ),
383  outputRasterPtr->getNumberOfRows() ) );
384  const unsigned int outColsBound = static_cast<unsigned int>(std::min(
385  te::common::Round< double, unsigned int >( outColsBoundDouble ),
386  outputRasterPtr->getNumberOfColumns() ) );
387 
388  const unsigned int nBands = static_cast<unsigned int>(m_inputParameters.m_inputRastersBands[ 0 ].size());
389  unsigned int outCol = 0;
390  unsigned int outRow = 0;
391  double inCol = 0;
392  double inRow = 0;
393  double bandNoDataValue = -1.0 * DBL_MAX;
394  std::complex< double > pixelCValue = 0;
395  te::rst::Interpolator interpInstance( inputRasterPtr,
397  unsigned int inputBandIdx = 0;
398 
399  for( unsigned int inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
400  nBands ; ++inputRastersBandsIdx )
401  {
402  inputBandIdx = m_inputParameters.m_inputRastersBands[ 0 ][
403  inputRastersBandsIdx ] ;
404  bandNoDataValue = m_inputParameters.m_forceInputNoDataValue ?
405  m_inputParameters.m_noDataValue : inputRasterPtr->getBand( inputBandIdx
407  te::rst::Band& outBand =
408  (*outputRasterPtr->getBand( inputRastersBandsIdx ));
409  unsigned long int validPixelsNumber = 0;
410 
411  double mean = 0;
412 
413  for( outRow = outFirstRow ; outRow < outRowsBound ; ++outRow )
414  {
415  inRow = (static_cast<double>(outRow)) - outFirstRowDouble;
416 
417  for( outCol = outFirstCol ; outCol < outColsBound ; ++outCol )
418  {
419  inCol = (static_cast<double>(outCol)) - outFirstColDouble;
420 
421  interpInstance.getValue( inCol, inRow, pixelCValue, inputBandIdx );
422 
423  if( pixelCValue.real() != bandNoDataValue )
424  {
425  outBand.setValue( outCol, outRow, pixelCValue );
426  mean += pixelCValue.real();
427  ++validPixelsNumber;
428  }
429  }
430  }
431 
432  // variance calcule
433 
434  if( m_inputParameters.m_autoEqualize && ( validPixelsNumber > 0 ) )
435  {
436  mean /= ( static_cast<double>(validPixelsNumber) );
437  mosaicTargetMeans[ inputRastersBandsIdx ] = mean;
438 
439  double& variance = mosaicTargetVariances[ inputRastersBandsIdx ];
440  variance = 0;
441 
442  double pixelValue = 0;
443 
444  for( outRow = outFirstRow ; outRow < outRowsBound ; ++outRow )
445  {
446  for( outCol = outFirstCol ; outCol < outColsBound ; ++outCol )
447  {
448  outBand.getValue( outCol, outRow, pixelValue );
449 
450  if( pixelValue != m_inputParameters.m_noDataValue )
451  {
452  variance += ( ( pixelValue - mean ) * ( pixelValue -
453  mean ) ) / ( static_cast<double>(validPixelsNumber) );
454  }
455  }
456  }
457  }
458  }
459  }
460 
461  TERP_DEBUG_TRUE_OR_THROW( rastersBBoxes.size() ==
463  "Rasters bounding boxes number mismatch" );
464 
466  {
467  progressPtr->pulse();
468  if( ! progressPtr->isActive() ) return false;
469  }
470 
471  // Initiating the mosaic bounding boxes union
472 
473  std::unique_ptr< te::gm::MultiPolygon > mosaicBBoxesUnionPtr(
475  outputRasterPtr->getSRID(), nullptr ) );
476  mosaicBBoxesUnionPtr->add( static_cast<te::gm::Polygon*>(rastersBBoxes[ 0 ].clone()) );
477 
478  // skipping the first raster
479 
482 
483  // iterating over the other rasters
484 
485  te::rst::Raster const* originalInputRasterPtr = nullptr;
486 
487  std::vector< unsigned int > outputRasterBands;
488  std::vector< double > dummyRasterOffsets;
489  std::vector< double > dummyRasterScales;
490  for( unsigned int outputRasterBandsIdx = 0 ; outputRasterBandsIdx <
491  outputRasterPtr->getNumberOfBands() ; ++outputRasterBandsIdx )
492  {
493  outputRasterBands.push_back( outputRasterBandsIdx );
494  dummyRasterOffsets.push_back( 0.0 );
495  dummyRasterScales.push_back( 1.0 );
496  }
497 
498  while( ( originalInputRasterPtr = m_inputParameters.m_feederRasterPtr->getCurrentObj() ) )
499  {
500  const unsigned int inputRasterIdx = m_inputParameters.m_feederRasterPtr->getCurrentOffset();
501 
502 // Copy2DiskRaster( outputRaster, boost::lexical_cast< std::string >( inputRasterIdx ) +
503 // "_output_raster_begininng.tif" );
504 
505  TERP_DEBUG_TRUE_OR_THROW( rastersBBoxes[ inputRasterIdx ].getSRID() == outputRasterPtr->getSRID(),
506  "Invalid boxes SRID" );
507 
508  te::rst::Raster const* inputRasterPtr = originalInputRasterPtr;
509 
510 // Copy2DiskRaster( *inputRasterPtr, boost::lexical_cast< std::string >( inputRasterIdx ) +
511 // "_input_raster.tif" );
512 
513  // reprojection / caching issues
514 
515  std::unique_ptr< te::rst::Raster > reprojectedInputRasterPtr;
516 
517  if( outputRasterPtr->getSRID() != inputRasterPtr->getSRID() )
518  {
519  std::map< std::string, std::string > rInfo;
520  rInfo[ "RTYPE" ] = "EXPANSIBLE";
521 
522  reprojectedInputRasterPtr.reset( inputRasterPtr->transform(
523  outputRasterPtr->getSRID(), rInfo,
525  inputRasterPtr = reprojectedInputRasterPtr.get();
526  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputRasterPtr, "Reprojection error" );
527 
528 // Copy2DiskRaster( *inputRasterPtr, boost::lexical_cast< std::string >( inputRasterIdx ) +
529 // "reprojected_input_raster.tif" );
530  }
531 
532  // Caching issues
533 
534  std::unique_ptr< te::mem::CachedRaster > cachedInputRasterPtr;
535 
536  if(
538  &&
539  ( reprojectedInputRasterPtr.get() == nullptr )
540  // Reprojected rasters already have internal cache
541  )
542  {
543  cachedInputRasterPtr.reset( new te::mem::CachedRaster(
544  *inputRasterPtr, 20, 0 ) );
545  inputRasterPtr = cachedInputRasterPtr.get();
546  }
547 
548  // The transformation mapping outputRaster pixels
549  // ( te::gm::GTParameters::TiePoint::first ) to input pixels
550  // ( te::gm::GTParameters::TiePoint::second )
551  // (Note: all coords are indexed by lines/columns).
552 
553  std::unique_ptr< te::gm::GeometricTransformation > transPtr;
554 
555  {
556  te::gm::GTParameters transParams;
557  double auxX;
558  double auxY;
560 
561  auxTP.first.x = 0;
562  auxTP.first.y = 0;
563  outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
564  inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
565  transParams.m_tiePoints.push_back( auxTP );
566 
567  auxTP.first.x = 0;
568  auxTP.first.y = static_cast<double>( outputRasterPtr->getNumberOfRows() - 1 );
569  outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
570  inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
571  transParams.m_tiePoints.push_back( auxTP );
572 
573  auxTP.first.x = static_cast<double>( outputRasterPtr->getNumberOfColumns() - 1);
574  auxTP.first.y = 0;
575  outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
576  inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
577  transParams.m_tiePoints.push_back( auxTP );
578 
579  auxTP.first.x = static_cast<double>( outputRasterPtr->getNumberOfColumns() - 1 );
580  auxTP.first.y = static_cast<double>( outputRasterPtr->getNumberOfRows() - 1 );
581  outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
582  inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
583  transParams.m_tiePoints.push_back( auxTP );
584 
585  transPtr.reset( te::gm::GTFactory::make( "Affine" ) );
586  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( transPtr.get(), "Could not instantiate a geometric transformation" );
587 
588  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( transPtr->initialize( transParams ),
589  "Could not initialize a geometric transformation" );
590  }
591 
592  // Generating the offset and gain info for eath band from the current raster
593 
594  std::vector< double > currentRasterBandsOffsets = dummyRasterOffsets;
595  std::vector< double > currentRasterBandsScales = dummyRasterScales;
596 
598  {
599  double currentRasterVariance = 0;
600  double currentRasterMean = 0;
601 
602  for( unsigned int inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
603  m_inputParameters.m_inputRastersBands[ inputRasterIdx ].size() ;
604  ++inputRastersBandsIdx )
605  {
606  const unsigned int inputBandIdx = m_inputParameters.m_inputRastersBands[ inputRasterIdx ][
607  inputRastersBandsIdx ];
608 
609  if(
610  ( mosaicTargetMeans[ inputRastersBandsIdx ] != 0.0 )
611  &&
612  ( mosaicTargetVariances[ inputRastersBandsIdx ] != 0.0 )
613  )
614  {
615  calcBandStatistics( (*inputRasterPtr->getBand( inputBandIdx ) ),
618  currentRasterMean,
619  currentRasterVariance );
620 
621  currentRasterBandsScales[ inputRastersBandsIdx ] =
622  (
623  std::sqrt( mosaicTargetVariances[ inputRastersBandsIdx ] )
624  /
625  std::sqrt( currentRasterVariance )
626  );
627  currentRasterBandsOffsets[ inputRastersBandsIdx ] =
628  (
629  mosaicTargetMeans[ inputRastersBandsIdx ]
630  -
631  (
632  currentRasterBandsScales[ inputRastersBandsIdx ]
633  *
634  currentRasterMean
635  )
636  );
637  }
638  }
639  }
640 
641  // blending
642 
643  te::rp::Blender blenderInstance;
644 
646  *outputRasterPtr,
647  outputRasterBands,
648  *inputRasterPtr,
649  m_inputParameters.m_inputRastersBands[ inputRasterIdx ],
654  false,
656  dummyRasterOffsets,
657  dummyRasterScales,
658  currentRasterBandsOffsets,
659  currentRasterBandsScales,
660  mosaicBBoxesUnionPtr.get(),
661  nullptr,
662  *transPtr,
664  false ), "Blender initiazing error" );
665 
667  "Error blending images" );
668 
669 // Copy2DiskRaster( outputRaster, boost::lexical_cast< std::string >( inputRasterIdx ) +
670 // "output_raster_after_blending_" +
671 // boost::lexical_cast< std::string >( mosaicBBoxesUnionIdx ) + ".tif" );
672 
673  // updating the gloabal mosaic boxes
674 
675  std::unique_ptr< te::gm::Geometry > boxesUnionResultPtr; // under the mosaic SRID
676  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( mosaicBBoxesUnionPtr->isValid(),
677  "Invalid mosaic bounding boxes union geometry" );
678  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( rastersBBoxes[ inputRasterIdx ].isValid(),
679  "Invalid raster bounding boxes union geometry (raster index:"
680  + boost::lexical_cast< std::string >( inputRasterIdx ) + ")" );
681 
682  try
683  {
684  boxesUnionResultPtr.reset( mosaicBBoxesUnionPtr->Union(
685  &( rastersBBoxes[ inputRasterIdx ] ) ) );
686  }
687  catch( const std::exception&/* e */)
688  {
689  TERP_INSTANCE_LOG_AND_RETURN_FALSE( "Mosaic bounding boxes union error" );
690  }
691 
692  TERP_TRUE_OR_THROW( boxesUnionResultPtr.get(), "Invalid pointer" );
693 
694  boxesUnionResultPtr->setSRID( outputRasterPtr->getSRID() );
695 
696  if(
697  ( boxesUnionResultPtr->getGeomTypeId() == te::gm::MultiPolygonType )
698  ||
699  ( boxesUnionResultPtr->getGeomTypeId() == te::gm::MultiPolygonZType )
700  ||
701  ( boxesUnionResultPtr->getGeomTypeId() == te::gm::MultiPolygonMType )
702  ||
703  ( boxesUnionResultPtr->getGeomTypeId() == te::gm::MultiPolygonZMType )
704  )
705  {
706  mosaicBBoxesUnionPtr.reset( static_cast<te::gm::MultiPolygon*>(boxesUnionResultPtr.release()) );
707  }
708  else if(
709  ( boxesUnionResultPtr->getGeomTypeId() == te::gm::PolygonType )
710  ||
711  ( boxesUnionResultPtr->getGeomTypeId() == te::gm::PolygonZType )
712  ||
713  ( boxesUnionResultPtr->getGeomTypeId() == te::gm::PolygonMType )
714  ||
715  ( boxesUnionResultPtr->getGeomTypeId() == te::gm::PolygonZMType )
716  )
717  {
718  // transforming it into a te::gm::MultiPolygon
719  te::gm::MultiPolygon* auxMultiPol = new te::gm::MultiPolygon( 0,
720  te::gm::MultiPolygonType, boxesUnionResultPtr->getSRID(), nullptr );
721  auxMultiPol->add( boxesUnionResultPtr.release() );
722 
723  mosaicBBoxesUnionPtr.reset( auxMultiPol );
724  }
725  else
726  {
727  TERP_LOGWARN( "Invalid union geometry type" );
728  }
729 
730  // Reseting the input cache
731 
732  cachedInputRasterPtr.reset();
733 
734  // moving to the next raster
735 
737 
739  {
740  progressPtr->pulse();
741  if( ! progressPtr->isActive() ) return false;
742  }
743  }
744 
745  // reseting the output cache
746 
747  if( outputCachedRasterInstancePtr.get() ) outputCachedRasterInstancePtr.reset();
748 
749  return true;
750  }
751 
753  {
755 
757  m_isInitialized = false;
758  }
759 
761  _NOEXCEPT_OP(false)
762  {
763  reset();
764 
765  GeoMosaic::InputParameters const* inputParamsPtr = dynamic_cast<
766  GeoMosaic::InputParameters const* >( &inputParams );
767  TERP_TRUE_OR_THROW( inputParamsPtr, "Invalid paramters pointer" );
768 
769  m_inputParameters = *inputParamsPtr;
770 
771  // Checking the feeder
772 
774  "Invalid m_feederRasterPtr" )
775 
778  "Invalid number of rasters" )
779 
780  // checking m_inputRastersBands
781 
783  (static_cast<unsigned int>(m_inputParameters.m_inputRastersBands.size())) ==
785  "Bands mismatch" );
786 
787  for( std::vector< std::vector< unsigned int > >::size_type
788  inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
789  m_inputParameters.m_inputRastersBands.size() ; ++inputRastersBandsIdx )
790  {
792  inputRastersBandsIdx ].size() > 0, "Invalid bands number" );
793 
795  inputRastersBandsIdx ].size() == m_inputParameters.m_inputRastersBands[
796  0 ].size(), "Bands number mismatch" );
797  }
798 
799  m_isInitialized = true;
800 
801  return true;
802  }
803 
805  {
806  return m_isInitialized;
807  }
808 
810  const bool& forceNoDataValue,
811  const double& noDataValue,
812  double& mean, double& variance )
813  {
814  mean = 0;
815  variance = 0;
816 
817  double internalNoDataValue = 0;
818  if( forceNoDataValue )
819  internalNoDataValue = noDataValue;
820  else
821  internalNoDataValue = band.getProperty()->m_noDataValue;
822 
823  const unsigned int nCols = static_cast<unsigned int>(band.getProperty()->m_blkw * band.getProperty()->m_nblocksx);
824  const unsigned int nLines = static_cast<unsigned int>(band.getProperty()->m_blkh * band.getProperty()->m_nblocksy);
825 
826  double pixelsNumber = 0;
827  double value = 0;
828  unsigned int col = 0;
829  unsigned int line = 0;
830 
831  for( line = 0 ; line < nLines ; ++line )
832  for( col = 0 ; col < nCols ; ++col )
833  {
834  band.getValue( col, line, value );
835 
836  if( value != internalNoDataValue )
837  {
838  mean += value;
839  ++pixelsNumber;
840  }
841  }
842 
843  if( pixelsNumber != 0.0 )
844  {
845  mean /= pixelsNumber;
846 
847  for( line = 0 ; line < nLines ; ++line )
848  for( col = 0 ; col < nCols ; ++col )
849  {
850  band.getValue( col, line, value );
851 
852  if( value != internalNoDataValue )
853  {
854  variance += ( ( value - mean ) * ( value - mean ) ) / pixelsNumber;
855  }
856  }
857 
858  }
859  }
860 
861  } // end namespace rp
862 } // end namespace te
863 
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
unsigned int band
AbstractParameters * clone() const
Create a clone copy of this instance.
Definition: GeoMosaic.cpp:111
Near neighborhood interpolation method.
std::vector< TiePoint > m_tiePoints
Tie points.
Definition: GTParameters.h:95
const OutputParameters & operator=(const OutputParameters &params)
Definition: GeoMosaic.cpp:139
TERASTEREXPORT void GetDataTypeRanges(const int &dataType, double &min, double &max)
Return the values range of a given data type.
Index into a lookup table.
AbstractParameters * clone() const
Create a clone copy of this instance.
Definition: GeoMosaic.cpp:151
te::rst::Interpolator::Method m_interpMethod
The raster interpolator method (default:NearestNeighbor).
Definition: GeoMosaic.h:64
bool isInitialized() const
Returns true if the algorithm instance is initialized and ready for execution.
Definition: GeoMosaic.cpp:804
A raster band description.
Definition: BandProperty.h:61
Blended pixel value calculation for two overlaped rasters.
Definition: Blender.h:58
int getSRID() const
Returns the grid spatial reference system identifier.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
GeoMosaic input parameters.
Definition: GeoMosaic.h:56
int m_nblocksx
The number of blocks in x.
Definition: BandProperty.h:145
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
#define TERP_LOGWARN(message)
Logs a warning message.
Definition: Macros.h:128
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
Raster Processing algorithm output parameters base interface.
double pixelValue
#define _NOEXCEPT_OP(x)
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
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
Definition: BandProperty.h:136
virtual te::rst::Raster const * getCurrentObj() const =0
Return the current sequence object.
No blending performed.
Definition: Blender.h:66
std::pair< Coord2D, Coord2D > TiePoint
Tie point type definition.
Definition: GTParameters.h:59
std::string m_rType
Output raster data source type (as described in te::raster::RasterFactory ).
Definition: GeoMosaic.h:104
void geoToGrid(const double &x, const double &y, double &col, double &row) const
Get the grid point associated to a spatial location.
bool execute(AlgorithmOutputParameters &outputParams) _NOEXCEPT_OP(false)
Executes the algorithm using the supplied parameters.
Definition: GeoMosaic.cpp:163
bool blendIntoRaster1()
Execute blending of the given input rasters and write the result into raster1.
Definition: Blender.cpp:1351
double getResolutionY() const
Returns the grid vertical (y-axis) resolution.
unsigned int line
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
unsigned int unsigned int nCols
std::unique_ptr< te::rst::Raster > m_outputRasterPtr
The generated output mosaic raster.
Definition: GeoMosaic.h:108
virtual void reset()=0
Reset the feeder to the first position (subsequent accesses will start from the first sequence obejct...
An Envelope defines a 2D rectangular region.
An abstract class for raster data strucutures.
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.
bool m_enableProgress
Enable/Disable the progress interface (default:false).
Definition: GeoMosaic.h:76
BandProperty * getProperty()
Returns the band property.
URI C++ Library.
Definition: Attributes.h:37
int m_blkw
Block width (pixels).
Definition: BandProperty.h:143
Create a mosaic from a set of geo-referenced rasters.
double getResolutionX() const
Returns the grid horizontal (x-axis) resolution.
te::rp::Blender::BlendMethod m_blendMethod
The pixel blending method (default: NoBlendMethod).
Definition: GeoMosaic.h:70
A RAM cache adaptor to an external existent raster that must always be avaliable. ...
Definition: CachedRaster.h:52
A raster band description.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
Grid * getGrid()
It returns the raster grid.
static GeometricTransformation * make(const std::string &factoryKey)
It creates an object with the appropriated factory.
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
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
Abstract parameters base interface.
bool m_isInitialized
Tells if this instance is initialized.
Definition: GeoMosaic.h:145
int getSRID() const
Returns the raster spatial reference system identifier.
bool initialize(const AlgorithmInputParameters &inputParams) _NOEXCEPT_OP(false)
Initialize the algorithm instance making it ready for execution.
Definition: GeoMosaic.cpp:760
static void calcBandStatistics(const te::rst::Band &band, const bool &forceNoDataValue, const double &noDataValue, double &mean, double &variance)
Raster band statistics calcule.
Definition: GeoMosaic.cpp:809
GeoMosaic output parameters.
Definition: GeoMosaic.h:100
void add(Geometry *g)
It adds the geometry into the collection.
bool m_autoEqualize
Auto equalization will be performed using the overlaped image areas (default:true).
Definition: GeoMosaic.h:72
GeoMosaic::InputParameters m_inputParameters
Input execution parameters.
Definition: GeoMosaic.h:143
bool m_enableMultiThread
Enable/disable the use of threads (default:true).
Definition: GeoMosaic.h:78
static Raster * make()
It creates and returns an empty raster with default raster driver.
#define TERP_DEBUG_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:415
te::gm::Envelope * getExtent()
Returns the geographic extension of the grid.
void gridToGeo(const double &col, const double &row, double &x, double &y) const
Get the spatial location of a grid point.
Raster Processing algorithm input parameters base interface.
2D Geometric transformation parameters.
Definition: GTParameters.h:50
void reset() _NOEXCEPT_OP(false)
Clear all internal allocated objects and reset the algorithm to its initial state.
Definition: GeoMosaic.cpp:752
void reset() _NOEXCEPT_OP(false)
Clear all internal allocated resources and reset the parameters instance to its initial state...
Definition: GeoMosaic.cpp:78
const InputParameters & operator=(const InputParameters &params)
Definition: GeoMosaic.cpp:92
Raster Processing functions.
virtual bool moveNext()=0
Advances to the next sequence obeject.
bool m_forceInputNoDataValue
If true, m_noDataValue will be used as the no-data value for input rasters (defalt:false).
Definition: GeoMosaic.h:68
int m_blkh
Block height (pixels).
Definition: BandProperty.h:144
std::vector< std::vector< unsigned int > > m_inputRastersBands
Bands to process for each input raster.
Definition: GeoMosaic.h:62
#define TERP_DEBUG_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:400
virtual void reset() _NOEXCEPT_OP(false)
Clear all internal allocated objects and reset the algorithm to its initial state.
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
double m_noDataValue
The pixel value used where no raster data is avaliable (defaul:0).
Definition: GeoMosaic.h:66
#define TERP_INSTANCE_TRUE_OR_RETURN_FALSE(value, message)
Checks if value is true. For false values a warning message will be logged, the current instance erro...
Definition: Macros.h:200
unsigned int nLines
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_useRasterCache
Enable(true) or disable the use of raster caching (default:true).
Definition: GeoMosaic.h:74
TEGEOMEXPORT Geometry * GetGeomFromEnvelope(const Envelope *const e, int srid)
It creates a Geometry (a polygon) from the given envelope.
FeederConstRaster * m_feederRasterPtr
Input rasters feeder.
Definition: GeoMosaic.h:60
void reset() _NOEXCEPT_OP(false)
Clear all internal allocated resources and reset the parameters instance to its initial state...
Definition: GeoMosaic.cpp:132
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
virtual unsigned int getCurrentOffset() const =0
Return the index of the current object.
virtual unsigned int getObjsCount() const =0
Return the total number of feeder objects.
std::map< std::string, std::string > m_rInfo
The necessary information to create the output rasters (as described in te::raster::RasterFactory).
Definition: GeoMosaic.h:106
#define TERP_INSTANCE_LOG_AND_RETURN_FALSE(message)
Logs a warning message, update the current instance error messsage and return false.
Definition: Macros.h:279