30 #include "../common/progress/TaskProgress.h" 
   31 #include "../common/StringUtils.h" 
   32 #include "../raster/Raster.h" 
   60       m_arithmeticString.clear();
 
   62       m_enableProgress = 
false;
 
  103       m_outputRasterPtr.reset();
 
  113       m_outputRasterPtr.reset();
 
  133       throw( te::rp::Exception )
 
  143      std::vector< te::rst::BandProperty* > bandsProperties;
 
  157           "Output raster creation error" );
 
  163       unsigned int operationsNumber = 0;
 
  165         for( 
unsigned sIdx = 0 ; sIdx < arithmetic_string.size() ; ++sIdx )
 
  168           auxStr.push_back( arithmetic_string[ sIdx ] );
 
  170           if( 
isOperator( auxStr ) ) ++operationsNumber;
 
  176       std::auto_ptr< te::common::TaskProgress > progressPtr;
 
  181         progressPtr->setTotalSteps( operationsNumber );
 
  183         progressPtr->setMessage( 
"Arithmetic Operations" );
 
  190       boost::shared_ptr<te::rst::Raster> auxRaster;
 
  193       "Arithmetic string execution error" );
 
  199       const unsigned int nLines = (
unsigned int)auxRaster->getNumberOfRows();
 
  200       const unsigned int nCols = (
unsigned int)auxRaster->getNumberOfColumns();
 
  201       unsigned int line = 0;
 
  202       unsigned int col = 0;
 
  207       double outAllowedMin = 0;
 
  208       double outAllowedMax = 0;
 
  216         double auxMin = DBL_MAX;
 
  217         double auxMax = -1.0 * auxMin;  
 
  219         for( line = 0 ; line < nLines ; ++line )
 
  221           for( col = 0 ; col < nCols ; ++col )
 
  223             auxRasterRef.
getValue( col, line, value, 0 );
 
  225             if( auxMin > value ) auxMin = value;
 
  226             if( auxMax < value ) auxMax = value;
 
  232         double outputOffset = 0;  
 
  233         double outputGain = 1.0;
 
  234         if( auxMax != auxMin ) 
 
  236           outputOffset = -1.0 * auxMin;
 
  237           outputGain = ( ( outAllowedMax - outAllowedMin ) / ( auxMax - auxMin ) );       
 
  240         for( line = 0 ; line < nLines ; ++line )
 
  242           for( col = 0 ; col < nCols ; ++col )
 
  244             auxRasterRef.
getValue( col, line, value, 0 );
 
  246             value += outputOffset;
 
  249             value = 
MIN( value, outAllowedMax );
 
  250             value = 
MAX( value, outAllowedMin );
 
  252             outRasterRef.
setValue( col, line, value, 0 );
 
  260         for( line = 0 ; line < nLines ; ++line )
 
  262           for( col = 0 ; col < nCols ; ++col )
 
  264             auxRasterRef.
getValue( col, line, value, 0 );
 
  266             value = 
MIN( value, outAllowedMax );
 
  267             value = 
MAX( value, outAllowedMin );        
 
  269             outRasterRef.
setValue( col, line, value, 0 );
 
  286       throw( te::rp::Exception )
 
  299         "Invalid number of rasters" );
 
  318         "Arithmetic string is empty" )
 
  320       boost::shared_ptr<te::rst::Raster> rasterNull;
 
  335       std::vector< boost::shared_ptr<te::rst::Raster> > inRasters,
 
  336       boost::shared_ptr<te::rst::Raster>& outRaster,
 
  337       bool generateOutput )
 const 
  339       std::vector< std::string > infixTokensVec;
 
  342       if( infixTokensVec.size() )
 
  344         std::vector< std::string > postfixTokensVec;
 
  349         unsigned int auxRasterIdx = 0;
 
  350         unsigned int auxBandIdx = 0;
 
  351         double auxRealValue = 0;
 
  353         for( 
unsigned int tIdx = 0 ; tIdx < postfixTokensVec.size() ; ++tIdx )
 
  355           const std::string& curToken = postfixTokensVec[ tIdx ];
 
  360             "Invalid raster index found at " + curToken );
 
  363             "Invalid band index" );
 
  367             auxEle.
m_raster = inRasters[auxRasterIdx];
 
  370             execStack.push( auxEle );
 
  378             execStack.push( auxEle );
 
  383             "Operator " + curToken + 
" execution error" );
 
  388             "Operator " + curToken + 
