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"
62 m_inputRasters.clear();
63 m_arithmeticString.clear();
65 m_enableProgress =
false;
108 m_outputRasterPtr.reset();
118 m_outputRasterPtr.reset();
138 throw( te::rp::Exception )
149 unsigned int operationsNumber = 0;
151 for(
unsigned sIdx = 0 ; sIdx < arithmetic_string.size() ; ++sIdx )
154 auxStr.push_back( arithmetic_string[ sIdx ] );
156 if(
isOperator( auxStr ) ) ++operationsNumber;
162 std::auto_ptr< te::common::TaskProgress > progressPtr;
167 progressPtr->setTotalSteps( operationsNumber );
169 progressPtr->setMessage(
"Arithmetic Operations" );
174 std::auto_ptr<te::rst::Raster> auxRasterPtr;
177 "Arithmetic string execution error" );
181 std::vector< te::rst::BandProperty* > bandsProperties;
186 bandsProperties[ 0 ]->m_type = auxRasterPtr->getBand( 0 )->getProperty()->m_type;
187 bandsProperties[ 0 ]->m_noDataValue = auxRasterPtr->getBand( 0 )->getProperty()->m_noDataValue;
199 "Output raster creation error" );
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;
211 double outAllowedMin = 0;
212 double outAllowedMax = 0;
214 outAllowedMin, outAllowedMax );
223 double auxMin = DBL_MAX;
224 double auxMax = -1.0 * auxMin;
226 for( row = 0 ; row < nRows ; ++row )
228 for( col = 0 ; col < nCols ; ++col )
230 auxRasterRef.
getValue( col, row, value, 0 );
232 if( auxNoDataValue != value )
234 if( auxMin > value ) auxMin = value;
235 if( auxMax < value ) auxMax = value;
240 double outputOffset = 0;
241 double outputGain = 1.0;
242 if( ( auxMin != DBL_MAX ) && ( auxMax != ( -1.0 * DBL_MAX ) ) && ( auxMax != auxMin ) )
244 outputOffset = -1.0 * auxMin;
245 outputGain = ( ( outAllowedMax - outAllowedMin ) / ( auxMax - auxMin ) );
248 for( row = 0 ; row < nRows ; ++row )
250 for( col = 0 ; col < nCols ; ++col )
252 auxRasterRef.
getValue( col, row, value, 0 );
254 if( auxNoDataValue == value )
256 outRasterRef.
setValue( col, row, outNoDataValue, 0 );
260 value += outputOffset;
263 value =
MIN( value, outAllowedMax );
264 value =
MAX( value, outAllowedMin );
266 outRasterRef.
setValue( col, row, value, 0 );
273 for( row = 0 ; row < nRows ; ++row )
275 for( col = 0 ; col < nCols ; ++col )
277 auxRasterRef.
getValue( col, row, value, 0 );
278 outRasterRef.
setValue( col, row, value, 0 );
293 throw( te::rp::Exception )
306 "Invalid number of rasters" );
319 "Arithmetic string is empty" )
321 std::auto_ptr<te::rst::Raster> rasterNull;
336 const std::vector< te::rst::Raster* >& inRasters,
337 std::auto_ptr<te::rst::Raster>& outRaster,
341 std::vector< std::string > infixTokensVec;
344 if( infixTokensVec.size() )
346 std::vector< std::string > postfixTokensVec;
351 unsigned int auxRasterIdx = 0;
352 unsigned int auxBandIdx = 0;
353 double auxRealValue = 0;
355 for(
unsigned int tIdx = 0 ; tIdx < postfixTokensVec.size() ; ++tIdx )
357 const std::string& curToken = postfixTokensVec[ tIdx ];
362 "Invalid raster index found at " + curToken );
365 "Invalid band index" );
372 execStack.push( auxEle );
380 execStack.push( auxEle );
385 "Operator " + curToken +
" execution error" );
393 progressPtr->
pulse();
399 "Operator " + curToken +
" execution error" );
407 progressPtr->
pulse();
419 outRaster.reset( execStack.top().m_rasterHandler.release() );
426 std::vector< std::string >& output )
const
430 std::stack< std::string > auxStack;
431 const unsigned int inputSize = (
unsigned int)input.size();
433 for(
unsigned int inIdx = 0 ; inIdx < inputSize ; ++inIdx )
435 const std::string& currInToken = input[ inIdx ];
439 while( ( ! auxStack.empty() ) && ( auxStack.top() !=
"(" ) )
443 output.push_back( auxStack.top() );
453 auxStack.push( currInToken );
455 else if( currInToken ==
"(" )
457 auxStack.push( currInToken );
459 else if( currInToken ==
")" )
461 while ( ( ! auxStack.empty() ) && ( auxStack.top() !=
"(" ) )
463 output.push_back( auxStack.top() );
468 if ( ! auxStack.empty() )
475 output.push_back( currInToken );
479 while ( ! auxStack.empty() )
481 output.push_back( auxStack.top() );
489 std::cout << std::endl;
491 for(
unsigned int idx = 0 ; idx < input.size() ; ++idx )
493 std::cout <<
"[" << input[ idx ] <<
"]";
496 std::cout << std::endl;
507 return ( ( inputToken ==
"+" ) || ( inputToken ==
"-" ) ||
508 ( inputToken ==
"*" ) || ( inputToken ==
"/" ) ) ?
518 const std::string& operator2 )
const
520 if( ( operator1 ==
"*" ) || ( operator1 ==
"/" ) )
526 if( ( operator2 ==
"+" ) || ( operator2 ==
"-" ) )
536 unsigned int& bandIdx )
const
538 if( token.size() < 4 )
return false;
539 if( token[ 0 ] !=
'R' )
return false;
541 std::string rasterIdxStr;
542 unsigned int tIdx = 1;
544 while( ( tIdx < token.size() ) && isdigit( token[ tIdx ] ) )
546 rasterIdxStr.push_back( token[ tIdx ] );
550 if( token[ tIdx ] !=
':' )
return false;
553 std::string bandIdxStr;
555 while( ( tIdx < token.size() ) && isdigit( token[ tIdx ] ) )
557 bandIdxStr.push_back( token[ tIdx ] );
561 if( ( rasterIdxStr.size() ) && ( bandIdxStr.size() ) )
563 rasterIdx = (
unsigned int)atoi( rasterIdxStr.c_str() );
564 bandIdx = (
unsigned int)atoi( bandIdxStr.c_str() );
574 execStack,
bool generateOutput )
const
576 if( execStack.size() < 2 )
595 else if( token ==
"-" )
599 else if( token ==
"*" )
603 else if( token ==
"/" )
625 "Operator execution error" );
633 "Operator execution error" );
641 "Operator execution error" );
650 execStack.push( outElement );
658 const unsigned int band2Idx,
660 std::auto_ptr<te::rst::Raster>& outRasterPtr )
const
677 unsigned int row = 0;
678 unsigned int col = 0;
683 for( row = 0 ; row < nRows ; ++row )
685 for( col = 0 ; col < nCols ; ++col )
687 inBand1.
getValue( col, row, value1 );
688 inBand2.
getValue( col, row, value2 );
690 if( ( value1 != inNoData1 ) && ( value2 != inNoData2 ) )
692 (this->*binOptFunctPtr)( value1, value2, outValue );
693 outBand.
setValue( col, row, outValue );
697 outBand.
setValue( col, row, outNoData );
709 double overlapULCol1 = 0;
710 double overpalULRow1 = 0;
711 inRaster1.
getGrid()->
geoToGrid( extent2.getLowerLeftX(), extent2.getUpperRightY(),
712 overlapULCol1, overpalULRow1 );
714 - 1 ), overlapULCol1 ) );
715 overpalULRow1 = std::max( 0.0, std::min( (
double)( inRaster1.
getNumberOfRows()
716 - 1 ), overpalULRow1 ) );
718 double overlapLRCol1 = 0;
719 double overlapLRRow1 = 0;
720 inRaster1.
getGrid()->
geoToGrid( extent2.getUpperRightX(), extent2.getLowerLeftY(),
721 overlapLRCol1, overlapLRRow1 );
723 - 1 ), overlapLRCol1 ) );
724 overlapLRRow1 = std::max( 0.0, std::min( (
double)( inRaster1.
getNumberOfRows()
725 - 1 ), overlapLRRow1 ) );
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 );
743 unsigned int row1 = 0;
744 unsigned int col1 = 0;
748 std::complex< double > value2;
755 for( row1 = 0 ; row1 < nRows1 ; ++row1 )
757 for( col1 = 0 ; col1 < nCols1 ; ++col1 )
759 if( ( row1 >= overlapFirstRow1 ) && ( row1 <= overlapLastRow1 ) &&
760 ( col1 >= overlapFirstCol1 ) && ( col1 <= overlapLastCol1 ) )
762 grid1.
gridToGeo( (
double)col1, (
double)row1, currX1, currY1 );
763 converter.convert( currX1, currY1, currX2, currY2 );
764 grid2.
geoToGrid( currX2, currY2, col2, row2 );
766 inBand1.
getValue( col1, row1, value1 );
767 interpolator2.getValue( col2, row2, value2, band2Idx );
769 if( ( value1 != inNoData1 ) && ( value2.real() != inNoData2 ) )
771 (this->*binOptFunctPtr)( value1, value2.real(), outValue );
772 outBand.
setValue( col1, row1, outValue );
776 outBand.
setValue( col1, row1, outNoData );
781 outBand.
setValue( col1, row1, outNoData );
794 const unsigned int bandIdx,
const double value,
796 std::auto_ptr<te::rst::Raster>& outRasterPtr,
797 const bool realNumberIsRigthtTerm )
const
810 unsigned int row = 0;
811 unsigned int col = 0;
815 if( realNumberIsRigthtTerm )
817 for( row = 0 ; row < nRows ; ++row )
819 for( col = 0 ; col < nCols ; ++col )
821 inBand.
getValue( col, row, value1 );
823 if( value1 != inNoData )
825 (this->*binOptFunctPtr)( value1, value, outValue );
826 outBand.
setValue( col, row, outValue );
830 outBand.
setValue( col, row, outNoData );
837 for( row = 0 ; row < nRows ; ++row )
839 for( col = 0 ; col < nCols ; ++col )
841 inBand.
getValue( col, row, value1 );
843 if( value1 != inNoData )
845 (this->*binOptFunctPtr)( value, value1, outValue );
846 outBand.
setValue( col, row, outValue );
850 outBand.
setValue( col, row, outNoData );
860 execStack,
bool generateOutput )
const
867 if( token.size() == 0 )
return false;
870 unsigned int initIdx = 0;
871 if( ( token[ 0 ] ==
'+' ) || ( token[ 0 ] ==
'-' ) )
873 if( token.size() == 1 )
return false;
877 for(
unsigned int tIdx = initIdx ; tIdx < token.size() ; ++tIdx )
879 if( token[ tIdx ] ==
'.' )
881 if( hasDot )
return false;
884 else if( ! isdigit( token[ tIdx ] ) )
return false;
887 realValue = atof( token.c_str() );
893 std::auto_ptr<te::rst::Raster>& rasterPtr )
const
895 std::map<std::string, std::string> rinfo;
897 std::vector< te::rst::BandProperty * > bandsProperties;
899 bandsProperties[ 0 ]->m_noDataValue = std::numeric_limits< double >::max();
901 bandsProperties[ 0 ]->m_blkh = 1;
902 bandsProperties[ 0 ]->m_nblocksx = 1;
906 grid ), bandsProperties ) );
912 std::vector< std::string >& outTokens )
const
916 const unsigned int inputStrSize = (
unsigned int)inputStr.size();
917 std::string bufferStr;
919 for(
unsigned int inputStrIdx = 0 ; inputStrIdx < inputStrSize ;
922 if( inputStr[ inputStrIdx ] ==
' ' )
925 if( bufferStr.size() )
927 outTokens.push_back( bufferStr );
933 if( ( inputStr[ inputStrIdx ] ==
'+' ) ||
934 ( inputStr[ inputStrIdx ] ==
'-' ) )
936 bufferStr.append( inputStr.substr( inputStrIdx, 1 ) );
938 else if( ( inputStr[ inputStrIdx ] ==
')' ) ||
939 ( inputStr[ inputStrIdx ] ==
'(' ) ||
940 isOperator( inputStr.substr( inputStrIdx, 1 ) ) )
943 if( bufferStr.size() )
945 outTokens.push_back( bufferStr );
949 outTokens.push_back( inputStr.substr( inputStrIdx, 1 ) );
953 bufferStr.append( inputStr.substr( inputStrIdx, 1 ) );
958 if( bufferStr.size() )
960 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.
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 ¶ms)
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.
int getSRID() const
Returns the grid spatial reference system identifier.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
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...
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).
double m_realNumberValue
Real number value.
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits::max().
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.
#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.
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 &)
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.
An abstract class for raster data strucutures.
unsigned int getNumberOfRows() const
Returns the raster number of rows.
BandProperty * getProperty()
Returns the band property.
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 pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
A raster band description.
Grid * getGrid()
It returns the raster grid.
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...
Abstract parameters base interface.
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.
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.
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.
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.
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.
void transform(int oldsrid, int newsrid)
It will transform the coordinates of the Envelope from the old SRS to the new one.
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.
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.
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. ...