// 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;
});
}
}
}