All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
60  void ArithmeticOperations::InputParameters::reset() throw( te::rp::Exception )
61  {
62  m_inputRasters.clear();
63  m_arithmeticString.clear();
64  m_normalize = false;
65  m_enableProgress = false;
66  m_interpMethod = te::rst::NearestNeighbor;
67  }
68 
71  {
72  reset();
73 
74  m_inputRasters = params.m_inputRasters;
75  m_arithmeticString = params.m_arithmeticString;
76  m_normalize = params.m_normalize;
77  m_enableProgress = params.m_enableProgress;
78  m_interpMethod = params.m_interpMethod;
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 
104  void ArithmeticOperations::OutputParameters::reset() throw( te::rp::Exception )
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  {
135  }
136 
138  throw( te::rp::Exception )
139  {
140  TERP_TRUE_OR_RETURN_FALSE( m_isInitialized, "Algoritm not initialized" );
141 
142  ArithmeticOperations::OutputParameters* outParamsPtr = dynamic_cast<
143  ArithmeticOperations::OutputParameters* >( &outputParams );
144  TERP_TRUE_OR_THROW( outParamsPtr, "Invalid paramters" );
145 
146  // Counting the number of operations to be done
147  std::string arithmetic_string = m_inputParameters.m_arithmeticString;
148 
149  unsigned int operationsNumber = 0;
150  {
151  for( unsigned sIdx = 0 ; sIdx < arithmetic_string.size() ; ++sIdx )
152  {
153  std::string auxStr;
154  auxStr.push_back( arithmetic_string[ sIdx ] );
155 
156  if( isOperator( auxStr ) ) ++operationsNumber;
157  }
158  }
159 
160  // progress
161 
162  std::auto_ptr< te::common::TaskProgress > progressPtr;
164  {
165  progressPtr.reset( new te::common::TaskProgress );
166 
167  progressPtr->setTotalSteps( operationsNumber );
168 
169  progressPtr->setMessage( "Arithmetic Operations" );
170  }
171 
172  // Executing the arithmetic string
173 
174  std::auto_ptr<te::rst::Raster> auxRasterPtr;
175  TERP_TRUE_OR_RETURN_FALSE( executeString( arithmetic_string,
176  m_inputParameters.m_inputRasters, auxRasterPtr, true, progressPtr.get() ),
177  "Arithmetic string execution error" );
178 
179  // Initializing the output raster
180 
181  std::vector< te::rst::BandProperty* > bandsProperties;
182  bandsProperties.push_back( new te::rst::BandProperty(
183  *( m_inputParameters.m_inputRasters[0]->getBand(0)->getProperty() ) ) );
185  {
186  bandsProperties[ 0 ]->m_type = auxRasterPtr->getBand( 0 )->getProperty()->m_type;
187  bandsProperties[ 0 ]->m_noDataValue = auxRasterPtr->getBand( 0 )->getProperty()->m_noDataValue;
188  }
189 
190  outParamsPtr->m_outputRasterPtr.reset(
192  outParamsPtr->m_rType,
193  new te::rst::Grid( *( auxRasterPtr->getGrid() ) ),
194  bandsProperties,
195  outParamsPtr->m_rInfo,
196  0,
197  0 ) );
198  TERP_TRUE_OR_RETURN_FALSE( outParamsPtr->m_outputRasterPtr.get(),
199  "Output raster creation error" );
200 
201  // Copy result data to output raster
202 
203  const unsigned int nRows = (unsigned int)auxRasterPtr->getNumberOfRows();
204  const unsigned int nCols = (unsigned int)auxRasterPtr->getNumberOfColumns();
205  unsigned int row = 0;
206  unsigned int col = 0;
207  double value = 0;
208  te::rst::Raster& auxRasterRef = *auxRasterPtr;
209  te::rst::Raster& outRasterRef = *outParamsPtr->m_outputRasterPtr;
210 
211  double outAllowedMin = 0;
212  double outAllowedMax = 0;
213  GetDataTypeRange( outParamsPtr->m_outputRasterPtr->getBandDataType( 0 ) ,
214  outAllowedMin, outAllowedMax );
215 
216  if( m_inputParameters.m_normalize && ( outRasterRef.getBand(0)->getProperty()->getType() !=
218  {
219  // Calculating the output gain and offset
220 
221  const double auxNoDataValue = auxRasterRef.getBand( 0 )->getProperty()->m_noDataValue;
222  const double outNoDataValue = outRasterRef.getBand( 0 )->getProperty()->m_noDataValue;
223  double auxMin = DBL_MAX;
224  double auxMax = -1.0 * auxMin;
225 
226  for( row = 0 ; row < nRows ; ++row )
227  {
228  for( col = 0 ; col < nCols ; ++col )
229  {
230  auxRasterRef.getValue( col, row, value, 0 );
231 
232  if( auxNoDataValue != value )
233  {
234  if( auxMin > value ) auxMin = value;
235  if( auxMax < value ) auxMax = value;
236  }
237  }
238  }
239 
240  double outputOffset = 0;
241  double outputGain = 1.0;
242  if( ( auxMin != DBL_MAX ) && ( auxMax != ( -1.0 * DBL_MAX ) ) && ( auxMax != auxMin ) )
243  {
244  outputOffset = -1.0 * auxMin;
245  outputGain = ( ( outAllowedMax - outAllowedMin ) / ( auxMax - auxMin ) );
246  }
247 
248  for( row = 0 ; row < nRows ; ++row )
249  {
250  for( col = 0 ; col < nCols ; ++col )
251  {
252  auxRasterRef.getValue( col, row, value, 0 );
253 
254  if( auxNoDataValue == value )
255  {
256  outRasterRef.setValue( col, row, outNoDataValue, 0 );
257  }
258  else
259  {
260  value += outputOffset;
261  value *= outputGain;
262 
263  value = MIN( value, outAllowedMax );
264  value = MAX( value, outAllowedMin );
265 
266  outRasterRef.setValue( col, row, value, 0 );
267  }
268  }
269  }
270  }
271  else
272  {
273  for( row = 0 ; row < nRows ; ++row )
274  {
275  for( col = 0 ; col < nCols ; ++col )
276  {
277  auxRasterRef.getValue( col, row, value, 0 );
278  outRasterRef.setValue( col, row, value, 0 );
279  }
280  }
281  }
282 
283  return true;
284  }
285 
286  void ArithmeticOperations::reset() throw( te::rp::Exception )
287  {
289  m_isInitialized = false;
290  }
291 
293  throw( te::rp::Exception )
294  {
295  reset();
296 
297  ArithmeticOperations::InputParameters const* inputParamsPtr = dynamic_cast<
298  ArithmeticOperations::InputParameters const* >( &inputParams );
299  TERP_TRUE_OR_THROW( inputParamsPtr, "Invalid paramters pointer" );
300 
301  m_inputParameters = *inputParamsPtr;
302 
303  // Checking the feeder
304 
306  "Invalid number of rasters" );
307 
308  for( std::size_t t = 0; t < m_inputParameters.m_inputRasters.size(); ++t )
309  {
311  "Invalid raster" )
313  & te::common::RAccess, "Invalid raster access policy" )
314  }
315 
316  // Checking the expression
317 
319  "Arithmetic string is empty" )
320 
321  std::auto_ptr<te::rst::Raster> rasterNull;
323  m_inputParameters.m_inputRasters, rasterNull, false, 0), "Invalid arithmetic string" )
324 
325  m_isInitialized = true;
326 
327  return true;
328  }
329 
331  {
332  return m_isInitialized;
333  }
334 
335  bool ArithmeticOperations::executeString( const std::string& aStr,
336  const std::vector< te::rst::Raster* >& inRasters,
337  std::auto_ptr<te::rst::Raster>& outRaster,
338  bool generateOutput,
339  te::common::TaskProgress* const progressPtr ) const
340  {
341  std::vector< std::string > infixTokensVec;
342  getTokensStrs( aStr, infixTokensVec );
343 
344  if( infixTokensVec.size() )
345  {
346  std::vector< std::string > postfixTokensVec;
347 
348  inFix2PostFix( infixTokensVec, postfixTokensVec );
349 
350  ExecStackT execStack;
351  unsigned int auxRasterIdx = 0;
352  unsigned int auxBandIdx = 0;
353  double auxRealValue = 0;
354 
355  for( unsigned int tIdx = 0 ; tIdx < postfixTokensVec.size() ; ++tIdx )
356  {
357  const std::string& curToken = postfixTokensVec[ tIdx ];
358 
359  if( isRasterBandToken( curToken, auxRasterIdx, auxBandIdx ) )
360  {
361  TERP_TRUE_OR_RETURN_FALSE( auxRasterIdx < inRasters.size(),
362  "Invalid raster index found at " + curToken );
363 
364  TERP_TRUE_OR_RETURN_FALSE( (std::size_t)auxBandIdx < inRasters[auxRasterIdx]->getNumberOfBands(),
365  "Invalid band index" );
366 
367  ExecStackElement auxEle;
368  auxEle.m_isRaster = true;
369  auxEle.m_rasterNPtr = inRasters[auxRasterIdx];
370  auxEle.m_rasterBand = auxBandIdx;
371 
372  execStack.push( auxEle );
373  }
374  else if( isRealNumberToken( curToken, auxRealValue ) )
375  {
376  ExecStackElement auxEle;
377  auxEle.m_isRealNumber = true;
378  auxEle.m_realNumberValue = auxRealValue;
379 
380  execStack.push( auxEle );
381  }
382  else if( isBinaryOperator( curToken ) )
383  {
384  TERP_TRUE_OR_RETURN_FALSE( execBinaryOperator( curToken, execStack, generateOutput ),
385  "Operator " + curToken + " execution error" );
386 
387  if( progressPtr )
388  {
389  if( ! progressPtr->isActive() )
390  {
391  return false;
392  }
393  progressPtr->pulse();
394  }
395  }
396  else if( isUnaryOperator( curToken ) )
397  {
398  TERP_TRUE_OR_RETURN_FALSE( execUnaryOperator( curToken, execStack, generateOutput ),
399  "Operator " + curToken + " execution error" );
400 
401  if( progressPtr )
402  {
403  if( ! progressPtr->isActive() )
404  {
405  return false;
406  }
407  progressPtr->pulse();
408  }
409  }
410  else
411  {
412  TERP_LOG_AND_RETURN_FALSE( "Invalid operator found: " + curToken );
413  }
414  }
415 
416  TERP_TRUE_OR_RETURN_FALSE( execStack.size() == 1, "Invalid stack size" );
417  TERP_TRUE_OR_RETURN_FALSE( execStack.top().m_isRaster, "Stack result error" );
418 
419  outRaster.reset( execStack.top().m_rasterHandler.release() );
420  }
421 
422  return true;
423  }
424 
425  void ArithmeticOperations::inFix2PostFix( const std::vector< std::string >& input,
426  std::vector< std::string >& output ) const
427  {
428  output.clear();
429 
430  std::stack< std::string > auxStack;
431  const unsigned int inputSize = (unsigned int)input.size();
432 
433  for( unsigned int inIdx = 0 ; inIdx < inputSize ; ++inIdx )
434  {
435  const std::string& currInToken = input[ inIdx ];
436 
437  if( isOperator( currInToken ) )
438  {
439  while( ( ! auxStack.empty() ) && ( auxStack.top() != "(" ) )
440  {
441  if ( op1HasGreaterOrEqualPrecedence( auxStack.top(), currInToken ) )
442  {
443  output.push_back( auxStack.top() );
444 
445  auxStack.pop();
446  }
447  else
448  {
449  break;
450  }
451  }
452 
453  auxStack.push( currInToken );
454  }
455  else if( currInToken == "(" )
456  {
457  auxStack.push( currInToken );
458  }
459  else if( currInToken == ")" )
460  {
461  while ( ( ! auxStack.empty() ) && ( auxStack.top() != "(" ) )
462  {
463  output.push_back( auxStack.top() );
464 
465  auxStack.pop();
466  }
467 
468  if ( ! auxStack.empty() )
469  {
470  auxStack.pop();
471  }
472  }
473  else
474  {
475  output.push_back( currInToken );
476  }
477  }
478 
479  while ( ! auxStack.empty() )
480  {
481  output.push_back( auxStack.top() );
482 
483  auxStack.pop();
484  }
485  }
486 
487  void ArithmeticOperations::printTokens( const std::vector< std::string >& input ) const
488  {
489  std::cout << std::endl;
490 
491  for( unsigned int idx = 0 ; idx < input.size() ; ++idx )
492  {
493  std::cout << "[" << input[ idx ] << "]";
494  }
495 
496  std::cout << std::endl;
497  }
498 
499  bool ArithmeticOperations::isOperator( const std::string& inputToken ) const
500  {
501  return ( isBinaryOperator( inputToken ) ||
502  isUnaryOperator( inputToken ) );
503  }
504 
505  bool ArithmeticOperations::isBinaryOperator( const std::string& inputToken ) const
506  {
507  return ( ( inputToken == "+" ) || ( inputToken == "-" ) ||
508  ( inputToken == "*" ) || ( inputToken == "/" ) ) ?
509  true : false;
510  }
511 
512  bool ArithmeticOperations::isUnaryOperator( const std::string& inputToken ) const
513  {
514  return false;
515  }
516 
517  bool ArithmeticOperations::op1HasGreaterOrEqualPrecedence( const std::string& operator1,
518  const std::string& operator2 ) const
519  {
520  if( ( operator1 == "*" ) || ( operator1 == "/" ) )
521  {
522  return true;
523  }
524  else
525  {
526  if( ( operator2 == "+" ) || ( operator2 == "-" ) )
527  {
528  return true;
529  }
530  }
531 
532  return false;
533  }
534 
535  bool ArithmeticOperations::isRasterBandToken( const std::string& token, unsigned int& rasterIdx,
536  unsigned int& bandIdx ) const
537  {
538  if( token.size() < 4 ) return false;
539  if( token[ 0 ] != 'R' ) return false;
540 
541  std::string rasterIdxStr;
542  unsigned int tIdx = 1;
543 
544  while( ( tIdx < token.size() ) && isdigit( token[ tIdx ] ) )
545  {
546  rasterIdxStr.push_back( token[ tIdx ] );
547  ++tIdx;
548  }
549 
550  if( token[ tIdx ] != ':' ) return false;
551  ++tIdx;
552 
553  std::string bandIdxStr;
554 
555  while( ( tIdx < token.size() ) && isdigit( token[ tIdx ] ) )
556  {
557  bandIdxStr.push_back( token[ tIdx ] );
558  ++tIdx;
559  }
560 
561  if( ( rasterIdxStr.size() ) && ( bandIdxStr.size() ) )
562  {
563  rasterIdx = (unsigned int)atoi( rasterIdxStr.c_str() );
564  bandIdx = (unsigned int)atoi( bandIdxStr.c_str() );
565  return true;
566  }
567  else
568  {
569  return false;
570  }
571  }
572 
573  bool ArithmeticOperations::execBinaryOperator( const std::string& token, ExecStackT&
574  execStack, bool generateOutput ) const
575  {
576  if( execStack.size() < 2 )
577  {
578  return false;
579  }
580 
581  ExecStackElement sElem1 = execStack.top();
582  execStack.pop();
583 
584  ExecStackElement sElem2 = execStack.top();
585  execStack.pop();
586 
587  // Choosing the binary operator function
588 
589  BinOpFuncPtrT binOptFunctPtr = 0;
590 
591  if( token == "+" )
592  {
593  binOptFunctPtr = &ArithmeticOperations::additionBinOp;
594  }
595  else if( token == "-" )
596  {
597  binOptFunctPtr = &ArithmeticOperations::subtractionBinOp;
598  }
599  else if( token == "*" )
600  {
602  }
603  else if( token == "/" )
604  {
605  binOptFunctPtr = &ArithmeticOperations::divisionBinOp;
606  }
607  else
608  {
609  TERP_LOG_AND_RETURN_FALSE( "Invalid operator" );
610  }
611 
612  // executing the choosen operator
613 
614  ExecStackElement outElement;
615  outElement.m_isRaster = true;
616  outElement.m_rasterBand = 0;
617 
618  if( generateOutput )
619  {
620  if( ( sElem1.m_isRaster ) && ( sElem2.m_isRaster ) )
621  {
623  *sElem2.m_rasterNPtr, sElem2.m_rasterBand, *sElem1.m_rasterNPtr,
624  sElem1.m_rasterBand, binOptFunctPtr, outElement.m_rasterHandler ),
625  "Operator execution error" );
626  outElement.m_rasterNPtr = outElement.m_rasterHandler.get();
627  }
628  else if( ( sElem1.m_isRaster ) && ( sElem2.m_isRealNumber ) )
629  {
631  *sElem1.m_rasterNPtr, sElem1.m_rasterBand, sElem2.m_realNumberValue,
632  binOptFunctPtr, outElement.m_rasterHandler, false ),
633  "Operator execution error" );
634  outElement.m_rasterNPtr = outElement.m_rasterHandler.get();
635  }
636  else if( ( sElem1.m_isRealNumber ) && ( sElem2.m_isRaster ) )
637  {
639  *sElem2.m_rasterNPtr, sElem2.m_rasterBand, sElem1.m_realNumberValue,
640  binOptFunctPtr, outElement.m_rasterHandler, true ),
641  "Operator execution error" );
642  outElement.m_rasterNPtr = outElement.m_rasterHandler.get();
643  }
644  else
645  {
646  TERP_LOG_AND_RETURN_FALSE( "Invalid stack elements" );
647  }
648  }
649 
650  execStack.push( outElement );
651 
652  return true;
653  }
654 
656  const te::rst::Raster& inRaster1,
657  const unsigned int band1Idx, const te::rst::Raster& inRaster2,
658  const unsigned int band2Idx,
659  const BinOpFuncPtrT binOptFunctPtr,
660  std::auto_ptr<te::rst::Raster>& outRasterPtr ) const
661  {
662  if( ! allocResultRaster( *inRaster1.getGrid(), outRasterPtr ) )
663  {
664  return false;
665  }
666 
667  if( inRaster1.getGrid()->operator==( *inRaster2.getGrid() ) )
668  {
669  const unsigned int nRows = inRaster1.getNumberOfRows();
670  const unsigned int nCols = inRaster1.getNumberOfColumns();
671  const te::rst::Band& inBand1 = *inRaster1.getBand( band1Idx );
672  const te::rst::Band& inBand2 = *inRaster2.getBand( band2Idx );
673  te::rst::Band& outBand = *outRasterPtr->getBand( 0 );
674  const double inNoData1 = inBand1.getProperty()->m_noDataValue;
675  const double inNoData2 = inBand2.getProperty()->m_noDataValue;
676  const double outNoData = outBand.getProperty()->m_noDataValue;
677  unsigned int row = 0;
678  unsigned int col = 0;
679  double value1 = 0;
680  double value2 = 0;
681  double outValue = 0;
682 
683  for( row = 0 ; row < nRows ; ++row )
684  {
685  for( col = 0 ; col < nCols ; ++col )
686  {
687  inBand1.getValue( col, row, value1 );
688  inBand2.getValue( col, row, value2 );
689 
690  if( ( value1 != inNoData1 ) && ( value2 != inNoData2 ) )
691  {
692  (this->*binOptFunctPtr)( value1, value2, outValue );
693  outBand.setValue( col, row, outValue );
694  }
695  else
696  {
697  outBand.setValue( col, row, outNoData );
698  }
699  }
700  }
701 
702  return true;
703  }
704  else
705  {
706  te::gm::Envelope extent2( *inRaster2.getGrid()->getExtent() );
707  extent2.transform( inRaster2.getGrid()->getSRID(), inRaster1.getGrid()->getSRID() );
708 
709  double overlapULCol1 = 0;
710  double overpalULRow1 = 0;
711  inRaster1.getGrid()->geoToGrid( extent2.getLowerLeftX(), extent2.getUpperRightY(),
712  overlapULCol1, overpalULRow1 );
713  overlapULCol1 = std::max( 0.0, std::min( (double)( inRaster1.getNumberOfColumns()
714  - 1 ), overlapULCol1 ) );
715  overpalULRow1 = std::max( 0.0, std::min( (double)( inRaster1.getNumberOfRows()
716  - 1 ), overpalULRow1 ) );
717 
718  double overlapLRCol1 = 0;
719  double overlapLRRow1 = 0;
720  inRaster1.getGrid()->geoToGrid( extent2.getUpperRightX(), extent2.getLowerLeftY(),
721  overlapLRCol1, overlapLRRow1 );
722  overlapLRCol1 = std::max( 0.0, std::min( (double)( inRaster1.getNumberOfColumns()
723  - 1 ), overlapLRCol1 ) );
724  overlapLRRow1 = std::max( 0.0, std::min( (double)( inRaster1.getNumberOfRows()
725  - 1 ), overlapLRRow1 ) );
726 
727  const unsigned int overlapFirstCol1 = (unsigned int)std::floor( overlapULCol1 );
728  const unsigned int overlapFirstRow1 = (unsigned int)std::floor( overpalULRow1 );
729  const unsigned int overlapLastCol1 = (unsigned int)std::ceil( overlapLRCol1 );
730  const unsigned int overlapLastRow1 = (unsigned int)std::ceil( overlapLRRow1 );
731 
732  const unsigned int nRows1 = inRaster1.getNumberOfRows();
733  const unsigned int nCols1 = inRaster1.getNumberOfColumns();
734  const te::rst::Band& inBand1 = *inRaster1.getBand( band1Idx );
735  const te::rst::Grid& grid1 = *inRaster1.getGrid();
736  const te::rst::Grid& grid2 = *inRaster2.getGrid();
737  te::rst::Band& outBand = *outRasterPtr->getBand( 0 );
738  const double inNoData1 = inBand1.getProperty()->m_noDataValue;
739  const double inNoData2 = inRaster2.getBand( band2Idx )->getProperty()->m_noDataValue;
740  const double outNoData = outBand.getProperty()->m_noDataValue;
741  te::srs::Converter converter( inRaster1.getSRID(), inRaster2.getSRID() );
742  te::rst::Interpolator interpolator2( &inRaster2, m_inputParameters.m_interpMethod );
743  unsigned int row1 = 0;
744  unsigned int col1 = 0;
745  double row2 = 0;
746  double col2 = 0;
747  double value1 = 0;
748  std::complex< double > value2;
749  double outValue = 0;
750  double currX1 = 0;
751  double currY1 = 0;
752  double currX2 = 0;
753  double currY2 = 0;
754 
755  for( row1 = 0 ; row1 < nRows1 ; ++row1 )
756  {
757  for( col1 = 0 ; col1 < nCols1 ; ++col1 )
758  {
759  if( ( row1 >= overlapFirstRow1 ) && ( row1 <= overlapLastRow1 ) &&
760  ( col1 >= overlapFirstCol1 ) && ( col1 <= overlapLastCol1 ) )
761  {
762  grid1.gridToGeo( (double)col1, (double)row1, currX1, currY1 );
763  converter.convert( currX1, currY1, currX2, currY2 );
764  grid2.geoToGrid( currX2, currY2, col2, row2 );
765 
766  inBand1.getValue( col1, row1, value1 );
767  interpolator2.getValue( col2, row2, value2, band2Idx );
768 
769  if( ( value1 != inNoData1 ) && ( value2.real() != inNoData2 ) )
770  {
771  (this->*binOptFunctPtr)( value1, value2.real(), outValue );
772  outBand.setValue( col1, row1, outValue );
773  }
774  else
775  {
776  outBand.setValue( col1, row1, outNoData );
777  }
778  }
779  else
780  {
781  outBand.setValue( col1, row1, outNoData );
782  }
783  }
784  }
785 
786  return true;
787  }
788 
789  return true;
790  }
791 
793  const te::rst::Raster& inRaster,
794  const unsigned int bandIdx, const double value,
795  const BinOpFuncPtrT binOptFunctPtr,
796  std::auto_ptr<te::rst::Raster>& outRasterPtr,
797  const bool realNumberIsRigthtTerm ) const
798  {
799  if( ! allocResultRaster( *inRaster.getGrid(), outRasterPtr ) )
800  {
801  return false;
802  }
803 
804  const unsigned int nRows = inRaster.getNumberOfRows();
805  const unsigned int nCols = inRaster.getNumberOfColumns();
806  const te::rst::Band& inBand = *inRaster.getBand( bandIdx );
807  te::rst::Band& outBand = *outRasterPtr->getBand( 0 );
808  const double inNoData = inBand.getProperty()->m_noDataValue;
809  const double outNoData = outBand.getProperty()->m_noDataValue;
810  unsigned int row = 0;
811  unsigned int col = 0;
812  double value1 = 0;
813  double outValue = 0;
814 
815  if( realNumberIsRigthtTerm )
816  {
817  for( row = 0 ; row < nRows ; ++row )
818  {
819  for( col = 0 ; col < nCols ; ++col )
820  {
821  inBand.getValue( col, row, value1 );
822 
823  if( value1 != inNoData )
824  {
825  (this->*binOptFunctPtr)( value1, value, outValue );
826  outBand.setValue( col, row, outValue );
827  }
828  else
829  {
830  outBand.setValue( col, row, outNoData );
831  }
832  }
833  }
834  }
835  else
836  {
837  for( row = 0 ; row < nRows ; ++row )
838  {
839  for( col = 0 ; col < nCols ; ++col )
840  {
841  inBand.getValue( col, row, value1 );
842 
843  if( value1 != inNoData )
844  {
845  (this->*binOptFunctPtr)( value, value1, outValue );
846  outBand.setValue( col, row, outValue );
847  }
848  else
849  {
850  outBand.setValue( col, row, outNoData );
851  }
852  }
853  }
854  }
855 
856  return true;
857  }
858 
859  bool ArithmeticOperations::execUnaryOperator( const std::string& token, ExecStackT&
860  execStack, bool generateOutput ) const
861  {
862  return false;
863  }
864 
865  bool ArithmeticOperations::isRealNumberToken( const std::string& token, double& realValue ) const
866  {
867  if( token.size() == 0 ) return false;
868  bool hasDot = false;
869 
870  unsigned int initIdx = 0;
871  if( ( token[ 0 ] == '+' ) || ( token[ 0 ] == '-' ) )
872  {
873  if( token.size() == 1 ) return false;
874  initIdx = 1;
875  }
876 
877  for( unsigned int tIdx = initIdx ; tIdx < token.size() ; ++tIdx )
878  {
879  if( token[ tIdx ] == '.' )
880  {
881  if( hasDot ) return false;
882  hasDot = true;
883  }
884  else if( ! isdigit( token[ tIdx ] ) ) return false;
885  }
886 
887  realValue = atof( token.c_str() );
888 
889  return true;
890  }
891 
893  std::auto_ptr<te::rst::Raster>& rasterPtr ) const
894  {
895  std::map<std::string, std::string> rinfo;
896 
897  std::vector< te::rst::BandProperty * > bandsProperties;
898  bandsProperties.push_back( new te::rst::BandProperty( 0, te::dt::DOUBLE_TYPE, "" ) );
899  bandsProperties[ 0 ]->m_noDataValue = std::numeric_limits< double >::max();
900  bandsProperties[ 0 ]->m_blkw = grid.getNumberOfColumns();
901  bandsProperties[ 0 ]->m_blkh = 1;
902  bandsProperties[ 0 ]->m_nblocksx = 1;
903  bandsProperties[ 0 ]->m_nblocksy = grid.getNumberOfRows();
904 
905  rasterPtr.reset( new te::mem::ExpansibleRaster( 50, new te::rst::Grid(
906  grid ), bandsProperties ) );
907 
908  return true;
909  }
910 
911  void ArithmeticOperations::getTokensStrs( const std::string& inputStr,
912  std::vector< std::string >& outTokens ) const
913  {
914  outTokens.clear();
915 
916  const unsigned int inputStrSize = (unsigned int)inputStr.size();
917  std::string bufferStr;
918 
919  for( unsigned int inputStrIdx = 0 ; inputStrIdx < inputStrSize ;
920  ++inputStrIdx )
921  {
922  if( inputStr[ inputStrIdx ] == ' ' )
923  {
924  // flush the last formed token
925  if( bufferStr.size() )
926  {
927  outTokens.push_back( bufferStr );
928  bufferStr.clear();
929  }
930  }
931  else
932  {
933  if( ( inputStr[ inputStrIdx ] == '+' ) ||
934  ( inputStr[ inputStrIdx ] == '-' ) )
935  {
936  bufferStr.append( inputStr.substr( inputStrIdx, 1 ) );
937  }
938  else if( ( inputStr[ inputStrIdx ] == ')' ) ||
939  ( inputStr[ inputStrIdx ] == '(' ) ||
940  isOperator( inputStr.substr( inputStrIdx, 1 ) ) )
941  {
942  // flush the last formed token
943  if( bufferStr.size() )
944  {
945  outTokens.push_back( bufferStr );
946  bufferStr.clear();
947  }
948 
949  outTokens.push_back( inputStr.substr( inputStrIdx, 1 ) );
950  }
951  else
952  {
953  bufferStr.append( inputStr.substr( inputStrIdx, 1 ) );
954  }
955  }
956  }
957 
958  if( bufferStr.size() )
959  {
960  outTokens.push_back( bufferStr );
961  }
962  }
963  }
964 }
void getTokensStrs(const std::string &inputStr, std::vector< std::string > &outTokens) const
Split the input string into a vector of token strings.
void printTokens(const std::vector< std::string > &input) const
Print tokens to stout.
unsigned int getNumberOfRows() const
Returns the grid number of rows.
Definition: Grid.cpp:209
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.
Definition: Raster.cpp:233
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.
Definition: Enums.h:95
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.
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
A raster band description.
Definition: BandProperty.h:61
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
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
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 reset()
Clear all internal allocated objects and reset the algorithm to its initial state.
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)...
Definition: Functions.h:180
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
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 allowed values range (default:false).
ArithmeticOperations::InputParameters m_inputParameters
Input execution parameters.
std::map< std::string, std::string > m_rInfo
The necessary information to create the output rasters (as described in te::raster::RasterFactory).
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits::max().
Definition: BandProperty.h:136
bool allocResultRaster(const te::rst::Grid &grid, std::auto_ptr< te::rst::Raster > &rasterPtr) const
Allocate a new RAM memory raster.
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.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
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.
Definition: Grid.cpp:307
std::stack< ExecStackElement > ExecStackT
Execution stack type definition.
Raster Processing functions.
#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
std::auto_ptr< te::rst::Raster > m_rasterHandler
Raster handler.
bool execBinaryOperatorRasterXRaster(const te::rst::Raster &inRaster1, const unsigned int band1, const te::rst::Raster &inRaster2, const unsigned int band2, const BinOpFuncPtrT binOptFunctPtr, std::auto_ptr< te::rst::Raster > &outRasterPtr) const
Execute the given binary operator using the given input rasters.
void(ArithmeticOperations::* BinOpFuncPtrT)(const double &inputValue1, const double &inputValue2, double &outputValue) const
Type definition for a operation function pointer.
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
An abstract class for raster data strucutures.
Definition: Raster.h:71
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Definition: Raster.cpp:208
BandProperty * getProperty()
Returns the band property.
Definition: Band.cpp:428
ArithmeticOperations output parameters.
unsigned int getNumberOfColumns() const
Returns the grid number of columns.
Definition: Grid.cpp:193
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 pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
A raster band description.
Definition: Band.h:63
Grid * getGrid()
It returns the raster grid.
Definition: Raster.cpp:94
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.
Definition: Raster.cpp:228
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.
int getSRID() const
Returns the raster spatial reference system identifier.
Definition: Raster.cpp:203
#define TERP_LOG_AND_RETURN_FALSE(message)
Logs a warning message will and return false.
Definition: Macros.h:236
bool isRealNumberToken(const std::string &token, double &realValue) const
Returns true if the given token is a real number.
std::auto_ptr< te::rst::Raster > m_outputRasterPtr
The generated output registered raster.
A raster (stored in memory and eventually swapped to disk) where it is possible to dynamically add li...
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.
Definition: Grid.cpp:275
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.
Definition: Grid.cpp:301
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.
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
int getType() const
It returns the data type of the elements in the band.
Definition: BandProperty.h:113
bool execBinaryOperator(const std::string &token, ExecStackT &execStack, bool generateOutput) const
Execute the given binary operator using the current given execution stack.
bool isInitialized() const
Returns true if the algorithm instance is initialized and ready for execution.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
A rectified grid is the spatial support for raster data.
Definition: 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.
Definition: Envelope.cpp:92
te::rst::Interpolator::Method m_interpMethod
The raster interpolator method (default:NearestNeighbor).
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
const InputParameters & operator=(const InputParameters &params)
ArithmeticOperations input parameters.
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:149
void multiplicationBinOp(const double &inputValue1, const double &inputValue2, double &outputValue) const
Multiplication binary operator function.
bool executeString(const std::string &aStr, const std::vector< te::rst::Raster * > &inRasters, std::auto_ptr< te::rst::Raster > &outRaster, bool generateOutput, te::common::TaskProgress *const progressPtr) const
Execute the automata parsing the given input string.
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.
bool execBinaryOperatorRasterXReal(const te::rst::Raster &inRaster, const unsigned int bandIdx, const double value, const BinOpFuncPtrT binOptFunctPtr, std::auto_ptr< te::rst::Raster > &outRasterPtr, const bool realNumberIsRigthtTerm) const
Execute the given binary operator using the given input raster and a real number. ...
std::string m_arithmeticString
Arithmetic string.