Navigation logic is now using microsoft library for location.

Spegeli [2016-07-23 15:59:24]
Navigation logic is now using microsoft library for location.

Inspired from: https://github.com/NecronomiconCoding/Pokemon-Go-Bot/pull/153
Filename
PokemonGo.RocketAPI.Logic/Inventory.cs
PokemonGo.RocketAPI.Logic/Logic.cs
PokemonGo.RocketAPI.Logic/Navigation.cs
PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
diff --git a/PokemonGo.RocketAPI.Logic/Inventory.cs b/PokemonGo.RocketAPI.Logic/Inventory.cs
index cfa45cd..3f18b8f 100644
--- a/PokemonGo.RocketAPI.Logic/Inventory.cs
+++ b/PokemonGo.RocketAPI.Logic/Inventory.cs
@@ -1,5 +1,8 @@
 #region

+using System.Collections.Concurrent;
+using System;
+using System.Threading;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
diff --git a/PokemonGo.RocketAPI.Logic/Logic.cs b/PokemonGo.RocketAPI.Logic/Logic.cs
index b611967..8ddf2e8 100644
--- a/PokemonGo.RocketAPI.Logic/Logic.cs
+++ b/PokemonGo.RocketAPI.Logic/Logic.cs
@@ -2,9 +2,8 @@

 using System;
 using System.Collections.Generic;
+using System.Device.Location;
 using System.Linq;
-using System.Reflection.Emit;
-using System.Text;
 using System.Threading.Tasks;
 using AllEnum;
 using PokemonGo.RocketAPI.Enums;
@@ -13,7 +12,6 @@ using PokemonGo.RocketAPI.Extensions;
 using PokemonGo.RocketAPI.GeneratedCode;
 using PokemonGo.RocketAPI.Logic.Utils;
 using PokemonGo.RocketAPI.Helpers;
-using System.Collections;

 #endregion

@@ -189,7 +187,19 @@ namespace PokemonGo.RocketAPI.Logic
         {
             var mapObjects = await _client.GetMapObjects();
             //var pokeStops = mapObjects.MapCells.SelectMany(i => i.Forts).Where(i => i.Type == FortType.Checkpoint && i.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime()).OrderBy(i => LocationUtils.CalculateDistanceInMeters(new Navigation.Location(_client.CurrentLat, _client.CurrentLng), new Navigation.Location(i.Latitude, i.Longitude)));
-            var pokeStops = Navigation.pathByNearestNeighbour(mapObjects.MapCells.SelectMany(i => i.Forts).Where(i => i.Type == FortType.Checkpoint && i.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime()).OrderBy(i => LocationUtils.CalculateDistanceInMeters(new Navigation.Location(_client.CurrentLat, _client.CurrentLng), new Navigation.Location(i.Latitude, i.Longitude))).ToArray());
+            //var pokeStops = Navigation.pathByNearestNeighbour(mapObjects.MapCells.SelectMany(i => i.Forts).Where(i => i.Type == FortType.Checkpoint && i.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime()).OrderBy(i => LocationUtils.CalculateDistanceInMeters(new Navigation.Location(_client.CurrentLat, _client.CurrentLng), new Navigation.Location(i.Latitude, i.Longitude))).ToArray());
+
+            var pokeStops =
+                Navigation.pathByNearestNeighbour(
+                mapObjects.MapCells.SelectMany(i => i.Forts)
+                .Where(
+                    i =>
+                    i.Type == FortType.Checkpoint &&
+                    i.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime())
+                    .OrderBy(
+                    i =>
+                    LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude)).ToArray());
+
             Logger.Normal(ConsoleColor.Green, $"Found {pokeStops.Count()} pokestops");

             foreach (var pokeStop in pokeStops)
@@ -198,8 +208,8 @@ namespace PokemonGo.RocketAPI.Logic
                 if (_clientSettings.EvolveAllPokemonWithEnoughCandy) await EvolveAllPokemonWithEnoughCandy(_clientSettings.PokemonsToEvolve);
                 if (_clientSettings.TransferDuplicatePokemon) await TransferDuplicatePokemon();

-                var update = await _navigation.HumanLikeWalking(new Navigation.Location(pokeStop.Latitude, pokeStop.Longitude), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);
-                var distance = Navigation.DistanceBetween2Coordinates(_client.CurrentLat, _client.CurrentLng, pokeStop.Latitude, pokeStop.Longitude);
+                var update = await _navigation.HumanLikeWalking(new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);
+                var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokeStop.Latitude, pokeStop.Longitude);
                 var fortInfo = await _client.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
                 var fortSearch = await _client.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);

@@ -218,13 +228,19 @@ namespace PokemonGo.RocketAPI.Logic
         private async Task ExecuteCatchAllNearbyPokemons()
         {
             var mapObjects = await _client.GetMapObjects();
-
+
             //var pokemons = mapObjects.MapCells.SelectMany(i => i.CatchablePokemons).OrderBy(i => LocationUtils.CalculateDistanceInMeters(new Navigation.Location(_client.CurrentLat, _client.CurrentLng), new Navigation.Location(i.Latitude, i.Longitude)));
-            var pokemons = mapObjects.MapCells.SelectMany(i => i.CatchablePokemons).OrderBy(i => LocationUtils.CalculateDistanceInMeters(new Navigation.Location(_client.CurrentLat, _client.CurrentLng), new Navigation.Location(i.Latitude, i.Longitude)));
+
+            var pokemons =
+                mapObjects.MapCells.SelectMany(i => i.CatchablePokemons)
+                .OrderBy(
+                    i =>
+                    LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude));
+
             if (_clientSettings.UsePokemonToNotCatchFilter)
             {
                 ICollection<PokemonId> filter = _clientSettings.PokemonsNotToCatch;
-                pokemons = mapObjects.MapCells.SelectMany(i => i.CatchablePokemons).Where(p => !filter.Contains(p.PokemonId)).OrderBy(i => LocationUtils.CalculateDistanceInMeters(new Navigation.Location(_client.CurrentLat, _client.CurrentLng), new Navigation.Location(i.Latitude, i.Longitude)));
+                pokemons = mapObjects.MapCells.SelectMany(i => i.CatchablePokemons).Where(p => !filter.Contains(p.PokemonId)).OrderBy(i => LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude));
             }

             if (pokemons != null && pokemons.Any())
@@ -232,7 +248,7 @@ namespace PokemonGo.RocketAPI.Logic

             foreach (var pokemon in pokemons)
             {
-                var distance = Navigation.DistanceBetween2Coordinates(_client.CurrentLat, _client.CurrentLng, pokemon.Latitude, pokemon.Longitude);
+                var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokemon.Latitude, pokemon.Longitude);
                 await Task.Delay(distance > 100 ? 1000 : 100);

                 var encounter = await _client.EncounterPokemon(pokemon.EncounterId, pokemon.SpawnpointId);
@@ -268,7 +284,7 @@ namespace PokemonGo.RocketAPI.Logic
                     await RandomHelper.RandomDelay(50, 200);
                 }

-                var distance = Navigation.DistanceBetween2Coordinates(_client.CurrentLat, _client.CurrentLng, pokemon.Latitude, pokemon.Longitude);
+                var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokemon.Latitude, pokemon.Longitude);
                 caughtPokemonResponse = await _client.CatchPokemon(pokemon.EncounterId, pokemon.SpawnpointId, pokemon.Latitude, pokemon.Longitude, bestPokeball);

                 if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
diff --git a/PokemonGo.RocketAPI.Logic/Navigation.cs b/PokemonGo.RocketAPI.Logic/Navigation.cs
index 8b39fdf..6073134 100644
--- a/PokemonGo.RocketAPI.Logic/Navigation.cs
+++ b/PokemonGo.RocketAPI.Logic/Navigation.cs
@@ -1,6 +1,7 @@
 #region

 using System;
+using System.Device.Location;
 using System.Threading.Tasks;
 using PokemonGo.RocketAPI.GeneratedCode;
 using PokemonGo.RocketAPI.Logic.Utils;
@@ -21,24 +22,12 @@ namespace PokemonGo.RocketAPI.Logic
             _client = client;
         }

-        public static double DistanceBetween2Coordinates(double lat1, double lng1, double lat2, double lng2)
-        {
-            const double rEarth = 6378137;
-            var dLat = (lat2 - lat1) * Math.PI / 180;
-            var dLon = (lng2 - lng1) * Math.PI / 180;
-            var alpha = Math.Sin(dLat / 2) * Math.Sin(dLat / 2)
-                        + Math.Cos(lat1 * Math.PI / 180) * Math.Cos(lat2 * Math.PI / 180)
-                        * Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
-            var d = 2 * rEarth * Math.Atan2(Math.Sqrt(alpha), Math.Sqrt(1 - alpha));
-            return d;
-        }
-
-        public async Task<PlayerUpdateResponse> HumanLikeWalking(Location targetLocation,
+        public async Task<PlayerUpdateResponse> HumanLikeWalking(GeoCoordinate targetLocation,
             double walkingSpeedInKilometersPerHour, Func<Task> functionExecutedWhileWalking)
         {
             var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6;

-            var sourceLocation = new Location(_client.CurrentLat, _client.CurrentLng);
+            var sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
             var distanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
             Logger.Normal(ConsoleColor.DarkCyan, $"(NAVIGATION) Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget / speedInMetersPerSecond:0.##} seconds!");

@@ -59,7 +48,7 @@ namespace PokemonGo.RocketAPI.Logic
                 var millisecondsUntilGetUpdatePlayerLocationResponse =
                     (DateTime.Now - requestSendDateTime).TotalMilliseconds;

-                sourceLocation = new Location(_client.CurrentLat, _client.CurrentLng);
+                sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
                 var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);

                 if (currentDistanceToTarget < 40)
@@ -87,28 +76,16 @@ namespace PokemonGo.RocketAPI.Logic
             return result;
         }

-        public class Location
-        {
-            public Location(double latitude, double longitude)
-            {
-                Latitude = latitude;
-                Longitude = longitude;
-            }
-
-            public double Latitude { get; set; }
-            public double Longitude { get; set; }
-        }
-
         public static FortData[] pathByNearestNeighbour(FortData[] pokeStops)
         {
             for (var i = 1; i < pokeStops.Length - 1; i++)
             {
                 var closest = i + 1;
-                var cloestDist = LocationUtils.CalculateDistanceInMeters(new Location(pokeStops[i].Latitude, pokeStops[i].Longitude), new Location(pokeStops[closest].Latitude, pokeStops[closest].Longitude));
+                var cloestDist = LocationUtils.CalculateDistanceInMeters(pokeStops[i].Latitude, pokeStops[i].Longitude, pokeStops[closest].Latitude, pokeStops[closest].Longitude);
                 for (var j = closest; j < pokeStops.Length; j++)
                 {
                     var initialDist = cloestDist;
-                    var newDist = LocationUtils.CalculateDistanceInMeters(new Location(pokeStops[i].Latitude, pokeStops[i].Longitude), new Location(pokeStops[j].Latitude, pokeStops[j].Longitude));
+                    var newDist = LocationUtils.CalculateDistanceInMeters(pokeStops[i].Latitude, pokeStops[i].Longitude, pokeStops[j].Latitude, pokeStops[j].Longitude);
                     if (initialDist > newDist)
                     {
                         cloestDist = newDist;
diff --git a/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj b/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
index ee5a957..bb4377b 100644
--- a/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
+++ b/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
@@ -42,6 +42,7 @@
     <Reference Include="System" />
     <Reference Include="System.Configuration" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Device" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
diff --git a/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs b/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
index 9ae5052..2a44693 100644
--- a/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
+++ b/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
@@ -1,68 +1,71 @@
 #region

 using System;
-using static PokemonGo.RocketAPI.Logic.Navigation;
+using System.Device.Location;

 #endregion

-
 namespace PokemonGo.RocketAPI.Logic.Utils
 {
     public static class LocationUtils
     {
-        public static Location CreateWaypoint(Location sourceLocation, double distanceInMeters, double bearingDegrees) //from http://stackoverflow.com/a/17545955
+        public static double CalculateDistanceInMeters(double sourceLat, double sourceLng, double destLat, double destLng)
+        // from http://stackoverflow.com/questions/6366408/calculating-distance-between-two-latitude-and-longitude-geocoordinates
         {
-            double distanceKm = distanceInMeters / 1000.0;
-            double distanceRadians = distanceKm / 6371; //6371 = Earth's radius in km
-
-            double bearingRadians = ToRad(bearingDegrees);
-            double sourceLatitudeRadians = ToRad(sourceLocation.Latitude);
-            double sourceLongitudeRadians = ToRad(sourceLocation.Longitude);
-
-            double targetLatitudeRadians = Math.Asin(Math.Sin(sourceLatitudeRadians) * Math.Cos(distanceRadians)
-                    + Math.Cos(sourceLatitudeRadians) * Math.Sin(distanceRadians) * Math.Cos(bearingRadians));
+            var sourceLocation = new GeoCoordinate(sourceLat, sourceLng);
+            var targetLocation = new GeoCoordinate(destLat, destLng);

-            double targetLongitudeRadians = sourceLongitudeRadians + Math.Atan2(Math.Sin(bearingRadians)
-                    * Math.Sin(distanceRadians) * Math.Cos(sourceLatitudeRadians), Math.Cos(distanceRadians)
-                    - Math.Sin(sourceLatitudeRadians) * Math.Sin(targetLatitudeRadians));
-
-            // adjust toLonRadians to be in the range -180 to +180...
-            targetLongitudeRadians = ((targetLongitudeRadians + 3 * Math.PI) % (2 * Math.PI)) - Math.PI;
+            return sourceLocation.GetDistanceTo(targetLocation);
+        }

-            return new Location(ToDegrees(targetLatitudeRadians), ToDegrees(targetLongitudeRadians));
+        public static double CalculateDistanceInMeters(GeoCoordinate sourceLocation, GeoCoordinate destinationLocation)
+        {
+            return CalculateDistanceInMeters(sourceLocation.Latitude, sourceLocation.Longitude, destinationLocation.Latitude, destinationLocation.Longitude);
         }

-        public static double CalculateDistanceInMeters(Location sourceLocation, Location targetLocation) // from http://stackoverflow.com/questions/6366408/calculating-distance-between-two-latitude-and-longitude-geocoordinates
+        public static GeoCoordinate CreateWaypoint(GeoCoordinate sourceLocation, double distanceInMeters, double bearingDegrees)
+        //from http://stackoverflow.com/a/17545955
         {
-            var baseRad = Math.PI * sourceLocation.Latitude / 180;
-            var targetRad = Math.PI * targetLocation.Latitude / 180;
-            var theta = sourceLocation.Longitude - targetLocation.Longitude;
-            var thetaRad = Math.PI * theta / 180;
+            var distanceKm = distanceInMeters / 1000.0;
+            var distanceRadians = distanceKm / 6371; //6371 = Earth's radius in km
+
+            var bearingRadians = ToRad(bearingDegrees);
+            var sourceLatitudeRadians = ToRad(sourceLocation.Latitude);
+            var sourceLongitudeRadians = ToRad(sourceLocation.Longitude);

-            double dist =
-                Math.Sin(baseRad) * Math.Sin(targetRad) + Math.Cos(baseRad) *
-                Math.Cos(targetRad) * Math.Cos(thetaRad);
-            dist = Math.Acos(dist);
+            var targetLatitudeRadians = Math.Asin(Math.Sin(sourceLatitudeRadians) * Math.Cos(distanceRadians)
+                                                  +
+                                                  Math.Cos(sourceLatitudeRadians) * Math.Sin(distanceRadians) *
+                                                  Math.Cos(bearingRadians));

-            dist = dist * 180 / Math.PI;
-            dist = dist * 60 * 1.1515 * 1.609344 * 1000;
+            var targetLongitudeRadians = sourceLongitudeRadians + Math.Atan2(Math.Sin(bearingRadians)
+                                                                             * Math.Sin(distanceRadians) *
+                                                                             Math.Cos(sourceLatitudeRadians),
+                Math.Cos(distanceRadians)
+                - Math.Sin(sourceLatitudeRadians) * Math.Sin(targetLatitudeRadians));
+
+            // adjust toLonRadians to be in the range -180 to +180...
+            targetLongitudeRadians = (targetLongitudeRadians + 3 * Math.PI) % (2 * Math.PI) - Math.PI;

-            return dist;
+            return new GeoCoordinate(ToDegrees(targetLatitudeRadians), ToDegrees(targetLongitudeRadians));
         }

-        public static double DegreeBearing(Location sourceLocation, Location targetLocation) // from http://stackoverflow.com/questions/2042599/direction-between-2-latitude-longitude-points-in-c-sharp
+        public static double DegreeBearing(GeoCoordinate sourceLocation, GeoCoordinate targetLocation)
+        // from http://stackoverflow.com/questions/2042599/direction-between-2-latitude-longitude-points-in-c-sharp
         {
             var dLon = ToRad(targetLocation.Longitude - sourceLocation.Longitude);
             var dPhi = Math.Log(
-                Math.Tan(ToRad(targetLocation.Latitude) / 2 + Math.PI / 4) / Math.Tan(ToRad(sourceLocation.Latitude) / 2 + Math.PI / 4));
+                Math.Tan(ToRad(targetLocation.Latitude) / 2 + Math.PI / 4) /
+                Math.Tan(ToRad(sourceLocation.Latitude) / 2 + Math.PI / 4));
             if (Math.Abs(dLon) > Math.PI)
-                dLon = dLon > 0 ? -(2 * Math.PI - dLon) : (2 * Math.PI + dLon);
+                dLon = dLon > 0 ? -(2 * Math.PI - dLon) : 2 * Math.PI + dLon;
             return ToBearing(Math.Atan2(dLon, dPhi));
         }

-        public static double ToRad(double degrees)
+        public static double ToBearing(double radians)
         {
-            return degrees * (Math.PI / 180);
+            // convert radians to degrees (as bearing: 0...360)
+            return (ToDegrees(radians) + 360) % 360;
         }

         public static double ToDegrees(double radians)
@@ -70,10 +73,9 @@ namespace PokemonGo.RocketAPI.Logic.Utils
             return radians * 180 / Math.PI;
         }

-        public static double ToBearing(double radians)
+        public static double ToRad(double degrees)
         {
-            // convert radians to degrees (as bearing: 0...360)
-            return (ToDegrees(radians) + 360) % 360;
+            return degrees * (Math.PI / 180);
         }
     }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj b/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
index 3cd273e..a61f670 100644
--- a/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
+++ b/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
@@ -17,7 +17,7 @@
     <UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
     <AssemblyVersionSettings>YearStamp.MonthStamp.DayStamp.Increment</AssemblyVersionSettings>
     <PrimaryVersionType>AssemblyVersionAttribute</PrimaryVersionType>
-    <AssemblyVersion>2016.7.23.129</AssemblyVersion>
+    <AssemblyVersion>2016.7.23.131</AssemblyVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
diff --git a/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs b/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
index 60e6d8f..2423822 100644
--- a/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
+++ b/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2016.7.23.129")]
+[assembly: AssemblyVersion("2016.7.23.132")]
 [assembly: AssemblyFileVersion("1.0.0.0")]
You may download the files in Public Git.