Added humanize route optimizer, still testing hard

Brian [2016-08-20 15:29:41]
Added humanize route optimizer, still testing hard
Filename
PokemonGo.RocketBot.Logic/Navigation.cs
PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
PokemonGo.RocketBot.Logic/Utils/RouteOptimizeUtil.cs
PokemonGo.RocketBot.Window/Forms/MainForm.cs
diff --git a/PokemonGo.RocketBot.Logic/Navigation.cs b/PokemonGo.RocketBot.Logic/Navigation.cs
index 7b7b661..efd7229 100644
--- a/PokemonGo.RocketBot.Logic/Navigation.cs
+++ b/PokemonGo.RocketBot.Logic/Navigation.cs
@@ -12,6 +12,7 @@ using GeoCoordinatePortable;
 using Newtonsoft.Json.Linq;
 using PokemonGo.RocketAPI;
 using PokemonGo.RocketBot.Logic.Event;
+using PokemonGo.RocketBot.Logic.Logging;
 using PokemonGo.RocketBot.Logic.State;
 using PokemonGo.RocketBot.Logic.Utils;
 using POGOProtos.Networking.Responses;
@@ -127,7 +128,6 @@ namespace PokemonGo.RocketBot.Logic
                             strResponse = reader.ReadToEnd();
                     }
                 }
-
                 var parseObject = JObject.Parse(strResponse);
                 result = Points(parseObject["routes"][0]["overview_polyline"]["points"].ToString(), 1e5);
             }
diff --git a/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs b/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
index 1c1a832..1de1eaf 100644
--- a/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
+++ b/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
@@ -55,7 +55,7 @@ namespace PokemonGo.RocketBot.Logic.Tasks
             var pokestopList = await GetPokeStops(session);

             //get optimized route
-            var pokeStops = RouteOptimizeUtil.Optimize(pokestopList.ToArray(), session.Client.CurrentLatitude, session.Client.CurrentLongitude);
+            var pokeStops = RouteOptimizeUtil.OptimizeHumanizeRoute(pokestopList.ToArray(), session.Client.CurrentLatitude, session.Client.CurrentLongitude);

             var stopsHit = 0;
             var rc = new Random(); //initialize pokestop random cleanup counter first time
diff --git a/PokemonGo.RocketBot.Logic/Utils/RouteOptimizeUtil.cs b/PokemonGo.RocketBot.Logic/Utils/RouteOptimizeUtil.cs
index d9b044c..72e35f7 100644
--- a/PokemonGo.RocketBot.Logic/Utils/RouteOptimizeUtil.cs
+++ b/PokemonGo.RocketBot.Logic/Utils/RouteOptimizeUtil.cs
@@ -4,6 +4,12 @@ using System.Linq;
 using POGOProtos.Map.Fort;
 using GMap.NET.WindowsForms;
 using PokemonGo.RocketBot.Logic.Logging;
