📄 grid_calculator.cpp
字号:
///////////////////////////////////////////////////////////
// //
// SAGA //
// //
// System for Automated Geoscientific Analyses //
// //
// Module Library: //
// Grid_Calculus //
// //
//-------------------------------------------------------//
// //
// Grid_Calculator.cpp //
// //
// Copyright (C) 2003 by //
// Andre Ringeler //
// //
//-------------------------------------------------------//
// //
// This file is part of 'SAGA - System for Automated //
// Geoscientific Analyses'. SAGA is free software; you //
// can redistribute it and/or modify it under the terms //
// of the GNU General Public License as published by the //
// Free Software Foundation; version 2 of the License. //
// //
// SAGA is distributed in the hope that it will be //
// useful, but WITHOUT ANY WARRANTY; without even the //
// implied warranty of MERCHANTABILITY or FITNESS FOR A //
// PARTICULAR PURPOSE. See the GNU General Public //
// License for more details. //
// //
// You should have received a copy of the GNU General //
// Public License along with this program; if not, //
// write to the Free Software Foundation, Inc., //
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, //
// USA. //
// //
//-------------------------------------------------------//
// //
// e-mail: aringel@gwdg.de //
// //
// contact: Andre Ringeler //
// Institute of Geography //
// University of Goettingen //
// Goldschmidtstr. 5 //
// 37077 Goettingen //
// Germany //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#include "Grid_Calculator.h"
#include <float.h>
CGrid_Calculator::CGrid_Calculator(void)
{
//-----------------------------------------------------
Set_Name(_TL("Grid Calculator"));
Set_Author(_TL("Copyrights (c) 2003 by Andre Ringeler"));
Set_Description(_TW(
"The Grid Calculator calculates a new grid based on existing grids and a mathematical formula.\n\n"
"The following operators are available for the formula definition:\n"
"+ Addition\n"
"- Subtraction\n"
"* Multiplication\n"
"/ Division\n"
"^ power\n"
"sin(a)\n"
"cos(a)\n"
"tan(a)\n"
"asin(a)\n"
"acos(a)\n"
"atan(a)\n"
"atan2(a,b)\n"
"abs(a)\n"
"int(a)\n"
"sqrt(a)\n"
"int(a)\n"
"ln(a)\n"
"mod(a,b)\n"
"gt(a, b) returns 1 if a greater b\n"
"lt(a, b) returns 1 if a lower b\n"
"eq(a, b) returns 1 if a equal b\n"
"ifelse(switch, x, y) returns x if switch equals 1 else y\n\n"
"The grid variables are single characters a which correspond in "
"alphabetical order with the grid list order ('a' = first grid, 'b' = second grid, ...)\n"
"Example with three grids: sin(a)*b+c\n")
);
//-----------------------------------------------------
Parameters.Add_Grid_List(
NULL, "INPUT" , _TL("Grids"),
_TL(""), PARAMETER_INPUT
);
Parameters.Add_Grid(
NULL, "RESULT" , _TL("Result"),
_TL(""),
PARAMETER_OUTPUT
);
Parameters.Add_String(
NULL, "FORMUL" , _TL("Formula"),
_TL(""),
SG_T("(a - b) / (a + b)")
);
}
//---------------------------------------------------------
CGrid_Calculator::~CGrid_Calculator(void)
{}
//---------------------------------------------------------
#if defined(_SAGA_LINUX)
bool _finite(double val)
{
return( true );
}
#endif
//---------------------------------------------------------
bool CGrid_Calculator::On_Execute(void)
{
char vars[27];
bool bContinue;
int i, x, y;
if (Parameters("INPUT")->asInt() <= 0) // Gr� von O.C...
{
Error_Set(_TL("No grid in list - Cannot execute calculator"));
return (false);
}
pResult = Parameters("RESULT")->asGrid();
pResult->Set_Name(Parameters("FORMUL")->asString());
nGrids = Parameters("INPUT")->asInt();
Grids =(CSG_Grid **)Parameters("INPUT")->asPointer();
for (i = 0, bContinue = true; i < nGrids - 1 && bContinue; i++)
{
if( (Grids[i]->Get_System() == Grids[i + 1]->Get_System()) == false )
{
bContinue = false;
}
}
CSG_Grid MissingMap(Grids[0], GRID_TYPE_Byte);
for (y = 0; y < Get_NY() && Set_Progress(y); y++)
for (x = 0; x < Get_NX(); x++)
{
int missing = 1;
for (i = 0; i < nGrids; i++)
{
//if (fabs(Grids[i]->asFloat(x, y) - Grids[0]->Get_NoData_Value()) < 0.0001)
// this was not a very robust way of cheking nodata values, was it?
if (Grids[i]->is_NoData(x,y))
{
//I think this works better, specially if you use a range of nodata values, not a single value
missing = 0;
}
}
MissingMap.Set_Value(x, y, missing);
}
pResult->Set_NoData_Value(Grids[0]->Get_NoData_Value());
for (char c = 'a'; c<'a'+(char) nGrids; c++)
vars[c - 'a'] = c;
CSG_Formula Formel;
Formel.Set_Formula(Parameters("FORMUL")->asString());
int Pos;
const SG_Char * Msg;
if (Formel.Get_Error(&Pos, &Msg))
{
CSG_String msg;
msg.Printf(_TL("Error at character #%d of the function: \n%s\n"), Pos, Parameters("FORMUL")->asString());
Message_Add(msg);
msg.Printf(SG_T("\n%s\n"), Msg);
Message_Add(msg);
return false;
}
double *Grid_Vals= new double[nGrids];
double val;
for (y = 0; y < Get_NY() && Set_Progress(y); y++)
for (x = 0; x < Get_NX(); x++)
{
for (i = 0; i < nGrids; i++)
{
Grid_Vals[i]=Grids[i]->asDouble(x,y);
}
val = Formel.Val(Grid_Vals, nGrids);
if (_finite(val) && MissingMap.asByte(x, y))
pResult->Set_Value(x, y, val);
else
pResult->Set_Value(x, y, Grids[0]->Get_NoData_Value());
}
delete[] Grid_Vals;
return (true);
}
// MinGW ERROR:
// Grid_Calculator.cpp: In member function `virtual bool CGrid_Calculator::On_Execute()':
// Grid_Calculator.cpp:187: error: name lookup of `y' changed for new ISO `for' scoping
// Grid_Calculator.cpp:145: error: using obsolete binding at `y'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -