Map and Table calculation

User-defined functions

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.
  • Choose Value when input maps or columns use a Value domain,
  • choose String when input maps or columns use a Class or ID domain or when columns use the String domain,
  • choose Coord when input columns use a coordinate system as domain,
  • choose Color when input maps or columns use the Color domain,
  • choose Bool when input maps or columns use the Bool, the YesNo, or the Bit domain.
Param is the name of an input parameter.
Parameter names:
  • must start with a character from A to Z,
  • may contain characters from A to Z, digits 0 to 9, and underscores.
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 parameters
Example 2 : Sum of two value maps without using parameters
Example 3 : Calculation of the seasonal rainfall and expressing it as the relative amount of total rainfall
Example 4 : Using Class or ID domains in user-defined functions
Example 5 : User-defined function in slope instability hazard analysis (advanced)
Example 6 : Calling a user-defined function in a user-defined function; Mean flow velocity of rivers
Example 7 : Conversion of LatLon to Mercator

Example 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.

Example 3 : Calculation of seasonal rainfall and expressing it as the relative amount of total rainfall

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. 

  1. 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;

  2. 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;

  3. 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: