src/terralib/rp/ArithmeticOperations.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/rp/GeoMosaic.cpp
22  \brief Create a mosaic from a set of geo-referenced rasters.
23 */
24 
25 #include "ArithmeticOperations.h"
26 
27 #include "Functions.h"
28 #include "Macros.h"
29 
30 #include "../common/progress/TaskProgress.h"
31 #include "../common/StringUtils.h"
32 #include "../raster/Raster.h"
33 #include "../raster/Band.h"
34 #include "../memory/ExpansibleRaster.h"
35 #include "../srs/Converter.h"
36 
37 #include <cfloat>
38 
39 namespace te
40 {
41  namespace rp
42  {
43 
45  {
46  reset();
47  }
48 
50  {
51  reset();
52  operator=( other );
53  }
54 
56  {
57  reset();
58  }
59 
61  {
62  m_inputRasters.clear();
63  m_arithmeticString.clear();
64  m_normalize = true;
65  m_enableProgress = false;
67  }
68 
71  {
72  reset();
73 
76  m_normalize = params.m_normalize;
79 
80  return *this;
81  }
82 
84  {
85  return new InputParameters( *this );
86  }
87 
89  {
90  reset();
91  }
92 
94  {
95  reset();
96  operator=( other );
97  }
98 
100  {
101  reset();
102  }
103 
105  {
106  m_rType.clear();
107  m_rInfo.clear();
108  m_outputRasterPtr.reset();
109  }
110 
113  {
114  reset();
115 
116  m_rType = params.m_rType;
117  m_rInfo = params.m_rInfo;
118  m_outputRasterPtr.reset();
119 
120  return *this;
121  }
122 
124  {
125  return new OutputParameters( *this );
126  }
127 
129  {
130  reset();
131  }
132 
134 
136  {
137  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( m_isInitialized, "Algoritm not initialized" );
138 
139  ArithmeticOperations::OutputParameters* outParamsPtr = dynamic_cast<
140  ArithmeticOperations::OutputParameters* >( &outputParams );
141  TERP_TRUE_OR_THROW( outParamsPtr, "Invalid paramters" );
142 
143  // Counting the number of operations to be done
144  std::string arithmetic_string = m_inputParameters.m_arithmeticString;
145 
146  unsigned int operationsNumber = 0;
147  {
148  for( unsigned sIdx = 0 ; sIdx < arithmetic_string.size() ; ++sIdx )
149  {
150  std::string auxStr;
151  auxStr.push_back( arithmetic_string[ sIdx ] );
152 
153  if( isOperator( auxStr ) ) ++operationsNumber;
154  }
155  }
156 
157  // progress
158 
159  std::unique_ptr< te::common::TaskProgress > progressPtr;
161  {
162  progressPtr.reset( new te::common::TaskProgress );
163 
164  progressPtr->setTotalSteps( static_cast<int>(operationsNumber) );
165 
166  progressPtr->setMessage( "Arithmetic Operations" );
167  }
168 
169  // Executing the arithmetic string
170 
171  std::unique_ptr<te::rst::Raster> auxRasterPtr;
173  m_inputParameters.m_inputRasters, auxRasterPtr, true, progressPtr.get() ),
174  "Arithmetic string execution error" );
175 
176  TERP_INSTANCE_TRUE_OR_RETURN_FALSE(auxRasterPtr.get(), "Arithmetic string execution error.");
177 
178  // Initializing the output raster
179 
180  std::vector< te::rst::BandProperty* > bandsProperties;
181  bandsProperties.push_back( new te::rst::BandProperty(
182  *( m_inputParameters.m_inputRasters[0]->getBand(0)->getProperty() ) ) );
184  {
185  bandsProperties[ 0 ]->m_type = auxRasterPtr->getBand( 0 )->getProperty()->m_type;
186  bandsProperties[ 0 ]->m_noDataValue = auxRasterPtr->getBand( 0 )->getProperty()->m_noDataValue;
187  }
188 
189  outParamsPtr->m_outputRasterPtr.reset(
191  outParamsPtr->m_rType,
192  new te::rst::Grid( *( auxRasterPtr->getGrid() ) ),
193  bandsProperties,
194  outParamsPtr->m_rInfo,
195  nullptr,
196  nullptr ) );
198  "Output raster creation error" );
199 
200  // Calculating the output gain and offset
201 
202  double outputOffset = 0;
203  double outputGain = 1.0;
204 
205  if(
207  &&
208  (
209  outParamsPtr->m_outputRasterPtr->getBand(0)->getProperty()->getType()
210  !=
212  )
213  )
214  {
215  double outAllowedMin = 0;
216  double outAllowedMax = 0;
217  GetDataTypeRange( outParamsPtr->m_outputRasterPtr->getBandDataType( 0 ) ,
218  outAllowedMin, outAllowedMax );
219 
220  const unsigned int nRows = static_cast<unsigned int>(auxRasterPtr->getNumberOfRows());
221  const unsigned int nCols = static_cast<unsigned int>(auxRasterPtr->getNumberOfColumns());
222  unsigned int row = 0;
223  unsigned int col = 0;
224  double value = 0;
225  te::rst::Raster& auxRasterRef = *auxRasterPtr;
226 
227  const double auxNoDataValue = auxRasterRef.getBand( 0 )->getProperty()->m_noDataValue;
228  double auxMin = DBL_MAX;
229  double auxMax = -1.0 * auxMin;
230 
231  for( row = 0 ; row < nRows ; ++row )
232  {
233  for( col = 0 ; col < nCols ; ++col )
234  {
235  auxRasterRef.getValue( col, row, value, 0 );
236 
237  if( auxNoDataValue != value )
238  {
239  if( auxMin > value ) auxMin = value;
240  if( auxMax < value ) auxMax = value;
241  }
242  }
243  }
244 
245  if( ( auxMin != DBL_MAX ) && ( auxMax != ( -1.0 * DBL_MAX ) ) &&
246  ( auxMax != auxMin ) )
247  {
248  outputOffset = -1.0 * auxMin;
249  outputGain = ( ( outAllowedMax - outAllowedMin ) / ( auxMax - auxMin ) );
250  }
251  }
252 
253  // Copy result data to output raster
254 
255  {
256  const unsigned int nRows = static_cast<unsigned int>(auxRasterPtr->getNumberOfRows());
257  const unsigned int nCols = static_cast<unsigned int>(auxRasterPtr->getNumberOfColumns());
258  unsigned int row = 0;
259  unsigned int col = 0;
260  double value = 0;
261  te::rst::Raster& auxRasterRef = *auxRasterPtr;
262  te::rst::Raster& outRasterRef = *outParamsPtr->m_outputRasterPtr;
263  const double auxNoDataValue = auxRasterRef.getBand( 0 )->getProperty()->m_noDataValue;
264  const double outNoDataValue = outRasterRef.getBand( 0 )->getProperty()->m_noDataValue;
265  double outAllowedMin = 0;
266  double outAllowedMax = 0;
267  GetDataTypeRange( outParamsPtr->m_outputRasterPtr->getBandDataType( 0 ) ,
268  outAllowedMin, outAllowedMax );
269 
270  for( row = 0 ; row < nRows ; ++row )
271  {
272  for( col = 0 ; col < nCols ; ++col )
273  {
274  auxRasterRef.getValue( col, row, value, 0 );
275 
276  if( auxNoDataValue == value )
277  {
278  outRasterRef.setValue( col, row, outNoDataValue, 0 );
279  }
280  else
281  {
282  value += outputOffset;
283  value *= outputGain;
284  value = MIN( value, outAllowedMax );
285  value = MAX( value, outAllowedMin );
286 
287  outRasterRef.setValue( col, row, value, 0 );
288  }
289  }
290  }
291  }
292 
293  return true;
294  }
295 
297  {
299 
301  m_isInitialized = false;
302  }
303 
305  {
306  reset();
307 
308  ArithmeticOperations::InputParameters const* inputParamsPtr = dynamic_cast<
309  ArithmeticOperations::InputParameters const* >( &inputParams );
310  TERP_TRUE_OR_THROW( inputParamsPtr, "Invalid paramters pointer" );
311 
312  m_inputParameters = *inputParamsPtr;
313 
314  // Checking the feeder
315 
317  "Invalid number of rasters" );
318 
319  for( std::size_t t = 0; t < m_inputParameters.m_inputRasters.size(); ++t )
320  {
322  "Invalid raster" )
324  & te::common::RAccess, "Invalid raster access policy" )
325  }
326 
327  // Checking the expression
328 
330  "Arithmetic string is empty" )
331 
332  std::unique_ptr<te::rst::Raster> rasterNull;
334  m_inputParameters.m_inputRasters, rasterNull, false, nullptr), "Invalid arithmetic string" )
335 
336  m_isInitialized = true;
337 
338  return true;
339  }
340 
342  {
343  return m_isInitialized;
344  }
345 
346  bool ArithmeticOperations::executeString( const std::string& aStr,
347  const std::vector< te::rst::Raster* >& inRasters,
348  std::unique_ptr<te::rst::Raster>& outRaster,
349  bool generateOutput,
350  te::common::TaskProgress* const progressPtr ) const
351  {
352  std::vector< std::string > infixTokensVec;
353  getTokensStrs( aStr, infixTokensVec );
354 
355  if( infixTokensVec.size() )
356  {
357  std::vector< std::string > postfixTokensVec;
358 
359  inFix2PostFix( infixTokensVec, postfixTokensVec );
360 
361  ExecStackT execStack;
362  unsigned int auxRasterIdx = 0;
363  unsigned int auxBandIdx = 0;
364  double auxRealValue = 0;
365 
366  for( unsigned int tIdx = 0 ; tIdx < postfixTokensVec.size() ; ++tIdx )
367  {
368  const std::string& curToken = postfixTokensVec[ tIdx ];
369 
370  if( isRasterBandToken( curToken, auxRasterIdx, auxBandIdx ) )
371  {
372  TERP_TRUE_OR_RETURN_FALSE( auxRasterIdx < inRasters.size(),
373  "Invalid raster index found at " + curToken );
374 
375  TERP_TRUE_OR_RETURN_FALSE( static_cast<size_t>(auxBandIdx) < inRasters[auxRasterIdx]->getNumberOfBands(),
376  "Invalid band index" );
377 
378  ExecStackElement auxEle;
379  auxEle.m_isRaster = true;
380  auxEle.m_rasterNPtr = inRasters[auxRasterIdx];
381  auxEle.m_rasterBand = auxBandIdx;
382 
383  execStack.push( auxEle );
384  }
385  else if( isRealNumberToken( curToken, auxRealValue ) )
386  {
387  ExecStackElement auxEle;
388  auxEle.m_isRealNumber = true;
389  auxEle.m_realNumberValue = auxRealValue;
390 
391  execStack.push( auxEle );
392  }
393  else if( isBinaryOperator( curToken ) )
394  {
395  TERP_TRUE_OR_RETURN_FALSE( execBinaryOperator( curToken, execStack, generateOutput ),
396  "Operator " + curToken + " execution error" );
397 
398  if( progressPtr )
399  {
400  if( ! progressPtr->isActive() )
401  {
402  return false;
403  }
404  progressPtr->pulse();
405  }
406  }
407  else if( isUnaryOperator( curToken ) )
408  {
409  TERP_TRUE_OR_RETURN_FALSE( execUnaryOperator( curToken, execStack, generateOutput ),
410  "Operator " + curToken + " execution error" );
411 
412  if( progressPtr )
413  {
414  if( ! progressPtr->isActive() )
415  {
416  return false;
417  }
418  progressPtr->pulse();
419  }
420  }
421  else
422  {
423  TERP_LOG_AND_RETURN_FALSE( "Invalid operator found: " + curToken );
424  }
425  }
426 
427  TERP_TRUE_OR_RETURN_FALSE( execStack.size() == 1, "Invalid stack size" );
428  TERP_TRUE_OR_RETURN_FALSE( execStack.top().m_isRaster, "Stack result error" );
429 
430  outRaster.reset( execStack.top().m_rasterHandler.release() );
431  }
432 
433  return true;
434  }
435 
436  void ArithmeticOperations::inFix2PostFix( const std::vector< std::string >& input,
437  std::vector< std::string >& output ) const
438  {
439  output.clear();
440 
441  std::stack< std::string > auxStack;
442  const unsigned int inputSize = static_cast<unsigned int>(input.size());
443 
444  for( unsigned int inIdx = 0 ; inIdx < inputSize ; ++inIdx )
445  {
446  const std::string& currInToken = input[ inIdx ];
447 
448  if( isOperator( currInToken ) )
449  {
450  while( ( ! auxStack.empty() ) && ( auxStack.top() != "(" ) )
451  {
452  if ( op1HasGreaterOrEqualPrecedence( auxStack.top(), currInToken ) )
453  {
454  output.push_back( auxStack.top() );
455 
456  auxStack.pop();
457  }
458  else
459  {
460  break;
461  }
462  }
463 
464  auxStack.push( currInToken );
465  }
466  else if( currInToken == "(" )
467  {
468  auxStack.push( currInToken );
469  }
470  else if( currInToken == ")" )
471  {
472  while ( ( ! auxStack.empty() ) && ( auxStack.top() != "(" ) )
473  {
474  output.push_back( auxStack.top() );
475 
476  auxStack.pop();
477  }
478 
479  if ( ! auxStack.empty() )
480  {
481  auxStack.pop();
482  }
483  }
484  else
485  {
486  output.push_back( currInToken );
487  }
488  }
489 
490  while ( ! auxStack.empty() )
491  {
492  output.push_back( auxStack.top() );
493 
494  auxStack.pop();
495  }
496  }
497 
498  void ArithmeticOperations::printTokens( const std::vector< std::string >& input ) const
499  {
500  std::cout << std::endl;
501 
502  for( unsigned int idx = 0 ; idx < input.size() ; ++idx )
503  {
504  std::cout << "[" << input[ idx ] << "]";
505  }
506 
507  std::cout << std::endl;
508  }
509 
510  bool ArithmeticOperations::isOperator( const std::string& inputToken ) const
511  {
512  return ( isBinaryOperator( inputToken ) ||
513  isUnaryOperator( inputToken ) );
514  }
515 
516  bool ArithmeticOperations::isBinaryOperator( const std::string& inputToken ) const
517  {
518  return ( ( inputToken == "+" ) || ( inputToken == "-" ) ||
519  (inputToken == "*") || (inputToken == "/") || (inputToken == "^")) ?
520  true : false;
521  }
522 
523  bool ArithmeticOperations::isUnaryOperator( const std::string& inputToken ) const
524  {
525  return ((inputToken == "sqrt") || (inputToken == "sin") || (inputToken == "asin") ||
526  (inputToken == "cos") || (inputToken == "acos") || (inputToken == "log") ||
527  (inputToken == "tan") || (inputToken == "atan") || (inputToken == "ln")) ?
528  true : false;
529  }
530 
531  bool ArithmeticOperations::op1HasGreaterOrEqualPrecedence( const std::string& operator1,
532  const std::string& operator2 ) const
533  {
534  if( ( operator1 == "*" ) || ( operator1 == "/" ) )
535  {
536  return true;
537  }
538  else
539  {
540  if( ( operator2 == "+" ) || ( operator2 == "-" ) )
541  {
542  return true;
543  }
544  }
545 
546  return false;
547  }
548 
549  bool ArithmeticOperations::isRasterBandToken( const std::string& token, unsigned int& rasterIdx,
550  unsigned int& bandIdx ) const
551  {
552  if( token.size() < 4 ) return false;
553  if( token[ 0 ] != 'R' ) return false;
554 
555  std::string rasterIdxStr;
556  unsigned int tIdx = 1;
557 
558  while( ( tIdx < token.size() ) && isdigit( token[ tIdx ] ) )
559  {
560  rasterIdxStr.push_back( token[ tIdx ] );
561  ++tIdx;
562  }
563 
564  if( token[ tIdx ] != ':' ) return false;
565  ++tIdx;
566 
567  std::string bandIdxStr;
568 
569  while( ( tIdx < token.size() ) && isdigit( token[ tIdx ] ) )
570  {
571  bandIdxStr.push_back( token[ tIdx ] );
572  ++tIdx;
573  }
574 
575  if( ( rasterIdxStr.size() ) && ( bandIdxStr.size() ) )
576  {
577  rasterIdx = static_cast<unsigned int>(atoi( rasterIdxStr.c_str() ));
578  bandIdx = static_cast<unsigned int>(atoi( bandIdxStr.c_str() ));
579  return true;
580  }
581  else
582  {
583  return false;
584  }
585  }
586 
587  bool ArithmeticOperations::execBinaryOperator( const std::string& token, ExecStackT&
588  execStack, bool generateOutput ) const
589  {
590  if( execStack.size() < 2 )
591  {
592  return false;
593  }
594 
595  ExecStackElement sElem1 = execStack.top();
596  execStack.pop();
597 
598  ExecStackElement sElem2 = execStack.top();
599  execStack.pop();
600 
601  // Choosing the binary operator function
602 
603  BinOpFuncPtrT binOptFunctPtr = nullptr;
604 
605  if( token == "+" )
606  {
607  binOptFunctPtr = &ArithmeticOperations::additionBinOp;
608  }
609  else if( token == "-" )
610  {
611  binOptFunctPtr = &ArithmeticOperations::subtractionBinOp;
612  }
613  else if( token == "*" )
614  {
616  }
617  else if( token == "/" )
618  {
619  binOptFunctPtr = &ArithmeticOperations::divisionBinOp;
620  }
621  else if (token == "^")
622  {
623  binOptFunctPtr = &ArithmeticOperations::exponencialBinOp;
624  }
625  else
626  {
627  TERP_LOG_AND_RETURN_FALSE( "Invalid operator" );
628  }
629 
630  // executing the choosen operator
631 
632  ExecStackElement outElement;
633  outElement.m_isRaster = true;
634  outElement.m_rasterBand = 0;
635 
636  if( generateOutput )
637  {
638  if( ( sElem1.m_isRaster ) && ( sElem2.m_isRaster ) )
639  {
641  *sElem2.m_rasterNPtr, sElem2.m_rasterBand, *sElem1.m_rasterNPtr,
642  sElem1.m_rasterBand, binOptFunctPtr, outElement.m_rasterHandler ),
643  "Operator execution error" );
644  outElement.m_rasterNPtr = outElement.m_rasterHandler.get();
645  }
646  else if( ( sElem1.m_isRaster ) && ( sElem2.m_isRealNumber ) )
647  {
649  *sElem1.m_rasterNPtr, sElem1.m_rasterBand, sElem2.m_realNumberValue,
650  binOptFunctPtr, outElement.m_rasterHandler, false ),
651  "Operator execution error" );
652  outElement.m_rasterNPtr = outElement.m_rasterHandler.get();
653  }
654  else if( ( sElem1.m_isRealNumber ) && ( sElem2.m_isRaster ) )
655  {
657  *sElem2.m_rasterNPtr, sElem2.m_rasterBand, sElem1.m_realNumberValue,
658  binOptFunctPtr, outElement.m_rasterHandler, true ),
659  "Operator execution error" );
660  outElement.m_rasterNPtr = outElement.m_rasterHandler.get();
661  }
662  else
663  {
664  TERP_LOG_AND_RETURN_FALSE( "Invalid stack elements" );
665  }
666  }
667 
668  execStack.push( outElement );
669 
670  return true;
671  }
672 
674  const te::rst::Raster& inRaster1,
675  const unsigned int band1Idx, const te::rst::Raster& inRaster2,
676  const unsigned int band2Idx,
677  const BinOpFuncPtrT binOptFunctPtr,
678  std::unique_ptr<te::rst::Raster>& outRasterPtr ) const
679  {
680  if( ! allocResultRaster( *inRaster1.getGrid(), outRasterPtr ) )
681  {
682  return false;
683  }
684 
685  if( inRaster1.getGrid()->operator==( *inRaster2.getGrid() ) )
686  {
687  const unsigned int nRows = inRaster1.getNumberOfRows();
688  const unsigned int nCols = inRaster1.getNumberOfColumns();
689  const te::rst::Band& inBand1 = *inRaster1.getBand( band1Idx );
690  const te::rst::Band& inBand2 = *inRaster2.getBand( band2Idx );
691  te::rst::Band& outBand = *outRasterPtr->getBand( 0 );
692  const double inNoData1 = inBand1.getProperty()->m_noDataValue;
693  const double inNoData2 = inBand2.getProperty()->m_noDataValue;
694  const double outNoData = outBand.getProperty()->m_noDataValue;
695  unsigned int row = 0;
696  unsigned int col = 0;
697  double value1 = 0;
698  double value2 = 0;
699  double outValue = 0;
700 
701  for( row = 0 ; row < nRows ; ++row )
702  {
703  for( col = 0 ; col < nCols ; ++col )
704  {
705  inBand1.getValue( col, row, value1 );
706  inBand2.getValue( col, row, value2 );
707 
708  if( ( value1 != inNoData1 ) && ( value2 != inNoData2 ) )
709  {
710  (this->*binOptFunctPtr)( value1, value2, outValue );
711  outBand.setValue( col, row, outValue );
712  }
713  else
714  {
715  outBand.setValue( col, row, outNoData );
716  }
717  }
718  }
719 
720  return true;
721  }
722  else
723  {
724  te::gm::Envelope extent2( *inRaster2.getGrid()->getExtent() );
725  extent2.transform( inRaster2.getGrid()->getSRID(), inRaster1.getGrid()->getSRID() );
726 
727  double overlapULCol1 = 0;
728  double overpalULRow1 = 0;
729  inRaster1.getGrid()->geoToGrid( extent2.getLowerLeftX(), extent2.getUpperRightY(),
730  overlapULCol1, overpalULRow1 );
731  overlapULCol1 = std::max( 0.0, std::min( static_cast<double>( inRaster1.getNumberOfColumns()
732  - 1 ), overlapULCol1 ) );
733  overpalULRow1 = std::max( 0.0, std::min( static_cast<double>( inRaster1.getNumberOfRows()
734  - 1 ), overpalULRow1 ) );
735 
736  double overlapLRCol1 = 0;
737  double overlapLRRow1 = 0;
738  inRaster1.getGrid()->geoToGrid( extent2.getUpperRightX(), extent2.getLowerLeftY(),
739  overlapLRCol1, overlapLRRow1 );
740  overlapLRCol1 = std::max( 0.0, std::min( static_cast<double>( inRaster1.getNumberOfColumns()
741  - 1 ), overlapLRCol1 ) );
742  overlapLRRow1 = std::max( 0.0, std::min( static_cast<double>( inRaster1.getNumberOfRows()
743  - 1 ), overlapLRRow1 ) );
744 
745  const unsigned int overlapFirstCol1 = static_cast<unsigned int>(std::floor( overlapULCol1 ));
746  const unsigned int overlapFirstRow1 = static_cast<unsigned int>(std::floor( overpalULRow1 ));
747  const unsigned int overlapLastCol1 = static_cast<unsigned int>(std::ceil( overlapLRCol1 ));
748  const unsigned int overlapLastRow1 = static_cast<unsigned int>(std::ceil( overlapLRRow1 ));
749 
750  const unsigned int nRows1 = inRaster1.getNumberOfRows();
751  const unsigned int nCols1 = inRaster1.getNumberOfColumns();
752  const te::rst::Band& inBand1 = *inRaster1.getBand( band1Idx );
753  const te::rst::Grid& grid1 = *inRaster1.getGrid();
754  const te::rst::Grid& grid2 = *inRaster2.getGrid();
755  te::rst::Band& outBand = *outRasterPtr->getBand( 0 );
756  const double inNoData1 = inBand1.getProperty()->m_noDataValue;
757  const double inNoData2 = inRaster2.getBand( band2Idx )->getProperty()->m_noDataValue;
758  const double outNoData = outBand.getProperty()->m_noDataValue;
759  te::srs::Converter converter( inRaster1.getSRID(), inRaster2.getSRID() );
760  te::rst::Interpolator interpolator2( &inRaster2, m_inputParameters.m_interpMethod );
761  unsigned int row1 = 0;
762  unsigned int col1 = 0;
763  double row2 = 0;
764  double col2 = 0;
765  double value1 = 0;
766  std::complex< double > value2;
767  double outValue = 0;
768  double currX1 = 0;
769  double currY1 = 0;
770  double currX2 = 0;
771  double currY2 = 0;
772 
773  for( row1 = 0 ; row1 < nRows1 ; ++row1 )
774  {
775  for( col1 = 0 ; col1 < nCols1 ; ++col1 )
776  {
777  if( ( row1 >= overlapFirstRow1 ) && ( row1 <= overlapLastRow1 ) &&
778  ( col1 >= overlapFirstCol1 ) && ( col1 <= overlapLastCol1 ) )
779  {
780  grid1.gridToGeo( static_cast<double>(col1), static_cast<double>(row1), currX1, currY1 );
781  converter.convert( currX1, currY1, currX2, currY2 );
782  grid2.geoToGrid( currX2, currY2, col2, row2 );
783 
784  inBand1.getValue( col1, row1, value1 );
785  interpolator2.getValue( col2, row2, value2, band2Idx );
786 
787  if( ( value1 != inNoData1 ) && ( value2.real() != inNoData2 ) )
788  {
789  (this->*binOptFunctPtr)( value1, value2.real(), outValue );
790  outBand.setValue( col1, row1, outValue );
791  }
792  else
793  {
794  outBand.setValue( col1, row1, outNoData );
795  }
796  }
797  else
798  {
799  outBand.setValue( col1, row1, outNoData );
800  }
801  }
802  }
803 
804  return true;
805  }
806 
807  return true;
808  }
809 
811  const te::rst::Raster& inRaster,
812  const unsigned int bandIdx, const double value,
813  const BinOpFuncPtrT binOptFunctPtr,
814  std::unique_ptr<te::rst::Raster>& outRasterPtr,
815  const bool realNumberIsRigthtTerm ) const
816  {
817  if( ! allocResultRaster( *inRaster.getGrid(), outRasterPtr ) )
818  {
819  return false;
820  }
821 
822  const unsigned int nRows = inRaster.getNumberOfRows();
823  const unsigned int nCols = inRaster.getNumberOfColumns();
824  const te::rst::Band& inBand = *inRaster.getBand( bandIdx );
825  te::rst::Band& outBand = *outRasterPtr->getBand( 0 );
826  const double inNoData = inBand.getProperty()->m_noDataValue;
827  const double outNoData = outBand.getProperty()->m_noDataValue;
828  unsigned int row = 0;
829  unsigned int col = 0;
830  double value1 = 0;
831  double outValue = 0;
832 
833  if( realNumberIsRigthtTerm )
834  {
835  for( row = 0 ; row < nRows ; ++row )
836  {
837  for( col = 0 ; col < nCols ; ++col )
838  {
839  inBand.getValue( col, row, value1 );
840 
841  if( value1 != inNoData )
842  {
843  (this->*binOptFunctPtr)( value1, value, outValue );
844  outBand.setValue( col, row, outValue );
845  }
846  else
847  {
848  outBand.setValue( col, row, outNoData );
849  }
850  }
851  }
852  }
853  else
854  {
855  for( row = 0 ; row < nRows ; ++row )
856  {
857  for( col = 0 ; col < nCols ; ++col )
858  {
859  inBand.getValue( col, row, value1 );
860 
861  if( value1 != inNoData )
862  {
863  (this->*binOptFunctPtr)( value, value1, outValue );
864  outBand.setValue( col, row, outValue );
865  }
866  else
867  {
868  outBand.setValue( col, row, outNoData );
869  }
870  }
871  }
872  }
873 
874  return true;
875  }
876 
877  bool ArithmeticOperations::execUnaryOperator( const std::string& token, ExecStackT&
878  execStack, bool generateOutput ) const
879  {
880  if (execStack.size() != 1)
881  {
882  return false;
883  }
884 
885  ExecStackElement sElem = execStack.top();
886  execStack.pop();
887 
888  // Choosing the binary operator function
889 
890  UnaryOpFuncPtrT unaryOptFunctPtr = nullptr;
891 
892  if (token == "sqrt")
893  {
894  unaryOptFunctPtr = &ArithmeticOperations::sqrtUnaryOp;
895  }
896  else if (token == "sin")
897  {
898  unaryOptFunctPtr = &ArithmeticOperations::sinUnaryOp;
899  }
900  else if (token == "asin")
901  {
902  unaryOptFunctPtr = &ArithmeticOperations::asinUnaryOp;
903  }
904  else if (token == "cos")
905  {
906  unaryOptFunctPtr = &ArithmeticOperations::cosUnaryOp;
907  }
908  else if (token == "acos")
909  {
910  unaryOptFunctPtr = &ArithmeticOperations::acosUnaryOp;
911  }
912  else if (token == "log")
913  {
914  unaryOptFunctPtr = &ArithmeticOperations::logUnaryOp;
915  }
916  else if (token == "tan")
917  {
918  unaryOptFunctPtr = &ArithmeticOperations::tanUnaryOp;
919  }
920  else if (token == "atan")
921  {
922  unaryOptFunctPtr = &ArithmeticOperations::atanUnaryOp;
923  }
924  else if (token == "ln")
925  {
926  unaryOptFunctPtr = &ArithmeticOperations::lnUnaryOp;
927  }
928  else
929  {
930  TERP_LOG_AND_RETURN_FALSE("Invalid operator");
931  }
932 
933  // executing the choosen operator
934 
935  ExecStackElement outElement;
936  outElement.m_isRaster = true;
937  outElement.m_rasterBand = 0;
938 
939  if (generateOutput)
940  {
941  if (sElem.m_isRaster)
942  {
944  *sElem.m_rasterNPtr, sElem.m_rasterBand,
945  unaryOptFunctPtr, outElement.m_rasterHandler),
946  "Operator execution error");
947  outElement.m_rasterNPtr = outElement.m_rasterHandler.get();
948  }
949  else
950  {
951  TERP_LOG_AND_RETURN_FALSE("Invalid stack elements");
952  }
953  }
954 
955  execStack.push(outElement);
956 
957  return true;
958  }
959 
961  const te::rst::Raster& inRaster,
962  const unsigned int bandIdx,
963  const UnaryOpFuncPtrT unaryOptFunctPtr,
964  std::unique_ptr<te::rst::Raster>& outRasterPtr) const
965  {
966  if (!allocResultRaster(*inRaster.getGrid(), outRasterPtr))
967  {
968  return false;
969  }
970 
971  const unsigned int nRows = inRaster.getNumberOfRows();
972  const unsigned int nCols = inRaster.getNumberOfColumns();
973  const te::rst::Band& inBand = *inRaster.getBand(bandIdx);
974  te::rst::Band& outBand = *outRasterPtr->getBand(0);
975  const double inNoData = inBand.getProperty()->m_noDataValue;
976  const double outNoData = outBand.getProperty()->m_noDataValue;
977  unsigned int row = 0;
978  unsigned int col = 0;
979  double value = 0;
980  double outValue = 0;
981 
982  for (row = 0; row < nRows; ++row)
983  {
984  for (col = 0; col < nCols; ++col)
985  {
986  inBand.getValue(col, row, value);
987 
988  if ((value != inNoData))
989  {
990  (this->*unaryOptFunctPtr)(value, outValue);
991  outBand.setValue(col, row, outValue);
992  }
993  else
994  {
995  outBand.setValue(col, row, outNoData);
996  }
997  }
998  }
999 
1000  return true;
1001  }
1002 
1004  const double value, const UnaryOpFuncPtrT unaryOptFunctPtr,
1005  std::unique_ptr<te::rst::Raster>& outRasterPtr,
1006  const bool realNumberIsRigthtTerm) const
1007  {
1008  const unsigned int nRows = outRasterPtr->getNumberOfRows();
1009  const unsigned int nCols = outRasterPtr->getNumberOfColumns();
1010  te::rst::Band& outBand = *outRasterPtr->getBand(0);
1011  const double outNoData = outBand.getProperty()->m_noDataValue;
1012  unsigned int row = 0;
1013  unsigned int col = 0;
1014  double outValue = 0;
1015 
1016  if (realNumberIsRigthtTerm)
1017  {
1018  for (row = 0; row < nRows; ++row)
1019  {
1020  for (col = 0; col < nCols; ++col)
1021  {
1022  if (value != outNoData)
1023  {
1024  (this->*unaryOptFunctPtr)(value, outValue);
1025  outBand.setValue(col, row, outValue);
1026  }
1027  else
1028  {
1029  outBand.setValue(col, row, outNoData);
1030  }
1031  }
1032  }
1033  }
1034 
1035  return true;
1036  }
1037 
1038  bool ArithmeticOperations::isRealNumberToken( const std::string& token, double& realValue ) const
1039  {
1040  if( token.size() == 0 ) return false;
1041  bool hasDot = false;
1042 
1043  unsigned int initIdx = 0;
1044  if( ( token[ 0 ] == '+' ) || ( token[ 0 ] == '-' ) )
1045  {
1046  if( token.size() == 1 ) return false;
1047  initIdx = 1;
1048  }
1049 
1050  for( unsigned int tIdx = initIdx ; tIdx < token.size() ; ++tIdx )
1051  {
1052  if( token[ tIdx ] == '.' )
1053  {
1054  if( hasDot ) return false;
1055  hasDot = true;
1056  }
1057  else if( ! isdigit( token[ tIdx ] ) ) return false;
1058  }
1059 
1060  realValue = atof( token.c_str() );
1061 
1062  return true;
1063  }
1064 
1066  std::unique_ptr<te::rst::Raster>& rasterPtr ) const
1067  {
1068  std::map<std::string, std::string> rinfo;
1069 
1070  std::vector< te::rst::BandProperty * > bandsProperties;
1071  bandsProperties.push_back( new te::rst::BandProperty( 0, te::dt::DOUBLE_TYPE, "" ) );
1072  bandsProperties[ 0 ]->m_noDataValue = std::numeric_limits< double >::max();
1073  bandsProperties[ 0 ]->m_blkw = static_cast<int>(grid.getNumberOfColumns());
1074  bandsProperties[ 0 ]->m_blkh = 1;
1075  bandsProperties[ 0 ]->m_nblocksx = 1;
1076  bandsProperties[ 0 ]->m_nblocksy = static_cast<int>(grid.getNumberOfRows());
1077 
1078  rasterPtr.reset( new te::mem::ExpansibleRaster( 50, new te::rst::Grid(
1079  grid ), bandsProperties ) );
1080 
1081  return true;
1082  }
1083 
1084  void ArithmeticOperations::getTokensStrs( const std::string& inputStr,
1085  std::vector< std::string >& outTokens ) const
1086  {
1087  outTokens.clear();
1088 
1089  const unsigned int inputStrSize = static_cast<unsigned int>(inputStr.size());
1090  std::string bufferStr;
1091 
1092  for( unsigned int inputStrIdx = 0 ; inputStrIdx < inputStrSize ;
1093  ++inputStrIdx )
1094  {
1095  if( inputStr[ inputStrIdx ] == ' ' )
1096  {
1097  // flush the last formed token
1098  if( bufferStr.size() )
1099  {
1100  outTokens.push_back( bufferStr );
1101  bufferStr.clear();
1102  }
1103  }
1104  else
1105  {
1106  if( ( inputStr[ inputStrIdx ] == '+' ) ||
1107  ( inputStr[ inputStrIdx ] == '-' ) )
1108  {
1109  bufferStr.append( inputStr.substr( inputStrIdx, 1 ) );
1110  }
1111  else if( ( inputStr[ inputStrIdx ] == ')' ) ||
1112  ( inputStr[ inputStrIdx ] == '(' ) ||
1113  isOperator( inputStr.substr( inputStrIdx, 1 ) ) )
1114  {
1115  // flush the last formed token
1116  if( bufferStr.size() )
1117  {
1118  outTokens.push_back( bufferStr );
1119  bufferStr.clear();
1120  }
1121 
1122  outTokens.push_back( inputStr.substr( inputStrIdx, 1 ) );
1123  }
1124  else
1125  {
1126  bufferStr.append( inputStr.substr( inputStrIdx, 1 ) );
1127  }
1128  }
1129  }
1130 
1131  if( bufferStr.size() )
1132  {
1133  outTokens.push_back( bufferStr );
1134  }
1135  }
1136  }
1137 }
void getTokensStrs(const std::string &inputStr, std::vector< std::string > &outTokens) const
Split the input string into a vector of token strings.
void asinUnaryOp(const double &inputValue, double &outputValue) const
Arc sine unary operator function.
void printTokens(const std::vector< std::string > &input) const
Print tokens to stout.
unsigned int getNumberOfRows() const
Returns the grid number of rows.
virtual void setValue(unsigned int c, unsigned int r, const double value, std::size_t b=0)
Sets the attribute value in a band of a cell.
std::string m_rType
Output raster data source type (as described in te::raster::RasterFactory ).
void divisionBinOp(const double &inputValue1, const double &inputValue2, double &outputValue) const
Division binary operator function.
Near neighborhood interpolation method.
bool isUnaryOperator(const std::string &inputToken) const
Returns true if the given token is a unary operator.
const OutputParameters & operator=(const OutputParameters &params)
AbstractParameters * clone() const
Create a clone copy of this instance.
void reset() _NOEXCEPT_OP(false)
Clear all internal allocated objects and reset the algorithm to its initial state.
A raster band description.
Definition: BandProperty.h:61
int getSRID() const
Returns the grid spatial reference system identifier.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
void cosUnaryOp(const double &inputValue, double &outputValue) const
Cosine unary operator function.
bool isBinaryOperator(const std::string &inputToken) const
Returns true if the given token is a binary operator.
It interpolates one pixel based on a selected algorithm. Methods currently available are Nearest Neig...
Definition: Interpolator.h:55
void TERPEXPORT GetDataTypeRange(const int dataType, double &min, double &max)
Returns the real data type range (all values that can be represented by the given data type)...
bool m_isInitialized
Tells if this instance is initialized.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
bool execute(AlgorithmOutputParameters &outputParams) _NOEXCEPT_OP(false)
Executes the algorithm using the supplied parameters.
Raster Processing algorithm output parameters base interface.
#define MIN(a, b)
Macro that returns min between two values.
bool execUnaryOperator(const std::string &token, ExecStackT &execStack, bool generateOutput) const
Execute the given unary operator using the current given execution stack.
bool m_normalize
Output values normalization will be performed to fit the original input raster values range (default:...
ArithmeticOperations::InputParameters m_inputParameters
Input execution parameters.
void exponencialBinOp(const double &inputValue1, const double &inputValue2, double &outputValue) const
Exponencial binary operator function.
std::map< std::string, std::string > m_rInfo
The necessary information to create the output rasters (as described in te::raster::RasterFactory).
#define _NOEXCEPT_OP(x)
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
Definition: BandProperty.h:136
bool initialize(const AlgorithmInputParameters &inputParams) _NOEXCEPT_OP(false)
Initialize the algorithm instance making it ready for execution.
Performs arithmetic operation over raster data.
bool m_enableProgress
Enable/Disable the progress interface (default:false).
#define MAX(a, b)
Macro that returns max between two values.
bool m_isRaster
true if this is a raster pointer element.
bool isActive() const
Verify if the task is active.
void geoToGrid(const double &x, const double &y, double &col, double &row) const
Get the grid point associated to a spatial location.
void acosUnaryOp(const double &inputValue, double &outputValue) const
Arc cosine unary operator function.
std::stack< ExecStackElement > ExecStackT
Execution stack type definition.
void(ArithmeticOperations::* UnaryOpFuncPtrT)(const double &inputValue1, double &outputValue) const
#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:185
unsigned int unsigned int nCols
An Envelope defines a 2D rectangular region.
An abstract class for raster data strucutures.
unsigned int getNumberOfRows() const
Returns the raster number of rows.
std::unique_ptr< te::rst::Raster > m_outputRasterPtr
The generated output registered raster.
BandProperty * getProperty()
Returns the band property.
URI C++ Library.
Definition: Attributes.h:37
bool execUnaryOperatorReal(const double value, const UnaryOpFuncPtrT unaryOptFunctPtr, std::unique_ptr< te::rst::Raster > &outRasterPtr, const bool realNumberIsRigthtTerm) const
Execute the given unary operator using the given a real number.
ArithmeticOperations output parameters.
unsigned int getNumberOfColumns() const
Returns the grid number of columns.
bool isRasterBandToken(const std::string &token, unsigned int &rasterIdx, unsigned int &bandIdx) const
Returns true if the given token is a raster data token.
void tanUnaryOp(const double &inputValue, double &outputValue) const
Tangent unary operator function.
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
bool execUnaryOperatorRaster(const te::rst::Raster &inRaster, const unsigned int band, const UnaryOpFuncPtrT unaryOptFunctPtr, std::unique_ptr< te::rst::Raster > &outRasterPtr) const
Execute the given unary operator using the given input raster.
A raster band description.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
bool executeString(const std::string &aStr, const std::vector< te::rst::Raster * > &inRasters, std::unique_ptr< te::rst::Raster > &outRaster, bool generateOutput, te::common::TaskProgress *const progressPtr) const
Execute the automata parsing the given input string.
Grid * getGrid()
It returns the raster grid.
void reset() _NOEXCEPT_OP(false)
Clear all internal allocated resources and reset the parameters instance to its initial state...
void sqrtUnaryOp(const double &inputValue, double &outputValue) const
Square root unary operator function.
virtual void getValue(unsigned int c, unsigned int r, double &value, std::size_t b=0) const
Returns the attribute value of a band of a cell.
te::rst::Raster * m_rasterNPtr
Raster pointer.
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
std::vector< te::rst::Raster * > m_inputRasters
Input rasters vector.
Abstract parameters base interface.
void reset() _NOEXCEPT_OP(false)
Clear all internal allocated resources and reset the parameters instance to its initial state...
int getSRID() const
Returns the raster spatial reference system identifier.
#define TERP_LOG_AND_RETURN_FALSE(message)
Logs a warning message will and return false.
Definition: Macros.h:269
void(ArithmeticOperations::* BinOpFuncPtrT)(const double &inputValue1, const double &inputValue2, double &outputValue) const
Type definition for a operation function pointer.
bool isRealNumberToken(const std::string &token, double &realValue) const
Returns true if the given token is a real number.
void logUnaryOp(const double &inputValue, double &outputValue) const
Common logarithm unary operator function.
void lnUnaryOp(const double &inputValue, double &outputValue) const
unary operator function.
A raster (stored in memory and eventually swapped to disk) where it is possible to dynamically add li...
void atanUnaryOp(const double &inputValue, double &outputValue) const
Arc Tangent unary operator function.
static Raster * make()
It creates and returns an empty raster with default raster driver.
te::gm::Envelope * getExtent()
Returns the geographic extension of the grid.
void inFix2PostFix(const std::vector< std::string > &input, std::vector< std::string > &output) const
Convert the input tokens vector from the infix notation to postfix notation.
void gridToGeo(const double &col, const double &row, double &x, double &y) const
Get the spatial location of a grid point.
void subtractionBinOp(const double &inputValue1, const double &inputValue2, double &outputValue) const
Subtraction binary operator function.
Raster Processing algorithm input parameters base interface.
bool op1HasGreaterOrEqualPrecedence(const std::string &operator1, const std::string &operator2) const
Returns true if operator1 has greater of equal precedence over operator2.
std::unique_ptr< te::rst::Raster > m_rasterHandler
Raster handler.
Raster Processing functions.
bool execBinaryOperator(const std::string &token, ExecStackT &execStack, bool generateOutput) const
Execute the given binary operator using the current given execution stack.
bool execBinaryOperatorRasterXRaster(const te::rst::Raster &inRaster1, const unsigned int band1, const te::rst::Raster &inRaster2, const unsigned int band2, const BinOpFuncPtrT binOptFunctPtr, std::unique_ptr< te::rst::Raster > &outRasterPtr) const
Execute the given binary operator using the given input rasters.
bool isInitialized() const
Returns true if the algorithm instance is initialized and ready for execution.
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
bool isOperator(const std::string &inputToken) const
Returns true if the given token is an operator.
bool m_isRealNumber
true if this is a real number element.
void transform(int oldsrid, int newsrid)
It will transform the coordinates of the Envelope from the old SRS to the new one.
#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
te::rst::Interpolator::Method m_interpMethod
The raster interpolator method (default:NearestNeighbor).
bool execBinaryOperatorRasterXReal(const te::rst::Raster &inRaster, const unsigned int bandIdx, const double value, const BinOpFuncPtrT binOptFunctPtr, std::unique_ptr< te::rst::Raster > &outRasterPtr, const bool realNumberIsRigthtTerm) const
Execute the given binary operator using the given input raster and a real number. ...
const InputParameters & operator=(const InputParameters &params)
unsigned int col
bool allocResultRaster(const te::rst::Grid &grid, std::unique_ptr< te::rst::Raster > &rasterPtr) const
Allocate a new RAM memory raster.
ArithmeticOperations input parameters.
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:150
void multiplicationBinOp(const double &inputValue1, const double &inputValue2, double &outputValue) const
Multiplication binary operator function.
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
void sinUnaryOp(const double &inputValue, double &outputValue) const
Sine unary operator function.
AbstractParameters * clone() const
Create a clone copy of this instance.
void additionBinOp(const double &inputValue1, const double &inputValue2, double &outputValue) const
Addition binary operator function.
std::string m_arithmeticString
Arithmetic string.