From aa3b669da95bb451ebc9c598d351dc60b8249759 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Wed, 30 Sep 2020 13:35:30 +0200 Subject: [PATCH] Fix tests, add profile metadata output --- AspectedRouting/IO/jsonParser/JsonParser.cs | 5 ++ AspectedRouting/Language/Analysis.cs | 3 +- .../Language/Expression/ProfileMetaData.cs | 6 +++ AspectedRouting/Program.cs | 41 ++++++++++++++-- AspectedRouting/Utils.cs | 47 ++++++++++++++++++- .../aspects/bicycle.network_by_operator.json | 9 +++- Profiles/bicycle/bicycle.json | 8 ++-- Profiles/bicycle/tests/bicycle.brussels.csv | 5 -- 8 files changed, 107 insertions(+), 17 deletions(-) delete mode 100644 Profiles/bicycle/tests/bicycle.brussels.csv diff --git a/AspectedRouting/IO/jsonParser/JsonParser.cs b/AspectedRouting/IO/jsonParser/JsonParser.cs index 8936eb7..d44c66a 100644 --- a/AspectedRouting/IO/jsonParser/JsonParser.cs +++ b/AspectedRouting/IO/jsonParser/JsonParser.cs @@ -51,6 +51,11 @@ namespace AspectedRouting.IO.jsonParser foreach (var obj in e.EnumerateObject()) { var nm = obj.Name.TrimStart('#'); + if (nm == "") + { + // This is a comment - not a parameter! + continue; + } switch (obj.Value.ValueKind) { case JsonValueKind.String: diff --git a/AspectedRouting/Language/Analysis.cs b/AspectedRouting/Language/Analysis.cs index 8cbb0bd..7257fe8 100644 --- a/AspectedRouting/Language/Analysis.cs +++ b/AspectedRouting/Language/Analysis.cs @@ -203,7 +203,8 @@ namespace AspectedRouting.Language public static void SanityCheckProfile(this ProfileMetaData pmd, Context context) { - var defaultParameters = pmd.DefaultParameters.Keys.Select(k => k.TrimStart('#')); + var defaultParameters = pmd.DefaultParameters.Keys + .Select(k => k.TrimStart('#')).ToList(); var usedMetadata = pmd.UsedParameters(context); diff --git a/AspectedRouting/Language/Expression/ProfileMetaData.cs b/AspectedRouting/Language/Expression/ProfileMetaData.cs index 7f4adfc..90a2941 100644 --- a/AspectedRouting/Language/Expression/ProfileMetaData.cs +++ b/AspectedRouting/Language/Expression/ProfileMetaData.cs @@ -14,6 +14,12 @@ namespace AspectedRouting.Language.Expression public string Author { get; } public string Filename { get; } public List VehicleTyps { get; } + + /* + * Which tags are included in the routerdb but are _not_ used for routeplanning? + * Typically these are tags that are useful for navigation (name of the road, is this a tunnel, ...) + * but not relevant for determining the road + */ public List Metadata { get; } public Dictionary DefaultParameters { get; } diff --git a/AspectedRouting/Program.cs b/AspectedRouting/Program.cs index 7d6f431..d36a548 100644 --- a/AspectedRouting/Program.cs +++ b/AspectedRouting/Program.cs @@ -114,6 +114,12 @@ namespace AspectedRouting return; // End of stream has been reached } + if (read == "") + { + Console.WriteLine("looƆ sᴉ dɐWʇǝǝɹʇSuǝdO"); + continue; + } + if (read.Equals("quit")) { return; @@ -141,6 +147,11 @@ namespace AspectedRouting var tags = new Dictionary(); foreach (var str in tagsRaw) { + if (str == "") + { + continue; + } + var strSplit = str.Split("="); var k = strSplit[0].Trim(); var v = strSplit[1].Trim(); @@ -206,9 +217,20 @@ namespace AspectedRouting var files = Directory.EnumerateFiles(inputDir, "*.json", SearchOption.AllDirectories) .ToList(); - var tests = Directory.EnumerateFiles(inputDir, "*test.csv", SearchOption.AllDirectories) + var tests = Directory.EnumerateFiles(inputDir, "*.csv", SearchOption.AllDirectories) .ToList(); + foreach (var test in tests) + { + if (test.EndsWith(".test.csv") || test.EndsWith(".behaviour_test.csv")) + { + continue; + } + + throw new ArgumentException( + $"Invalid name for csv file ${test}, should end with either '.behaviour_test.csv' or '.test.csv'"); + } + var context = new Context(); var aspects = ParseAspects(files, tests, context); @@ -235,7 +257,7 @@ namespace AspectedRouting } } - + foreach (var (profile, profileTests) in profiles) { foreach (var test in profileTests) @@ -274,8 +296,19 @@ namespace AspectedRouting } } - Repl(context, - profiles.First(p => p.profile.Name.Equals("bicycle")).profile); + File.WriteAllText($"{outputDir}/metadata.json", + Utils.GenerateExplanationJson(profiles.Select(p => p.profile)) + ); + + if (!args.Contains("--no-repl")) + { + Repl(context, + profiles.First(p => p.profile.Name.Equals("bicycle")).profile); + } + else + { + Console.WriteLine("Not starting REPL as --no-repl is specified"); + } } } } \ No newline at end of file diff --git a/AspectedRouting/Utils.cs b/AspectedRouting/Utils.cs index 80bf2d4..f3832f3 100644 --- a/AspectedRouting/Utils.cs +++ b/AspectedRouting/Utils.cs @@ -1,4 +1,7 @@ using System.Collections.Generic; +using System.Linq; +using AspectedRouting.Language; +using AspectedRouting.Language.Expression; namespace AspectedRouting { @@ -18,7 +21,7 @@ namespace AspectedRouting { return string.Join("\n", lines); } - + public static int Multiply(this IEnumerable ints) { var factor = 1; @@ -30,6 +33,48 @@ namespace AspectedRouting return factor; } + /// + /// Generates a JSON file where all the profiles are listed, together with descriptions and other metadata. + /// Useful for other apps, e.g. the routing api to have + /// + /// + /// + public static string GenerateExplanationJson(IEnumerable profiles) + { + var metaItems = new List(); + foreach (var profile in profiles) + { + var profileName = profile.Name; + var author = profile.Author; + var profileDescription = profile.Description; + + + foreach (var behaviour in profile.Behaviours) + { + var behaviourDescription = behaviour.Value["description"].Evaluate(new Context()) as string; + behaviourDescription ??= ""; + if (behaviourDescription.ToLower().Contains("[private]")) + { + // This profile is marked as private, we are hiding it + continue; + } + + var meta = new Dictionary + { + {"name", behaviour.Key}, + {"type", profileName}, + {"author", author}, + {"description", behaviourDescription + " (" + profileDescription + ")"} + }; + + var json = string.Join(",", meta.Select(d => + $"\"{d.Key}\": \"{d.Value}\"")); + metaItems.Add("{" + json + "}\n"); + } + } + + return "[" + string.Join(",", metaItems) + "]"; + } } } \ No newline at end of file diff --git a/Profiles/bicycle/aspects/bicycle.network_by_operator.json b/Profiles/bicycle/aspects/bicycle.network_by_operator.json index f32ba33..327717c 100644 --- a/Profiles/bicycle/aspects/bicycle.network_by_operator.json +++ b/Profiles/bicycle/aspects/bicycle.network_by_operator.json @@ -5,10 +5,15 @@ "$mustMatch": { "type": "route", "route": "bicycle", + "operator": { + "$containedIn": "#networkOperator" + }, "#": { "note": "This block is commented out. A lot of networks we want to perform route planning on, are still proposed", - "state": {"$not": "proposed"}}, - "operator": {"$containedIn": "#networkOperator"} + "state": { + "$not": "proposed" + } + } } } } diff --git a/Profiles/bicycle/bicycle.json b/Profiles/bicycle/bicycle.json index 1fbd367..c36c7f1 100644 --- a/Profiles/bicycle/bicycle.json +++ b/Profiles/bicycle/bicycle.json @@ -1,6 +1,6 @@ { "name": "bicycle", - "description": "A simple profile which routes a normal bicycle", + "description": "Profile for a normal bicycle", "vehicletypes": [ "vehicle", "bicycle" @@ -122,11 +122,11 @@ }, "genk": { "description": "A route preferring the cycling network by operator 'Stad Genk'", - "#operatorNetworkScore": 5, + "#operatorNetworkScore": 50, "#networkOperator": [ "Stad Genk" ], - "#safety": 1 + "#safety": 0.1 }, "cycle_highway": { "description": "A route preferring the 'cycle-highways'. On non-cycleways, fastest is used (with a very low factor) in order to make sure the behaviour there is defined ", @@ -151,7 +151,7 @@ "#safety": 3 }, "b2w": { - "description": "[Custom] Route specifically for Bike2Work. Same as commute at this moment. A route preferring the 'cycle-highways' or the cycling network by operator 'Brussels Mobility'", + "description": "[Custom][Private] Route specifically for Bike2Work. Same as commute at this moment. A route preferring the 'cycle-highways' or the cycling network by operator 'Brussels Mobility'", "#operatorNetworkScore": 3, "#networkOperator": [ "Brussels Mobility" diff --git a/Profiles/bicycle/tests/bicycle.brussels.csv b/Profiles/bicycle/tests/bicycle.brussels.csv deleted file mode 100644 index e333db0..0000000 --- a/Profiles/bicycle/tests/bicycle.brussels.csv +++ /dev/null @@ -1,5 +0,0 @@ -access,oneway,speed,priority,highway,_relation:bicycle.network_by_operator -no,both,0,0,, -yes,both,15,1.9,residential, -yes,both,15,6.9,residential,yes -dismount,both,2.25,0.0195,footway,