+using System.Diagnostics;
+using System.IO;
+using System.Net;
+using Newtonsoft.Json.Linq;
+using PokemonGo.RocketBot.Logic.Event;
+using System.Threading.Tasks;

 namespace PokemonGo.RocketBot.Logic.Utils
 {
@@ -11,11 +17,15 @@ namespace PokemonGo.RocketBot.Logic.Utils

     public static class RouteOptimizeUtil
     {
-        public static List<FortData> Optimize(FortData[] pokeStops, double lat, double lng)
+        public static List<FortData> Optimize(FortData[] pokeStops, double lat, double lng,
+            bool randomizestartpoint = false)
         {
             var optimizedRoute = new List<FortData>(pokeStops);
             // NN
-            var nn = FindNn(optimizedRoute, lat, lng);
+            var nn = !randomizestartpoint
+                ? FindNn(optimizedRoute, lat, lng)
+                : optimizedRoute[new Random().Next(optimizedRoute.Count)];
+
             optimizedRoute.Remove(nn);
             optimizedRoute.Insert(0, nn);
             for (var i = 1; i < pokeStops.Length; i++)
@@ -32,11 +42,118 @@ namespace PokemonGo.RocketBot.Logic.Utils
             {
                 optimizedRoute = Optimize2Opt(optimizedRoute, out isOptimized);
             } while (isOptimized);
-            OnRouteOptimizeEvent(optimizedRoute);
+            //OnRouteOptimizeEvent(optimizedRoute);

             return optimizedRoute;
         }

+        public static List<FortData> OptimizeHumanizeRoute(FortData[] pokeStops, double lat, double lng,
+            bool randomizestartpoint = false)
+        {
+            var apikey = "AIzaSyD-9h_V9GjpczxcOOBb5payKuWrrAjk_jg";
+            //THIS IS THE LIST WITHOUT ANY MODIFY
+            var originalroute = new List<FortData>(Optimize(pokeStops, lat, lng, randomizestartpoint));
+
+            //Split list into lists with length smaller or equal to 24
+            var splitroutecontainer = SplitList(originalroute, 24);
+
+            List<FortData> finaList = new List<FortData>();
+            for (var scc = 0; scc < splitroutecontainer.Count; scc++)
+            {
+                var splitedroutes = splitroutecontainer[scc];
+                //Getting the starting point. The start point is the same as the end point if this isn't the first list
+                var start = scc == 0 ? splitedroutes[0] : splitroutecontainer[scc - 1][splitroutecontainer[scc - 1].Count - 1];
+                var end = splitedroutes[splitedroutes.Count - 1];
+                var requesturl =
+                    $"https://maps.googleapis.com/maps/api/directions/json?origin={start.Latitude},{start.Longitude}&destination={end.Latitude},{end.Longitude}&waypoints=optimize:true|";
+
+                //Create list to store waypoints
+                List<FortData> waypoints = new List<FortData>(splitedroutes);
+                //Excluded start only if this is the first list
+                if (scc == 0)
+                    waypoints.Remove(waypoints[0]);
+                //Excluded end
+                waypoints.Remove(waypoints[waypoints.Count - 1]);
+
+                foreach (var waypoint in waypoints)
+                {
+                    //Building request url
+                    requesturl += $"{waypoint.Latitude},{waypoint.Longitude}|";
+                }
+                requesturl += $"&mode=walking&units=metric&key={apikey}";
+
+                //Get resond from Google
+                var parseObject = JObject.Parse(GetRespond(requesturl));
+                //A list storing the order of waypoints
+                var orderlist = parseObject["routes"][0]["waypoint_order"].ToList();
+
+                //Initialize a list to store the sorted waypoints
+                List<FortData> buildinglist = new List<FortData>(waypoints);
+                if (scc == 0)
+                {
+                    buildinglist.Insert(0, start);
+                }
+                for (var d = 0; d < orderlist.Count; d++)
+                {
+                    if (scc == 0)
+                    {
+                        buildinglist[d + 1] = waypoints[(int)orderlist[d]];
+                    }
+                    else
+                    {
+                        buildinglist[d] = waypoints[(int)orderlist[d]];
+                    }
+                }
+                buildinglist.Add(end);
+
+                finaList.AddRange(buildinglist);
+            }
+            OnRouteOptimizeEvent(finaList);
+            return finaList;
+
+            /*var start = route[0];
+            //var endpoint = route[route.Count - 1];
+            var end = route[24];
+            var requesturl =
+                $"https://maps.googleapis.com/maps/api/directions/json?origin={start.Latitude},{start.Longitude}&destination={end.Latitude},{end.Longitude}&waypoints=optimize:true|";
+            for (var i = 1; i < 24; i++)
+            {
+                var point = route[i];
+                requesturl += $"{point.Latitude},{point.Longitude}|";
+            }
+            requesturl += $"&mode=walking&units=metric&key={apikey}";
+            Logger.Write(requesturl);
+            try
+            {
+                var web = WebRequest.Create(requesturl);
+                web.Credentials = CredentialCache.DefaultCredentials;
+
+                string strResponse;
+                using (var response = web.GetResponse())
+                {
+                    using (var stream = response.GetResponseStream())
+                    {
+                        Debug.Assert(stream != null, "stream != null");
+                        using (var reader = new StreamReader(stream))
+                            strResponse = reader.ReadToEnd();
+                    }
+                }
+                var parseObject = JObject.Parse(strResponse);
+                var l = parseObject["routes"][0]["waypoint_order"].ToString();
+                Logger.Write(strResponse);
+            }
+            catch (WebException e)
+            {
+
+            }
+            catch (NullReferenceException e)
+            {
+
+            }
+
+            return null; */
+        }
+
         private static List<FortData> Optimize2Opt(List<FortData> pokeStops, out bool isOptimized)
         {
             var n = pokeStops.Count;
@@ -130,8 +247,50 @@ namespace PokemonGo.RocketBot.Logic.Utils
             RouteOptimizeEvent?.Invoke(optimizedroute);
         }

+        public static List<List<T>> SplitList<T>(List<T> locations, int nSize = 30)
+        {
+            var list = new List<List<T>>();
+
+            for (int i = 0; i < locations.Count; i += nSize)
+            {
+                list.Add(locations.GetRange(i, Math.Min(nSize, locations.Count - i)));
+            }
+
+            return list;
+        }
+
+        public static String GetRespond(string request)
+        {
+            try
+            {
+                var web = WebRequest.Create(request);
+                web.Credentials = CredentialCache.DefaultCredentials;
+
+                string strResponse;
+                using (var response = web.GetResponse())
+                {
+                    using (var stream = response.GetResponseStream())
+                    {
+                        Debug.Assert(stream != null, "stream != null");
+                        using (var reader = new StreamReader(stream))
+                            strResponse = reader.ReadToEnd();
+                    }
+                }
+                return strResponse;
+            }
+            catch (WebException e)
+            {
+                Logger.Write(e.Message, LogLevel.Error);
+            }
+            catch (NullReferenceException e)
+            {
+                Logger.Write(e.Message, LogLevel.Error);
+
+            }
+            return null;
+        }
+
         public static event RouteOptimizeDelegate RouteOptimizeEvent;

     }
-
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Window/Forms/MainForm.cs b/PokemonGo.RocketBot.Window/Forms/MainForm.cs
index e90bb4d..fb5e580 100644
--- a/PokemonGo.RocketBot.Window/Forms/MainForm.cs
+++ b/PokemonGo.RocketBot.Window/Forms/MainForm.cs
@@ -255,8 +255,6 @@ namespace PokemonGo.RocketBot.Window.Forms
                     (from pokeStop in pokeStops
                         where pokeStop != null
                         select new PointLatLng(pokeStop.Latitude, pokeStop.Longitude)).ToList();
-                foreach(var pks in pokeStops)
-                    Logger.Write(pks.Latitude + ", " + pks.Longitude);

                 // Temporary removed it since the route is calculated on the fly with gmap api's
                 var route = new GMapRoute(routePoint, "Walking Path")
@@ -415,8 +413,8 @@ namespace PokemonGo.RocketBot.Window.Forms
                 Instance.Invoke(new Action<Color, string>(ColoredConsoleWrite), color, message);
                 return;
             }
-            Instance.logTextBox.SelectionStart = Instance.logTextBox.Text.Length;
-            Instance.logTextBox.ScrollToCaret();
+            //Instance.logTextBox.SelectionStart = Instance.logTextBox.Text.Length;
+            //Instance.logTextBox.ScrollToCaret();
             Instance.logTextBox.SelectionColor = color;
             Instance.logTextBox.AppendText(message);
         }
You may download the files in Public Git.