All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TiePointsMosaic.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/TiePointsMosaic.cpp
22  \brief Create a mosaic from a set of rasters using tie-points.
23 */
24 
25 #include "TiePointsMosaic.h"
26 
27 #include "Macros.h"
28 #include "../raster/Interpolator.h"
29 #include "../raster/Enums.h"
30 #include "../raster/RasterFactory.h"
31 #include "../raster/Grid.h"
32 #include "../raster/Band.h"
33 #include "../raster/BandProperty.h"
34 #include "../raster/PositionIterator.h"
35 #include "../raster/Utils.h"
36 #include "../memory/CachedRaster.h"
37 #include "../geometry/Envelope.h"
38 #include "../geometry/GTFactory.h"
39 #include "../geometry/Polygon.h"
40 #include "../geometry/LinearRing.h"
41 #include "../geometry/MultiPolygon.h"
42 #include "../srs/Converter.h"
43 #include "../common/progress/TaskProgress.h"
44 
45 #include <boost/shared_ptr.hpp>
46 #include <boost/scoped_array.hpp>
47 
48 #include <climits>
49 #include <cfloat>
50 #include <cmath>
51 #include <memory>
52 
53 namespace te
54 {
55  namespace rp
56  {
57 
59  {
60  reset();
61  }
62 
64  {
65  reset();
66  operator=( other );
67  }
68 
70  {
71  reset();
72  }
73 
74  void TiePointsMosaic::InputParameters::reset() throw( te::rp::Exception )
75  {
76  m_feederRasterPtr = 0;
77  m_inputRastersBands.clear();
78  m_tiePoints.clear();
79  m_geomTransfName = "Affine";
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 TiePointsMosaic::InputParameters& params )
92  {
93  reset();
94 
95  m_feederRasterPtr = params.m_feederRasterPtr;
96  m_inputRastersBands = params.m_inputRastersBands;
97  m_tiePoints = params.m_tiePoints;
98  m_geomTransfName = params.m_geomTransfName;
99  m_interpMethod = params.m_interpMethod;
100  m_noDataValue = params.m_noDataValue;
101  m_forceInputNoDataValue = params.m_forceInputNoDataValue;
102  m_blendMethod = params.m_blendMethod;
103  m_autoEqualize = params.m_autoEqualize;
104  m_useRasterCache = params.m_useRasterCache;
105  m_enableProgress = params.m_enableProgress;
106  m_enableMultiThread = params.m_enableMultiThread;
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 
132  void TiePointsMosaic::OutputParameters::reset() throw( te::rp::Exception )
133  {
134  m_rType.clear();
135  m_rInfo.clear();
136  m_outputRasterPtr.reset();
137  }
138 
140  const TiePointsMosaic::OutputParameters& params )
141  {
142  reset();
143 
144  m_rType = params.m_rType;
145  m_rInfo = params.m_rInfo;
146 
147  return *this;
148  }
149 
151  {
152  return new OutputParameters( *this );
153  }
154 
156  {
157  reset();
158  }
159 
161  {
162  }
163 
165  throw( te::rp::Exception )
166  {
167  if( ! m_isInitialized ) return false;
168 
169  TiePointsMosaic::OutputParameters* outParamsPtr = dynamic_cast<
170  TiePointsMosaic::OutputParameters* >( &outputParams );
171  TERP_TRUE_OR_THROW( outParamsPtr, "Invalid paramters" );
172 
173  // progress
174 
175  std::auto_ptr< te::common::TaskProgress > progressPtr;
177  {
178  progressPtr.reset( new te::common::TaskProgress );
179 
180  progressPtr->setTotalSteps( 4 + m_inputParameters.m_feederRasterPtr->getObjsCount() );
181 
182  progressPtr->setMessage( "Mosaic" );
183  }
184 
185  // First pass: getting global mosaic info
186 
187  double mosaicXResolution = 0.0;
188  double mosaicYResolution = 0.0;
189  double mosaicLLX = DBL_MAX; // world coords
190  double mosaicLLY = DBL_MAX; // world coords
191  double mosaicURX = -1.0 * DBL_MAX; // world coords
192  double mosaicURY = -1.0 * DBL_MAX; // world coords
193  int mosaicSRID = 0;
194  std::vector< double > mosaicBandsRangeMin;
195  std::vector< double > mosaicBandsRangeMax;
196  te::rst::BandProperty mosaicBaseBandProperties( 0, 0, "" );
197  std::vector< te::gm::Polygon > rastersBBoxes; // all rasters bounding boxes (under the first raster world coords.
198 
199  {
200  std::vector< boost::shared_ptr< te::gm::GeometricTransformation > >
201  eachRasterPixelToFirstRasterPixelGeomTransfms;
202  // Mapping indexed points from each raster to the first raster indexed points.
203  // te::gm::GTParameters::TiePoint::first are mosaic reaster indexed points (lines/cols),
204  // te::gm::GTParameters::TiePoint::second are the other rasters indexed points (lines/cols).
205 
206  std::vector< te::rst::Grid > rastersGrids; //all rasters original grids under their original SRSs
207 
208  te::gm::Polygon auxPolygon( 0, te::gm::PolygonType, 0 );
209  te::gm::LinearRing* auxLinearRingPtr = 0;
210  te::rst::Raster const* inputRasterPtr = 0;
211  unsigned int inputRasterIdx = 0;
212  te::srs::Converter convInstance;
213  boost::shared_ptr< te::gm::GeometricTransformation > auxTransPtr;
214  te::gm::Coord2D llCoord1;
215  te::gm::Coord2D urCoord1;
216  te::gm::Coord2D llCoord2;
217  te::gm::Coord2D urCoord2;
218 
220  while( ( inputRasterPtr = m_inputParameters.m_feederRasterPtr->getCurrentObj() ) )
221  {
224  inputRasterPtr->getAccessPolicy() & te::common::RAccess,
225  "Invalid raster" );
226 
227  rastersGrids.push_back( (*inputRasterPtr->getGrid()) );
228 
229  // Defining the base mosaic info
230 
231  if( inputRasterIdx == 0 )
232  {
233  mosaicXResolution = inputRasterPtr->getGrid()->getResolutionX();
234  mosaicYResolution = inputRasterPtr->getGrid()->getResolutionY();
235 
236  mosaicLLX = inputRasterPtr->getGrid()->getExtent()->m_llx;
237  mosaicLLY = inputRasterPtr->getGrid()->getExtent()->m_lly;
238  mosaicURX = inputRasterPtr->getGrid()->getExtent()->m_urx;
239  mosaicURY = inputRasterPtr->getGrid()->getExtent()->m_ury;
240 
241  mosaicSRID = inputRasterPtr->getGrid()->getSRID();
242 
243  mosaicBaseBandProperties = *inputRasterPtr->getBand( 0 )->getProperty();
244 
245  // finding the current raster bounding box polygon (first raster world coordinates)
246 
247  auxPolygon.clear();
248  auxLinearRingPtr = new te::gm::LinearRing(5, te::gm::LineStringType);
249  auxLinearRingPtr->setPoint( 0, mosaicLLX, mosaicURY );
250  auxLinearRingPtr->setPoint( 1, mosaicURX, mosaicURY );
251  auxLinearRingPtr->setPoint( 2, mosaicURX, mosaicLLY );
252  auxLinearRingPtr->setPoint( 3, mosaicLLX, mosaicLLY );
253  auxLinearRingPtr->setPoint( 4, mosaicLLX, mosaicURY );
254  auxPolygon.push_back( auxLinearRingPtr );
255  auxPolygon.setSRID( mosaicSRID );
256  rastersBBoxes.push_back( auxPolygon );
257  }
258  else
259  {
260  te::gm::GTParameters transParams;
261 
262  if( ( inputRasterIdx == 1 ) ||
264  {
265  transParams.m_tiePoints = m_inputParameters.m_tiePoints[ inputRasterIdx - 1 ];
266  }
267  else
268  {
269  // converting the current tie-points to map coords from the
270  // current raster to the first one
271 
273  const std::vector< te::gm::GTParameters::TiePoint >& inputTPs =
274  m_inputParameters.m_tiePoints[ inputRasterIdx - 1 ];
275  const unsigned int inputTPsSize = inputTPs.size();
276  const te::gm::GeometricTransformation& lastTransf =
277  (*eachRasterPixelToFirstRasterPixelGeomTransfms[ inputRasterIdx - 2 ].get());
278 
279  for( unsigned int inputTPsIdx = 0 ; inputTPsIdx < inputTPsSize ;
280  ++inputTPsIdx )
281  {
282  auxTP.second = inputTPs[ inputTPsIdx ].second;
283  lastTransf.inverseMap( inputTPs[ inputTPsIdx ].first, auxTP.first );
284  transParams.m_tiePoints.push_back( auxTP );
285  }
286  }
287 
288  auxTransPtr.reset( te::gm::GTFactory::make(
290  TERP_TRUE_OR_RETURN_FALSE( auxTransPtr.get() != 0,
291  "Geometric transformation instatiation error" );
292  TERP_TRUE_OR_RETURN_FALSE( auxTransPtr->initialize( transParams ),
293  "Geometric transformation parameters calcule error" );
294  eachRasterPixelToFirstRasterPixelGeomTransfms.push_back( auxTransPtr );
295 
296  // current raster corner coords (line/column)
297 
298  urCoord2.x = ((double)inputRasterPtr->getGrid()->getNumberOfColumns())
299  - 1.0;
300  urCoord2.y = 0.0;
301  llCoord2.x = 0.0;
302  llCoord2.y = ((double)inputRasterPtr->getGrid()->getNumberOfRows())
303  - 1.0;
304 
305  // current raster corner coords (line/column) over the
306  // first raster coords system (lines/columns)
307 
308  auxTransPtr->inverseMap( urCoord2, urCoord1 );
309  auxTransPtr->inverseMap( llCoord2, llCoord1 );
310 
311  // the respective coords in world space (first raster)
312 
313  rastersGrids[ 0 ].gridToGeo( urCoord1.x, urCoord1.y, urCoord2.x,
314  urCoord2.y );
315  rastersGrids[ 0 ].gridToGeo( llCoord1.x, llCoord1.y, llCoord2.x,
316  llCoord2.y );
317 
318  // expanding mosaic area
319 
320  mosaicLLX = std::min( mosaicLLX, urCoord2.x );
321  mosaicLLX = std::min( mosaicLLX, llCoord2.x );
322 
323  mosaicLLY = std::min( mosaicLLY, urCoord2.y );
324  mosaicLLY = std::min( mosaicLLY, llCoord2.y );
325 
326  mosaicURX = std::max( mosaicURX, urCoord2.x );
327  mosaicURX = std::max( mosaicURX, llCoord2.x );
328 
329  mosaicURY = std::max( mosaicURY, urCoord2.y );
330  mosaicURY = std::max( mosaicURY, llCoord2.y );
331 
332  // finding the current raster bounding box polygon (first raster world coordinates)
333 
334  auxPolygon.clear();
335  auxLinearRingPtr = new te::gm::LinearRing(5, te::gm::LineStringType);
336  auxLinearRingPtr->setPoint( 0, llCoord2.x, urCoord2.y );
337  auxLinearRingPtr->setPoint( 1, urCoord2.x, urCoord2.y );
338  auxLinearRingPtr->setPoint( 2, urCoord2.x, llCoord2.y );
339  auxLinearRingPtr->setPoint( 3, llCoord2.x, llCoord2.y );
340  auxLinearRingPtr->setPoint( 4, llCoord2.x, urCoord2.y );
341  auxPolygon.push_back( auxLinearRingPtr );
342  auxPolygon.setSRID( mosaicSRID );
343  rastersBBoxes.push_back( auxPolygon );
344  }
345 
346  // checking the input bands
347 
348  for( std::vector< unsigned int >::size_type inputRastersBandsIdx = 0 ;
349  inputRastersBandsIdx <
350  m_inputParameters.m_inputRastersBands[ inputRasterIdx ].size() ;
351  ++inputRastersBandsIdx )
352  {
353  const unsigned int& currBand =
354  m_inputParameters.m_inputRastersBands[ inputRasterIdx ][ inputRastersBandsIdx ];
355 
356  TERP_TRUE_OR_RETURN_FALSE( currBand < inputRasterPtr->getNumberOfBands(),
357  "Invalid band" )
358  }
359 
360 
362  }
363 
364 
365  }
366 
368  {
369  progressPtr->pulse();
370  if( ! progressPtr->isActive() ) return false;
371  }
372 
373  // creating the output raster
374 
375  te::rst::Raster* outputRasterPtr = 0;
376 
377  {
378  mosaicBandsRangeMin.resize(
379  m_inputParameters.m_inputRastersBands[ 0 ].size(), 0 );
380  mosaicBandsRangeMax.resize(
381  m_inputParameters.m_inputRastersBands[ 0 ].size(), 0 );
382 
383  std::vector< te::rst::BandProperty* > bandsProperties;
384  for( std::vector< unsigned int >::size_type bandIdx = 0 ; bandIdx <
385  m_inputParameters.m_inputRastersBands[ 0 ].size() ; ++bandIdx )
386  {
387  bandsProperties.push_back( new te::rst::BandProperty( mosaicBaseBandProperties ) );
388  bandsProperties[ bandIdx ]->m_colorInterp = te::rst::GrayIdxCInt;
389  bandsProperties[ bandIdx ]->m_noDataValue = m_inputParameters.m_noDataValue;
390 
391  te::rst::GetDataTypeRanges( bandsProperties[ bandIdx ]->m_type,
392  mosaicBandsRangeMin[ bandIdx ],
393  mosaicBandsRangeMax[ bandIdx ]);
394  }
395 
396  te::rst::Grid* outputGrid = new te::rst::Grid( mosaicXResolution,
397  mosaicYResolution, new te::gm::Envelope( mosaicLLX, mosaicLLY, mosaicURX,
398  mosaicURY ), mosaicSRID );
399 
400  outParamsPtr->m_outputRasterPtr.reset(
402  outParamsPtr->m_rType,
403  outputGrid,
404  bandsProperties,
405  outParamsPtr->m_rInfo,
406  0,
407  0 ) );
408  TERP_TRUE_OR_RETURN_FALSE( outParamsPtr->m_outputRasterPtr.get(),
409  "Output raster creation error" );
410 
411  outputRasterPtr = outParamsPtr->m_outputRasterPtr.get();
412  }
413 
414  std::auto_ptr< te::mem::CachedRaster > cachedOutputRasterInstancePtr;
415 
417  {
418  cachedOutputRasterInstancePtr.reset( new te::mem::CachedRaster(
419  *(outParamsPtr->m_outputRasterPtr.get()), 25, 0 ) );
420 
421  outputRasterPtr = cachedOutputRasterInstancePtr.get();
422  }
423 
425  {
426  progressPtr->pulse();
427  if( ! progressPtr->isActive() ) return false;
428  }
429 
430  // Finding the transformation mapping indexed points from each raster to the first raster indexed points.
431  // te::gm::GTParameters::TiePoint::first are mosaic reaster indexed points (lines/cols),
432  // te::gm::GTParameters::TiePoint::second are the other rasters indexed points (lines/cols).
433 
434  std::vector< boost::shared_ptr< te::gm::GeometricTransformation > >
435  eachRasterPixelToMosaicRasterPixelGeomTransfms;
436 
437  {
438  const double firstRasterColOffset = std::abs( rastersBBoxes[ 0 ].getMBR()->m_llx -
439  outParamsPtr->m_outputRasterPtr->getGrid()->getExtent()->getLowerLeftX() ) /
440  outParamsPtr->m_outputRasterPtr->getGrid()->getResolutionX();
441  const double firstRasterLinOffset = std::abs( rastersBBoxes[ 0 ].getMBR()->m_ury -
442  outParamsPtr->m_outputRasterPtr->getGrid()->getExtent()->getUpperRightY() ) /
443  outParamsPtr->m_outputRasterPtr->getGrid()->getResolutionY();
444 
445  for( unsigned int tiePointsIdx = 0 ; tiePointsIdx < m_inputParameters.m_tiePoints.size() ;
446  ++tiePointsIdx )
447  {
448  te::gm::GTParameters transfParams;
449  transfParams.m_tiePoints = m_inputParameters.m_tiePoints[ tiePointsIdx ];
450 
451  const double prevRasterColOffset = std::abs( rastersBBoxes[ tiePointsIdx ].getMBR()->m_llx -
452  outParamsPtr->m_outputRasterPtr->getGrid()->getExtent()->getLowerLeftX() ) /
453  outParamsPtr->m_outputRasterPtr->getGrid()->getResolutionX();
454  const double prevRasterLinOffset = std::abs( rastersBBoxes[ tiePointsIdx ].getMBR()->m_ury -
455  outParamsPtr->m_outputRasterPtr->getGrid()->getExtent()->getUpperRightY() ) /
456  outParamsPtr->m_outputRasterPtr->getGrid()->getResolutionY();
457 
458  for( unsigned int tpIdx = 0 ; tpIdx < transfParams.m_tiePoints.size() ;
459  ++tpIdx )
460  {
462  {
463  transfParams.m_tiePoints[ tpIdx ].first.x += firstRasterColOffset;
464  transfParams.m_tiePoints[ tpIdx ].first.y += firstRasterLinOffset;
465  }
466  else
467  {
468  transfParams.m_tiePoints[ tpIdx ].first.x += prevRasterColOffset;
469  transfParams.m_tiePoints[ tpIdx ].first.y += prevRasterLinOffset;
470  }
471  }
472 
473  boost::shared_ptr< te::gm::GeometricTransformation > auxTransPtr(
475  TERP_TRUE_OR_RETURN_FALSE( auxTransPtr.get() != 0,
476  "Geometric transformation instatiation error" );
477  TERP_TRUE_OR_RETURN_FALSE( auxTransPtr->initialize( transfParams ),
478  "Geometric transformation parameters calcule error" );
479  eachRasterPixelToMosaicRasterPixelGeomTransfms.push_back( auxTransPtr );
480  }
481  }
482 
484  {
485  progressPtr->pulse();
486  if( ! progressPtr->isActive() ) return false;
487  }
488 
489  // fill output with no data values
490 
491  {
492  const unsigned int nBands = outputRasterPtr->getNumberOfBands();
493  const unsigned int nRows = outputRasterPtr->getNumberOfRows();
494  const unsigned int nCols = outputRasterPtr->getNumberOfColumns();
495  unsigned int col = 0;
496  unsigned int row = 0;
497  unsigned int bandIdx = 0;
498 
499  for( bandIdx = 0 ; bandIdx < nBands ; ++bandIdx )
500  {
501  te::rst::Band& outBand = ( *( outputRasterPtr->getBand( bandIdx ) ) );
502 
503  for( row = 0 ; row < nRows ; ++row )
504  {
505  for( col = 0 ; col < nCols ; ++col )
506  {
507  outBand.setValue( col, row, m_inputParameters.m_noDataValue );
508  }
509  }
510  }
511  }
512 
514  {
515  progressPtr->pulse();
516  if( ! progressPtr->isActive() ) return false;
517  }
518 
519  // Copying the first image data to the output mosaic
520  // and find the base mosaic mean and offset values
521 
522  std::vector< double > mosaicTargetMeans( outputRasterPtr->getNumberOfBands(), 0 );
523  std::vector< double > mosaicTargetVariances( outputRasterPtr->getNumberOfBands(), 0 );
524 
525  {
527 
528  te::rst::Raster const* inputRasterPtr =
530  TERP_DEBUG_TRUE_OR_RETURN_FALSE( inputRasterPtr, "Invalid raster pointer" );
531 
532  double inXStartGeo = 0;
533  double inYStartGeo = 0;
534  inputRasterPtr->getGrid()->gridToGeo( 0.0, 0.0, inXStartGeo, inYStartGeo );
535  double outRowStartDouble = 0;
536  double outColStartDouble = 0;
537  outputRasterPtr->getGrid()->geoToGrid( inXStartGeo, inYStartGeo,
538  outColStartDouble, outRowStartDouble );
539 
540  const unsigned int outRowStart = (unsigned int)std::max( 0.0, outRowStartDouble );
541  const unsigned int outColStart = (unsigned int)std::max( 0.0, outColStartDouble );
542  const unsigned int outRowsBound = std::min( outRowStart +
543  inputRasterPtr->getNumberOfRows(),
544  outputRasterPtr->getNumberOfRows() );
545  const unsigned int outColsBound = std::min( outColStart +
546  inputRasterPtr->getNumberOfColumns(),
547  outputRasterPtr->getNumberOfColumns() );
548 
549  const unsigned int nBands = (unsigned int)
551  unsigned int outCol = 0;
552  unsigned int outRow = 0;
553  double inCol = 0;
554  double inRow = 0;
555  double bandNoDataValue = -1.0 * DBL_MAX;
556  std::complex< double > pixelCValue = 0;
557  te::rst::Interpolator interpInstance( inputRasterPtr,
559  unsigned int inputBandIdx = 0;
560 
561  for( unsigned int inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
562  nBands ; ++inputRastersBandsIdx )
563  {
564  inputBandIdx = m_inputParameters.m_inputRastersBands[ 0 ][
565  inputRastersBandsIdx ] ;
566  bandNoDataValue = m_inputParameters.m_forceInputNoDataValue ?
567  m_inputParameters.m_noDataValue : inputRasterPtr->getBand( inputBandIdx
569  te::rst::Band& outBand =
570  (*outputRasterPtr->getBand( inputRastersBandsIdx ));
571  unsigned int validPixelsNumber = 0;
572 
573  double& mean = mosaicTargetMeans[ inputRastersBandsIdx ];
574  mean = 0;
575 
576  for( outRow = outRowStart ; outRow < outRowsBound ; ++outRow )
577  {
578  inRow = ((double)outRow) - outRowStartDouble;
579 
580  for( outCol = outColStart ; outCol < outColsBound ; ++outCol )
581  {
582  inCol = ((double)outCol) - outColStartDouble;
583 
584  interpInstance.getValue( inCol, inRow, pixelCValue, inputBandIdx );
585 
586  if( pixelCValue.real() != bandNoDataValue )
587  {
588  outBand.setValue( outCol, outRow, pixelCValue );
589  mean += pixelCValue.real();
590  ++validPixelsNumber;
591  }
592  }
593  }
594 
595  mean /= ( (double)validPixelsNumber );
596 
597  // variance calcule
598 
600  {
601  double& variance = mosaicTargetVariances[ inputRastersBandsIdx ];
602  variance = 0;
603 
604  double pixelValue = 0;
605 
606  for( outRow = outRowStart ; outRow < outRowsBound ; ++outRow )
607  {
608  for( outCol = outColStart ; outCol < outColsBound ; ++outCol )
609  {
610  outBand.getValue( outCol, outRow, pixelValue );
611 
612  if( pixelValue != m_inputParameters.m_noDataValue )
613  {
614  variance += ( ( pixelValue - mean ) * ( pixelValue -
615  mean ) ) / ( (double)validPixelsNumber );
616  }
617  }
618  }
619  }
620  }
621  }
622 
624  {
625  progressPtr->pulse();
626  if( ! progressPtr->isActive() ) return false;
627  }
628 
629  // Initiating the mosaic bounding boxes union
630 
631  std::auto_ptr< te::gm::MultiPolygon > mosaicBBoxesUnionPtr(
633  rastersBBoxes[ 0 ].getSRID(), 0 ) );
634 
635  mosaicBBoxesUnionPtr->add( (te::gm::Polygon*)( rastersBBoxes[ 0 ].clone() ) );
636 
637  // globals
638 
639  std::vector< unsigned int > outputRasterBands;
640  std::vector< double > dummyRasterOffsets;
641  std::vector< double > dummyRasterScales;
642  for( unsigned int outputRasterBandsIdx = 0 ; outputRasterBandsIdx <
643  outputRasterPtr->getNumberOfBands() ; ++outputRasterBandsIdx )
644  {
645  outputRasterBands.push_back( outputRasterBandsIdx );
646  dummyRasterOffsets.push_back( 0.0 );
647  dummyRasterScales.push_back( 1.0 );
648  }
649 
650  // iterating over the other rasters
651 
652  te::rst::Raster const* nonCachedInputRasterPtr = 0;
653 
656 
657  while( ( nonCachedInputRasterPtr = m_inputParameters.m_feederRasterPtr->getCurrentObj() ) )
658  {
659  const unsigned int inputRasterIdx = m_inputParameters.m_feederRasterPtr->getCurrentOffset();
660 
661  te::rst::Raster const* inputRasterPtr = nonCachedInputRasterPtr;
662 
663  std::auto_ptr< te::mem::CachedRaster > cachedInputRasterPtr;
665  {
666  cachedInputRasterPtr.reset( new te::mem::CachedRaster(
667  *nonCachedInputRasterPtr, 25, 0 ) );
668  inputRasterPtr = cachedInputRasterPtr.get();
669  }
670 
671  // Generating the offset and gain info for eath band from the current raster
672 
673  std::vector< double > currentRasterBandsOffsets;
674  std::vector< double > currentRasterBandsScales;
675 
677  {
678  double currentRasterVariance = 0;
679  double currentRasterMean = 0;
680 
681  for( unsigned int inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
682  m_inputParameters.m_inputRastersBands[ inputRasterIdx ].size() ;
683  ++inputRastersBandsIdx )
684  {
685  const unsigned int inputBandIdx = m_inputParameters.m_inputRastersBands[ inputRasterIdx ][
686  inputRastersBandsIdx ];
687 
688  calcBandStatistics( (*inputRasterPtr->getBand( inputBandIdx ) ),
691  currentRasterMean,
692  currentRasterVariance );
693 
694  currentRasterBandsScales.push_back( std::sqrt( mosaicTargetVariances[ inputRastersBandsIdx ] /
695  currentRasterVariance ) );
696  currentRasterBandsOffsets.push_back( mosaicTargetMeans[ inputRastersBandsIdx ] -
697  ( currentRasterBandsScales[ inputRastersBandsIdx ] * currentRasterMean ) );
698  }
699  }
700  else
701  {
702  currentRasterBandsOffsets = dummyRasterOffsets;
703  currentRasterBandsScales = dummyRasterScales;
704  }
705 
706  // blending with the mosaic boxes union
707 
708  te::rp::Blender blenderInstance;
709 
710  TERP_TRUE_OR_RETURN_FALSE( blenderInstance.initialize(
711  *outputRasterPtr,
712  outputRasterBands,
713  *inputRasterPtr,
714  m_inputParameters.m_inputRastersBands[ inputRasterIdx ],
720  dummyRasterOffsets,
721  dummyRasterScales,
722  currentRasterBandsOffsets,
723  currentRasterBandsScales,
724  mosaicBBoxesUnionPtr.get(),
725  0,
726  *( eachRasterPixelToMosaicRasterPixelGeomTransfms[ inputRasterIdx - 1 ] ),
728  false ),
729  "Blender initiazing error" );
730 
731  TERP_TRUE_OR_RETURN_FALSE( blenderInstance.blendIntoRaster1(),
732  "Error blending images" );
733 
734 
735  // updating the mosaic related polygons
736 
737  {
738  // union of the current raster box with the current mosaic valid area under the mosaic SRID
739 
740  std::auto_ptr< te::gm::Geometry > unionMultiPolPtr;
741  unionMultiPolPtr.reset( mosaicBBoxesUnionPtr->Union(
742  &( rastersBBoxes[ inputRasterIdx ] ) ) );
743  TERP_TRUE_OR_RETURN_FALSE( unionMultiPolPtr.get(), "Invalid pointer" );
744  unionMultiPolPtr->setSRID( mosaicBBoxesUnionPtr->getSRID() );
745 
746  if( unionMultiPolPtr->getGeomTypeId() == te::gm::MultiPolygonType )
747  {
748  mosaicBBoxesUnionPtr.reset( (te::gm::MultiPolygon*)unionMultiPolPtr.release() );
749  }
750  else if( unionMultiPolPtr->getGeomTypeId() == te::gm::PolygonType )
751  {
753  unionMultiPolPtr->getSRID(), 0 );
754  mPolPtr->add( (te::gm::Polygon*)unionMultiPolPtr.release() );
755  mosaicBBoxesUnionPtr.reset( mPolPtr );
756  }
757  else
758  {
759  TERP_LOG_AND_RETURN_FALSE( "Invalid union geometry type" );
760  }
761  }
762 
763  // moving to the next raster
764 
765  cachedInputRasterPtr.reset();
766 
768 
770  {
771  progressPtr->pulse();
772  if( ! progressPtr->isActive() ) return false;
773  }
774  }
775 
776  return true;
777  }
778 
779  void TiePointsMosaic::reset() throw( te::rp::Exception )
780  {
782  m_isInitialized = false;
783  }
784 
786  throw( te::rp::Exception )
787  {
788  reset();
789 
790  TiePointsMosaic::InputParameters const* inputParamsPtr = dynamic_cast<
791  TiePointsMosaic::InputParameters const* >( &inputParams );
792  TERP_TRUE_OR_THROW( inputParamsPtr, "Invalid paramters pointer" );
793 
794  m_inputParameters = *inputParamsPtr;
795 
796  // Checking the feeder
797 
799  "Invalid m_feederRasterPtr" )
800 
803  "Invalid number of rasters" )
804 
805  // checking m_inputRastersBands
806 
808  ((unsigned int)m_inputParameters.m_inputRastersBands.size()) ==
810  "Bands mismatch" );
811 
812  for( std::vector< std::vector< unsigned int > >::size_type
813  inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
814  m_inputParameters.m_inputRastersBands.size() ; ++inputRastersBandsIdx )
815  {
817  inputRastersBandsIdx ].size() > 0, "Invalid bands number" );
818 
820  inputRastersBandsIdx ].size() == m_inputParameters.m_inputRastersBands[
821  0 ].size(), "Bands number mismatch" );
822  }
823 
824  // checking other parameters
825 
827  ( m_inputParameters.m_tiePoints.size() ==
829  "Bands mismatch" );
830 
831  m_isInitialized = true;
832 
833  return true;
834  }
835 
837  {
838  return m_isInitialized;
839  }
840 
842  const bool& forceNoDataValue,
843  const double& noDataValue,
844  double& mean, double& variance )
845  {
846  mean = 0;
847  variance = 0;
848 
849  double internalNoDataValue = 0;
850  if( forceNoDataValue )
851  internalNoDataValue = noDataValue;
852  else
853  internalNoDataValue = band.getProperty()->m_noDataValue;
854 
855  const unsigned int nCols = band.getProperty()->m_blkw *
856  band.getProperty()->m_nblocksx;
857  const unsigned int nLines = band.getProperty()->m_blkh *
858  band.getProperty()->m_nblocksy;
859 
860  double pixelsNumber = 0;
861  double value = 0;
862  unsigned int col = 0;
863  unsigned int line = 0;
864 
865  for( line = 0 ; line < nLines ; ++line )
866  for( col = 0 ; col < nCols ; ++col )
867  {
868  band.getValue( col, line, value );
869 
870  if( value != internalNoDataValue )
871  {
872  mean += value;
873  ++pixelsNumber;
874  }
875  }
876 
877  if( pixelsNumber != 0.0 )
878  {
879  mean /= pixelsNumber;
880 
881  for( line = 0 ; line < nLines ; ++line )
882  for( col = 0 ; col < nCols ; ++col )
883  {
884  band.getValue( col, line, value );
885 
886  if( value != internalNoDataValue )
887  {
888  variance += ( ( value - mean ) * ( value - mean ) ) / pixelsNumber;
889  }
890  }
891 
892  }
893  }
894 
895  } // end namespace rp
896 } // end namespace te
897 
virtual unsigned int getObjsCount() const =0
Return the total number of feeder objects.
unsigned int getNumberOfRows() const
Returns the grid number of rows.
Definition: Grid.cpp:209
bool m_autoEqualize
Auto equalization will be performed using the overlaped image areas (default:true).
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
std::map< std::string, std::string > m_rInfo
The necessary information to create the output rasters (as described in te::raster::RasterFactory).
const OutputParameters & operator=(const OutputParameters &params)
te::rp::Blender::BlendMethod m_blendMethod
The pixel blending method (default: NoBlendMethod).
std::vector< TiePoint > m_tiePoints
Tie points.
Definition: GTParameters.h:95
double y
y-coordinate.
Definition: Coord2D.h:87
AbstractParameters * clone() const
Create a clone copy of this instance.
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 reset()
Clear all internal allocated objects and reset the algorithm to its initial state.
void setSRID(int srid)
It sets the Spatial Reference System ID of the geometry and all its parts if it is a GeometryCollecti...
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
bool m_enableProgress
Enable/Disable the progress interface (default:false).
A raster band description.
Definition: BandProperty.h:61
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
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.
Tie-points linking any raster to the first sequence raster (te::gm::GTParameters::TiePoint::first are...
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
AbstractParameters * clone() const
Create a clone copy of this instance.
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
double m_noDataValue
The pixel value used where no raster data is avaliable (defaul:0).
static void calcBandStatistics(const te::rst::Band &band, const bool &forceNoDataValue, const double &noDataValue, double &mean, double &variance)
Raster band statistics calcule.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
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
2D Geometric transformation base class.
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits::max().
Definition: BandProperty.h:136
bool m_isInitialized
Tells if this instance is initialized.
No blending performed.
Definition: Blender.h:64
std::pair< Coord2D, Coord2D > TiePoint
Tie point type definition.
Definition: GTParameters.h:59
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 m_enableMultiThread
Enable/disable the use of threads (default:true).
bool blendIntoRaster1()
Execute blending of the given input rasters and write the result into raster1.
Definition: Blender.cpp:942
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
std::vector< std::vector< unsigned int > > m_inputRastersBands
Bands to process for each input raster.
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
std::vector< std::vector< te::gm::GTParameters::TiePoint > > m_tiePoints
Tie-points between each adjacent raster pair (te::gm::GTParameters::TiePoint::first are raster (with ...
TiePointsLinkType m_tiePointsLinkType
The given tie points linking type, see TiePointsLinkType.
FeederConstRaster * m_feederRasterPtr
Input rasters feeder.
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
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
const InputParameters & operator=(const InputParameters &params)
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Definition: Raster.cpp:208
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.
unsigned int getNumberOfColumns() const
Returns the grid number of columns.
Definition: Grid.cpp:193
double getResolutionX() const
Returns the grid horizontal (x-axis) resolution.
Definition: Grid.cpp:253
A RAM cache adaptor to an external existent raster that must always be avaliable. ...
Definition: CachedRaster.h:50
std::string m_rType
Output raster data source type (as described in te::raster::RasterFactory ).
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
bool m_useRasterCache
Enable(true) or disable the use of raster caching (default:true).
Abstract parameters base interface.
#define TERP_LOG_AND_RETURN_FALSE(message)
Logs a warning message will and return false.
Definition: Macros.h:236
bool isInitialized() const
Returns true if the algorithm instance is initialized and ready for execution.
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
std::string m_geomTransfName
The name of the geometric transformation used if tie-points are supplied (see each te::gm::GTFactory ...
void add(Geometry *g)
It adds the geometry into the collection.
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: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
std::auto_ptr< te::rst::Raster > m_outputRasterPtr
The generated output mosaic raster.
Raster Processing algorithm input parameters base interface.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
2D Geometric transformation parameters.
Definition: GTParameters.h:50
Create a mosaic from a set of rasters using tie-points.
TiePointsMosaic::InputParameters m_inputParameters
Input execution parameters.
virtual bool moveNext()=0
Advances to the next sequence obeject.
int m_blkh
Block height (pixels).
Definition: BandProperty.h:144
Near neighborhood interpolation method.
Definition: Interpolator.h:63
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
bool m_forceInputNoDataValue
If true, m_noDataValue will be used as the no-data value for input rasters (defalt:false).
virtual void inverseMap(const GTParameters &params, const double &pt2X, const double &pt2Y, double &pt1X, double &pt1Y) const =0
Inverse mapping (from pt2 space into pt1 space).
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
te::rst::Interpolator::Method m_interpMethod
The raster interpolator method (default:NearestNeighbor).