" execution error" );
 
  399         outRaster = execStack.top().m_raster;
 
  406       std::vector< std::string >& output )
 const 
  410       std::stack< std::string > auxStack;
 
  411       const unsigned int inputSize = (
unsigned int)input.size();
 
  413       for( 
unsigned int inIdx = 0 ; inIdx < inputSize ; ++inIdx )
 
  415         const std::string& currInToken = input[ inIdx ];
 
  419           while( ( ! auxStack.empty() ) && ( auxStack.top() != 
"(" ) )
 
  423               output.push_back( auxStack.top() );
 
  433           auxStack.push( currInToken );
 
  435         else if( currInToken == 
"(" )
 
  437           auxStack.push( currInToken );
 
  439         else if( currInToken == 
")" )
 
  441           while ( ( ! auxStack.empty() ) && ( auxStack.top() != 
"(" ) )
 
  443             output.push_back( auxStack.top() );
 
  448           if ( ! auxStack.empty() ) 
 
  455           output.push_back( currInToken );
 
  459       while ( ! auxStack.empty() )
 
  461         output.push_back( auxStack.top() );
 
  469       std::cout << std::endl;
 
  471       for( 
unsigned int idx = 0 ; idx < input.size() ; ++idx )
 
  473         std::cout << 
"[" << input[ idx ] << 
"]";
 
  476       std::cout << std::endl;
 
  487       return ( ( inputToken == 
"+" ) || ( inputToken == 
"-" ) || 
 
  488         ( inputToken == 
"*" ) || ( inputToken == 
"/" ) ) ? 
 
  498       const std::string& operator2 )
 const 
  500       if( ( operator1 == 
"*" ) || ( operator1 == 
"/" ) )
 
  506         if( ( operator2 == 
"+" ) || ( operator2 == 
"-" ) )
 
  516       unsigned int& bandIdx )
 const 
  518       if( token.size() < 4 ) 
return false;
 
  519       if( token[ 0 ] != 
'R' ) 
return false;
 
  521       std::string rasterIdxStr;
 
  522       unsigned int tIdx = 1;
 
  524       while( ( tIdx < token.size() ) && isdigit( token[ tIdx ] ) )
 
  526         rasterIdxStr.push_back( token[ tIdx ] );
 
  530       if( token[ tIdx ] != 
':' ) 
return false;
 
  533       std::string bandIdxStr;
 
  535       while( ( tIdx < token.size() ) && isdigit( token[ tIdx ] ) )
 
  537         bandIdxStr.push_back( token[ tIdx ] );
 
  541       if( ( rasterIdxStr.size() ) && ( bandIdxStr.size() ) )
 
  543         rasterIdx = (
unsigned int)atoi( rasterIdxStr.c_str() );
 
  544         bandIdx = (
unsigned int)atoi( bandIdxStr.c_str() );
 
  554       execStack, 
bool generateOutput )
 const 
  556       if( execStack.size() < 2 )
 
  572             const unsigned int nLines = (
unsigned int) sElem1.
m_raster->getNumberOfRows();
 
  573             const unsigned int nCols = (
unsigned int) sElem1.
m_raster->getNumberOfColumns();
 
  578               "Raster allocation error" );
 
  586               unsigned int line = 0;
 
  587               unsigned int col = 0;
 
  591               for( line = 0 ; line < nLines ; ++line )
 
  593                 for( col = 0 ; col < nCols ; ++col )
 
  598                   outRasterRef.
setValue( col, line, value1 + value2, 0 );
 
  605             execStack.push( outElement );
 
  609             const unsigned int nLines = (
unsigned int) sElem1.
m_raster->getNumberOfRows();
 
  610             const unsigned int nCols = (
unsigned int) sElem1.
m_raster->getNumberOfColumns();
 
  615               "Raster allocation error" );
 
  622               unsigned int line = 0;
 
  623               unsigned int col = 0;
 
  626               for( line = 0 ; line < nLines ; ++line )
 
  628                 for( col = 0 ; col < nCols ; ++col )
 
  639             execStack.push( outElement );
 
  643             const unsigned int nLines = (
unsigned int) sElem2.
m_raster->getNumberOfRows();
 
  644             const unsigned int nCols = (
unsigned int) sElem2.
m_raster->getNumberOfColumns();
 
  649               "Raster allocation error" );
 
  656               unsigned int line = 0;
 
  657               unsigned int col = 0;
 
  660               for( line = 0 ; line < nLines ; ++line )
 
  662                 for( col = 0 ; col < nCols ; ++col )
 
  673             execStack.push( outElement );
 
  680         else if( token == 
"-" )
 
  684             const unsigned int nLines = (
unsigned int) sElem1.
m_raster->getNumberOfRows();
 
  685             const unsigned int nCols = (
unsigned int) sElem1.
m_raster->getNumberOfColumns();
 
  690               "Raster allocation error" );
 
  698               unsigned int line = 0;
 
  699               unsigned int col = 0;
 
  703               for( line = 0 ; line < nLines ; ++line )
 
  705                 for( col = 0 ; col < nCols ; ++col )
 
  710                   outRasterRef.
setValue( col, line, value2 - value1, 0 );
 
  717             execStack.push( outElement );
 
  721             const unsigned int nLines = (
unsigned int) sElem1.
m_raster->getNumberOfRows();
 
  722             const unsigned int nCols = (
unsigned int) sElem1.
m_raster->getNumberOfColumns();
 
  727               "Raster allocation error" );
 
  734               unsigned int line = 0;
 
  735               unsigned int col = 0;
 
  738               for( line = 0 ; line < nLines ; ++line )
 
  740                 for( col = 0 ; col < nCols ; ++col )
 
  751             execStack.push( outElement );
 
  755             const unsigned int nLines = (
unsigned int) sElem2.
m_raster->getNumberOfRows();
 
  756             const unsigned int nCols = (
unsigned int)sElem2.
m_raster->getNumberOfColumns();
 
  761               "Raster allocation error" );
 
  768               unsigned int line = 0;
 
  769               unsigned int col = 0;
 
  772               for( line = 0 ; line < nLines ; ++line )
 
  774                 for( col = 0 ; col < nCols ; ++col )
 
  785             execStack.push( outElement );
 
  792         else if( token == 
"*" )
 
  796             const unsigned int nLines = (
unsigned int) sElem1.
m_raster->getNumberOfRows();
 
  797             const unsigned int nCols = (
unsigned int) sElem1.
m_raster->getNumberOfColumns();
 
  802               "Raster allocation error" );
 
  810               unsigned int line = 0;
 
  811               unsigned int col = 0;
 
  815               for( line = 0 ; line < nLines ; ++line )
 
  817                 for( col = 0 ; col < nCols ; ++col )
 
  822                   outRasterRef.
setValue( col, line, value1 * value2, 0 );
 
  829             execStack.push( outElement );
 
  833             const unsigned int nLines = (
unsigned int) sElem1.
m_raster->getNumberOfRows();
 
  834             const unsigned int nCols = (
unsigned int) sElem1.
m_raster->getNumberOfColumns();
 
  839               "Raster allocation error" );
 
  846               unsigned int line = 0;
 
  847               unsigned int col = 0;
 
  850               for( line = 0 ; line < nLines ; ++line )
 
  852                 for( col = 0 ; col < nCols ; ++col )
 
  863             execStack.push( outElement );
 
  867             const unsigned int nLines = (
unsigned int) sElem2.
m_raster->getNumberOfRows();
 
  868             const unsigned int nCols = (
unsigned int) sElem2.
m_raster->getNumberOfColumns();
 
  873               "Raster allocation error" );
 
  880               unsigned int line = 0;
 
  881               unsigned int col = 0;
 
  884               for( line = 0 ; line < nLines ; ++line )
 
  886                 for( col = 0 ; col < nCols ; ++col )
 
  897             execStack.push( outElement );
 
  904         else if( token == 
"/" )
 
  908             const unsigned int nLines = (
unsigned int) sElem1.
m_raster->getNumberOfRows();
 
  909             const unsigned int nCols = (
unsigned int) sElem1.
m_raster->getNumberOfColumns();
 
  914               "Raster allocation error" );
 
  922               unsigned int line = 0;
 
  923               unsigned int col = 0;
 
  927               for( line = 0 ; line < nLines ; ++line )
 
  929                 for( col = 0 ; col < nCols ; ++col )
 
  934                   outRasterRef.
setValue( col, line, value2 / value1, 0 );
 
  941             execStack.push( outElement );
 
  945             const unsigned int nLines = (
unsigned int) sElem1.
m_raster->getNumberOfRows();
 
  946             const unsigned int nCols = (
unsigned int) sElem1.
m_raster->getNumberOfColumns();
 
  951               "Raster allocation error" );
 
  958               unsigned int line = 0;
 
  959               unsigned int col = 0;
 
  962               for( line = 0 ; line < nLines ; ++line )
 
  964                 for( col = 0 ; col < nCols ; ++col )
 
  975             execStack.push( outElement );
 
  979             const unsigned int nLines = (
unsigned int) sElem2.
m_raster->getNumberOfRows();
 
  980             const unsigned int nCols = (
unsigned int) sElem2.
m_raster->getNumberOfColumns();
 
  985               "Raster allocation error" );
 
  992               unsigned int line = 0;
 
  993               unsigned int col = 0;
 
  996               for( line = 0 ; line < nLines ; ++line )
 
  998                 for( col = 0 ; col < nCols ; ++col )
 
 1009             execStack.push( outElement );
 
 1026       execStack, 
bool generateOutput )
 const 
 1033       if( token.size() == 0 ) 
return false;
 
 1034       bool hasDot = 
