From 0e5a366c6ec15890f032c1e4120cee8645bedde2 Mon Sep 17 00:00:00 2001 From: Kenneth van Ewijk Date: Thu, 21 Jan 2016 20:04:37 +0100 Subject: [PATCH] Direction helper --- YJMPD-UWP/Helpers/Util.cs | 38 +++++++++++++++++++++++++- YJMPD-UWP/MainPage.xaml.cs | 5 ++++ YJMPD-UWP/Model/GameHandler.cs | 2 ++ YJMPD-UWP/ViewModels/MatchVM.cs | 47 ++++++++++++++++++++++++++++++++- YJMPD-UWP/Views/MatchView.xaml | 6 ++++- 5 files changed, 95 insertions(+), 3 deletions(-) diff --git a/YJMPD-UWP/Helpers/Util.cs b/YJMPD-UWP/Helpers/Util.cs index c5756e1..d8395ab 100644 --- a/YJMPD-UWP/Helpers/Util.cs +++ b/YJMPD-UWP/Helpers/Util.cs @@ -1,6 +1,7 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Windows.Data.Xml.Dom; @@ -11,7 +12,7 @@ using Windows.UI.Popups; namespace YJMPD_UWP.Helpers { - class Util + public class Util { public enum DialogType { YESNO, OKCANCEL } @@ -129,6 +130,41 @@ namespace YJMPD_UWP.Helpers return address; } + public static double Distance(BasicGeoposition pos1, BasicGeoposition pos2) + { + var R = 6371; // Radius of the earth in km + var dLat = toRadian((pos2.Latitude - pos1.Latitude)); // deg2rad below + var dLon = toRadian(pos2.Longitude - pos1.Longitude); + var a = + Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + + Math.Cos(toRadian(pos1.Latitude)) * Math.Cos(toRadian(pos2.Latitude)) * + Math.Sin(dLon / 2) * Math.Sin(dLon / 2) + ; + var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); + var d = R * c; // Distance in m + return d; + } + + public static double DegreeBearing(BasicGeoposition pos1, BasicGeoposition pos2) + { + double lat1 = toRadian(pos1.Latitude); + double lat2 = toRadian(pos2.Latitude); + double dLon = toRadian(pos2.Longitude - pos2.Latitude); + + double dPhi = Math.Log(Math.Tan(lat2 / 2 + Math.PI / 4) / Math.Tan(lat1 / 2 + Math.PI / 4)); + if (Math.Abs(dLon) > Math.PI) dLon = (dLon > 0) ? -(2 * Math.PI - dLon) : (2 * Math.PI + dLon); + double brng = Math.Atan2(dLon, dPhi); + + Debug.WriteLine(brng); + + return ((180.0 * brng / Math.PI) + 360) % 360; + } + + private static double toRadian(double val) + { + return (Math.PI / 180) * val; + } + public static void ShowToastNotification(string title, string text) { ToastTemplateType toastTemplate = ToastTemplateType.ToastText02; diff --git a/YJMPD-UWP/MainPage.xaml.cs b/YJMPD-UWP/MainPage.xaml.cs index 04d98a0..d72d48f 100644 --- a/YJMPD-UWP/MainPage.xaml.cs +++ b/YJMPD-UWP/MainPage.xaml.cs @@ -9,6 +9,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Navigation; +using Windows.Devices.Geolocation; namespace YJMPD_UWP { @@ -50,6 +51,10 @@ namespace YJMPD_UWP { if (e.Handled) return; + App.Game.MoveToStarted(new BasicGeoposition { Latitude = 44.768187, Longitude = -0.472412 }); + e.Handled = true; + return; + if (App.Game.Status == Model.GameHandler.GameStatus.STARTED) { e.Handled = true; diff --git a/YJMPD-UWP/Model/GameHandler.cs b/YJMPD-UWP/Model/GameHandler.cs index 2125594..4b094b3 100644 --- a/YJMPD-UWP/Model/GameHandler.cs +++ b/YJMPD-UWP/Model/GameHandler.cs @@ -227,6 +227,8 @@ namespace YJMPD_UWP.Model public async void CalculateDistanceWalked() { + if (App.Geo.History.Count <= 1) return; + MapRoute r = await Util.FindWalkingRoute(App.Geo.History.Select(p => p.Coordinate.Point).ToList()); Settings.Statistics.Distance += r.LengthInMeters; } diff --git a/YJMPD-UWP/ViewModels/MatchVM.cs b/YJMPD-UWP/ViewModels/MatchVM.cs index a4e0fca..dfbb81b 100644 --- a/YJMPD-UWP/ViewModels/MatchVM.cs +++ b/YJMPD-UWP/ViewModels/MatchVM.cs @@ -1,16 +1,51 @@ -using Windows.UI.Xaml.Media; +using System.Diagnostics; +using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Imaging; +using YJMPD_UWP.Helpers; namespace YJMPD_UWP.ViewModels { public class MatchVM : TemplateVM { + private int angle; + public MatchVM() : base("Match") { Error = ""; Message = ""; + Degrees = 0; + angle = (int)Util.DegreeBearing(App.Geo.Position.Coordinate.Point.Position, App.Game.Destination); + HeadingVisible = false; App.Game.OnDestinationEnter += Game_OnDestinationEnter; App.Game.OnDestinationLeave += Game_OnDestinationLeave; + App.Geo.OnPositionUpdate += Geo_OnPositionUpdate; + App.Compass.OnHeadingUpdate += Compass_OnHeadingUpdate; + } + + private void Compass_OnHeadingUpdate(object sender, Helpers.EventArgs.HeadingUpdatedEventArgs e) + { + dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => + { + Degrees = (int)(angle + -e.Heading.HeadingMagneticNorth); + NotifyPropertyChanged(nameof(Degrees)); + Debug.WriteLine("Degrees " + Degrees + " / " + angle); + }); + } + + private void Geo_OnPositionUpdate(object sender, Helpers.EventArgs.PositionUpdatedEventArgs e) + { + dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => + { + if (App.Game.Status == Model.GameHandler.GameStatus.STARTED) + return; + + angle = (int)Util.DegreeBearing(e.Position.Coordinate.Point.Position, App.Game.Destination); + HeadingVisible = Util.Distance(e.Position.Coordinate.Point.Position, App.Game.Destination) > 500; + + Debug.WriteLine(HeadingVisible); + + NotifyPropertyChanged(nameof(HeadingVisible)); + }); } private void Game_OnDestinationLeave(object sender, System.EventArgs e) @@ -42,6 +77,16 @@ namespace YJMPD_UWP.ViewModels }); } + public int Degrees + { + get; private set; + } + + public bool HeadingVisible + { + get; private set; + } + public bool MessageVisible { get diff --git a/YJMPD-UWP/Views/MatchView.xaml b/YJMPD-UWP/Views/MatchView.xaml index d9d53c6..e5045d1 100644 --- a/YJMPD-UWP/Views/MatchView.xaml +++ b/YJMPD-UWP/Views/MatchView.xaml @@ -14,7 +14,11 @@ - + + + + +