TiePointsMosaic.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/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 "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_ptr.hpp>
47 #include <boost/scoped_array.hpp>
48 
49 #include <climits>
50 #include <cfloat>
51 #include <cmath>
52 #include <memory>
53 
54 namespace te
55 {
56  namespace rp
57  {
58 
60  {
61  reset();
62  }
63 
65  {
66  reset();
67  operator=( other );
68  }
69 
71  {
72  reset();
73  }
74 
76  {
77  m_feederRasterPtr = nullptr;
78  m_inputRastersBands.clear();
79  m_tiePoints.clear();
80  m_geomTransfName = "Affine";
82  m_noDataValue = 0.0;
85  m_autoEqualize = true;
86  m_useRasterCache = true;
87  m_enableProgress = false;
88  m_enableMultiThread = true;
89  }
90 
92  const TiePointsMosaic::InputParameters& params )
93  {
94  reset();
95 
98  m_tiePoints = params.m_tiePoints;
101  m_noDataValue = params.m_noDataValue;
103  m_blendMethod = params.m_blendMethod;
108 
109  return *this;
110  }
111 
113  {
114  return new InputParameters( *this );
115  }
116 
118  {
119  reset();
120  }
121 
123  {
124  reset();
125  operator=( other );
126  }
127 
129  {
130  reset();
131  }
132 
134  {
135  m_rType.clear();
136  m_rInfo.clear();
137  m_outputRasterPtr.reset();
138  }
139 
141  const TiePointsMosaic::OutputParameters& params )
142  {
143  reset();
144 
145  m_rType = params.m_rType;
146  m_rInfo = params.m_rInfo;
147 
148  return *this;
149  }
150 
152  {
153  return new OutputParameters( *this );
154  }
155 
157  {
158  reset();
159  }
160 
162 
164  throw( te::rp::Exception )
165  {
166  if( ! m_isInitialized ) return false;
167 
168  TiePointsMosaic::OutputParameters* outParamsPtr = dynamic_cast<
169  TiePointsMosaic::OutputParameters* >( &outputParams );
170  TERP_TRUE_OR_THROW( outParamsPtr, "Invalid paramters" );
171 
172  // progress
173 
174  std::unique_ptr< te::common::TaskProgress > progressPtr;
176  {
177  progressPtr.reset( new te::common::TaskProgress );
178 
179  progressPtr->setTotalSteps( 4 + m_inputParameters.m_feederRasterPtr->getObjsCount() );
180 
181  progressPtr->setMessage( "Mosaic" );
182  }
183 
184  // First pass: getting global mosaic info
185 
186  double mosaicXResolution = 0.0;
187  double mosaicYResolution = 0.0;
188  double mosaicLLX = DBL_MAX; // world coords
189  double mosaicLLY = DBL_MAX; // world coords
190  double mosaicURX = -1.0 * DBL_MAX; // world coords
191  double mosaicURY = -1.0 * DBL_MAX; // world coords
192  int mosaicSRID = 0;
193  std::vector< double > mosaicBandsRangeMin;
194  std::vector< double > mosaicBandsRangeMax;
195  te::rst::BandProperty mosaicBaseBandProperties( 0, 0, "" );
196  std::vector< te::gm::Polygon > rastersBBoxes; // all rasters bounding boxes (under the first raster world coords.
197 
198  {
199  std::vector< boost::shared_ptr< te::gm::GeometricTransformation > >
200  eachRasterPixelToFirstRasterPixelGeomTransfms;
201  // Mapping indexed points from each raster to the first raster indexed points.
202  // te::gm::GTParameters::TiePoint::first are mosaic reaster indexed points (lines/cols),
203  // te::gm::GTParameters::TiePoint::second are the other rasters indexed points (lines/cols).
204 
205  std::vector< te::rst::Grid > rastersGrids; //all rasters original grids under their original SRSs
206 
207  te::rst::Raster const* inputRasterPtr = nullptr;
208  unsigned int inputRasterIdx = 0;
209  te::srs::Converter convInstance;
210 
212  while( ( inputRasterPtr = m_inputParameters.m_feederRasterPtr->getCurrentObj() ) )
213  {
216  inputRasterPtr->getAccessPolicy() & te::common::RAccess,
217  "Invalid raster" );
218 
219  rastersGrids.push_back( (*inputRasterPtr->getGrid()) );
220 
221  // Defining the base mosaic info
222 
223  if( inputRasterIdx == 0 )
224  {
225  mosaicXResolution = inputRasterPtr->getGrid()->getResolutionX();
226  mosaicYResolution = inputRasterPtr->getGrid()->getResolutionY();
227 
228  mosaicLLX = inputRasterPtr->getGrid()->getExtent()->m_llx;
229  mosaicLLY = inputRasterPtr->getGrid()->getExtent()->m_lly;
230  mosaicURX = inputRasterPtr->getGrid()->getExtent()->m_urx;
231  mosaicURY = inputRasterPtr->getGrid()->getExtent()->m_ury;
232 
233  mosaicSRID = inputRasterPtr->getGrid()->getSRID();
234 
235  mosaicBaseBandProperties = *inputRasterPtr->getBand( 0 )->getProperty();
236 
237  // finding the current raster bounding box polygon (first raster world coordinates)
238 
240  auxLinearRingPtr->setPoint( 0, mosaicLLX, mosaicURY );
241  auxLinearRingPtr->setPoint( 1, mosaicURX, mosaicURY );
242  auxLinearRingPtr->setPoint( 2, mosaicURX, mosaicLLY );
243  auxLinearRingPtr->setPoint( 3, mosaicLLX, mosaicLLY );
244  auxLinearRingPtr->setPoint( 4, mosaicLLX, mosaicURY );
245  auxLinearRingPtr->setSRID( mosaicSRID );
246 
247  te::gm::Polygon auxPolygon( 0, te::gm::PolygonType, 0 );
248  auxPolygon.push_back( auxLinearRingPtr );
249  auxPolygon.setSRID( mosaicSRID );
250  rastersBBoxes.push_back( auxPolygon );
251  }
252  else
253  {
254  te::gm::GTParameters transParams;
255 
256  if( ( inputRasterIdx == 1 ) ||
258  {
259  transParams.m_tiePoints = m_inputParameters.m_tiePoints[ inputRasterIdx - 1 ];
260  }
261  else
262  {
263  // converting the current tie-points to map coords from the
264  // current raster to the first one
265 
267  const std::vector< te::gm::GTParameters::TiePoint >& inputTPs =
268  m_inputParameters.m_tiePoints[ inputRasterIdx - 1 ];
269  const unsigned int inputTPsSize = static_cast<unsigned int>(inputTPs.size());
270  const te::gm::GeometricTransformation& lastTransf =
271  (*eachRasterPixelToFirstRasterPixelGeomTransfms[ inputRasterIdx - 2 ].get());
272 
273  for( unsigned int inputTPsIdx = 0 ; inputTPsIdx < inputTPsSize ;
274  ++inputTPsIdx )
275  {
276  auxTP.second = inputTPs[ inputTPsIdx ].second;
277  lastTransf.inverseMap( inputTPs[ inputTPsIdx ].first, auxTP.first );
278  transParams.m_tiePoints.push_back( auxTP );
279  }
280  }
281 
282  // The transformation
283  // inverse mapping current raster lines/cols into the first raster lines/cols.
284 
285  boost::shared_ptr< te::gm::GeometricTransformation > auxTransPtr(
287  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( auxTransPtr.get() != nullptr,
288  "Geometric transformation instatiation error" );
289  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( auxTransPtr->initialize( transParams ),
290  "Geometric transformation parameters calcule error" );
291  eachRasterPixelToFirstRasterPixelGeomTransfms.push_back( auxTransPtr );
292 
293  // The indexed detailed extent of input raster
294 
295  te::gm::LinearRing inRasterIndexedDetailedExtent( te::gm::LineStringType, 0, nullptr );
297  *inputRasterPtr->getGrid(), inRasterIndexedDetailedExtent ),
298  "Error creating the raster detailed extent" );
299 
300  // The input rasters detailed extent over the expanded mosaic
301 
302  te::gm::LinearRing inRasterDetailedExtent(
303  inRasterIndexedDetailedExtent.size(), te::gm::LineStringType,
304  mosaicSRID, (te::gm::Envelope*)nullptr );
305 
306  {
307  double mappedX = 0;
308  double mappedY = 0;
309  double geoX = 0;
310  double geoY = 0;
311 
312  for( unsigned int inRasterDetExtentIdx = 0 ; inRasterDetExtentIdx <
313  inRasterIndexedDetailedExtent.size() ; ++inRasterDetExtentIdx )
314  {
315  auxTransPtr->inverseMap(
316  inRasterIndexedDetailedExtent.getX( inRasterDetExtentIdx ),
317  inRasterIndexedDetailedExtent.getY( inRasterDetExtentIdx ),
318  mappedX,
319  mappedY);
320 
321  rastersGrids[ 0 ].gridToGeo( mappedX, mappedY, geoX,
322  geoY );
323 
324  inRasterDetailedExtent.setPoint( inRasterDetExtentIdx, geoX, geoY );
325  }
326  }
327 
328  // expanding mosaic area
329 
330  mosaicLLX = std::min( mosaicLLX, inRasterDetailedExtent.getMBR()->getLowerLeftX() );
331  mosaicLLY = std::min( mosaicLLY, inRasterDetailedExtent.getMBR()->getLowerLeftY() );
332 
333  mosaicURX = std::max( mosaicURX, inRasterDetailedExtent.getMBR()->getUpperRightX() );
334  mosaicURY = std::max( mosaicURY, inRasterDetailedExtent.getMBR()->getUpperRightY() );
335 
336  // finding the current raster bounding box polygon (first raster world coordinates)
337 
338  te::gm::Polygon auxPolygon( 0, te::gm::PolygonType, 0 );
339  auxPolygon.push_back( new te::gm::LinearRing( inRasterDetailedExtent ) );
340  auxPolygon.setSRID( mosaicSRID );
341  rastersBBoxes.push_back( auxPolygon );
342  }
343 
344  // checking the input bands
345 
346  for( std::vector< unsigned int >::size_type inputRastersBandsIdx = 0 ;
347  inputRastersBandsIdx <
348  m_inputParameters.m_inputRastersBands[ inputRasterIdx ].size() ;
349  ++inputRastersBandsIdx )
350  {
351  const unsigned int& currBand =
352  m_inputParameters.m_inputRastersBands[ inputRasterIdx ][ inputRastersBandsIdx ];
353 
354  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( currBand < inputRasterPtr->getNumberOfBands(),
355  "Invalid band" )
356  }
357 
358 
360  }
361 
362 
363  }
364 
366  {
367  progressPtr->pulse();
368  if( ! progressPtr->isActive() ) return false;
369  }
370 
371  // creating the output raster
372 
373  te::rst::Raster* outputRasterPtr = nullptr;
374 
375  {
376  mosaicBandsRangeMin.resize(
377  m_inputParameters.m_inputRastersBands[ 0 ].size(), 0 );
378  mosaicBandsRangeMax.resize(
379  m_inputParameters.m_inputRastersBands[ 0 ].size(), 0 );
380 
381  std::vector< te::rst::BandProperty* > bandsProperties;
382  for( std::vector< unsigned int >::size_type bandIdx = 0 ; bandIdx <
383  m_inputParameters.m_inputRastersBands[ 0 ].size() ; ++bandIdx )
384  {
385  bandsProperties.push_back( new te::rst::BandProperty( mosaicBaseBandProperties ) );
386  bandsProperties[ bandIdx ]->m_colorInterp = te::rst::GrayIdxCInt;
387  bandsProperties[ bandIdx ]->m_noDataValue = m_inputParameters.m_noDataValue;
388 
389  te::rst::GetDataTypeRanges( bandsProperties[ bandIdx ]->m_type,
390  mosaicBandsRangeMin[ bandIdx ],
391  mosaicBandsRangeMax[ bandIdx ]);
392  }
393 
394  te::rst::Grid* outputGrid = new te::rst::Grid( mosaicXResolution,
395  mosaicYResolution, new te::gm::Envelope( mosaicLLX, mosaicLLY, mosaicURX,
396  mosaicURY ), mosaicSRID );
397 
398  outParamsPtr->m_outputRasterPtr.reset(
400  outParamsPtr->m_rType,
401  outputGrid,
402  bandsProperties,
403  outParamsPtr->m_rInfo,
404  nullptr,
405  nullptr ) );
407  "Output raster creation error" );
408 
409  outputRasterPtr = outParamsPtr->m_outputRasterPtr.get();
410  }
411 
412  std::unique_ptr< te::mem::CachedRaster > cachedOutputRasterInstancePtr;
413 
415  {
416  cachedOutputRasterInstancePtr.reset( new te::mem::CachedRaster(
417  *(outParamsPtr->m_outputRasterPtr.get()), 25, 0 ) );
418 
419  outputRasterPtr = cachedOutputRasterInstancePtr.get();
420  }
421 
423  {
424  progressPtr->pulse();
425  if( ! progressPtr->isActive() ) return false;
426  }
427 
428  // Finding the transformation mapping indexed points from each raster to the first raster indexed points.
429  // te::gm::GTParameters::TiePoint::first are mosaic reaster indexed points (lines/cols),
430  // te::gm::GTParameters::TiePoint::second are the other rasters indexed points (lines/cols).
431 
432  std::vector< boost::shared_ptr< te::gm::GeometricTransformation > >
433  eachRasterPixelToMosaicRasterPixelGeomTransfms;
434 
435  {
436  const double firstRasterColOffset = std::abs( rastersBBoxes[ 0 ].getMBR()->m_llx -
437  outParamsPtr->m_outputRasterPtr->getGrid()->getExtent()->getLowerLeftX() ) /
438  outParamsPtr->m_outputRasterPtr->getGrid()->getResolutionX();
439  const double firstRasterLinOffset = std::abs( rastersBBoxes[ 0 ].getMBR()->m_ury -
440  outParamsPtr->m_outputRasterPtr->getGrid()->getExtent()->getUpperRightY() ) /
441  outParamsPtr->m_outputRasterPtr->getGrid()->getResolutionY();
442 
443  for( unsigned int tiePointsIdx = 0 ; tiePointsIdx < m_inputParameters.m_tiePoints.size() ;
444  ++tiePointsIdx )
445  {
446  te::gm::GTParameters transfParams;
447  transfParams.m_tiePoints = m_inputParameters.m_tiePoints[ tiePointsIdx ];
448 
449  const double prevRasterColOffset = std::abs( rastersBBoxes[ tiePointsIdx ].getMBR()->m_llx -
450  outParamsPtr->m_outputRasterPtr->getGrid()->getExtent()->getLowerLeftX() ) /
451  outParamsPtr->m_outputRasterPtr->getGrid()->getResolutionX();
452  const double prevRasterLinOffset = std::abs( rastersBBoxes[ tiePointsIdx ].getMBR()->m_ury -
453  outParamsPtr->m_outputRasterPtr->getGrid()->getExtent()->getUpperRightY() ) /
454  outParamsPtr->m_outputRasterPtr->getGrid()->getResolutionY();
455 
456  for( unsigned int tpIdx = 0 ; tpIdx < transfParams.m_tiePoints.size() ;
457  ++tpIdx )
458  {
460  {
461  transfParams.m_tiePoints[ tpIdx ].first.x += firstRasterColOffset;
462  transfParams.m_tiePoints[ tpIdx ].first.y += firstRasterLinOffset;
463  }
464  else
465  {
466  transfParams.m_tiePoints[ tpIdx ].first.x += prevRasterColOffset;
467  transfParams.m_tiePoints[ tpIdx ].first.y += prevRasterLinOffset;
468  }
469  }
470 
471  boost::shared_ptr< te::gm::GeometricTransformation > auxTransPtr(
473  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( auxTransPtr.get() != nullptr,
474  "Geometric transformation instatiation error" );
475  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( auxTransPtr->initialize( transfParams ),
476  "Geometric transformation parameters calcule error" );
477  eachRasterPixelToMosaicRasterPixelGeomTransfms.push_back( auxTransPtr );
478  }
479  }
480 
482  {
483  progressPtr->pulse();
484  if( ! progressPtr->isActive() ) return false;
485  }
486 
487  // fill output with no data values
488 
489  {
490  const unsigned int nBands = static_cast<unsigned int>(outputRasterPtr->getNumberOfBands());
491  const unsigned int nRows = outputRasterPtr->getNumberOfRows();
492  const unsigned int nCols = outputRasterPtr->getNumberOfColumns();
493  unsigned int col = 0;
494  unsigned int row = 0;
495  unsigned int bandIdx = 0;
496 
497  for( bandIdx = 0 ; bandIdx < nBands ; ++bandIdx )
498  {
499  te::rst::Band& outBand = ( *( outputRasterPtr->getBand( bandIdx ) ) );
500 
501  for( row = 0 ; row < nRows ; ++row )
502  {
503  for( col = 0 ; col < nCols ; ++col )
504  {
505  outBand.setValue( col, row, m_inputParameters.m_noDataValue );
506  }
507  }
508  }
509  }
510 
512  {
513  progressPtr->pulse();
514  if( ! progressPtr->isActive() ) return false;
515  }
516 
517  // Copying the first image data to the output mosaic
518  // and find the base mosaic mean and offset values
519 
520  std::vector< double > mosaicTargetMeans( outputRasterPtr->getNumberOfBands(), 0 );
521  std::vector< double > mosaicTargetVariances( outputRasterPtr->getNumberOfBands(), 0 );
522 
523  {
525 
526  te::rst::Raster const* inputRasterPtr =
528  TERP_DEBUG_TRUE_OR_RETURN_FALSE( inputRasterPtr, "Invalid raster pointer" );
529 
530  double inXStartGeo = 0;
531  double inYStartGeo = 0;
532  inputRasterPtr->getGrid()->gridToGeo( 0.0, 0.0, inXStartGeo, inYStartGeo );
533 
534  double outFirstRowDouble = 0;
535  double outFirstColDouble = 0;
536  outputRasterPtr->getGrid()->geoToGrid( inXStartGeo, inYStartGeo,
537  outFirstColDouble, outFirstRowDouble );
538 
539  const double outRowsBoundDouble = outFirstRowDouble +
540  (double)( inputRasterPtr->getNumberOfRows() );
541  const double outColsBoundDouble = outFirstColDouble +
542  (double)( inputRasterPtr->getNumberOfColumns() );
543 
544  const unsigned int outFirstRow = (unsigned int)std::max( 0u,
545  te::common::Round< double, unsigned int >( outFirstRowDouble ) );
546  const unsigned int outFirstCol = (unsigned int)std::max( 0u,
547  te::common::Round< double, unsigned int >( outFirstColDouble ) );
548 
549  const unsigned int outRowsBound = (unsigned int)std::min(
550  te::common::Round< double, unsigned int >( outRowsBoundDouble ),
551  outputRasterPtr->getNumberOfRows() );
552  const unsigned int outColsBound = (unsigned int)std::min(
553  te::common::Round< double, unsigned int >( outColsBoundDouble ),
554  outputRasterPtr->getNumberOfColumns() );
555 
556  const unsigned int nBands = (unsigned int)
558  unsigned int outCol = 0;
559  unsigned int outRow = 0;
560  double inCol = 0;
561  double inRow = 0;
562  double bandNoDataValue = -1.0 * DBL_MAX;
563  std::complex< double > pixelCValue = 0;
564  te::rst::Interpolator interpInstance( inputRasterPtr,
566  unsigned int inputBandIdx = 0;
567 
568  for( unsigned int inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
569  nBands ; ++inputRastersBandsIdx )
570  {
571  inputBandIdx = m_inputParameters.m_inputRastersBands[ 0 ][
572  inputRastersBandsIdx ] ;
573  bandNoDataValue = m_inputParameters.m_forceInputNoDataValue ?
574  m_inputParameters.m_noDataValue : inputRasterPtr->getBand( inputBandIdx
576  te::rst::Band& outBand =
577  (*outputRasterPtr->getBand( inputRastersBandsIdx ));
578  unsigned long int validPixelsNumber = 0;
579 
580  double mean = 0;
581 
582  for( outRow = outFirstRow ; outRow < outRowsBound ; ++outRow )
583  {
584  inRow = ((double)outRow) - outFirstRowDouble;
585 
586  for( outCol = outFirstCol ; outCol < outColsBound ; ++outCol )
587  {
588  inCol = ((double)outCol) - outFirstColDouble;
589 
590  interpInstance.getValue( inCol, inRow, pixelCValue, inputBandIdx );
591 
592  if( pixelCValue.real() != bandNoDataValue )
593  {
594  outBand.setValue( outCol, outRow, pixelCValue );
595  mean += pixelCValue.real();
596  ++validPixelsNumber;
597  }
598  }
599  }
600 
601  // variance calcule
602 
603  if( m_inputParameters.m_autoEqualize && ( validPixelsNumber > 0 ) )
604  {
605  mean /= ( (double)validPixelsNumber );
606  mosaicTargetMeans[ inputRastersBandsIdx ] = mean;
607 
608  double& variance = mosaicTargetVariances[ inputRastersBandsIdx ];
609  variance = 0;
610 
611  double pixelValue = 0;
612 
613  for( outRow = outFirstRow ; outRow < outRowsBound ; ++outRow )
614  {
615  for( outCol = outFirstCol ; outCol < outColsBound ; ++outCol )
616  {
617  outBand.getValue( outCol, outRow, pixelValue );
618 
619  if( pixelValue != m_inputParameters.m_noDataValue )
620  {
621  variance += ( ( pixelValue - mean ) * ( pixelValue -
622  mean ) ) / ( (double)validPixelsNumber );
623  }
624  }
625  }
626  }
627  }
628  }
629 
631  {
632  progressPtr->pulse();
633  if( ! progressPtr->isActive() ) return false;
634  }
635 
636  // Initiating the mosaic bounding boxes union
637 
638  std::unique_ptr< te::gm::MultiPolygon > mosaicBBoxesUnionPtr(
640  rastersBBoxes[ 0 ].getSRID(), nullptr ) );
641 
642  mosaicBBoxesUnionPtr->add( (te::gm::Polygon*)( rastersBBoxes[ 0 ].clone() ) );
643 
644  // globals
645 
646  std::vector< unsigned int > outputRasterBands;
647  std::vector< double > dummyRasterOffsets;
648  std::vector< double > dummyRasterScales;
649  for( unsigned int outputRasterBandsIdx = 0 ; outputRasterBandsIdx <
650  outputRasterPtr->getNumberOfBands() ; ++outputRasterBandsIdx )
651  {
652  outputRasterBands.push_back( outputRasterBandsIdx );
653  dummyRasterOffsets.push_back( 0.0 );
654  dummyRasterScales.push_back( 1.0 );
655  }
656 
657  // iterating over the other rasters
658 
659  te::rst::Raster const* nonCachedInputRasterPtr = nullptr;
660 
663 
664  while( ( nonCachedInputRasterPtr = m_inputParameters.m_feederRasterPtr->getCurrentObj() ) )
665  {
666  const unsigned int inputRasterIdx = m_inputParameters.m_feederRasterPtr->getCurrentOffset();
667 
668  te::rst::Raster const* inputRasterPtr = nonCachedInputRasterPtr;
669 
670  std::unique_ptr< te::mem::CachedRaster > cachedInputRasterPtr;
672  {
673  cachedInputRasterPtr.reset( new te::mem::CachedRaster(
674  *nonCachedInputRasterPtr, 25, 0 ) );
675  inputRasterPtr = cachedInputRasterPtr.get();
676  }
677 
678  // Generating the offset and gain info for eath band from the current raster
679 
680  std::vector< double > currentRasterBandsOffsets = dummyRasterOffsets;
681  std::vector< double > currentRasterBandsScales = dummyRasterScales;
682 
684  {
685  double currentRasterVariance = 0;
686  double currentRasterMean = 0;
687 
688  for( unsigned int inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
689  m_inputParameters.m_inputRastersBands[ inputRasterIdx ].size() ;
690  ++inputRastersBandsIdx )
691  {
692  const unsigned int inputBandIdx = m_inputParameters.m_inputRastersBands[ inputRasterIdx ][
693  inputRastersBandsIdx ];
694 
695  if(
696  ( mosaicTargetMeans[ inputRastersBandsIdx ] != 0.0 )
697  &&
698  ( mosaicTargetVariances[ inputRastersBandsIdx ] != 0.0 )
699  )
700  {
701  calcBandStatistics( (*inputRasterPtr->getBand( inputBandIdx ) ),
704  currentRasterMean,
705  currentRasterVariance );
706 
707  currentRasterBandsScales[ inputRastersBandsIdx ] =
708  (
709  std::sqrt( mosaicTargetVariances[ inputRastersBandsIdx ] )
710  /
711  std::sqrt( currentRasterVariance )
712  );
713  currentRasterBandsOffsets[ inputRastersBandsIdx ] =
714  (
715  mosaicTargetMeans[ inputRastersBandsIdx ]
716  -
717  (
718  currentRasterBandsScales[ inputRastersBandsIdx ]
719  *
720  currentRasterMean
721  )
722  );
723  }
724  }
725  }
726 
727  // blending with the mosaic boxes union
728 
729  te::rp::Blender blenderInstance;
730 
732  *outputRasterPtr,
733  outputRasterBands,
734  *inputRasterPtr,
735  m_inputParameters.m_inputRastersBands[ inputRasterIdx ],
740  false,
742  dummyRasterOffsets,
743  dummyRasterScales,
744  currentRasterBandsOffsets,
745  currentRasterBandsScales,
746  mosaicBBoxesUnionPtr.get(),
747  nullptr,
748  *( eachRasterPixelToMosaicRasterPixelGeomTransfms[ inputRasterIdx - 1 ] ),
750  false ),
751  "Blender initiazing error" );
752 
754  "Error blending images" );
755 
756 
757  // updating the mosaic related polygons
758 
759  {
760  // union of the current raster box with the current mosaic valid area under the mosaic SRID
761 
762  std::unique_ptr< te::gm::Geometry > unionMultiPolPtr;
763  unionMultiPolPtr.reset( mosaicBBoxesUnionPtr->Union(
764  &( rastersBBoxes[ inputRasterIdx ] ) ) );
765  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( unionMultiPolPtr.get(), "Invalid pointer" );
766  unionMultiPolPtr->setSRID( mosaicBBoxesUnionPtr->getSRID() );
767 
768  if(
769  ( unionMultiPolPtr->getGeomTypeId() == te::gm::MultiPolygonType )
770  ||
771  ( unionMultiPolPtr->getGeomTypeId() == te::gm::MultiPolygonZType )
772  ||
773  ( unionMultiPolPtr->getGeomTypeId() == te::gm::MultiPolygonMType )
774  ||
775  ( unionMultiPolPtr->getGeomTypeId() == te::gm::MultiPolygonZMType )
776  )
777  {
778  mosaicBBoxesUnionPtr.reset( (te::gm::MultiPolygon*)unionMultiPolPtr.release() );
779  }
780  else if(
781  ( unionMultiPolPtr->getGeomTypeId() == te::gm::PolygonType )
782  ||
783  ( unionMultiPolPtr->getGeomTypeId() == te::gm::PolygonZType )
784  ||
785  ( unionMultiPolPtr->getGeomTypeId() == te::gm::PolygonMType )
786  ||
787  ( unionMultiPolPtr->getGeomTypeId() == te::gm::PolygonZMType )
788  )
789  {
791  unionMultiPolPtr->getSRID(), nullptr );
792  mPolPtr->add( (te::gm::Polygon*)unionMultiPolPtr.release() );
793  mosaicBBoxesUnionPtr.reset( mPolPtr );
794  }
795  else
796  {
797  TERP_LOGWARN( "Invalid union geometry type" );
798  }
799  }
800 
801  // moving to the next raster
802 
803  cachedInputRasterPtr.reset();
804 
806 
808  {
809  progressPtr->pulse();
810  if( ! progressPtr->isActive() ) return false;
811  }
812  }
813 
814  return true;
815  }
816 
817  void TiePointsMosaic::reset() throw( te::rp::Exception )
818  {
820 
822  m_isInitialized = false;
823  }
824 
826  throw( te::rp::Exception )
827  {
828  reset();
829 
830  TiePointsMosaic::InputParameters const* inputParamsPtr = dynamic_cast<
831  TiePointsMosaic::InputParameters const* >( &inputParams );
832  TERP_TRUE_OR_THROW( inputParamsPtr, "Invalid paramters pointer" );
833 
834  m_inputParameters = *inputParamsPtr;
835 
836  // Checking the feeder
837 
839  "Invalid m_feederRasterPtr" )
840 
843  "Invalid number of rasters" )
844 
845  // checking m_inputRastersBands
846 
848  ((unsigned int)m_inputParameters.m_inputRastersBands.size()) ==
850  "Bands mismatch" );
851 
852  for( std::vector< std::vector< unsigned int > >::size_type
853  inputRastersBandsIdx = 0 ; inputRastersBandsIdx <
854  m_inputParameters.m_inputRastersBands.size() ; ++inputRastersBandsIdx )
855  {
857  inputRastersBandsIdx ].size() > 0, "Invalid bands number" );
858 
860  inputRastersBandsIdx ].size() == m_inputParameters.m_inputRastersBands[
861  0 ].size(), "Bands number mismatch" );
862  }
863 
864  // checking other parameters
865 
867  ( m_inputParameters.m_tiePoints.size() ==
869  "Bands mismatch" );
870 
871  m_isInitialized = true;
872 
873  return true;
874  }
875 
877  {
878  return m_isInitialized;
879  }
880 
882  const bool& forceNoDataValue,
883  const double& noDataValue,
884  double& mean, double& variance )
885  {
886  mean = 0;
887  variance = 0;
888 
889  double internalNoDataValue = 0;
890  if( forceNoDataValue )
891  internalNoDataValue = noDataValue;
892  else
893  internalNoDataValue = band.getProperty()->m_noDataValue;
894 
895  const unsigned int nCols = band.getProperty()->m_blkw *
896  band.getProperty()->m_nblocksx;
897  const unsigned int nLines = band.getProperty()->m_blkh *
898  band.getProperty()->m_nblocksy;
899 
900  double pixelsNumber = 0;
901  double value = 0;
902  unsigned int col = 0;
903  unsigned int line = 0;
904 
905  for( line = 0 ; line < nLines ; ++line )
906  for( col = 0 ; col < nCols ; ++col )
907  {
908  band.getValue( col, line, value );
909 
910  if( value != internalNoDataValue )
911  {
912  mean += value;
913  ++pixelsNumber;
914  }
915  }
916 
917  if( pixelsNumber != 0.0 )
918  {
919  mean /= pixelsNumber;
920 
921  for( line = 0 ; line < nLines ; ++line )
922  for( col = 0 ; col < nCols ; ++col )
923  {
924  band.getValue( col, line, value );
925 
926  if( value != internalNoDataValue )
927  {
928  variance += ( ( value - mean ) * ( value - mean ) ) / pixelsNumber;
929  }
930  }
931 
932  }
933  }
934 
935  } // end namespace rp
936 } // end namespace te
937 
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.
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
unsigned int band
std::map< std::string, std::string > m_rInfo
The necessary information to create the output rasters (as described in te::raster::RasterFactory).
Near neighborhood interpolation method.
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
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.
Index into a lookup table.
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...
std::unique_ptr< te::rst::Raster > m_outputRasterPtr
The generated output mosaic raster.
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
Blended pixel value calculation for two overlaped rasters.
Definition: Blender.h:58
int getSRID() const
Returns the grid spatial reference system identifier.
Base exception class for plugin module.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
int m_nblocksx
The number of blocks in x.
Definition: BandProperty.h:145
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: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.
#define TERP_LOGWARN(message)
Logs a warning message.
Definition: Macros.h:128
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.
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.
const double & getLowerLeftY() const
It returns a constant refernce to the y coordinate of the lower left corner.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
double pixelValue
void getValue(const double &c, const double &r, std::complex< double > &v, const std::size_t &b)
Get the interpolated value at specific band.
Definition: Interpolator.h:93
2D Geometric transformation base class.
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
Definition: BandProperty.h:136
const double & getUpperRightY() const
It returns a constant refernce to the x coordinate of the upper right corner.
virtual te::rst::Raster const * getCurrentObj() const =0
Return the current sequence object.
bool m_isInitialized
Tells if this instance is initialized.
No blending performed.
Definition: Blender.h:66
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.
bool m_enableMultiThread
Enable/disable the use of threads (default:true).
const double & getY(std::size_t i) const
It returns the n-th y coordinate value.
bool blendIntoRaster1()
Execute blending of the given input rasters and write the result into raster1.
Definition: Blender.cpp:1351
double getResolutionY() const
Returns the grid vertical (y-axis) resolution.
unsigned int line
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
std::vector< std::vector< unsigned int > > m_inputRastersBands
Bands to process for each input raster.
unsigned int unsigned int nCols
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.
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
const Envelope * getMBR() const _NOEXCEPT_OP(true)
It returns the minimum bounding rectangle for the geometry in an internal representation.
void setPoint(std::size_t i, const double &x, const double &y)
It sets the value of the specified point.
virtual void reset()=0
Reset the feeder to the first position (subsequent accesses will start from the first sequence obejct...
An Envelope defines a 2D rectangular region.
An abstract class for raster data strucutures.
const InputParameters & operator=(const InputParameters &params)
unsigned int getNumberOfRows() const
Returns the raster number of rows.
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
const double & getX(std::size_t i) const
It returns the n-th x coordinate value.
BandProperty * getProperty()
Returns the band property.
URI C++ Library.
Definition: Attributes.h:37
int m_blkw
Block width (pixels).
Definition: BandProperty.h:143
double getResolutionX() const
Returns the grid horizontal (x-axis) resolution.
A RAM cache adaptor to an external existent raster that must always be avaliable. ...
Definition: CachedRaster.h:52
std::string m_rType
Output raster data source type (as described in te::raster::RasterFactory ).
A raster band description.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
Grid * getGrid()
It returns the raster grid.
static GeometricTransformation * make(const std::string &factoryKey)
It creates an object with the appropriated factory.
bool initialize(te::rst::Raster &raster1, const std::vector< unsigned int > &raster1Bands, const te::rst::Raster &raster2, const std::vector< unsigned int > &raster2Bands, const BlendMethod &blendMethod, const te::rst::Interpolator::Method &interpMethod1, const te::rst::Interpolator::Method &interpMethod2, const double &noDataValue, const bool forceRaster1NoDataValue, const bool forceRaster2NoDataValue, const std::vector< double > &pixelOffsets1, const std::vector< double > &pixelScales1, const std::vector< double > &pixelOffsets2, const std::vector< double > &pixelScales2, te::gm::MultiPolygon const *const r1ValidDataDelimiterPtr, te::gm::MultiPolygon const *const r2ValidDataDelimiterPtr, const te::gm::GeometricTransformation &geomTransformation, const unsigned int threadsNumber, const bool enableProgressInterface)
Inititate the blender instance.
Definition: Blender.cpp:178
double m_lly
Lower left corner y-coordinate.
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.
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.
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.
const double & getLowerLeftX() const
It returns a constant reference to the x coordinate of the lower left corner.
bool GetIndexedDetailedExtent(const te::rst::Grid &grid, te::gm::LinearRing &indexedDetailedExtent)
Create a indexed (lines,columns) datailed extent from the given grid.
#define TERP_DEBUG_TRUE_OR_RETURN_FALSE(value, message)
Checks if value is true. For false values a warning message will be logged and a return of context wi...
Definition: Macros.h:415
te::gm::Envelope * getExtent()
Returns the geographic extension of the grid.
void gridToGeo(const double &col, const double &row, double &x, double &y) const
Get the spatial location of a grid point.
void setSRID(int srid)
It sets the Spatial Reference System ID of the linestring.
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.
Raster Processing functions.
virtual bool moveNext()=0
Advances to the next sequence obeject.
int m_blkh
Block height (pixels).
Definition: BandProperty.h:144
virtual void reset() _NOEXCEPT_OP(false)
Clear all internal allocated objects and reset the algorithm to its initial state.
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
#define TERP_INSTANCE_TRUE_OR_RETURN_FALSE(value, message)
Checks if value is true. For false values a warning message will be logged, the current instance erro...
Definition: Macros.h:200
unsigned int nLines
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).
unsigned int col
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:150
te::rst::Interpolator::Method m_interpMethod
The raster interpolator method (default:NearestNeighbor).
std::size_t size() const
It returns the number of points (vertexes) in the geometry.
Definition: LineString.h:262
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
virtual unsigned int getCurrentOffset() const =0
Return the index of the current object.
virtual unsigned int getObjsCount() const =0
Return the total number of feeder objects.