// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for details. using System; using System.Collections.Generic; using System.Linq; using Windows.Devices.Geolocation; using Windows.Foundation; using Windows.Storage.Streams; using Windows.UI; using Windows.UI.Core; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls.Maps; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Navigation; using MyDriving.DataObjects; using MyDriving.ViewModel; using MyDriving.Utils; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 namespace MyDriving.UWP.Views { /// /// An empty page that can be used on its own or navigated to within a Frame. /// public sealed partial class PastTripMapView { readonly PastTripsDetailViewModel viewModel; public Trip SelectedTrip; public PastTripMapView() { InitializeComponent(); viewModel = new PastTripsDetailViewModel(); Locations = new List(); DataContext = this; if (Logger.BingMapsAPIKey != "Ar6iuHZYgX1BrfJs6SRJaXWbpU_HKdoe7G-OO9b2kl3rWvcawYx235GGx5FPM76O") { MyMap.MapServiceToken = Logger.BingMapsAPIKey; } } public IList Locations { get; set; } public List TripPoints { get; set; } protected override async void OnNavigatedTo(NavigationEventArgs e) { var trip = e.Parameter as Trip; base.OnNavigatedTo(e); viewModel.Trip = trip; App.SetTitle("PAST TRIPS"); MyMap.Loaded += MyMap_Loaded; MyMap.MapElements.Clear(); var success = await viewModel.ExecuteLoadTripCommandAsync(trip.Id); if(!success) { Frame.GoBack(); return; } DrawPath(); foreach (var poi in viewModel.POIs) DrawPoiOnMap(poi); // Currently Points are all jumbled. We need to investigate why this is happening. // As a workaround I am sorting the points based on timestamp. TripPoints = viewModel.Trip.Points.OrderBy(p => p.RecordedTimeStamp).ToList(); if (TripPoints.Any()) { viewModel.CurrentPosition = TripPoints[0]; UpdateStats(); } if (mapLoaded) InitialSetup(); // Enable the back button navigation SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView(); systemNavigationManager.BackRequested += SystemNavigationManager_BackRequested; } protected override void OnNavigatedFrom(NavigationEventArgs e) { base.OnNavigatedFrom(e); SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView(); systemNavigationManager.BackRequested -= SystemNavigationManager_BackRequested; } private void SystemNavigationManager_BackRequested(object sender, BackRequestedEventArgs e) { if (!e.Handled) { e.Handled = TryGoBack(); } } private bool TryGoBack() { bool navigated = false; if (Frame.CanGoBack) { Frame.GoBack(); navigated = true; } return navigated; } bool initialized; void InitialSetup() { if (initialized) return; initialized = true; MyMap.ZoomLevel = 16; if (viewModel.Trip.Points.Count > 0) PositionSlider.Maximum = TripPoints.Count - 1; else PositionSlider.Maximum = 0; PositionSlider.Minimum = 0; PositionSlider.IsThumbToolTipEnabled = false; TextStarttime.Text = viewModel.Trip.StartTimeDisplay; TextEndtime.Text = viewModel.Trip.EndTimeDisplay; } bool mapLoaded; private void MyMap_Loaded(object sender, RoutedEventArgs e) { mapLoaded = true; if (!initialized && TripPoints != null) InitialSetup(); } private async void DrawPath() { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { MapPolyline mapPolyLine = new MapPolyline(); Locations = TripPoints.Select(s => new BasicGeoposition() {Latitude = s.Latitude, Longitude = s.Longitude}) .ToList(); mapPolyLine.Path = new Geopath(Locations); mapPolyLine.ZIndex = 1; mapPolyLine.Visible = true; mapPolyLine.StrokeColor = new Color { A = 255, R = 0, G = 94, B = 147 }; mapPolyLine.StrokeThickness = 4; // Starting off with the first point as center if (Locations.Count > 0) MyMap.Center = new Geopoint(Locations.First()); MyMap.MapElements.Add(mapPolyLine); // Draw Start Icon MapIcon mapStartIcon = new MapIcon { Location = new Geopoint(Locations.First()), NormalizedAnchorPoint = new Point(0.5, 0.5), Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/A100.png")), ZIndex = 1, CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible }; MyMap.MapElements.Add(mapStartIcon); //Draw End Icon MapIcon mapEndIcon = new MapIcon { Location = new Geopoint(Locations.Last()), NormalizedAnchorPoint = new Point(0.5, 0.5), Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/B100.png")), ZIndex = 1, CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible }; MyMap.MapElements.Add(mapEndIcon); // Draw the Car DrawCarOnMap(Locations.First()); }); } private void DrawPoiOnMap(POI poi) { // Foreach POI point. Put it on Maps. var poiIcon = new MapIcon { Location = new Geopoint(new BasicGeoposition { Latitude = poi.Latitude, Longitude = poi.Longitude }), NormalizedAnchorPoint = new Point(0.5, 0.5), Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/POI.png")), ZIndex = 2, CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible }; MyMap.MapElements.Add(poiIcon); } private void DrawCarOnMap(BasicGeoposition basicGeoposition) { MapIcon carIcon = null; // Find if there is a MapIcon with title Car if (MyMap.MapElements != null) { var mapIcons = MyMap.MapElements.OfType().ToList(); foreach (var item in mapIcons) { if (item.Title == "Car") carIcon = item; } } if (carIcon == null) { // Car Icon not found creating it at the position and adding to maps carIcon = new MapIcon { Location = new Geopoint(basicGeoposition), NormalizedAnchorPoint = new Point(0.5, 0.5), Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/BlueCar.png")), ZIndex = 2, CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible, Title = "Car" }; MyMap.MapElements.Add(carIcon); } else { carIcon.Location = new Geopoint(basicGeoposition); } MyMap.Center = carIcon.Location; } private async void positionSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e) { viewModel.CurrentPosition = TripPoints[(int) e.NewValue]; var basicGeoposition = Locations[(int) e.NewValue]; DrawCarOnMap(basicGeoposition); await MyMap.TrySetViewAsync(new Geopoint(basicGeoposition)); UpdateStats(); } private async void UpdateStats() { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // TODO: Need to fix data binding and remove this code. TextTime.Text = viewModel.ElapsedTime; TextDistance.Text = viewModel.Distance; TextFuel.Text = viewModel.FuelConsumption; TextFuelunits.Text = viewModel.FuelConsumptionUnits; TextSpeed.Text = viewModel.Speed; TextSpeedunits.Text = viewModel.SpeedUnits; TextDistanceunits.Text = viewModel.DistanceUnits; }); } } }