All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
46 #include <boost/shared_array.hpp>
47 #include <boost/filesystem.hpp>
48 
49 #include <climits>
50 #include <cfloat>
51 #include <cmath>
52 #include <memory>
53 #include <cstdio>
54 
55 namespace te
56 {
57  namespace rp
58  {
59 
61  {
62  reset();
63  }
64 
66  {
67  reset();
68  operator=( other );
69  }
70 
72  {
73  reset();
74  }
75 
76  void GeoMosaic::InputParameters::reset() throw( te::rp::Exception )
77  {
78  m_feederRasterPtr = 0;
79  m_inputRastersBands.clear();
80  m_interpMethod = te::rst::NearestNeighbor;
81  m_noDataValue = 0.0;
82  m_forceInputNoDataValue = false;
83  m_blendMethod = te::rp::Blender::NoBlendMethod;
84  m_autoEqualize = true;
85  m_useRasterCache = true;
86  m_enableProgress = false;
87  m_enableMultiThread = true;
88  }
89 
91  const GeoMosaic::InputParameters& params )
92  {
93  reset();
94 
95  m_feederRasterPtr = params.m_feederRasterPtr;
96  m_inputRastersBands = params.m_inputRastersBands;
97  m_interpMethod = params.m_interpMethod;
98  m_noDataValue = params.m_noDataValue;
99  m_forceInputNoDataValue = params.m_forceInputNoDataValue;
100  m_blendMethod = params.m_blendMethod;
101  m_autoEqualize = params.m_autoEqualize;
102  m_useRasterCache = params.m_useRasterCache;
103  m_enableProgress = params.m_enableProgress;
104  m_enableMultiThread = params.m_enableMultiThread;
105 
106  return *this;
107  }
108 
110  {
111  return new InputParameters( *this );
112  }
113 
115  {
116  reset();
117  }
118 
120  {
121  reset();
122  operator=( other );
123  }
124 
126  {
127  reset();
128  }
129 
130  void GeoMosaic::OutputParameters::reset() throw( te::rp::Exception )
131  {
132  m_rType.clear();
133  m_rInfo.clear();
134  m_outputRasterPtr.reset();
135  }
136 
138  const GeoMosaic::OutputParameters& params )
139  {
140  reset();
141 
142  m_rType = params.m_rType;
143  m_rInfo = params.m_rInfo;
144  m_outputRasterPtr.reset();;
145 
146  return *this;
147  }
148 
150  {
151  return new OutputParameters( *this );
152  }
153 
155  {
156  reset();
157  }
158 
160  {
161  }
162 
164  throw( te::rp::Exception )
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::auto_ptr< te::common::TaskProgress > progressPtr;
178  {
179  progressPtr.reset( new te::common::TaskProgress );
180 
181  progressPtr->setTotalSteps( 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  std::vector< double > mosaicBandsRangeMin;
196  std::vector< double > mosaicBandsRangeMax;
197  te::rst::BandProperty mosaicBaseBandProperties( 0, 0, "" );
198  std::vector< te::gm::Polygon > rastersBBoxes; // all rasters bounding boxes (under the first raster world coords.
199 
200  {
201  te::gm::Polygon auxPolygon( 0, te::gm::PolygonType, 0 );
202  te::gm::LinearRing* auxLinearRingPtr = 0;
203  te::rst::Raster const* inputRasterPtr = 0;
204  unsigned int inputRasterIdx = 0;
205  te::srs::Converter convInstance;
206  te::gm::LinearRing reprojectedExtent(te::gm::LineStringType, 0, 0);
207 
209  while( ( inputRasterPtr = m_inputParameters.m_feederRasterPtr->getCurrentObj() ) )
210  {
213  inputRasterPtr->getAccessPolicy() & te::common::RAccess,
214  "Invalid raster" );
215 
216  // Defining the base mosaic info
217 
218  if( inputRasterIdx == 0 )
219  {
220  mosaicXResolution = inputRasterPtr->getGrid()->getResolutionX();
221  mosaicYResolution = inputRasterPtr->getGrid()->getResolutionY();
222 
223  mosaicLLX = inputRasterPtr->getGrid()->getExtent()->m_llx;
224  mosaicLLY = inputRasterPtr->getGrid()->getExtent()->m_lly;
225  mosaicURX = inputRasterPtr->getGrid()->getExtent()->m_urx;
226  mosaicURY = inputRasterPtr->getGrid()->getExtent()->m_ury;
227 
228  mosaicSRID = inputRasterPtr->getGrid()->getSRID();
229 
230  mosaicBaseBandProperties = *inputRasterPtr->getBand( 0 )->getProperty();
231 
232  // finding the current raster bounding box polygon (first raster world coordinates)
233  auxPolygon.clear();
234  auxLinearRingPtr = new te::gm::LinearRing(5, te::gm::LineStringType);
235  auxLinearRingPtr->setPoint( 0, mosaicLLX, mosaicURY );
236  auxLinearRingPtr->setPoint( 1, mosaicURX, mosaicURY );
237  auxLinearRingPtr->setPoint( 2, mosaicURX, mosaicLLY );
238  auxLinearRingPtr->setPoint( 3, mosaicLLX, mosaicLLY );
239  auxLinearRingPtr->setPoint( 4, mosaicLLX, mosaicURY );
240  auxLinearRingPtr->setSRID( mosaicSRID );
241  auxPolygon.push_back( auxLinearRingPtr );
242  auxPolygon.setSRID( mosaicSRID );
243  rastersBBoxes.push_back( auxPolygon );
244  }
245  else
246  {
248  *inputRasterPtr->getGrid(), reprojectedExtent ),
249  "Detailed raster extent calcule error" );
250 
251  if( mosaicSRID != inputRasterPtr->getGrid()->getSRID() )
252  {
253  reprojectedExtent.transform( mosaicSRID );
254  }
255 
256  // expanding mosaic area
257 
258  mosaicLLX = std::min( mosaicLLX, reprojectedExtent.getMBR()->getLowerLeftX() );
259  mosaicLLY = std::min( mosaicLLY, reprojectedExtent.getMBR()->getLowerLeftY() );
260 
261  mosaicURX = std::max( mosaicURX, reprojectedExtent.getMBR()->getUpperRightX() );
262  mosaicURY = std::max( mosaicURY, reprojectedExtent.getMBR()->getUpperRightY() );
263 
264  // finding the current raster bounding box polygon (first raster world coordinates)
265 
266  auxPolygon.clear();
267  auxLinearRingPtr = new te::gm::LinearRing( reprojectedExtent );
268  auxPolygon.push_back( auxLinearRingPtr );
269  auxPolygon.setSRID( mosaicSRID );
270  rastersBBoxes.push_back( auxPolygon );
271  }
272 
273  // checking the input bands
274 
275  for( std::vector< unsigned int >::size_type inputRastersBandsIdx = 0 ;
276  inputRastersBandsIdx <
277  m_inputParameters.m_inputRastersBands[ inputRasterIdx ].size() ;
278  ++inputRastersBandsIdx )
279  {
280  const unsigned int& currBand =
281  m_inputParameters.m_inputRastersBands[ inputRasterIdx ][ inputRastersBandsIdx ];
282 
283  TERP_TRUE_OR_RETURN_FALSE( currBand < inputRasterPtr->getNumberOfBands(),
284  "Invalid band" )
285  }
286 
287 
289  }
290  }
291 
293  {
294  progressPtr->pulse();
295  if( ! progressPtr->isActive() ) return false;
296  }
297 
298  // creating the output raster
299 
300  te::rst::Raster* outputRasterPtr = 0;
301 
302  {
303  mosaicBandsRangeMin.resize(
304  m_inputParameters.m_inputRastersBands[ 0 ].size(), 0 );
305  mosaicBandsRangeMax.resize(
306  m_inputParameters.m_inputRastersBands[ 0 ].size(), 0 );
307 
308  std::vector< te::rst::BandProperty* > bandsProperties;
309  for( std::vector< unsigned int >::size_type bandIdx = 0 ; bandIdx <
310  m_inputParameters.m_inputRastersBands[ 0 ].size() ; ++bandIdx )
311  {
312  bandsProperties.push_back( new te::rst::BandProperty( mosaicBaseBandProperties ) );
313  bandsProperties[ bandIdx ]->m_colorInterp = te::rst::GrayIdxCInt;
314  bandsProperties[ bandIdx ]->m_noDataValue = m_inputParameters.m_noDataValue;
315 
316  te::rst::GetDataTypeRanges( bandsProperties[ bandIdx ]->m_type,
317  mosaicBandsRangeMin[ bandIdx ],
318  mosaicBandsRangeMax[ bandIdx ]);
319  }
320 
321  te::rst::Grid* outputGrid = new te::rst::Grid( mosaicXResolution,
322  mosaicYResolution, new te::gm::Envelope( mosaicLLX, mosaicLLY, mosaicURX,
323  mosaicURY ), mosaicSRID );
324 
325  outParamsPtr->m_outputRasterPtr.reset(
327  outParamsPtr->m_rType,
328  outputGrid,
329  bandsProperties,
330  outParamsPtr->m_rInfo,
331  0,
332  0 ) );
333  TERP_TRUE_OR_RETURN_FALSE( outParamsPtr->m_outputRasterPtr.get(),
334  "Output raster creation error" );
335 
336  outputRasterPtr = outParamsPtr->m_outputRasterPtr.get();
337  }
338 
339  std::auto_ptr< te::mem::CachedRaster > cachedRasterInstancePtr;
340 
342  {
343  cachedRasterInstancePtr.reset( new te::mem::CachedRaster(
344  *(outParamsPtr->m_outputRasterPtr.get()), 20, 0 ) );
345 
346  outputRasterPtr = cachedRasterInstancePtr.get();
347  }
348 
349  // fill output with no data values
350 
351  {
352  const unsigned int nBands = outputRasterPtr->getNumberOfBands();
353  const unsigned int nRows = outputRasterPtr->getNumberOfRows();
354  const unsigned int nCols = outputRasterPtr->getNumberOfColumns();
355  unsigned int col = 0;
356  unsigned int row = 0;
357  unsigned int bandIdx = 0;
358 
359  for( bandIdx = 0 ; bandIdx < nBands ; ++bandIdx )
360  {
361  te::rst::Band& outBand = ( *( outputRasterPtr->getBand( bandIdx ) ) );
362 
363  for( row = 0 ; row < nRows ; ++row )
364  {
365  for( col = 0 ; col < nCols ; ++col )
366  {
367  outBand.setValue( col, row, m_inputParameters.m_noDataValue );
368  }
369  }
370  }
371  }
372 
374  {
375  progressPtr->pulse();
376  if( ! progressPtr->isActive() ) return false;
377  }
378 
379  // Copying the first image data to the output mosaic
380  // and find the base mosaic mean and offset values
381 
382  std::vector< double > mosaicTargetMeans( outputRasterPtr->getNumberOfBands(), 0 );
383  std::vector< double > mosaicTargetVariances( outputRasterPtr->getNumberOfBands(), 0 );
384 
385  {
387 
388  te::rst::Raster const* inputRasterPtr =
390  TERP_DEBUG_TRUE_OR_RETURN_FALSE( inputRasterPtr, "Invalid raster pointer" );
391 
392  double inXStartGeo = 0;
393  double inYStartGeo = 0;
394  inputRasterPtr->getGrid()->gridToGeo( 0.0, 0.0, inXStartGeo, inYStartGeo );
395  double outRowStartDouble = 0;
396  double outColStartDouble = 0;
397  outputRasterPtr->getGrid()->geoToGrid( inXStartGeo, inYStartGeo,
398  outColStartDouble, outRowStartDouble );
399 
400  const unsigned int outRowStart = (unsigned int)std::max( 0.0, outRowStartDouble );
401  const unsigned int outColStart = (unsigned int)std::max( 0.0, outColStartDouble );
402  const unsigned int outRowsBound = std::min( outRowStart +
403  inputRasterPtr->getNumberOfRows(),
404  outputRasterPtr->getNumberOfRows() );
405  const unsigned int outColsBound = std::min( outColStart +
406  inputRasterPtr->getNumberOfColumns(),
407  outputRasterPtr->getNumberOfColumns() );
408 
409  const unsigned int nBands = (unsigned int)
411  unsigned int outCol = 0;
412  unsigned int outRow = 0;
413  double inCol = 0;
414  double inRow = 0;
415  double bandNoDataValue = -1.0 * DBL_MAX;
416  std::complex< double > pixelCValue = 0;
417  te::rst::Interpolator interpInstance( inputRasterPtr,
419  unsigned int inputBandIdx = 0;
420 
421  for( unsigned int inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
422  nBands ; ++inputRastersBandsIdx )
423  {
424  inputBandIdx = m_inputParameters.m_inputRastersBands[ 0 ][
425  inputRastersBandsIdx ] ;
426  bandNoDataValue = m_inputParameters.m_forceInputNoDataValue ?
427  m_inputParameters.m_noDataValue : inputRasterPtr->getBand( inputBandIdx
429  te::rst::Band& outBand =
430  (*outputRasterPtr->getBand( inputRastersBandsIdx ));
431  unsigned int validPixelsNumber = 0;
432 
433  double& mean = mosaicTargetMeans[ inputRastersBandsIdx ];
434  mean = 0;
435 
436  for( outRow = outRowStart ; outRow < outRowsBound ; ++outRow )
437  {
438  inRow = ((double)outRow) - outRowStartDouble;
439 
440  for( outCol = outColStart ; outCol < outColsBound ; ++outCol )
441  {
442  inCol = ((double)outCol) - outColStartDouble;
443 
444  interpInstance.getValue( inCol, inRow, pixelCValue, inputBandIdx );
445 
446  if( pixelCValue.real() != bandNoDataValue )
447  {
448  outBand.setValue( outCol, outRow, pixelCValue );
449  mean += pixelCValue.real();
450  ++validPixelsNumber;
451  }
452  }
453  }
454 
455  mean /= ( (double)validPixelsNumber );
456 
457  // variance calcule
458 
460  {
461  double& variance = mosaicTargetVariances[ inputRastersBandsIdx ];
462  variance = 0;
463 
464  double pixelValue = 0;
465 
466  for( outRow = outRowStart ; outRow < outRowsBound ; ++outRow )
467  {
468  for( outCol = outColStart ; outCol < outColsBound ; ++outCol )
469  {
470  outBand.getValue( outCol, outRow, pixelValue );
471 
472  if( pixelValue != m_inputParameters.m_noDataValue )
473  {
474  variance += ( ( pixelValue - mean ) * ( pixelValue -
475  mean ) ) / ( (double)validPixelsNumber );
476  }
477  }
478  }
479  }
480  }
481  }
482 
483  TERP_DEBUG_TRUE_OR_THROW( rastersBBoxes.size() ==
485  "Rasters bounding boxes number mismatch" );
486 
488  {
489  progressPtr->pulse();
490  if( ! progressPtr->isActive() ) return false;
491  }
492 
493  // Initiating the mosaic bounding boxes union
494 
495  std::auto_ptr< te::gm::MultiPolygon > mosaicBBoxesUnionPtr(
497  outputRasterPtr->getSRID(), 0 ) );
498  mosaicBBoxesUnionPtr->add( (te::gm::Polygon*)rastersBBoxes[ 0 ].clone() );
499 
500  // skipping the first raster
501 
504 
505  // iterating over the other rasters
506 
507  te::rst::Raster const* originalInputRasterPtr = 0;
508 
509  std::vector< unsigned int > outputRasterBands;
510  std::vector< double > dummyRasterOffsets;
511  std::vector< double > dummyRasterScales;
512  for( unsigned int outputRasterBandsIdx = 0 ; outputRasterBandsIdx <
513  outputRasterPtr->getNumberOfBands() ; ++outputRasterBandsIdx )
514  {
515  outputRasterBands.push_back( outputRasterBandsIdx );
516  dummyRasterOffsets.push_back( 0.0 );
517  dummyRasterScales.push_back( 1.0 );
518  }
519 
520  while( ( originalInputRasterPtr = m_inputParameters.m_feederRasterPtr->getCurrentObj() ) )
521  {
522  const unsigned int inputRasterIdx = m_inputParameters.m_feederRasterPtr->getCurrentOffset();
523 
524 // Copy2DiskRaster( outputRaster, boost::lexical_cast< std::string >( inputRasterIdx ) +
525 // "_output_raster_begininng.tif" );
526 
527  TERP_DEBUG_TRUE_OR_THROW( rastersBBoxes[ inputRasterIdx ].getSRID() == outputRasterPtr->getSRID(),
528  "Invalid boxes SRID" );
529 
530  te::rst::Raster const* inputRasterPtr = originalInputRasterPtr;
531 
532 // Copy2DiskRaster( *inputRasterPtr, boost::lexical_cast< std::string >( inputRasterIdx ) +
533 // "_input_raster.tif" );
534 
535  // reprojection / caching issues
536 
537  std::auto_ptr< te::rst::Raster > reprojectedInputRasterPtr;
538 
539  std::string reprojectedRasterFileName;
540 
541  if( outputRasterPtr->getSRID() != inputRasterPtr->getSRID() )
542  {
543  reprojectedRasterFileName = boost::filesystem::unique_path(
544  boost::filesystem::temp_directory_path() /=
545  boost::filesystem::path( "TerralibRGeoMosaic_%%%%-%%%%-%%%%-%%%%" ) ).string();
546  TERP_TRUE_OR_RETURN_FALSE( !reprojectedRasterFileName.empty(),
547  "Invalid temporary raster file name" );
548  reprojectedRasterFileName += ".tif";
549 
550  std::map< std::string, std::string > rInfo;
551  rInfo[ "URI" ] = reprojectedRasterFileName;
552 
553  reprojectedInputRasterPtr.reset( inputRasterPtr->transform(
554  outputRasterPtr->getSRID(), rInfo,
556  inputRasterPtr = reprojectedInputRasterPtr.get();
557  TERP_TRUE_OR_RETURN_FALSE( inputRasterPtr, "Reprojection error" );
558 
559 // Copy2DiskRaster( *inputRasterPtr, boost::lexical_cast< std::string >( inputRasterIdx ) +
560 // "reprojected_input_raster.tif" );
561  }
562 
563  // Caching issues
564 
565  std::auto_ptr< te::mem::CachedRaster > cachedInputRasterPtr;
566 
568  {
569  cachedInputRasterPtr.reset( new te::mem::CachedRaster(
570  *inputRasterPtr, 20, 0 ) );
571  inputRasterPtr = cachedInputRasterPtr.get();
572  }
573 
574  // The transformation mapping outputRaster pixels
575  // ( te::gm::GTParameters::TiePoint::first ) to input pixels
576  // ( te::gm::GTParameters::TiePoint::second )
577  // (Note: all coords are indexed by lines/columns).
578 
579  std::auto_ptr< te::gm::GeometricTransformation > transPtr;
580 
581  {
582  te::gm::GTParameters transParams;
583  double auxX;
584  double auxY;
586 
587  auxTP.first.x = 0;
588  auxTP.first.y = 0;
589  outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
590  inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
591  transParams.m_tiePoints.push_back( auxTP );
592 
593  auxTP.first.x = 0;
594  auxTP.first.y = (double)( outputRasterPtr->getNumberOfRows() - 1 );
595  outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
596  inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
597  transParams.m_tiePoints.push_back( auxTP );
598 //
599 // auxTP.first.x = (double)( outputRasterPtr->getNumberOfColumns() - 1);
600 // auxTP.first.y = 0;
601 // outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
602 // inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
603 // transParams.m_tiePoints.push_back( auxTP );
604 
605  auxTP.first.x = (double)( outputRasterPtr->getNumberOfColumns() - 1 );
606  auxTP.first.y = (double)( outputRasterPtr->getNumberOfRows() - 1 );
607  outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
608  inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
609  transParams.m_tiePoints.push_back( auxTP );
610 
611  transPtr.reset( te::gm::GTFactory::make( "Affine" ) );
612  TERP_TRUE_OR_RETURN_FALSE( transPtr.get(), "Could not instantiate a geometric transformation" );
613 
614  TERP_TRUE_OR_RETURN_FALSE( transPtr->initialize( transParams ),
615  "Could not initialize a geometric transformation" );
616  }
617 
618  // Generating the offset and gain info for eath band from the current raster
619 
620  std::vector< double > currentRasterBandsOffsets;
621  std::vector< double > currentRasterBandsScales;
622 
624  {
625  double currentRasterVariance = 0;
626  double currentRasterMean = 0;
627 
628  for( unsigned int inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
629  m_inputParameters.m_inputRastersBands[ inputRasterIdx ].size() ;
630  ++inputRastersBandsIdx )
631  {
632  const unsigned int inputBandIdx = m_inputParameters.m_inputRastersBands[ inputRasterIdx ][
633  inputRastersBandsIdx ];
634 
635  calcBandStatistics( (*inputRasterPtr->getBand( inputBandIdx ) ),
638  currentRasterMean,
639  currentRasterVariance );
640 
641  currentRasterBandsScales.push_back(
642  std::sqrt( mosaicTargetVariances[ inputRastersBandsIdx ] )
643  /
644  std::sqrt( currentRasterVariance ) );
645  currentRasterBandsOffsets.push_back( mosaicTargetMeans[ inputRastersBandsIdx ]
646  - ( currentRasterBandsScales[ inputRastersBandsIdx ] * currentRasterMean ) );
647  }
648  }
649  else
650  {
651  currentRasterBandsOffsets = dummyRasterOffsets;
652  currentRasterBandsScales = dummyRasterScales;
653  }
654 
655  // blending
656 
657  te::rp::Blender blenderInstance;
658 
659  TERP_TRUE_OR_RETURN_FALSE( blenderInstance.initialize(
660  *outputRasterPtr,
661  outputRasterBands,
662  *inputRasterPtr,
663  m_inputParameters.m_inputRastersBands[ inputRasterIdx ],
668  false,
670  dummyRasterOffsets,
671  dummyRasterScales,
672  currentRasterBandsOffsets,
673  currentRasterBandsScales,
674  mosaicBBoxesUnionPtr.get(),
675  0,
676  *transPtr,
678  false ), "Blender initiazing error" );
679 
680  TERP_TRUE_OR_RETURN_FALSE( blenderInstance.blendIntoRaster1(),
681  "Error blending images" );
682 
683 // Copy2DiskRaster( outputRaster, boost::lexical_cast< std::string >( inputRasterIdx ) +
684 // "output_raster_after_blending_" +
685 // boost::lexical_cast< std::string >( mosaicBBoxesUnionIdx ) + ".tif" );
686 
687  // updating the gloabal mosaic boxes
688 
689  std::auto_ptr< te::gm::Geometry > boxesUnionResultPtr; // under the mosaic SRID
690  boxesUnionResultPtr.reset( mosaicBBoxesUnionPtr->Union(
691  &( rastersBBoxes[ inputRasterIdx ] ) ) );
692  TERP_TRUE_OR_THROW( boxesUnionResultPtr.get(), "Invalid pointer" );
693  boxesUnionResultPtr->setSRID( outputRasterPtr->getSRID() );
694 
695  if( boxesUnionResultPtr->getGeomTypeId() == te::gm::MultiPolygonType )
696  {
697  mosaicBBoxesUnionPtr.reset( (te::gm::MultiPolygon*)boxesUnionResultPtr.release() );
698  }
699  else if( boxesUnionResultPtr->getGeomTypeId() == te::gm::PolygonType )
700  {
701  // transforming it into a te::gm::MultiPolygon
702  te::gm::MultiPolygon* auxMultiPol = new te::gm::MultiPolygon( 0,
703  te::gm::MultiPolygonType, boxesUnionResultPtr->getSRID(), 0 );
704  auxMultiPol->add( boxesUnionResultPtr.release() );
705 
706  mosaicBBoxesUnionPtr.reset( auxMultiPol );
707  }
708  else
709  {
710  TERP_LOG_AND_RETURN_FALSE( "Invalid union geometry type" );
711  }
712 
713  // Reseting the input cache
714 
715  cachedInputRasterPtr.reset();
716 
717  // deleting the reprojected raster
718 
719  if( reprojectedInputRasterPtr.get() )
720  {
721  reprojectedInputRasterPtr.reset();
722  remove( reprojectedRasterFileName.c_str() );
723  }
724 
725  // moving to the next raster
726 
728 
730  {
731  progressPtr->pulse();
732  if( ! progressPtr->isActive() ) return false;
733  }
734  }
735 
736  // reseting the output cache
737 
738  if( cachedRasterInstancePtr.get() ) cachedRasterInstancePtr.reset();
739 
740  return true;
741  }
742 
743  void GeoMosaic::reset() throw( te::rp::Exception )
744  {
746  m_isInitialized = false;
747  }
748 
750  throw( te::rp::Exception )
751  {
752  reset();
753 
754  GeoMosaic::InputParameters const* inputParamsPtr = dynamic_cast<
755  GeoMosaic::InputParameters const* >( &inputParams );
756  TERP_TRUE_OR_THROW( inputParamsPtr, "Invalid paramters pointer" );
757 
758  m_inputParameters = *inputParamsPtr;
759 
760  // Checking the feeder
761 
763  "Invalid m_feederRasterPtr" )
764 
767  "Invalid number of rasters" )
768 
769  // checking m_inputRastersBands
770 
772  ((unsigned int)m_inputParameters.m_inputRastersBands.size()) ==
774  "Bands mismatch" );
775 
776  for( std::vector< std::vector< unsigned int > >::size_type
777  inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
778  m_inputParameters.m_inputRastersBands.size() ; ++inputRastersBandsIdx )
779  {
781  inputRastersBandsIdx ].size() > 0, "Invalid bands number" );
782 
784  inputRastersBandsIdx ].size() == m_inputParameters.m_inputRastersBands[
785  0 ].size(), "Bands number mismatch" );
786  }
787 
788  m_isInitialized = true;
789 
790  return true;
791  }
792 
794  {
795  return m_isInitialized;
796  }
797 
799  const bool& forceNoDataValue,
800  const double& noDataValue,
801  double& mean, double& variance )
802  {
803  mean = 0;
804  variance = 0;
805 
806  double internalNoDataValue = 0;
807  if( forceNoDataValue )
808  internalNoDataValue = noDataValue;
809  else
810  internalNoDataValue = band.getProperty()->m_noDataValue;
811 
812  const unsigned int nCols = band.getProperty()->m_blkw *
813  band.getProperty()->m_nblocksx;
814  const unsigned int nLines = band.getProperty()->m_blkh *
815  band.getProperty()->m_nblocksy;
816 
817  double pixelsNumber = 0;
818  double value = 0;
819  unsigned int col = 0;
820  unsigned int line = 0;
821 
822  for( line = 0 ; line < nLines ; ++line )
823  for( col = 0 ; col < nCols ; ++col )
824  {
825  band.getValue( col, line, value );
826 
827  if( value != internalNoDataValue )
828  {
829  mean += value;
830  ++pixelsNumber;
831  }
832  }
833 
834  if( pixelsNumber != 0.0 )
835  {
836  mean /= pixelsNumber;
837 
838  for( line = 0 ; line < nLines ; ++line )
839  for( col = 0 ; col < nCols ; ++col )
840  {
841  band.getValue( col, line, value );
842 
843  if( value != internalNoDataValue )
844  {
845  variance += ( ( value - mean ) * ( value - mean ) ) / pixelsNumber;
846  }
847  }
848 
849  }
850  }
851 
852  } // end namespace rp
853 } // end namespace te
854 
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
Definition: GeoMosaic.cpp:130
virtual unsigned int getObjsCount() const =0
Return the total number of feeder objects.
void push_back(Curve *ring)
It adds the curve to the curve polygon.
Definition: CurvePolygon.h:279
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
Definition: GeoMosaic.cpp:749
AbstractParameters * clone() const
Create a clone copy of this instance.
Definition: GeoMosaic.cpp:109
Near neighborhood interpolation method.
Definition: Enums.h:95
std::vector< TiePoint > m_tiePoints
Tie points.
Definition: GTParameters.h:95
void reset()
Clear all internal allocated objects and reset the algorithm to its initial state.
Definition: GeoMosaic.cpp:743
const OutputParameters & operator=(const OutputParameters &params)
Definition: GeoMosaic.cpp:137
TERASTEREXPORT void GetDataTypeRanges(const int &dataType, double &min, double &max)
Return the values range of a given data type.
Definition: Utils.cpp:334
Index into a lookup table.
Definition: Enums.h:57
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
void setSRID(int srid)
It sets the Spatial Reference System ID of the geometry and all its parts if it is a GeometryCollecti...
AbstractParameters * clone() const
Create a clone copy of this instance.
Definition: GeoMosaic.cpp:149
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:793
A raster band description.
Definition: BandProperty.h:61
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
Definition: GeoMosaic.cpp:163
Blended pixel value calculation for two overlaped rasters.
Definition: Blender.h:58
int getSRID() const
Returns the grid spatial reference system identifier.
Definition: Grid.cpp:265
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
Definition: Raster.cpp:213
GeoMosaic input parameters.
Definition: GeoMosaic.h:56
int m_nblocksx
The number of blocks in x.
Definition: BandProperty.h:145
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
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
const double & getUpperRightX() const
It returns a constant refernce to the x coordinate of the upper right corner.
Definition: Envelope.h:410
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
Raster Processing algorithm output parameters base interface.
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
const double & getLowerLeftY() const
It returns a constant refernce to the y coordinate of the lower left corner.
Definition: Envelope.h:400
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:92
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits::max().
Definition: BandProperty.h:136
const double & getUpperRightY() const
It returns a constant refernce to the x coordinate of the upper right corner.
Definition: Envelope.h:420
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.
Definition: Grid.cpp:307
bool blendIntoRaster1()
Execute blending of the given input rasters and write the result into raster1.
Definition: Blender.cpp:1060
Raster Processing functions.
double getResolutionY() const
Returns the grid vertical (y-axis) resolution.
Definition: Grid.cpp:259
#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:183
const Algorithm & operator=(const Algorithm &)
Definition: Algorithm.cpp:43
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
Definition: Raster.cpp:89
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
void setPoint(std::size_t i, const double &x, const double &y)
It sets the value of the specified point.
Definition: LineString.cpp:353
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.
Definition: Envelope.h:51
An abstract class for raster data strucutures.
Definition: Raster.h:71
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Definition: Raster.cpp:208
bool m_enableProgress
Enable/Disable the progress interface (default:false).
Definition: GeoMosaic.h:76
BandProperty * getProperty()
Returns the band property.
Definition: Band.cpp:428
int m_blkw
Block width (pixels).
Definition: BandProperty.h:143
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
Create a mosaic from a set of geo-referenced rasters.
double getResolutionX() const
Returns the grid horizontal (x-axis) resolution.
Definition: Grid.cpp:253
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.
Definition: Band.h:63
bool GetDetailedExtent(const te::rst::Grid &grid, te::gm::LinearRing &detailedExtent)
Create a datailed extent from the given grid.
Definition: Functions.cpp:2244
Grid * getGrid()
It returns the raster grid.
Definition: Raster.cpp:94
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:170
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
A Converter is responsible for the conversion of coordinates between different Coordinate Systems (CS...
Definition: Converter.h:53
Abstract parameters base interface.
std::auto_ptr< te::rst::Raster > m_outputRasterPtr
The generated output mosaic raster.
Definition: GeoMosaic.h:108
bool m_isInitialized
Tells if this instance is initialized.
Definition: GeoMosaic.h:145
int getSRID() const
Returns the raster spatial reference system identifier.
Definition: Raster.cpp:203
#define TERP_LOG_AND_RETURN_FALSE(message)
Logs a warning message will and return false.
Definition: Macros.h:236
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
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:798
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.
const double & getLowerLeftX() const
It returns a constant reference to the x coordinate of the lower left corner.
Definition: Envelope.h:390
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
Definition: GeoMosaic.cpp:76
#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:371
te::gm::Envelope * getExtent()
Returns the geographic extension of the grid.
Definition: Grid.cpp:275
void clear()
It deletes all the rings of the CurvePolygon and clear it.
void gridToGeo(const double &col, const double &row, double &x, double &y) const
Get the spatial location of a grid point.
Definition: Grid.cpp:301
void setSRID(int srid)
It sets the Spatial Reference System ID of the linestring.
Definition: LineString.cpp:176
Raster Processing algorithm input parameters base interface.
2D Geometric transformation parameters.
Definition: GTParameters.h:50
const InputParameters & operator=(const InputParameters &params)
Definition: GeoMosaic.cpp:90
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:356
virtual te::rst::Raster const * getCurrentObj() const =0
Return the current sequence object.
A rectified grid is the spatial support for raster data.
Definition: Grid.h:68
double m_noDataValue
The pixel value used where no raster data is avaliable (defaul:0).
Definition: GeoMosaic.h:66
const Envelope * getMBR() const
It returns the minimum bounding rectangle for the geometry in an internal representation.
Definition: Geometry.cpp:104
virtual unsigned int getCurrentOffset() const =0
Return the index of the current object.
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:149
bool m_useRasterCache
Enable(true) or disable the use of raster caching (default:true).
Definition: GeoMosaic.h:74
void transform(int srid)
It converts the coordinate values of the linestring to the new spatial reference system.
Definition: LineString.cpp:181
FeederConstRaster * m_feederRasterPtr
Input rasters feeder.
Definition: GeoMosaic.h:60
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