Improve documentation and formatting
This commit is contained in:
parent
7391a10344
commit
ff98d2fcf3
8 changed files with 38 additions and 28 deletions
3
AspectedRouting/IO/itinero2/Relations.md
Normal file
3
AspectedRouting/IO/itinero2/Relations.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# What about relations in Itinero 2.0?
|
||||||
|
|
||||||
|
Relations have moved to the preprocessor, where they do put a tag on the members of the relation. This is done with a TagsFilter
|
|
@ -163,11 +163,9 @@ namespace AspectedRouting.IO.jsonParser
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly IExpression _mconst =
|
private static readonly IExpression _mconst = Funcs.EitherFunc.Apply( Funcs.Id, Funcs.Const);
|
||||||
new Apply(new Apply(Funcs.EitherFunc, Funcs.Id), Funcs.Const);
|
|
||||||
|
|
||||||
private static readonly IExpression _mappingWrapper =
|
private static readonly IExpression _mappingWrapper = Funcs.EitherFunc.Apply( Funcs.Id, Funcs.StringStringToTags);
|
||||||
new Apply(new Apply(Funcs.EitherFunc, Funcs.Id), Funcs.StringStringToTags);
|
|
||||||
|
|
||||||
private static IExpression ParseMapping(IEnumerable<JsonProperty> allArgs, Context context)
|
private static IExpression ParseMapping(IEnumerable<JsonProperty> allArgs, Context context)
|
||||||
{
|
{
|
||||||
|
@ -201,7 +199,7 @@ namespace AspectedRouting.IO.jsonParser
|
||||||
{
|
{
|
||||||
var simpleMapping = new Mapping(keys, exprs);
|
var simpleMapping = new Mapping(keys, exprs);
|
||||||
|
|
||||||
var wrapped = (IExpression) new Apply(_mappingWrapper, simpleMapping);
|
var wrapped = _mappingWrapper.Apply(simpleMapping);
|
||||||
if (keys.Count == 1)
|
if (keys.Count == 1)
|
||||||
{
|
{
|
||||||
// We can interpret this directly without going through a list
|
// We can interpret this directly without going through a list
|
||||||
|
|
|
@ -697,7 +697,7 @@ Consider the mapping `{'someKey':'someValue'}`. Under normal circumstances, this
|
||||||
converting the string `someKey` into `someValue`, just like an ordinary dictionary would do. However, in the context
|
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`,
|
of `mustMatch`, we would prefer this to act as a _check_, that the highway _has_ a key `someKey` which is `someValue`,
|
||||||
thus acting
|
thus acting
|
||||||
as `{'someKey': {'$eq':'someValue'}}. Both behaviours are automatically supported in parsing, by parsing the string as `(
|
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.
|
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_
|
Disclaimer: _you should never ever need this in your profiles_
|
||||||
|
|
|
@ -245,7 +245,7 @@ namespace AspectedRouting.Language.Functions
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return _o.Pretty();
|
return ObjectExtensions.Pretty(_o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,6 +254,7 @@ namespace AspectedRouting.Language.Functions
|
||||||
public static string Pretty(this object o, Context context = null)
|
public static string Pretty(this object o, Context context = null)
|
||||||
{
|
{
|
||||||
switch (o) {
|
switch (o) {
|
||||||
|
case null: return "null";
|
||||||
case Dictionary<string, string> d:
|
case Dictionary<string, string> d:
|
||||||
var txt = "";
|
var txt = "";
|
||||||
foreach (var (k, v) in d) {
|
foreach (var (k, v) in d) {
|
||||||
|
|
|
@ -13,9 +13,9 @@ namespace AspectedRouting.Language.Functions
|
||||||
"" +
|
"" +
|
||||||
"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. " +
|
"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 " +
|
"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'}}. " +
|
"`{'someKey': {'$eq':'someValue'}}`. " +
|
||||||
"Both behaviours are automatically supported in parsing, by parsing the string as `(eitherFunc id eq) 'someValue'`. " +
|
"Both behaviours are automatically supported in parsing, by parsing all string as `(eitherFunc id eq) 'someValue'`. " +
|
||||||
"The type system is then able to figure out which implementation is needed.\n\n" +
|
"The type system is then able to figure out which implementation is needed an discards the unneeded implementations.\n\n" +
|
||||||
"Disclaimer: _you should never ever need this in your profiles_";
|
"Disclaimer: _you should never ever need this in your profiles_";
|
||||||
|
|
||||||
public override List<string> ArgNames { get; } = new List<string>{"f","g","a"};
|
public override List<string> ArgNames { get; } = new List<string>{"f","g","a"};
|
||||||
|
|
|
@ -8,15 +8,18 @@ namespace AspectedRouting.Language.Functions
|
||||||
{
|
{
|
||||||
public class FirstMatchOf : Function
|
public class FirstMatchOf : Function
|
||||||
{
|
{
|
||||||
public override string Description { get; } = "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.\n\n" +
|
public override string Description { get; } = "This higher-order function takes a list of keys, a mapping (function over tags) and a collection of tags." +
|
||||||
"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`.";
|
"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.\n\n" +
|
||||||
|
"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`.";
|
||||||
public override List<string> ArgNames { get; } = new List<string> {"s"};
|
public override List<string> ArgNames { get; } = new List<string> {"s"};
|
||||||
|
|
||||||
public FirstMatchOf() : base("first_match_of", true,
|
public FirstMatchOf() : base("first_match_of", true,
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
// [String] -> (Tags -> [a]) -> Tags -> a
|
// [String] -> (Tags -> [a]) -> Tags -> a
|
||||||
Curry.ConstructFrom(new Var("a"), // Result type on top!
|
Curry.ConstructFrom(
|
||||||
|
new Var("a"), // Result type on top!
|
||||||
new ListType(Typs.String),
|
new ListType(Typs.String),
|
||||||
new Curry(Typs.Tags, new ListType(new Var("a"))),
|
new Curry(Typs.Tags, new ListType(new Var("a"))),
|
||||||
Typs.Tags
|
Typs.Tags
|
||||||
|
|
|
@ -10,8 +10,9 @@ namespace AspectedRouting.Language.Functions
|
||||||
private static Var b = new Var("b");
|
private static Var b = new Var("b");
|
||||||
|
|
||||||
public override string Description { get; } = "Selects either one of the branches, depending on the condition." +
|
public override string Description { get; } = "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`)" +
|
" The 'then' branch is returned if the condition returns the string `yes` or `true`." +
|
||||||
"If the `else` branch is not set, `null` is returned in the condition is false.";
|
" Otherwise, the `else` branch is taken (including if the condition returns `null`)" +
|
||||||
|
"If the `else` branch is not set, `null` is returned if the condition evaluates to false.";
|
||||||
public override List<string> ArgNames { get; } = new List<string> {"condition", "then", "else"};
|
public override List<string> ArgNames { get; } = new List<string> {"condition", "then", "else"};
|
||||||
|
|
||||||
public If() : base("if_then_else", true,
|
public If() : base("if_then_else", true,
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace AspectedRouting.Language.Functions
|
||||||
" a flag `_relation:<aspect_name>=\"yes\"` will be set if the aspect matches on every way for where this aspect matches.\n" +
|
" a flag `_relation:<aspect_name>=\"yes\"` will be set if the aspect matches on every way for where this aspect matches.\n" +
|
||||||
"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`?) " +
|
"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_:" +
|
"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." +
|
"`_relation:<profile_name>:<aspect_name>=yes'. The subfunction is thus executed `countOf(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.\n\n" +
|
" The profile function then picks the tags for himself and strips the `<profile_name>:` away from the key.\n\n" +
|
||||||
"\n\n" +
|
"\n\n" +
|
||||||
"In the test.csv, one can simply use `_relation:<aspect_name>=yes` to mimic relations in your tests";
|
"In the test.csv, one can simply use `_relation:<aspect_name>=yes` to mimic relations in your tests";
|
||||||
|
@ -49,19 +49,23 @@ namespace AspectedRouting.Language.Functions
|
||||||
// In the case of tests, relations might be added with "_relation:1:<key>"
|
// In the case of tests, relations might be added with "_relation:1:<key>"
|
||||||
// So, we create this table as dictionary
|
// So, we create this table as dictionary
|
||||||
var relationTags = new Dictionary<string, Dictionary<string, string>>();
|
var relationTags = new Dictionary<string, Dictionary<string, string>>();
|
||||||
foreach (var tag in tags) {
|
foreach (var tag in tags)
|
||||||
if (tag.Key.StartsWith("_relation:")) {
|
{
|
||||||
var keyParts = tag.Key.Split(":");
|
if (!tag.Key.StartsWith("_relation:"))
|
||||||
if (keyParts.Length != 3) {
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
var relationName = keyParts[1];
|
|
||||||
if (!relationTags.ContainsKey(relationName)) {
|
|
||||||
relationTags.Add(relationName, new Dictionary<string, string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
relationTags[relationName].Add(keyParts[2], tag.Value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var keyParts = tag.Key.Split(":");
|
||||||
|
if (keyParts.Length != 3) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var relationName = keyParts[1];
|
||||||
|
if (!relationTags.ContainsKey(relationName)) {
|
||||||
|
relationTags.Add(relationName, new Dictionary<string, string>());
|
||||||
|
}
|
||||||
|
|
||||||
|
relationTags[relationName].Add(keyParts[2], tag.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var relationTagging in relationTags) {
|
foreach (var relationTagging in relationTags) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue