A user-defined function can be created:
A user-defined function may contain any combination of existing MapCalc/TabCalc operators and functions, and may use parameters representing maps and columns.
Syntax
For a function with parameters:
Function FunctionName (ParamDomain Param [,ParamDomain
Param]) : OutputDomain
Begin
Return Expression;
End;
For a function without parameters:
Function FunctionName() : OutputDomain
Begin
Return Expression;
End;
Where:
FunctionName | is the name of the function as specified in the Create Function dialog box. |
ParamDomain | is the domain type of an input parameter. You can use e.g.
Value | String | Coord |
Color | Bool.
By default, the domain type of input parameters is set to Value.
|
Param | is the name of an input parameter.
Parameter names:
|
OutputDomain | is the domain that should be used for the output object (a column or a map) of the function. You can choose any domain available in your data set as well as a coordinate system. By default, the output domain is set to the system Value domain. When you choose a value output domain, the value range is determined by the selected domain. |
Expression | is the expression that the function should perform, as defined before in the Create Function dialog box. |
Notes:
To create a user-defined function:
The Create Function dialog box appears where:
The different parameters in your function may be characters (a, b, c etc.) but it is recommended to give parameters logic names. Clear names make the application of user-defined functions much easier.
After the Create Function dialog box, the Function editor will be opened. The Function editor shows the newly created function. If necessary you can edit the function until it satisfies your purposes.
Applying a user-defined function:
You apply your function on the command line of the Main window or a Table window.
The syntax to apply a user-defined function is:
OUTPUT = FunctionName(a, b, c, ...)
where:
OUTPUT | is the output map name (when applied on the command line of the Main window) or the output column name (when applied on the command line of a Table window). |
FunctionName | is the name of the user-defined function. |
a, b, c, ... | are the parameters such as values, map names or table column names, used in the function; parameters should be typed in the same order as they appear in the function definition. |
Examples:
Example 1 : Sum of two value maps/columns using parametersExample 1: Sum of two value maps/columns using parameters
In the Create Function dialog box, define a function SUM to sum two value maps or two value columns as:
a + b
In the Function editor, this function is listed as:
Function SUM(Value a,Value b) : Value
Begin
Return a + b;
End;
This means that the function SUM has two parameters (a and b) which have a value domain and that the output of the function will also be a value (system domain Value). The calculation itself is defined as: return the sum of a and b.
To apply this function, type on the command line:
Output1=SUM(Parameter1, Parameter2)where:
Output1 |
is the output object (value domain); |
Parameter1,Parameter2 |
are the parameters replacing the a and b in the function, e.g. Map1 and Map2 or Col1 and Col2. |
This example shows the functionality of a user-defined function. However in such a simple example, it would have been easier for example to directly type on the command line:
Output1 = Map1 + Map2
Example 2: Sum of two value maps without using parameters
Although it is not common, you may define functions which use existing data that are not mentioned as parameters. In this example, two existing maps will be used; the resulting function can thus only be used in a MapCalc expression.
To define a function AVG2 to calculate the average of two existing maps (MyMap1 and MyMap2), you may create a function AVG2 defined as:
(MyMap1+MyMap2)/2
In the Function editor this will appear as:
Function AVG2(value MyMap1, value MyMap2) : Value
Remove the parameters between the brackets; and keep the default output domain Value.
Function AVG2() : Value
Further, the Function editor states the calculation that should be performed with the parameters of the function; in this case:
Begin
Return (MyMap1+MyMap2)/2;
End;
To use this function, type on the command line:
OUT=AVG2()
where:
OUT |
is the output object, |
AVG2 |
is the function which already contains the map names MyMap1 and MyMap2 on which the function should be performed. |
Another and a little bit more complicated example is the calculation of the seasonal rainfall which should be expressed as the relative amount of total rainfall. In this example, a table named Rainfall is used. It shows the amount of rainfall per month for several rainfall stations. A new column total was already calculated, showing the total rainfall per year for each rainfall station.
In the Create Function dialog box, define a function SEASON as:
100 * (Month1 + Month2 + Month3) / Totrain
For the description of this function, you may type for instance:
Seasonal rainfall as relative amount of total rainfall
In the Function editor, the function is listed as:
Function SEASON(Value Month1,Value Month2,Value Month3,Value Totrain) : Value
Begin
Return 100 * (Month1 + Month2 + Month3) / Totrain;
End;
This means:
The parameters Month1, Month2, Month3 and Totrain are values, the values for these parameters are retrieved and the output is calculated; the output of function Season will also be a value.
In this example the output value domain is changed into domain Perc (Percentage) as follows:
Now the definition of the function should read:
Function SEASON(Value Month1,Value Month2,Value Month3,Value Totrain) : Perc
Begin
Return 100 * (Month1 + Month2 + Month3) / Totrain;
End;
To apply this function for the first three months of the year, type on the command line of the Table window:
Relative_Amount1 = SEASON (January, February, March, Total)
Column Relative_Amount1 stores the relative amount of rainfall which fell in the months January, February and March compared to the total rainfall in that year.
You may use the function again to calculate the relative amount of rainfall for the months of April, May, and June.
Relative_Amount2 = SEASON (April, May, June, Total)
Example 4 : Using Class or ID domains in user-defined functions
You can also use Class or ID domains in user-defined functions.
This example uses a table with information on parcels. Imagine that we want to build extra houses, but only on parcels which are already in residential use and only when there is enough space to build. If the parcels satisfy certain conditions, specified in the user-defined function, they are assigned "suitable" else "not suitable".
In the Create Function dialog box, define a function SUITABLE as:
IFF ((landuse = "Residential") and (Area/Nrhouses > 10000), "Suitable", "Not Suitable")
Because ILWIS assigns by default value domains to landuse and to the output column an error message appears to warn you that ILWIS does not recognize the quotation mark " before the word Residential. This needs to be changed in the Function editor.
In the Function editor, the function is listed as:
Function SUITABLE (Value Landuse,Value Area,Value Nrhouses) : Value
Begin
Return IFF ((Landuse = "Residential") and (Area/Nrhouses > 10000) , "Suitable", "Not Suitable");
End;
Now the function should read:
Function SUITABLE(String Landuse,Value Area,Value Nrhouses) : String
Begin
Return iff ((Landuse = "Residential") and (Area/Nrhouses > 10000) , "Suitable", "Not Suitable");
End;
To apply the function on the Parcel table that is displayed in a Table window, type on
the command line of the Table window:
Suit = SUITABLE (Landuse, Area, Units)
Parcel |
Landuse |
Area |
Units |
Suit |
100 |
Residential |
58200 |
5 |
suitable |
124 |
Commercial |
16600 |
4 |
not suitable |
157 |
Residential |
82540 |
12 |
suitable |
162 |
Residential |
65925 |
4 |
not suitable |
181 |
Industrial |
8365 |
3 |
not suitable |
202 |
Institutional |
82470 |
5 |
not suitable |
225 |
Residential |
19830 |
7 |
not suitable |
269 |
Commercial |
52945 |
9 |
not suitable |
288 |
Institutional |
29400 |
6 |
not suitable |
295 |
Residential |
7235 |
4 |
not suitable |
Only parcels having a Residential landuse as well as an area per unit over 10000 square meters are assigned "Suitable".
Example 5 : User-defined function in slope instability hazard analysis (advanced)
The hazard degree of slope instability can be expressed by the Safety Factor (F). This is the ratio between the forces that make the slope fail and those that prevent the slope from failing. F-values larger than 1 indicate stable conditions, and F-values smaller than 1 instable conditions. At F=1 the slope is at the point of failure. Many different models exist for the calculation of Safety Factors. Here one of the simplest models is used.
When the model is applied on each pixel, a hazard map of safety factors is calculated. The safety factor is calculated according the following formula (Brunsden and Prior, 1979) :
F = (c' + (g - m * gw) z cos2b * tan f') / (gz sinb * cosb )
Below, the meaning of the symbols is briefly explained, and some average values are given from laboratory analysis:
c' | = effective cohesion | = 10000 | [Pa= N/m2] |
g | = unit weight of soil | = 11000 | [N/m3] |
m | = relative water depth | = zw/w | [-] |
gw | = unit weight of water | = 10000 | [N/m3] |
z | = depth of failure surface below the surface | = map Asht | [m] |
zw | = height of water table above failure surface | = ? | [m] |
b | = slope surface inclination | = map Slope | [�] |
f | = effective angle of shearing resistance | = 30 | [�] |
tan(f') | = tangent of the effective angle of shearing resistance | = 0.58 | [�] |
For detailed information on this formula refer to Chapter 6 of the Applications Guide.
In this example the slope stability analysis is made by using only two parameter maps: Asht (thickness of volcanic ashes) and Slope (slope angles in degrees). The depth of the possible failure plane is taken at the contact of the volcanic ashes and the underlying material. As a consequence, safety factors will not be calculated for the entire area, but only for the areas where there is volcanic ash at the surface.
The only unknown parameter yet is the depth of the water table. In the formula this is expressed as the value m, which is the relation between the depth of the water table and the depth of the failure surface.
ILWIS does not recognize symbols such as: c' , g, or f . Therefore, give clear name to these symbols in the user-defined function. Later, while applying the user-defined function, you fill out the values of the parameters which are represented by symbols now.
Create a function SAFETY with the following expression:
EffectiveCohesion + (SoilWeight - RelWaterDepth * WaterWeight) * FailureDepth * SQ(COS(DEGRAD(MapSlope))) * TanAngleRes / SoilWeight * FailureDepth * SIN(DEGRAD(MapSlope)) * COS(DEGRAD(MapSlope))
For the description of the function, you can type for instance: Safety factor.
In the Function editor, the expression is listed as:
Function SAFETY (Value EffectiveCohesion,Value SoilWeight,Value RelWaterDepth,Value WaterWeight,Value FailureDepth,Value MapSlope,Value TanAngleRes) : Value
Begin
Return EffectiveCohesion + (SoilWeight - RelWaterDepth * WaterWeight) * FailureDepth * SQ(COS(DEGRAD(Mapslope))) * TanAngleRes / SoilWeight * FailureDepth * SIN(DEGRAD(MapSlope)) * COS(DEGRAD(MapSlope));
End;
Firstly calculate the safety factor for the volcanic ashes under the assumption that the soil is completely dry. In that case the parameter m equals zero. In the expression, m is represented by parameter 'RelWaterDepth'; it describes the relation between the depth of the water-table and the depth of the failure surface.
Type on the command line of the Main window:
Fdry = SAFETY (10000, 11000, 0, Asht, Slope, 0.58)
This means: apply the function SAFETY using the values and maps which are specified between the brackets and store the result in map Fdry. Map Fdry shows the safety factors for extremely dry conditions.
You can imagine that a situation with a completely dry situation does not occur in many tropical regions such as for instance Manizales in Colombia.
You can easily calculate a next scenario that will evaluate a condition in which the slopes are completely saturated. This is also not a very realistic situation, but it will give us the most pessimistic estimation of slope stability.
When the soil is saturated, the m factor from the formula is equal to 1 which means that the water-table is at the surface. There is also another factor which is different for saturated conditions:
g = unit weight of soil | = 16000 N/m3 |
Now you can simply apply the user-defined function again, this time using the new saturated values.
Fsat = SAFETY (10000, 16000, 1, Asht, Slope, 0.58)
This means: apply the function SAFETY using the values and maps which are specified between the brackets and store the result in map Fsat. The map shows the safety factors for extremely wet conditions.
As soon as you have created your user-defined function, you are able to perform many similar calculations only by using different values for your parameters.
Example 6 : Calling a user-defined function in a user-defined function: Mean flow velocity
An equation that is often used to calculate the river's mean flow velocity is the Manning equation:
V=(R2/3 * S1/2)/n
where:
V | = the mean flow velocity | [m/s] |
R | = hydraulic radius | [m] |
S | = slope gradient | [�] |
n | = Manning roughness coefficient | [-] |
The Manning equation refers to the relationship between the velocity of a stream and its channel geometry. For a rectangular channel the hydraulic radius R is:
R=(W*H)/(W+2*H)
where:
W | = width of the channel | [m] |
H | = height of the water in the channel | [m] |
For a straight artificial concrete-lined culvert the Manning roughness coefficient is 0.013. For an unvegetated straight channel at bankfull discharge the roughness fluctuates between 0.025 - 0.033. In ILWIS, functions can call other functions but calls cannot be recursive, i.e. a function cannot call itself. In the example below, Manning function (V) calls another function (R) that calculates the Hydraulic radius.
Create a function R with the following expression:
(W*H)/(W+2*H)
For the description of the function, you can type for instance: Hydraulic radius for a rectangular channel
In the Function editor, the function reads:
Function R(Value W,Value H) : Value
Begin
Return (W*H)/(W+2*H);
End;
Then, create another function V that calls function R and calculates the mean flow velocity:
(POW(R(W,H),2/3)*SQRT(S))/n
For the description of this function, you can type for instance: Manning equation to calculate the mean flow velocity
In the Function editor, the function reads:
Function V(Value W,Value H,Value S,Value n) : Value
Begin
Return (POW(R(W,H),2/3)*SQRT(S))/n;
End;
To apply this function, using for example a channel width of 10 meter (W), a water depth of 4 meter (H), a channel slope of 5 degrees (S) and a Manning roughness coefficient of 0.013 (n), type on the command line of a Table window:
Velocity = V(10,4,5,0.013)
Example 7 : Conversion of LatLon to Mercator
To convert coordinates from LatLon to Mercator create a function LatLonMerc as:
Function LatLonMerc(Value Lat,Value Lon) : Coord
Begin
Value xx;
Value yy;
Value k;
k:=1;
xx:=k*Lon
yy:=k*LOG(TAN(PIDIV4+0.5*Lat));
Return COORD(xx,yy);
End;
Additional information and examples (advanced)
Besides the normal MapCalc and TabCalc expressions, the ILWIS calculator has the basic functionality of a Pascal like program. With this Pascal like functionality you can build functions that contain IF, THEN, ELSE loops, FOR loops, WHILE loops and REPEAT/UNTIL loops. For more information, see Map and Table calculation : User-defined functions (advanced).
See also:
Function editor : functionality
Map and Table calculation : User-defined functions (advanced)
Map and Table calculation : Alphabetical overview of operators and functions
Map and Table calculation : Functional overview of operators and functions