コード例 #1
0
        // https://openrouteservice.org/dev/#/api-docs/geocode/search/get
        // Returns a JSON formatted list of objects corresponding to the search input.
        public static async Task <Standort[]> SearchLocations(string query, string apiTokenKey = "5b3ce3597851110001cf62482a3dd38109654fe6a5bc6b31ac037d30")
        {
            using (var httpClient = new HttpClient {
                BaseAddress = new Uri("https://api.openrouteservice.org")
            })
            {
                httpClient.DefaultRequestHeaders.Clear();
                httpClient.DefaultRequestHeaders.TryAddWithoutValidation("accept", "application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8");

                using (var response = await httpClient.GetAsync("/geocode/search?api_key=" + HttpUtility.UrlEncode(apiTokenKey) + "&size=25&text=" + HttpUtility.UrlEncode(query)))
                {
                    string responseData = await response.Content.ReadAsStringAsync();

                    JsonElement data = JsonSerializer.Deserialize <JsonElement>(responseData);

                    Standort[] standorte = new Standort[data.GetProperty("features").GetArrayLength()];
                    for (int i = 0; i < standorte.Length; i++)
                    {
                        standorte[i] = new Standort(data.GetProperty("features")[i]);
                    }
                    return(standorte);
                }
            }
        }
コード例 #2
0
        static async Task Main(string[] args)
        {
            Console.OutputEncoding = Encoding.Unicode;


            // Laden der Standorte - entweder kann die csv-Datei mit den msg-Standorten geladen werden, oder man sucht nach eigenen Orten
            Standort[] standorte = null;
            while (standorte == null)
            {
                Console.Clear();
                MyConsole.WriteLine("Hallo :),");
                MyConsole.Write("dies ist die Einsendung von *red*Leo Decking** zur Coding-Challenge 2020 von *|white**black*get in *green*{*black*IT*green*}** und *|white**dRed*.*dGray*msg**.");
                MyConsole.WriteLine("\nMach diese Konsole am besten in den *red*Vollbildmodus** und stell die *red*Schriftgröße** etwas kleiner.\n");

                MyConsole.WriteLine("Wie willst du die Standorte, für die der beste Rundweg gefunden werden soll, laden?");
                MyConsole.WriteLine("*green*1** - csv-Datei mit *|white**dRed*.*dGray*msg**-Standorten");
                MyConsole.WriteLine("*green*2** - Suche nach eigenen Adressen/Städten");
                if (oldStandorte != null)
                {
                    MyConsole.WriteLine("*green*3** - Suche nach eigenen Adressen/Städten - *yellow* vorherige Standorte übernehmen**");
                }
                MyConsole.Write(oldStandorte == null ? "(*green*1** oder *green*2**): > " : "(*green*1**, *green*2** oder *green*3**): > ");

                string input = Console.ReadLine().Trim();
                if (input == "1")
                {
                    Console.Clear();
                    MyConsole.WriteLine("*green*1** - csv-Datei mit *|white**dRed*.*dGray*msg**-Standorten laden\n");

                    MyConsole.WriteLine("Bitte füge den Inhalt der .csv-Datei *dGray*(in einem Texteditor öffnen und kopieren)** hier ein:");
                    MyConsole.Write("Die Überschriften müssen übereinstimmen: *dMagenta*Nummer,msg Standort,Straße,Hausnummer,PLZ,Ort,Breitengrad,Längengrad\n*cyan*");

                    while (Console.KeyAvailable)
                    {
                        Console.ReadKey();
                    }

                    List <Standort> standorteList = new List <Standort>();
                    // Zeilen mit falschen Eingaben werden solange übersprungen bis die richtigen Spaltenüberschriften eingefügt werden
                    while (Console.ReadLine() != "Nummer,msg Standort,Straße,Hausnummer,PLZ,Ort,Breitengrad,Längengrad")
                    {
                        Console.CursorTop--;
                    }

                    string line;
                    while (!string.IsNullOrEmpty(line = Console.ReadLine()))
                    {
                        standorteList.Add(new Standort(line));
                    }
                    standorte = standorteList.ToArray();
                }
                else if (input == "2" || (oldStandorte != null && input == "3"))
                {
                    List <Standort> standorteList = new List <Standort>();
                    if (input == "3")
                    {
                        standorteList.AddRange(oldStandorte);
                    }
                    while (standorte == null)
                    {
                        Console.Clear();
                        MyConsole.WriteLine(input == "2" ? "*green*2** - Suche nach eigenen Adressen/Städten" : "*green*3** - Suche nach eigenen Adressen/Städten - *yellow* vorherige Standorte übernehmen**");

                        MyConsole.WriteLine("\n\nDie Standorten werden mit Hilfe der *blue*Openrouteservice API** (*cyan*https://openrouteservice.org/**) gesucht.");
                        MyConsole.WriteLine("Es wird eine Internetverbindung benötigt.");
                        MyConsole.WriteLine("Weitere Informationen zu den Begrifflichkeiten findest du hier: *blue*https://github.com/pelias/documentation/blob/master/search.md#filter-by-data-type**");

                        if (standorteList.Count > 0)
                        {
                            MyConsole.WriteLine("\n**Es wurden bisher folgende *green*" + standorteList.Count + "** Orte geladen:\n");
                            for (int i = 0; i < standorteList.Count; i++)
                            {
                                Standort s = standorteList[i];
                                MyConsole.WriteLine("*green*" + (new string(' ', (standorteList.Count + " ").Length - ((i + 1) + "").Length) + (i + 1)) + "**: " + (i % 2 == 0 ? "*magenta*" : "*dYellow*") + s.name + "*dGray*: " + s.text + " *dRed*" + s.lon + " " + s.lat);
                            }
                            ;
                        }
                        MyConsole.WriteLine("**");

                        MyConsole.Write("Suchbegriff: (*red*a** zum Abbrechen, *dYellow*e** zum Entfernen, *green*w** für weiter) > ");
                        string consoleInput = Console.ReadLine().Trim().ToLower();
                        Console.CursorTop--;
                        MyConsole.Write(new string(' ', Console.WindowWidth) + "\r");
                        Console.CursorTop--;
                        if (consoleInput == "a") // Abbrechen
                        {
                            bool abbrechen;
                            while (true)
                            {
                                MyConsole.Write("Willst du die Suche wirklich abbrechen / von vorne beginnen? (*red*ja** oder *yellow*nein**): > ");
                                string read = Console.ReadLine().Trim().ToLower();
                                if (read == "ja")
                                {
                                    abbrechen = true;
                                    break;
                                }
                                else if (read == "nein")
                                {
                                    abbrechen = false;
                                    break;
                                }
                                else
                                {
                                    Console.CursorTop--;
                                    MyConsole.Write(new string(' ', Console.WindowWidth) + "\r");
                                    Console.CursorTop--;
                                }
                            }
                            if (abbrechen)
                            {
                                break;
                            }
                        }
                        else if (consoleInput == "e") // Entfernen eines Standorts
                        {
                            if (standorteList.Count == 0)
                            {
                                MyConsole.Write("Es wurden noch *red*keine** Standorte hinzugefügt, welche entfernt werden können. *dGray*[**OK*dGray*]**");
                                Console.ReadLine();
                            }
                            else
                            {
                                while (true)
                                {
                                    MyConsole.Write("Welchen Standort willst du entfernen? (*red*0** zum Abbrechen) (*red*0**-*green*" + standorteList.Count + "**)> ");
                                    int index;
                                    if (int.TryParse(Console.ReadLine().Trim(), out index) && index >= 0 && index <= standorteList.Count)
                                    {
                                        if (index > 0)
                                        {
                                            standorteList.RemoveAt(index - 1);
                                        }
                                        break;
                                    }
                                    else
                                    {
                                        Console.CursorTop--;
                                        MyConsole.Write(new string(' ', Console.WindowWidth) + "\r");
                                        Console.CursorTop--;
                                    }
                                }
                            }
                        }
                        else if (consoleInput == "w") // Weiter zur Routen-Berechnung
                        {
                            if (standorteList.Count < 3)
                            {
                                MyConsole.Write("Es werden mindestens *red*3** Standorte benötigt. Füge weitere hinzu. *dGray*[**OK*dGray*]**");
                                Console.ReadLine();
                            }
                            else
                            {
                                while (true)
                                {
                                    MyConsole.Write("Willst du mit *green*" + standorteList.Count + "** Standorten fortfahren? (*green*ja** oder *red*nein**): > ");
                                    string read = Console.ReadLine().Trim().ToLower();
                                    if (read == "ja")
                                    {
                                        standorte = standorteList.ToArray();
                                        break;
                                    }
                                    else if (read == "nein")
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        Console.CursorTop--;
                                        MyConsole.Write(new string(' ', Console.WindowWidth) + "\r");
                                        Console.CursorTop--;
                                    }
                                }
                            }
                        }
                        else // Sucheingabe
                        {
                            Standort[] newStandorte = await OpenRouteService.SearchLocations(consoleInput);

                            if (newStandorte.Length == 0)
                            {
                                MyConsole.Write("Es wurden leider *red*keine** passenden Orte gefunden, versuche es erneut mit einem anderen Suchbegriff. *dGray*[**OK*dGray*]**");
                                Console.ReadLine();
                            }
                            else if (newStandorte.Length == 1)
                            {
                                MyConsole.WriteLine("Willst du folgenden Ort hinzufügen:");
                                Standort s = newStandorte[0];
                                MyConsole.WriteLine("*blue*" + s.name + "*dGray*: " + s.text + " *dRed*" + s.lon + " " + s.lat);
                                MyConsole.WriteLine("**");
                                while (true)
                                {
                                    MyConsole.Write("(*green*ja** oder *red*nein**): > ");
                                    string read = Console.ReadLine().Trim().ToLower();
                                    if (read == "ja")
                                    {
                                        standorteList.Add(s);
                                        break;
                                    }
                                    else if (read == "nein")
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        Console.CursorTop--;
                                        MyConsole.Write(new string(' ', Console.WindowWidth) + "\r");
                                        Console.CursorTop--;
                                    }
                                }
                            }
                            else
                            {
                                MyConsole.WriteLine("Es wurden folgende *yellow*" + newStandorte.Length + "** Orte gefunden, welchen willst du hinzufügen?\n");
                                MyConsole.WriteLine("*yellow*" + new string(' ', (newStandorte.Length + " ").Length - 1) + "0**: *red*Keinen** dieser Orte hinzufügen");
                                for (int i = 0; i < newStandorte.Length; i++)
                                {
                                    Standort s = newStandorte[i];
                                    MyConsole.WriteLine("*yellow*" + new string(' ', (newStandorte.Length + " ").Length - ((i + 1) + "").Length) + (i + 1) + "**: " + (i % 2 == 0 ? "*blue*" : "*dGreen*") + s.name + "*dGray*: " + s.text + " *dRed*" + s.lon + " " + s.lat);
                                }
                                ;
                                MyConsole.WriteLine("**");
                                while (true)
                                {
                                    MyConsole.Write("Eingabe: > ");
                                    int index;
                                    if (int.TryParse(Console.ReadLine().Trim(), out index) && index >= 0 && index <= newStandorte.Length)
                                    {
                                        if (index > 0)
                                        {
                                            standorteList.Add(newStandorte[index - 1]);
                                        }
                                        break;
                                    }
                                    else
                                    {
                                        Console.CursorTop--;
                                        MyConsole.Write(new string(' ', Console.WindowWidth) + "\r");
                                        Console.CursorTop--;
                                    }
                                }
                            }
                        }
                    }
                }
            }


            // Auswahl des Fortbewegungsprofils
            MyConsole.WriteLine("**Für welche Fortbewegungsprofil soll der Weg berechnet werden?:\n");
            for (int i = 0; i < Profile.Profiles.Length; i++)
            {
                MyConsole.WriteLine("*yellow*" + (i + 1) + ": " + Profile.Profiles[i].Color + Profile.Profiles[i].Name);
            }
            ;
            MyConsole.WriteLine();
            Profile profile = new Profile();

            while (true)
            {
                MyConsole.Write("**(*yellow*1**-*yellow*" + (Profile.Profiles.Length) + "**): > ");
                int input;
                if (int.TryParse(Console.ReadLine(), out input) && input >= 1 && input <= Profile.Profiles.Length)
                {
                    profile = Profile.Profiles[input - 1];
                    break;
                }
                Console.CursorTop--;
                MyConsole.Write("\r" + new string(' ', Console.WindowWidth) + "\r");
                Console.CursorTop--;
            }

            Console.Clear();

            // Anzeige der geladenen Standorte
            MyConsole.WriteLine("**Es wurden folgende *green*" + standorte.Length + "** Standorte geladen:\n");
            for (int i = 0; i < standorte.Length; i++)
            {
                Standort s = standorte[i];
                MyConsole.WriteLine((i % 2 == 0 ? "*magenta*" : "*dYellow*") + s.name + "*dGray*: " + s.text + " *dRed*" + s.lon + " " + s.lat);
            }
            ;


            if (profile.Id == "linear")
            {
                MyConsole.WriteLine("\n**Die Entfernungen zwischen den einzelnen Standorten für *dGray*'" + profile.Color + profile.Name + "*dGray*'** werden jetzt berechnet. [OK]");
            }
            else
            {
                MyConsole.WriteLine("\n**Die Entfernungen zwischen den einzelnen Standorten für *dGray*'" + profile.Color + profile.Name + "*dGray*'** werden jetzt mit Hilfe der *blue*Openrouteservice API** geladen.");
                MyConsole.WriteLine("Da die Wege möglichst effizient sein sollen, wird nicht der *red*kürzeste**, sondern der *green*schnellste** Weg genommen.");
                MyConsole.Write("Hierfür wird eine Internetverbindung benötigt. [OK]");
            }
            while (Console.KeyAvailable)
            {
                Console.ReadKey();
            }
            Console.ReadLine();
            // Die Entfernungen zwischen den einzelnen Standorten werden als Matrix mit der von https://openrouteservice.org/ bereitgestellten API geladen
            // Es wird für den jeweils schnellsten Weg die Entfernung und die Zeit angegeben
            int[][][] matrixes = profile.Id == "linear" ? OpenRouteService.GetLinearDistances(standorte) : await OpenRouteService.GetDistances(standorte, profile);

            int[][] distanceMatrix = matrixes[0];
            int[][] durationMatrix = matrixes[1];


            // Anzeige der Entfernungen
            Console.Clear();
            MyConsole.WriteLine("Die Entfernungen für *dGray*'" + profile.Color + profile.Name + "*dGray*'** wurden geladen.");
            MyConsole.WriteLine("Es wird jeweils von den angebgebenen Koordinaten, bzw. der nächsten Straße ausgegangen.");
            MyConsole.WriteLine("Alle Werte sind in Stunden:Minuten angegeben.");
            MyConsole.WriteLine("Die Zeilen geben den jeweiligen Start- und die Spalten den Zielstandort an:");
            MyConsole.WriteLine("\tVon *dRed*" + standorte[1].name + "** nach *dRed*" + standorte[2].name + "** dauert es zum Beispiel *red*" + DurationToString(durationMatrix[1][2]) + "**.\n");

            MyConsole.WriteLine("  ↓von↓  nach→ " + string.Join("*dGray*|**", standorte.Select(s => s.name.Length > 9 ? s.name.Substring(0, 9) : (new string(' ', 9 - s.name.Length) + s.name))));

            for (int i = 0; i < durationMatrix.Length; i++)
            {
                Standort s     = standorte[i];
                string   sName = s.name.Length > 14 ? s.name.Substring(0, 14) : (new string(' ', 14 - s.name.Length) + s.name);
                MyConsole.WriteLine(sName + ": " + string.Join(" *dGray*|** ", durationMatrix[i].Select(x => new string(' ', 6 - DurationToString(x).Length) + DurationToString(x) + " ")));
            }
            MyConsole.WriteLine();
            MyConsole.WriteLine("\nEs wird nun die optimale Reihenfolge zum Anfahren der Standorte berechnet.");

            //Berechnung des effizientesten Weges
            Path path = Algorithm.GetShortestPath(durationMatrix, distanceMatrix);

            // Arbeitsspeicher bereinigen
            GC.Collect();
            Console.CursorTop--;
            MyConsole.Write(new string(' ', Console.WindowWidth) + "\r");

            // Anzeigen des schnellsten Weges
            MyConsole.WriteLine("Der schnellste Weg wurde in *red*" + Math.Round(path.ComputationTime, 2) + "ms** gefunden:\n");

            for (int i = 0; i < standorte.Length; i++)
            {
                MyConsole.Write("*green*" + standorte[path.Places[i]].name + "** → *blue*" + DurationToString(path.Durations[i]) + " (" + Math.Round((double)path.Distances[i] / 1000, 1) + "km) **→ ");
            }
            MyConsole.WriteLine("*green*" + standorte[0].name + "**");

            MyConsole.WriteLine("\nFortbewegungsprofil: *blue*" + profile.Name);
            MyConsole.WriteLine("**Gesamtdauer: *blue*" + DurationToString(path.Duration));
            MyConsole.WriteLine("**Gesamtdistanz: *blue*" + Math.Round((double)path.Distance / 1000, 2) + "km**");

            MyConsole.WriteLine("\nÖffne diesen Link in deinem Browser, um dir den Streckenverlauf genauer anzusehen:");
            MyConsole.WriteLine("*blue*https://maps.openrouteservice.org/*cyan*directions?a=" + string.Join(',', path.Places.Select(i => standorte[i].lat.ToString(CultureInfo.InvariantCulture) + "," + standorte[i].lon.ToString(CultureInfo.InvariantCulture))) + "&b=" + profile.Code + "&c=0&k1=de-DE&k2=km");
            if (profile.Id == "linear")
            {
                MyConsole.WriteLine("*red*Achtung**: Da die openrouteserve-Karte leider keine Luftlinien-Routen unterstützt, wird der Weg stattdessen für *cyan*Fußgänger** angezeigt, die dort angegebenen Routen-Informationen *red*weichen** also etwas *red*ab**.");
            }


            MyConsole.Write("**\nDieses Programm wurde im Juli 2020 von *red*Leo Decking** als Beitrag zur Coding-Challenge 2020 von *|white**black*get in *green*{*black*IT*green*}** und *|white**dRed*.*dGray*msg** programmiert.\n");

            // Programm neustarten
            MyConsole.WriteLine("Drücke *dGray*[*green*Enter*dGray*]**, um von vorne zu beginnen.");
            MyConsole.WriteLine("Mit *dGray*[*red*Escape*dGray*]** kannst du das Programm beenden.");

            while (Console.KeyAvailable)
            {
                Console.ReadKey();
            }
            while (true)
            {
                ConsoleKeyInfo k = Console.ReadKey();
                if (k.Key == ConsoleKey.Enter)
                {
                    oldStandorte = standorte;
                    await Main(args);

                    return;
                }
                else if (k.Key == ConsoleKey.Escape)
                {
                    return;
                }
                else
                {
                    MyConsole.Write("\r \r");
                }
            }
        }