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) 2001-2009 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();
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::Coord2D llCoord1;
207  te::gm::Coord2D urCoord1;
208  te::gm::Coord2D llCoord2;
209  te::gm::Coord2D urCoord2;
210 
212  while( ( inputRasterPtr = m_inputParameters.m_feederRasterPtr->getCurrentObj() ) )
213  {
216  inputRasterPtr->getAccessPolicy() & te::common::RAccess,
217  "Invalid raster" );
218 
219  // Defining the base mosaic info
220 
221  if( inputRasterIdx == 0 )
222  {
223  mosaicXResolution = inputRasterPtr->getGrid()->getResolutionX();
224  mosaicYResolution = inputRasterPtr->getGrid()->getResolutionY();
225 
226  mosaicLLX = inputRasterPtr->getGrid()->getExtent()->m_llx;
227  mosaicLLY = inputRasterPtr->getGrid()->getExtent()->m_lly;
228  mosaicURX = inputRasterPtr->getGrid()->getExtent()->m_urx;
229  mosaicURY = inputRasterPtr->getGrid()->getExtent()->m_ury;
230 
231  mosaicSRID = inputRasterPtr->getGrid()->getSRID();
232 
233  mosaicBaseBandProperties = *inputRasterPtr->getBand( 0 )->getProperty();
234 
235  // finding the current raster bounding box polygon (first raster world coordinates)
236  auxPolygon.clear();
237  auxLinearRingPtr = new te::gm::LinearRing(5, te::gm::LineStringType);
238  auxLinearRingPtr->setPoint( 0, mosaicLLX, mosaicURY );
239  auxLinearRingPtr->setPoint( 1, mosaicURX, mosaicURY );
240  auxLinearRingPtr->setPoint( 2, mosaicURX, mosaicLLY );
241  auxLinearRingPtr->setPoint( 3, mosaicLLX, mosaicLLY );
242  auxLinearRingPtr->setPoint( 4, mosaicLLX, mosaicURY );
243  auxPolygon.push_back( auxLinearRingPtr );
244  auxPolygon.setSRID( mosaicSRID );
245  rastersBBoxes.push_back( auxPolygon );
246  }
247  else
248  {
249  if( mosaicSRID == inputRasterPtr->getGrid()->getSRID() )
250  {
251  urCoord1.x = inputRasterPtr->getGrid()->getExtent()->m_urx;
252  urCoord1.y = inputRasterPtr->getGrid()->getExtent()->m_ury;
253  llCoord1.x = inputRasterPtr->getGrid()->getExtent()->m_llx;
254  llCoord1.y = inputRasterPtr->getGrid()->getExtent()->m_lly;
255  }
256  else
257  {
258  convInstance.setSourceSRID( inputRasterPtr->getGrid()->getSRID() );
259  convInstance.setTargetSRID( mosaicSRID );
260 
261  convInstance.convert(
262  inputRasterPtr->getGrid()->getExtent()->m_urx,
263  inputRasterPtr->getGrid()->getExtent()->m_ury,
264  urCoord1.x,
265  urCoord1.y );
266  convInstance.convert(
267  inputRasterPtr->getGrid()->getExtent()->m_llx,
268  inputRasterPtr->getGrid()->getExtent()->m_lly,
269  llCoord1.x,
270  llCoord1.y );
271  }
272 
273  // expanding mosaic area
274 
275  mosaicLLX = std::min( mosaicLLX, urCoord1.x );
276  mosaicLLX = std::min( mosaicLLX, llCoord1.x );
277 
278  mosaicLLY = std::min( mosaicLLY, urCoord1.y );
279  mosaicLLY = std::min( mosaicLLY, llCoord1.y );
280 
281  mosaicURX = std::max( mosaicURX, urCoord1.x );
282  mosaicURX = std::max( mosaicURX, llCoord1.x );
283 
284  mosaicURY = std::max( mosaicURY, urCoord1.y );
285  mosaicURY = std::max( mosaicURY, llCoord1.y );
286 
287  // finding the current raster bounding box polygon (first raster world coordinates)
288 
289  auxPolygon.clear();
290  auxLinearRingPtr = new te::gm::LinearRing(5, te::gm::LineStringType);
291  auxLinearRingPtr->setPoint( 0, llCoord1.x, urCoord1.y );
292  auxLinearRingPtr->setPoint( 1, urCoord1.x, urCoord1.y );
293  auxLinearRingPtr->setPoint( 2, urCoord1.x, llCoord1.y );
294  auxLinearRingPtr->setPoint( 3, llCoord1.x, llCoord1.y );
295  auxLinearRingPtr->setPoint( 4, llCoord1.x, urCoord1.y );
296  auxPolygon.push_back( auxLinearRingPtr );
297  auxPolygon.setSRID( mosaicSRID );
298  rastersBBoxes.push_back( auxPolygon );
299  }
300 
301  // checking the input bands
302 
303  for( std::vector< unsigned int >::size_type inputRastersBandsIdx = 0 ;
304  inputRastersBandsIdx <
305  m_inputParameters.m_inputRastersBands[ inputRasterIdx ].size() ;
306  ++inputRastersBandsIdx )
307  {
308  const unsigned int& currBand =
309  m_inputParameters.m_inputRastersBands[ inputRasterIdx ][ inputRastersBandsIdx ];
310 
311  TERP_TRUE_OR_RETURN_FALSE( currBand < inputRasterPtr->getNumberOfBands(),
312  "Invalid band" )
313  }
314 
315 
317  }
318  }
319 
321  {
322  progressPtr->pulse();
323  if( ! progressPtr->isActive() ) return false;
324  }
325 
326  // creating the output raster
327 
328  te::rst::Raster* outputRasterPtr = 0;
329 
330  {
331  mosaicBandsRangeMin.resize(
332  m_inputParameters.m_inputRastersBands[ 0 ].size(), 0 );
333  mosaicBandsRangeMax.resize(
334  m_inputParameters.m_inputRastersBands[ 0 ].size(), 0 );
335 
336  std::vector< te::rst::BandProperty* > bandsProperties;
337  for( std::vector< unsigned int >::size_type bandIdx = 0 ; bandIdx <
338  m_inputParameters.m_inputRastersBands[ 0 ].size() ; ++bandIdx )
339  {
340  bandsProperties.push_back( new te::rst::BandProperty( mosaicBaseBandProperties ) );
341  bandsProperties[ bandIdx ]->m_colorInterp = te::rst::GrayIdxCInt;
342  bandsProperties[ bandIdx ]->m_noDataValue = m_inputParameters.m_noDataValue;
343 
344  te::rst::GetDataTypeRanges( bandsProperties[ bandIdx ]->m_type,
345  mosaicBandsRangeMin[ bandIdx ],
346  mosaicBandsRangeMax[ bandIdx ]);
347  }
348 
349  te::rst::Grid* outputGrid = new te::rst::Grid( mosaicXResolution,
350  mosaicYResolution, new te::gm::Envelope( mosaicLLX, mosaicLLY, mosaicURX,
351  mosaicURY ), mosaicSRID );
352 
353  outParamsPtr->m_outputRasterPtr.reset(
355  outParamsPtr->m_rType,
356  outputGrid,
357  bandsProperties,
358  outParamsPtr->m_rInfo,
359  0,
360  0 ) );
361  TERP_TRUE_OR_RETURN_FALSE( outParamsPtr->m_outputRasterPtr.get(),
362  "Output raster creation error" );
363 
364  outputRasterPtr = outParamsPtr->m_outputRasterPtr.get();
365  }
366 
367  std::auto_ptr< te::mem::CachedRaster > cachedRasterInstancePtr;
368 
370  {
371  cachedRasterInstancePtr.reset( new te::mem::CachedRaster(
372  *(outParamsPtr->m_outputRasterPtr.get()), 20, 0 ) );
373 
374  outputRasterPtr = cachedRasterInstancePtr.get();
375  }
376 
377  // fill output with no data values
378 
379  {
380  const unsigned int nBands = outputRasterPtr->getNumberOfBands();
381  const unsigned int nRows = outputRasterPtr->getNumberOfRows();
382  const unsigned int nCols = outputRasterPtr->getNumberOfColumns();
383  unsigned int col = 0;
384  unsigned int row = 0;
385  unsigned int bandIdx = 0;
386 
387  for( bandIdx = 0 ; bandIdx < nBands ; ++bandIdx )
388  {
389  te::rst::Band& outBand = ( *( outputRasterPtr->getBand( bandIdx ) ) );
390 
391  for( row = 0 ; row < nRows ; ++row )
392  {
393  for( col = 0 ; col < nCols ; ++col )
394  {
395  outBand.setValue( col, row, m_inputParameters.m_noDataValue );
396  }
397  }
398  }
399  }
400 
402  {
403  progressPtr->pulse();
404  if( ! progressPtr->isActive() ) return false;
405  }
406 
407  // Copying the first image data to the output mosaic
408  // and find the base mosaic mean and offset values
409 
410  std::vector< double > mosaicTargetMeans( outputRasterPtr->getNumberOfBands(), 0 );
411  std::vector< double > mosaicTargetVariances( outputRasterPtr->getNumberOfBands(), 0 );
412 
413  {
415 
416  te::rst::Raster const* inputRasterPtr =
418  TERP_DEBUG_TRUE_OR_RETURN_FALSE( inputRasterPtr, "Invalid raster pointer" );
419 
420  double inXStartGeo = 0;
421  double inYStartGeo = 0;
422  inputRasterPtr->getGrid()->gridToGeo( 0.0, 0.0, inXStartGeo, inYStartGeo );
423  double outRowStartDouble = 0;
424  double outColStartDouble = 0;
425  outputRasterPtr->getGrid()->geoToGrid( inXStartGeo, inYStartGeo,
426  outColStartDouble, outRowStartDouble );
427 
428  const unsigned int outRowStart = (unsigned int)std::max( 0.0, outRowStartDouble );
429  const unsigned int outColStart = (unsigned int)std::max( 0.0, outColStartDouble );
430  const unsigned int outRowsBound = std::min( outRowStart +
431  inputRasterPtr->getNumberOfRows(),
432  outputRasterPtr->getNumberOfRows() );
433  const unsigned int outColsBound = std::min( outColStart +
434  inputRasterPtr->getNumberOfColumns(),
435  outputRasterPtr->getNumberOfColumns() );
436 
437  const unsigned int nBands = (unsigned int)
439  unsigned int outCol = 0;
440  unsigned int outRow = 0;
441  double inCol = 0;
442  double inRow = 0;
443  double bandNoDataValue = -1.0 * DBL_MAX;
444  std::complex< double > pixelCValue = 0;
445  te::rst::Interpolator interpInstance( inputRasterPtr,
447  unsigned int inputBandIdx = 0;
448 
449  for( unsigned int inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
450  nBands ; ++inputRastersBandsIdx )
451  {
452  inputBandIdx = m_inputParameters.m_inputRastersBands[ 0 ][
453  inputRastersBandsIdx ] ;
454  bandNoDataValue = m_inputParameters.m_forceInputNoDataValue ?
455  m_inputParameters.m_noDataValue : inputRasterPtr->getBand( inputBandIdx
457  te::rst::Band& outBand =
458  (*outputRasterPtr->getBand( inputRastersBandsIdx ));
459  unsigned int validPixelsNumber = 0;
460 
461  double& mean = mosaicTargetMeans[ inputRastersBandsIdx ];
462  mean = 0;
463 
464  for( outRow = outRowStart ; outRow < outRowsBound ; ++outRow )
465  {
466  inRow = ((double)outRow) - outRowStartDouble;
467 
468  for( outCol = outColStart ; outCol < outColsBound ; ++outCol )
469  {
470  inCol = ((double)outCol) - outColStartDouble;
471 
472  interpInstance.getValue( inCol, inRow, pixelCValue, inputBandIdx );
473 
474  if( pixelCValue.real() != bandNoDataValue )
475  {
476  outBand.setValue( outCol, outRow, pixelCValue );
477  mean += pixelCValue.real();
478  ++validPixelsNumber;
479  }
480  }
481  }
482 
483  mean /= ( (double)validPixelsNumber );
484 
485  // variance calcule
486 
488  {
489  double& variance = mosaicTargetVariances[ inputRastersBandsIdx ];
490  variance = 0;
491 
492  double pixelValue = 0;
493 
494  for( outRow = outRowStart ; outRow < outRowsBound ; ++outRow )
495  {
496  for( outCol = outColStart ; outCol < outColsBound ; ++outCol )
497  {
498  outBand.getValue( outCol, outRow, pixelValue );
499 
500  if( pixelValue != m_inputParameters.m_noDataValue )
501  {
502  variance += ( ( pixelValue - mean ) * ( pixelValue -
503  mean ) ) / ( (double)validPixelsNumber );
504  }
505  }
506  }
507  }
508  }
509  }
510 
511  TERP_DEBUG_TRUE_OR_THROW( rastersBBoxes.size() ==
513  "Rasters bounding boxes number mismatch" );
514 
516  {
517  progressPtr->pulse();
518  if( ! progressPtr->isActive() ) return false;
519  }
520 
521  // Initiating the mosaic bounding boxes union
522 
523  std::auto_ptr< te::gm::MultiPolygon > mosaicBBoxesUnionPtr(
525  outputRasterPtr->getSRID(), 0 ) );
526  mosaicBBoxesUnionPtr->add( (te::gm::Polygon*)rastersBBoxes[ 0 ].clone() );
527 
528  // skipping the first raster
529 
532 
533  // iterating over the other rasters
534 
535  te::rst::Raster const* originalInputRasterPtr = 0;
536 
537  std::vector< unsigned int > outputRasterBands;
538  std::vector< double > dummyRasterOffsets;
539  std::vector< double > dummyRasterScales;
540  for( unsigned int outputRasterBandsIdx = 0 ; outputRasterBandsIdx <
541  outputRasterPtr->getNumberOfBands() ; ++outputRasterBandsIdx )
542  {
543  outputRasterBands.push_back( outputRasterBandsIdx );
544  dummyRasterOffsets.push_back( 0.0 );
545  dummyRasterScales.push_back( 1.0 );
546  }
547 
548  while( ( originalInputRasterPtr = m_inputParameters.m_feederRasterPtr->getCurrentObj() ) )
549  {
550  const unsigned int inputRasterIdx = m_inputParameters.m_feederRasterPtr->getCurrentOffset();
551 
552 // Copy2DiskRaster( outputRaster, boost::lexical_cast< std::string >( inputRasterIdx ) +
553 // "_output_raster_begininng.tif" );
554 
555  TERP_DEBUG_TRUE_OR_THROW( rastersBBoxes[ inputRasterIdx ].getSRID() == outputRasterPtr->getSRID(),
556  "Invalid boxes SRID" );
557 
558  te::rst::Raster const* inputRasterPtr = originalInputRasterPtr;
559 
560 // Copy2DiskRaster( *inputRasterPtr, boost::lexical_cast< std::string >( inputRasterIdx ) +
561 // "_input_raster.tif" );
562 
563  // reprojection / caching issues
564 
565  std::auto_ptr< te::rst::Raster > reprojectedInputRasterPtr;
566 
567  std::string reprojectedRasterFileName;
568 
569  if( outputRasterPtr->getSRID() != inputRasterPtr->getSRID() )
570  {
571  reprojectedRasterFileName = boost::filesystem::unique_path(
572  boost::filesystem::temp_directory_path() /=
573  boost::filesystem::path( "TerralibRGeoMosaic_%%%%-%%%%-%%%%-%%%%" ) ).string();
574  TERP_TRUE_OR_RETURN_FALSE( !reprojectedRasterFileName.empty(),
575  "Invalid temporary raster file name" );
576  reprojectedRasterFileName += ".tif";
577 
578  std::map< std::string, std::string > rInfo;
579  rInfo[ "URI" ] = reprojectedRasterFileName;
580 
581  reprojectedInputRasterPtr.reset( inputRasterPtr->transform(
582  outputRasterPtr->getSRID(), rInfo,
584  inputRasterPtr = reprojectedInputRasterPtr.get();
585  TERP_TRUE_OR_RETURN_FALSE( inputRasterPtr, "Reprojection error" );
586 
587 // Copy2DiskRaster( *inputRasterPtr, boost::lexical_cast< std::string >( inputRasterIdx ) +
588 // "reprojected_input_raster.tif" );
589  }
590 
591  // Caching issues
592 
593  std::auto_ptr< te::mem::CachedRaster > cachedInputRasterPtr;
594 
596  {
597  cachedInputRasterPtr.reset( new te::mem::CachedRaster(
598  *inputRasterPtr, 20, 0 ) );
599  inputRasterPtr = cachedInputRasterPtr.get();
600  }
601 
602  // The transformation mapping outputRaster pixels
603  // ( te::gm::GTParameters::TiePoint::first ) to input pixels
604  // ( te::gm::GTParameters::TiePoint::second )
605  // (Note: all coords are indexed by lines/columns).
606 
607  std::auto_ptr< te::gm::GeometricTransformation > transPtr;
608 
609  {
610  te::gm::GTParameters transParams;
611  double auxX;
612  double auxY;
614 
615  auxTP.first.x = 0;
616  auxTP.first.y = 0;
617  outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
618  inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
619  transParams.m_tiePoints.push_back( auxTP );
620 
621  auxTP.first.x = 0;
622  auxTP.first.y = (double)outputRasterPtr->getNumberOfRows();
623  outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
624  inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
625  transParams.m_tiePoints.push_back( auxTP );
626 
627  auxTP.first.x = (double)outputRasterPtr->getNumberOfColumns();
628  auxTP.first.y = 0;
629  outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
630  inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
631  transParams.m_tiePoints.push_back( auxTP );
632 
633  auxTP.first.x = (double)outputRasterPtr->getNumberOfColumns();
634  auxTP.first.y = (double)outputRasterPtr->getNumberOfRows();
635  outputRasterPtr->getGrid()->gridToGeo( auxTP.first.x, auxTP.first.y, auxX, auxY );
636  inputRasterPtr->getGrid()->geoToGrid( auxX, auxY, auxTP.second.x, auxTP.second.y );
637  transParams.m_tiePoints.push_back( auxTP );
638 
639  transPtr.reset( te::gm::GTFactory::make( "RST" ) );
640  TERP_TRUE_OR_RETURN_FALSE( transPtr.get(), "Could not instantiate a geometric transformation" );
641 
642  TERP_TRUE_OR_RETURN_FALSE( transPtr->initialize( transParams ),
643  "Could not initialize a geometric transformation" );
644  }
645 
646  // Generating the offset and gain info for eath band from the current raster
647 
648  std::vector< double > currentRasterBandsOffsets;
649  std::vector< double > currentRasterBandsScales;
650 
652  {
653  double currentRasterVariance = 0;
654  double currentRasterMean = 0;
655 
656  for( unsigned int inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
657  m_inputParameters.m_inputRastersBands[ inputRasterIdx ].size() ;
658  ++inputRastersBandsIdx )
659  {
660  const unsigned int inputBandIdx = m_inputParameters.m_inputRastersBands[ inputRasterIdx ][
661  inputRastersBandsIdx ];
662 
663  calcBandStatistics( (*inputRasterPtr->getBand( inputBandIdx ) ),
666  currentRasterMean,
667  currentRasterVariance );
668 
669  currentRasterBandsScales.push_back( std::sqrt( mosaicTargetVariances[ inputRastersBandsIdx ] /
670  currentRasterVariance ) );
671  currentRasterBandsOffsets.push_back( mosaicTargetMeans[ inputRastersBandsIdx ] -
672  ( currentRasterBandsScales[ inputRastersBandsIdx ] * currentRasterMean ) );
673  }
674  }
675  else
676  {
677  currentRasterBandsOffsets = dummyRasterOffsets;
678  currentRasterBandsScales = dummyRasterScales;
679  }
680 
681  // blending
682 
683  te::rp::Blender blenderInstance;
684 
685  TERP_TRUE_OR_RETURN_FALSE( blenderInstance.initialize(
686  *outputRasterPtr,
687  outputRasterBands,
688  *inputRasterPtr,
689  m_inputParameters.m_inputRastersBands[ inputRasterIdx ],
695  dummyRasterOffsets,
696  dummyRasterScales,
697  currentRasterBandsOffsets,
698  currentRasterBandsScales,
699  mosaicBBoxesUnionPtr.get(),
700  0,
701  *transPtr,
703  false ), "Blender initiazing error" );
704 
705  TERP_TRUE_OR_RETURN_FALSE( blenderInstance.blendIntoRaster1(),
706  "Error blending images" );
707 
708 // Copy2DiskRaster( outputRaster, boost::lexical_cast< std::string >( inputRasterIdx ) +
709 // "output_raster_after_blending_" +
710 // boost::lexical_cast< std::string >( mosaicBBoxesUnionIdx ) + ".tif" );
711 
712  // updating the gloabal mosaic boxes
713 
714  std::auto_ptr< te::gm::Geometry > boxesUnionResultPtr; // under the mosaic SRID
715  boxesUnionResultPtr.reset( mosaicBBoxesUnionPtr->Union(
716  &( rastersBBoxes[ inputRasterIdx ] ) ) );
717  TERP_TRUE_OR_THROW( boxesUnionResultPtr.get(), "Invalid pointer" );
718  boxesUnionResultPtr->setSRID( outputRasterPtr->getSRID() );
719 
720  if( boxesUnionResultPtr->getGeomTypeId() == te::gm::MultiPolygonType )
721  {
722  mosaicBBoxesUnionPtr.reset( (te::gm::MultiPolygon*)boxesUnionResultPtr.release() );
723  }
724  else if( boxesUnionResultPtr->getGeomTypeId() == te::gm::PolygonType )
725  {
726  // transforming it into a te::gm::MultiPolygon
727  te::gm::MultiPolygon* auxMultiPol = new te::gm::MultiPolygon( 0,
728  te::gm::MultiPolygonType, boxesUnionResultPtr->getSRID(), 0 );
729  auxMultiPol->add( boxesUnionResultPtr.release() );
730 
731  mosaicBBoxesUnionPtr.reset( auxMultiPol );
732  }
733  else
734  {
735  TERP_LOG_AND_RETURN_FALSE( "Invalid union geometry type" );
736  }
737 
738  // Reseting the input cache
739 
740  cachedInputRasterPtr.reset();
741 
742  // deleting the reprojected raster
743 
744  if( reprojectedInputRasterPtr.get() )
745  {
746  reprojectedInputRasterPtr.reset();
747  remove( reprojectedRasterFileName.c_str() );
748  }
749 
750  // moving to the next raster
751 
753 
755  {
756  progressPtr->pulse();
757  if( ! progressPtr->isActive() ) return false;
758  }
759  }
760 
761  // reseting the output cache
762 
763  if( cachedRasterInstancePtr.get() ) cachedRasterInstancePtr.reset();
764 
765  return true;
766  }
767 
768  void GeoMosaic::reset() throw( te::rp::Exception )
769  {
771  m_isInitialized = false;
772  }
773 
775  throw( te::rp::Exception )
776  {
777  reset();
778 
779  GeoMosaic::InputParameters const* inputParamsPtr = dynamic_cast<
780  GeoMosaic::InputParameters const* >( &inputParams );
781  TERP_TRUE_OR_THROW( inputParamsPtr, "Invalid paramters pointer" );
782 
783  m_inputParameters = *inputParamsPtr;
784 
785  // Checking the feeder
786 
788  "Invalid m_feederRasterPtr" )
789 
792  "Invalid number of rasters" )
793 
794  // checking m_inputRastersBands
795 
797  ((unsigned int)m_inputParameters.m_inputRastersBands.size()) ==
799  "Bands mismatch" );
800 
801  for( std::vector< std::vector< unsigned int > >::size_type
802  inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
803  m_inputParameters.m_inputRastersBands.size() ; ++inputRastersBandsIdx )
804  {
806  inputRastersBandsIdx ].size() > 0, "Invalid bands number" );
807 
809  inputRastersBandsIdx ].size() == m_inputParameters.m_inputRastersBands[
810  0 ].size(), "Bands number mismatch" );
811  }
812 
813  m_isInitialized = true;
814 
815  return true;
816  }
817 
819  {
820  return m_isInitialized;
821  }
822 
824  const bool& forceNoDataValue,
825  const double& noDataValue,
826  double& mean, double& variance )
827  {
828  mean = 0;
829  variance = 0;
830 
831  double internalNoDataValue = 0;
832  if( forceNoDataValue )
833  internalNoDataValue = noDataValue;
834  else
835  internalNoDataValue = band.getProperty()->m_noDataValue;
836 
837  const unsigned int nCols = band.getProperty()->m_blkw *
838  band.getProperty()->m_nblocksx;
839  const unsigned int nLines = band.getProperty()->m_blkh *
840  band.getProperty()->m_nblocksy;
841 
842  double pixelsNumber = 0;
843  double value = 0;
844  unsigned int col = 0;
845  unsigned int line = 0;
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  mean += value;
855  ++pixelsNumber;
856  }
857  }
858 
859  if( pixelsNumber != 0.0 )
860  {
861  mean /= pixelsNumber;
862 
863  for( line = 0 ; line < nLines ; ++line )
864  for( col = 0 ; col < nCols ; ++col )
865  {
866  band.getValue( col, line, value );
867 
868  if( value != internalNoDataValue )
869  {
870  variance += ( ( value - mean ) * ( value - mean ) ) / pixelsNumber;
871  }
872  }
873 
874  }
875  }
876 
877  } // end namespace rp
878 } // end namespace te
879 
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
bool convert(double *xIn, double *yIn, double *xOut, double *yOut, long numCoord, int coordOffset=1) const
Converts a vector of coordinates from source SRS to target SRS.
Definition: Converter.cpp:211
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:774
AbstractParameters * clone() const
Create a clone copy of this instance.
Definition: GeoMosaic.cpp:109
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:768
double y
y-coordinate.
Definition: Coord2D.h:87
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:331
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:818
A raster band description.
Definition: BandProperty.h:61
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
Definition: GeoMosaic.cpp:163
double x
x-coordinate.
Definition: Coord2D.h:86
Blended pixel value calculation for two overlaped rasters.
Definition: Blender.h:56
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:54
int m_nblocksy
The number of blocks in y.
Definition: BandProperty.h:146
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
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
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:96
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits::max().
Definition: BandProperty.h:136
No blending performed.
Definition: Blender.h:64
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:942
Raster Processing functions.
double getResolutionY() const
Returns the grid vertical (y-axis) resolution.
Definition: Grid.cpp:259
void setSourceSRID(int sourceSRID)
Sets the source SRS identifier.
Definition: Converter.cpp:101
#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:352
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:370
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
void setTargetSRID(int targetSRID)
Sets the target SRS identifier.
Definition: Converter.cpp:156
A RAM cache adaptor to an external existent raster that must always be avaliable. ...
Definition: CachedRaster.h:50
A raster band description.
Definition: Band.h:63
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.
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:823
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.
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
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
Near neighborhood interpolation method.
Definition: Interpolator.h:63
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
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 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 forceInputNoDataValue, 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:169
bool m_useRasterCache
Enable(true) or disable the use of raster caching (default:true).
Definition: GeoMosaic.h:74
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