- double
- pdouble
- nat
- int
- string
- tags
- bool
- eq
- notEq
- not
- inv
- default
- parse
- to_string
- concat
- containedIn
- min
- and
- max
- or
- sum
- plus
- add
- multiply
- atleast
- firstMatchOf
- mustMatch
- memberOf
- if_then_else
- if
- if_then_else_dotted
- ifdotted
- ifDotted
- id
- const
- constRight
- dot
- listDot
- eitherFunc
- stringToTags
- head
a | b | returns |
---|---|---|
$a | $a | bool |
$a | $a | string |
Returns 'yes' if both values are the same
Lua implementation:
function eq(a, b)
if (a == b) then
return "yes"
else
return "no"
end
end
a | b | returns |
---|---|---|
$a | $a | bool |
$a | $a | string |
bool | bool |
OVerloaded function, either boolean not or returns 'yes' if the two passed in values are not the same;
Lua implementation:
function notEq(a, b)
if (b == nil) then
b = "yes"
end
if (a ~= b) then
return "yes"
else
return "no"
end
end
a | b | returns |
---|---|---|
$a | $a | bool |
$a | $a | string |
bool | bool |
OVerloaded function, either boolean not or returns 'yes' if the two passed in values are not the same;
Lua implementation:
function notEq(a, b)
if (b == nil) then
b = "yes"
end
if (a ~= b) then
return "yes"
else
return "no"
end
end
d | returns |
---|---|
pdouble | pdouble |
double | double |
Calculates 1/d
Lua implementation:
function inv(n)
return 1/n
end
defaultValue | f | returns |
---|---|---|
$a | $b -> $a | $b |
Calculates function f
for the given argument. If the result is null
, the default value is returned instead
Lua implementation:
function default(defaultValue, realValue)
if(realValue ~= nil) then
return realValue
end
return defaultValue
end
s | returns |
---|---|
string | double |
string | pdouble |
Parses a string into a numerical value. Returns 'null' if parsing fails or no input is given. If a duration is given (e.g. 01:15
), then the number of minutes (75) is returned
Lua implementation:
function parse(string)
if (string == nil) then
return 0
end
if (type(string) == "number") then
return string
end
if (string == "yes" or string == "true") then
return 1
end
if (string == "no" or string == "false") then
return 0
end
if (type(string) == "boolean") then
if (string) then
return 1
else
return 0
end
end
if(string:match("%d+:%d+")) then
-- duration in minute
local duration = 0
for part in string:gmatch "%d+" do
duration = duration * 60 + tonumber(part)
end
return duration
end
return tonumber(string)
end
obj | returns |
---|---|
$a | string |
Converts a value into a human readable string
Lua implementation:
function to_string(o)
return o;
end
a | b | returns |
---|---|---|
string | string | string |
Concatenates two strings
Lua implementation:
function concat(a, b)
return a .. b
end
list | a | returns |
---|---|---|
list ($a) | $a | bool |
Given a list of values, checks if the argument is contained in the list.
Lua implementation:
function containedIn(list, a)
for _, value in pairs(list) do
if (value == a) then
return true
end
end
return false;
end
list | returns |
---|---|
list (nat) | nat |
list (int) | int |
list (pdouble) | pdouble |
list (double) | double |
list (bool) | bool |
Out of a list of values, gets the smallest value. In case of a list of bools, this acts as and
. Note that 'null'-values are ignored.
Lua implementation:
function min(list)
local min
for _, value in pairs(list) do
if(value ~= nil) then
if (min == nil) then
min = value
elseif (value < min) then
min = value
end
end
end
return min;
end
list | returns |
---|---|
list (nat) | nat |
list (int) | int |
list (pdouble) | pdouble |
list (double) | double |
list (bool) | bool |
Out of a list of values, gets the smallest value. In case of a list of bools, this acts as and
. Note that 'null'-values are ignored.
Lua implementation:
function min(list)
local min
for _, value in pairs(list) do
if(value ~= nil) then
if (min == nil) then
min = value
elseif (value < min) then
min = value
end
end
end
return min;
end
list | returns |
---|---|
list (nat) | nat |
list (int) | int |
list (pdouble) | pdouble |
list (double) | double |
list (bool) | bool |
Returns the biggest value in the list. For a list of booleans, this acts as 'or'
Lua implementation:
function max(list)
local max
for _, value in pairs(list) do
if (value ~= nil) then
if (max == nil) then
max = value
elseif (max < value) then
max = value
end
end
end
return max;
end
list | returns |
---|---|
list (nat) | nat |
list (int) | int |
list (pdouble) | pdouble |
list (double) | double |
list (bool) | bool |
Returns the biggest value in the list. For a list of booleans, this acts as 'or'
Lua implementation:
function max(list)
local max
for _, value in pairs(list) do
if (value ~= nil) then
if (max == nil) then
max = value
elseif (max < value) then
max = value
end
end
end
return max;
end
list | returns |
---|---|
list (nat) | nat |
list (int) | int |
list (pdouble) | pdouble |
list (double) | double |
list (bool) | int |
Sums all the numbers in the given list. If the list is a list of booleans, yes
or true
will be considered to equal 1
. Null values are ignored (and thus handled as being 0
)
Lua implementation:
function sum(list)
local sum = 0
for _, value in pairs(list) do
if(value ~= nil) then
if(value == 'yes' or value == 'true') then
value = 1
end
sum = sum + value
end
end
return sum;
end
list | returns |
---|---|
list (nat) | nat |
list (int) | int |
list (pdouble) | pdouble |
list (double) | double |
list (bool) | int |
Sums all the numbers in the given list. If the list is a list of booleans, yes
or true
will be considered to equal 1
. Null values are ignored (and thus handled as being 0
)
Lua implementation:
function sum(list)
local sum = 0
for _, value in pairs(list) do
if(value ~= nil) then
if(value == 'yes' or value == 'true') then
value = 1
end
sum = sum + value
end
end
return sum;
end
list | returns |
---|---|
list (nat) | nat |
list (int) | int |
list (pdouble) | pdouble |
list (double) | double |
list (bool) | int |
Sums all the numbers in the given list. If the list is a list of booleans, yes
or true
will be considered to equal 1
. Null values are ignored (and thus handled as being 0
)
Lua implementation:
function sum(list)
local sum = 0
for _, value in pairs(list) do
if(value ~= nil) then
if(value == 'yes' or value == 'true') then
value = 1
end
sum = sum + value
end
end
return sum;
end
list | returns |
---|---|
list (nat) | nat |
list (int) | int |
list (pdouble) | pdouble |
list (double) | double |
list (bool) | bool |
Multiplies all the values in a given list. On a list of booleans, this acts as 'and' or 'all', as false
and no
are interpreted as zero. Null values are ignored and thus considered to be one
Lua implementation:
function multiply(list)
local factor = 1
for _, value in pairs(list) do
if (value ~= nil) then
factor = factor * value
end
end
return factor;
end
minimum | f | then | else | returns |
---|---|---|---|---|
double | $b -> double | $a | $a | $b |
Returns 'yes' if the second argument is bigger then the first argument. (Works great in combination with $dot)
Lua implementation:
function atleast(minimumExpected, actual, thn, els)
if (minimumExpected <= actual) then
return thn;
end
return els
end
s | returns |
---|---|
list (string) | tags -> list ($a) |
This higherorder function takes a list of keys, a mapping (function over tags) and a collection of tags. It will try the function for the first key (and it's respective value). If the function fails (it gives null), it'll try the next key.
E.g. $firstMatchOf ['maxspeed','highway'] {'maxspeed' --> $parse, 'highway' --> {residential --> 30, tertiary --> 50}}
applied on {maxspeed=70, highway=tertiary}
will yield 70
as that is the first key in the list; {highway=residential}
will yield 30
.
Lua implementation:
function first_match_of(tags, result, order_of_keys, table)
for _, key in pairs(order_of_keys) do
local v = tags[key]
if (v ~= nil) then
local mapping = table[key]
if (type(mapping) == "table") then
local resultValue = mapping[v]
if (resultValue ~= nil) then
result.attributes_to_keep[key] = v
return resultValue
end
else
result.attributes_to_keep[key] = v
return mapping
end
end
end
return nil;
end
neededKeys (filled in by parser) | f | returns |
---|---|---|
list (string) | tags -> list (string) | tags |
Checks that every specified key is present and gives a non-false value . If, on top, a value is present with a mapping, every key/value will be executed and must return a value that is not 'no' or 'false' Note that this is a privileged builtin function, as the parser will automatically inject the keys used in the called function.
Lua implementation:
--[[
must_match checks that a collection of tags matches a specification.
The function is not trivial and contains a few subtilities.
Consider the following source:
{"$mustMatch":{ "a":"X", "b":{"not":"Y"}}}
This is desugared into
{"$mustMatch":{ "a":{"$eq":"X"}, "b":{"not":"Y"}}}
When applied on the tags {"a" : "X"}, this yields the table {"a":"yes", "b":"yes} (as `notEq` "Y" "nil") yields "yes"..
MustMatch checks that every key in this last table yields yes - even if it is not in the original tags!
]]
function must_match(tags, result, needed_keys, table)
for _, key in ipairs(needed_keys) do
local v = table[key] -- use the table here, as a tag that must _not_ match might be 'nil' in the tags
if (v == nil) then
return false
end
local mapping = table[key]
if (type(mapping) == "table") then
local resultValue = mapping[v]
if (resultValue == nil or
resultValue == false or
resultValue == "no" or
resultValue == "false") then
return false
end
elseif (type(mapping) == "string") then
local bool = mapping
if (bool == "no" or bool == "0") then
return false
end
if (bool ~= "yes" and bool ~= "1") then
error("MustMatch got a string value it can't handle: " .. bool)
end
elseif (type(mapping) == "boolean") then
if(not mapping) then
return false
end
else
error("The mapping is not a table. This is not supported. We got " .. tostring(mapping) .. " (" .. type(mapping)..")")
end
end
-- Now that we know for sure that every key matches, we add them all
for _, key in ipairs(needed_keys) do
local v = tags[key] -- this is the only place where we use the original tags
if (v ~= nil) then
result.attributes_to_keep[key] = v
end
end
return true
end
f | tags | returns |
---|---|---|
tags -> bool | tags | bool |
This function returns true, if the way is member of a relation matching the specified function.
In order to use this for itinero 1.0, the membership must be the top level expression.
Conceptually, when the aspect is executed for a way, every relation will be used as argument in the subfunction f
If this subfunction returns 'true', the entire aspect will return true.
In the lua implementation for itinero 1.0, this is implemented slightly different: a flag _relation:<aspect_name>="yes"
will be set if the aspect matches on every way for where this aspect matches.
However, this plays poorly with parameters (e.g.: what if we want to cycle over a highway which is part of a certain cycling network with a certain #network_name
?) Luckily, parameters can only be simple values. To work around this problem, an extra tag is introduced for every single profile:_relation:<profile_name>:<aspect_name>=yes'. The subfunction is thus executed
countOr(relations) * countOf(profiles)time, yielding
countOf(profiles)tags. The profile function then picks the tags for himself and strips the
<profile_name>:` away from the key.
In the test.csv, one can simply use _relation:<aspect_name>=yes
to mimic relations in your tests
Lua implementation:
function member_of(calledIn, parameters, tags, result)
local k = "_relation:" .. calledIn
-- This tag is conventiently setup by all the preprocessors, which take the parameters into account
local doesMatch = tags[k]
if (doesMatch == "yes") then
result.attributes_to_keep[k] = "yes"
return true
end
return false
end
condition | then | else | returns |
---|---|---|---|
bool | $a | $a | $a |
bool | $a | $a | |
string | $a | $a | $a |
string | $a | $a |
Selects either one of the branches, depending on the condition. The 'then' branch is returned if the condition returns the string yes
or true
. Otherwise, the else
branch is taken (including if the condition returns null
)If the else
branch is not set, null
is returned in the condition is false.
Lua implementation:
function if_then_else(condition, thn, els)
if (condition ~= nil and (condition == "yes" or condition == true or condition == "true") then
return thn
else
return els -- if no third parameter is given, 'els' will be nil
end
end
condition | then | else | returns |
---|---|---|---|
bool | $a | $a | $a |
bool | $a | $a | |
string | $a | $a | $a |
string | $a | $a |
Selects either one of the branches, depending on the condition. The 'then' branch is returned if the condition returns the string yes
or true
. Otherwise, the else
branch is taken (including if the condition returns null
)If the else
branch is not set, null
is returned in the condition is false.
Lua implementation:
function if_then_else(condition, thn, els)
if (condition ~= nil and (condition == "yes" or condition == true or condition == "true") then
return thn
else
return els -- if no third parameter is given, 'els' will be nil
end
end
condition | then | else | returns |
---|---|---|---|
$b -> bool | $b -> $a | $b | $a |
$b -> string | $b -> $a | $b | $a |
$b -> bool | $b -> $a | $b -> $a | $b |
$b -> string | $b -> $a | $b -> $a | $b |
An if_then_else, but one which takes an extra argument and applies it on the condition, then and else.
Consider fc
, fthen
and felse
are all functions taking an a
, then:
(ifDotted fc fthen felse) a
=== (if (fc a) (fthen a) (felse a)Selects either one of the branches, depending on the condition. The 'then' branch is returned if the condition returns the string
yesor
trueor the boolean
trueIf the
elsebranch is not set,
null` is returned in the condition is false.In case the condition returns 'null', then the 'else'-branch is taken.
Lua implementation:
function applyIfNeeded(f, arg)
if(f == nil) then
return nil
end
if(type(f) == "function") then
return f(arg)
else
return f
end
end
function if_then_else_dotted(conditionf, thnf, elsef, arg)
local condition = applyIfNeeded(conditionf, arg);
if (condition) then
return applyIfNeeded(thnf, arg)
else
return applyIfNeeded(elsef, arg) -- if no third parameter is given, 'els' will be nil
end
end
condition | then | else | returns |
---|---|---|---|
$b -> bool | $b -> $a | $b | $a |
$b -> string | $b -> $a | $b | $a |
$b -> bool | $b -> $a | $b -> $a | $b |
$b -> string | $b -> $a | $b -> $a | $b |
An if_then_else, but one which takes an extra argument and applies it on the condition, then and else.
Consider fc
, fthen
and felse
are all functions taking an a
, then:
(ifDotted fc fthen felse) a
=== (if (fc a) (fthen a) (felse a)Selects either one of the branches, depending on the condition. The 'then' branch is returned if the condition returns the string
yesor
trueor the boolean
trueIf the
elsebranch is not set,
null` is returned in the condition is false.In case the condition returns 'null', then the 'else'-branch is taken.
Lua implementation:
function applyIfNeeded(f, arg)
if(f == nil) then
return nil
end
if(type(f) == "function") then
return f(arg)
else
return f
end
end
function if_then_else_dotted(conditionf, thnf, elsef, arg)
local condition = applyIfNeeded(conditionf, arg);
if (condition) then
return applyIfNeeded(thnf, arg)
else
return applyIfNeeded(elsef, arg) -- if no third parameter is given, 'els' will be nil
end
end
condition | then | else | returns |
---|---|---|---|
$b -> bool | $b -> $a | $b | $a |
$b -> string | $b -> $a | $b | $a |
$b -> bool | $b -> $a | $b -> $a | $b |
$b -> string | $b -> $a | $b -> $a | $b |
An if_then_else, but one which takes an extra argument and applies it on the condition, then and else.
Consider fc
, fthen
and felse
are all functions taking an a
, then:
(ifDotted fc fthen felse) a
=== (if (fc a) (fthen a) (felse a)Selects either one of the branches, depending on the condition. The 'then' branch is returned if the condition returns the string
yesor
trueor the boolean
trueIf the
elsebranch is not set,
null` is returned in the condition is false.In case the condition returns 'null', then the 'else'-branch is taken.
Lua implementation:
function applyIfNeeded(f, arg)
if(f == nil) then
return nil
end
if(type(f) == "function") then
return f(arg)
else
return f
end
end
function if_then_else_dotted(conditionf, thnf, elsef, arg)
local condition = applyIfNeeded(conditionf, arg);
if (condition) then
return applyIfNeeded(thnf, arg)
else
return applyIfNeeded(elsef, arg) -- if no third parameter is given, 'els' will be nil
end
end
a | returns |
---|---|
$a | $a |
Returns the argument unchanged - the identity function. Seems useless at first sight, but useful in parsing
Lua implementation:
function id(v)
return v
end
a | b | returns |
---|---|---|
$a | $b | $a |
Small utility function, which takes two arguments a
and b
and returns a
. Used extensively to insert freedom
Lua implementation:
function const(a, b)
return a
end
a | b | returns |
---|---|---|
$a | $b | $b |
Small utility function, which takes two arguments a
and b
and returns b
. Used extensively to insert freedom
Lua implementation:
f | g | a | returns |
---|---|---|---|
$b -> $c | $a -> $b | $a | $c |
Higher order function: converts f (g a)
into (dot f g) a
. In other words, this fuses f
and g
in a new function, which allows the argument to be lifted out of the expression
Lua implementation:
list | a | returns |
---|---|---|
list ($a -> $b) | $a | list ($b) |
Listdot takes a list of functions [f, g, h]
and and an argument a
. It applies the argument on every single function.It conveniently lifts the argument out of the list.
Lua implementation:
-- TODO
-- listDot
f | g | a | returns |
---|---|---|---|
$a -> $b | $c -> $d | $a | $b |
$a -> $b | $c -> $d | $c | $d |
EitherFunc is a small utility function, mostly used in the parser. It allows the compiler to choose a function, based on the types.
Consider the mapping {'someKey':'someValue'}
. Under normal circumstances, this acts as a pointwise-function, converting the string someKey
into someValue
, just like an ordinary dictionary would do. However, in the context of mustMatch
, we would prefer this to act as a check, that the highway has a key someKey
which is someValue
, thus acting as {'someKey': {'$eq':'someValue'}}. Both behaviours are automatically supported in parsing, by parsing the string as
(eitherFunc id eq) 'someValue'`. The type system is then able to figure out which implementation is needed.
Disclaimer: you should never ever need this in your profiles
Lua implementation:
f | tags | returns |
---|---|---|
string -> string -> $a | tags | list ($a) |
stringToTags converts a function string -> string -> a
into a function tags -> [a]
Lua implementation:
print("ERROR: stringToTag is needed. This should not happen")
ls | returns |
---|---|
list ($a) | $a |
Select the first non-null value of a list; returns 'null' on empty list or on null
Lua implementation:
function head(ls)
if(ls == nil) then
return nil
end
for _, v in pairs(ls) do
if(v ~= nil) then
return v
end
end
return nil
end