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.