bool QgsRasterCalcNode::calculate( QMap<QString, QgsRasterBlock* >& rasterData, QgsRasterMatrix& result, int row ) const { //if type is raster ref: return a copy of the corresponding matrix //if type is operator, call the proper matrix operations if ( mType == tRasterRef ) { QMap<QString, QgsRasterBlock*>::iterator it = rasterData.find( mRasterName ); if ( it == rasterData.end() ) { return false; } int nRows = ( row >= 0 ? 1 : ( *it )->height() ); int startRow = ( row >= 0 ? row : 0 ); int endRow = startRow + nRows; int nCols = ( *it )->width(); int nEntries = nCols * nRows; double* data = new double[nEntries]; //convert input raster values to double, also convert input no data to result no data int outRow = 0; for ( int dataRow = startRow; dataRow < endRow ; ++dataRow, ++outRow ) { for ( int dataCol = 0; dataCol < nCols; ++dataCol ) { data[ dataCol + nCols * outRow] = ( *it )->isNoData( dataRow , dataCol ) ? result.nodataValue() : ( *it )->value( dataRow, dataCol ); } } result.setData( nCols, nRows, data, result.nodataValue() ); return true; } else if ( mType == tOperator ) { QgsRasterMatrix leftMatrix, rightMatrix; leftMatrix.setNodataValue( result.nodataValue() ); rightMatrix.setNodataValue( result.nodataValue() ); if ( !mLeft || !mLeft->calculate( rasterData, leftMatrix, row ) ) { return false; } if ( mRight && !mRight->calculate( rasterData, rightMatrix, row ) ) { return false; } switch ( mOperator ) { case opPLUS: leftMatrix.add( rightMatrix ); break; case opMINUS: leftMatrix.subtract( rightMatrix ); break; case opMUL: leftMatrix.multiply( rightMatrix ); break; case opDIV: leftMatrix.divide( rightMatrix ); break; case opPOW: leftMatrix.power( rightMatrix ); break; case opEQ: leftMatrix.equal( rightMatrix ); break; case opNE: leftMatrix.notEqual( rightMatrix ); break; case opGT: leftMatrix.greaterThan( rightMatrix ); break; case opLT: leftMatrix.lesserThan( rightMatrix ); break; case opGE: leftMatrix.greaterEqual( rightMatrix ); break; case opLE: leftMatrix.lesserEqual( rightMatrix ); break; case opAND: leftMatrix.logicalAnd( rightMatrix ); break; case opOR: leftMatrix.logicalOr( rightMatrix ); break; case opSQRT: leftMatrix.squareRoot(); break; case opSIN: leftMatrix.sinus(); break; case opCOS: leftMatrix.cosinus(); break; case opTAN: leftMatrix.tangens(); break; case opASIN: leftMatrix.asinus(); break; case opACOS: leftMatrix.acosinus(); break; case opATAN: leftMatrix.atangens(); break; case opSIGN: leftMatrix.changeSign(); break; case opLOG: leftMatrix.log(); break; case opLOG10: leftMatrix.log10(); break; default: return false; } int newNColumns = leftMatrix.nColumns(); int newNRows = leftMatrix.nRows(); result.setData( newNColumns, newNRows, leftMatrix.takeData(), leftMatrix.nodataValue() ); return true; } else if ( mType == tNumber ) { double* data = new double[1]; data[0] = mNumber; result.setData( 1, 1, data, result.nodataValue() ); return true; } else if ( mType == tMatrix ) { int nEntries = mMatrix->nColumns() * mMatrix->nRows(); double* data = new double[nEntries]; for ( int i = 0; i < nEntries; ++i ) { data[i] = mMatrix->data()[i] == mMatrix->nodataValue() ? result.nodataValue() : mMatrix->data()[i]; } result.setData( mMatrix->nColumns(), mMatrix->nRows(), data, result.nodataValue() ); return true; } return false; }
bool QgsRasterCalcNode::calculate( QMap<QString, QgsRasterMatrix*>& rasterData, QgsRasterMatrix& result ) const { //if type is raster ref: return a copy of the corresponding matrix //if type is operator, call the proper matrix operations if ( mType == tRasterRef ) { QMap<QString, QgsRasterMatrix*>::iterator it = rasterData.find( mRasterName ); if ( it == rasterData.end() ) { return false; } int nEntries = ( *it )->nColumns() * ( *it )->nRows(); float* data = new float[nEntries]; memcpy( data, ( *it )->data(), nEntries * sizeof( float ) ); result.setData(( *it )->nColumns(), ( *it )->nRows(), data, ( *it )->nodataValue() ); return true; } else if ( mType == tOperator ) { QgsRasterMatrix leftMatrix, rightMatrix; QgsRasterMatrix resultMatrix; if ( !mLeft || !mLeft->calculate( rasterData, leftMatrix ) ) { return false; } if ( mRight && !mRight->calculate( rasterData, rightMatrix ) ) { return false; } switch ( mOperator ) { case opPLUS: leftMatrix.add( rightMatrix ); break; case opMINUS: leftMatrix.subtract( rightMatrix ); break; case opMUL: leftMatrix.multiply( rightMatrix ); break; case opDIV: leftMatrix.divide( rightMatrix ); break; case opPOW: leftMatrix.power( rightMatrix ); break; case opEQ: leftMatrix.equal( rightMatrix ); break; case opNE: leftMatrix.notEqual( rightMatrix ); break; case opGT: leftMatrix.greaterThan( rightMatrix ); break; case opLT: leftMatrix.lesserThan( rightMatrix ); break; case opGE: leftMatrix.greaterEqual( rightMatrix ); break; case opLE: leftMatrix.lesserEqual( rightMatrix ); break; case opAND: leftMatrix.logicalAnd( rightMatrix ); break; case opOR: leftMatrix.logicalOr( rightMatrix ); break; case opSQRT: leftMatrix.squareRoot(); break; case opSIN: leftMatrix.sinus(); break; case opCOS: leftMatrix.cosinus(); break; case opTAN: leftMatrix.tangens(); break; case opASIN: leftMatrix.asinus(); break; case opACOS: leftMatrix.acosinus(); break; case opATAN: leftMatrix.atangens(); break; case opSIGN: leftMatrix.changeSign(); break; default: return false; } int newNColumns = leftMatrix.nColumns(); int newNRows = leftMatrix.nRows(); result.setData( newNColumns, newNRows, leftMatrix.takeData(), leftMatrix.nodataValue() ); return true; } else if ( mType == tNumber ) { float* data = new float[1]; data[0] = mNumber; result.setData( 1, 1, data, -FLT_MAX ); return true; } return false; }