false;
 
 1036       unsigned int initIdx = 0;
 
 1037       if( ( token[ 0 ] == 
'+' ) || ( token[ 0 ] == 
'-' ) )
 
 1039         if( token.size() == 1 ) 
return false;
 
 1043       for( 
unsigned int tIdx = initIdx ; tIdx < token.size() ; ++tIdx )
 
 1045         if( token[ tIdx ] == 
'.' )
 
 1047           if( hasDot ) 
return false;
 
 1050         else if( ! isdigit( token[ tIdx ] ) ) 
return false;
 
 1053       realValue = atof( token.c_str() );
 
 1059       boost::shared_ptr<te::rst::Raster>& rasterPtr )
 const 
 1061       std::map<std::string, std::string> rinfo;
 
 1063       rinfo[
"MEM_RASTER_NROWS"] = boost::lexical_cast<std::string>(nLines);
 
 1064       rinfo[
"MEM_RASTER_NCOLS"] = boost::lexical_cast<std::string>(nCols);
 
 1066       rinfo[
"MEM_RASTER_NBANDS"] = 
"1";
 
 1074       std::vector< std::string >& outTokens )
 const 
 1078       const unsigned int inputStrSize = (
unsigned int)inputStr.size();
 
 1079       std::string bufferStr;
 
 1081       for( 
unsigned int inputStrIdx = 0 ; inputStrIdx < inputStrSize ;
 
 1084         if( inputStr[ inputStrIdx ] == 
' ' )
 
 1087           if( bufferStr.size() )
 
 1089             outTokens.push_back( bufferStr );
 
 1095           if( ( inputStr[ inputStrIdx ] == 
'+' ) ||
 
 1096             ( inputStr[ inputStrIdx ] == 
'-' ) )
 
 1098             bufferStr.append( inputStr.substr( inputStrIdx, 1 ) );
 
 1100           else if( ( inputStr[ inputStrIdx ] == 
')' ) ||
 
 1101             ( inputStr[ inputStrIdx ] == 
'(' ) ||
 
 1102             isOperator( inputStr.substr( inputStrIdx, 1 ) ) )
 
 1105             if( bufferStr.size() )
 
 1107               outTokens.push_back( bufferStr );
 
 1111             outTokens.push_back( inputStr.substr( inputStrIdx, 1 ) );
 
 1115             bufferStr.append( inputStr.substr( inputStrIdx, 1 ) );
 
 1120       if( bufferStr.size() )
 
 1122         outTokens.push_back( bufferStr );
 
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. 
 
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 ). 
 
bool isUnaryOperator(const std::string &inputToken) const 
Returns true if the given token is a unary operator. 
 
const OutputParameters & operator=(const OutputParameters ¶ms)
 
AbstractParameters * clone() const 
Create a clone copy of this instance. 
 
A raster band description. 
 
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. 
 
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)...
 
bool m_isInitialized
Tells if this instance is initialized. 
 
This class can be used to inform the progress of a task. 
 
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. 
 
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). 
 
bool allocResultRaster(unsigned int nLines, unsigned int nCols, boost::shared_ptr< te::rst::Raster > &rasterPtr) const 
Allocate a new RAM memory raster. 
 
double m_realNumberValue
Real number value. 
 
Performs arithmetic operation over raster data. 
 
#define MAX(a, b)
Macro that returns max between two values. 
 
bool m_isRaster
true if this is a raster pointer element. 
 
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...
 
const Algorithm & operator=(const Algorithm &)
 
An abstract class for raster data strucutures. 
 
BandProperty * getProperty()
Returns the band property. 
 
ArithmeticOperations output parameters. 
 
bool isRasterBandToken(const std::string &token, unsigned int &rasterIdx, unsigned int &bandIdx) const 
Returns true if the given token is a raster data token. 
 
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. 
 
Abstract parameters base interface. 
 
bool executeString(const std::string &aStr, std::vector< boost::shared_ptr< te::rst::Raster > > inRasters, boost::shared_ptr< te::rst::Raster > &outRaster, bool generateOutput) const 
Execute the automata parsing the given input string. 
 
#define TERP_LOG_AND_RETURN_FALSE(message)
Logs a warning message will and return false. 
 
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. 
 
static Raster * make()
It creates and returns an empty raster with default raster driver. 
 
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. 
 
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. 
 
unsigned int m_rasterBand
Raster band index. 
 
bool execBinaryOperator(const std::string &token, ExecStackT &execStack, bool generateOutput) const 
Execute the given binary operator using the current given execution stack. 
 
std::string Convert2String(boost::int16_t value)
It converts a short integer value to a string. 
 
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. 
 
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. 
 
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters. 
 
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not. 
 
boost::shared_ptr< te::rst::Raster > m_raster
Raster pointer.