public void TrackNavigateToParkingLotEvent(MetaDataCityRow city, ParkingLot parkingLot) { var properties = new Dictionary<string, string> { { "city", city.Id }, { "parkingLot", parkingLot.Id } }; _client.TrackEvent("Navigate to parking lot", properties); _tracker.SendEvent("ui_action", "navigate_to_parking_lot", city.Id + " > " + parkingLot.Id, 0); }
public void TrackForecastRangeEvent(ParkingLot parkingLot, ParkingLotForecastTimespanEnum? mode) { if (parkingLot == null) return; var properties = new Dictionary<string, string> { { "parkingLot", parkingLot.Id }, { "mode", mode?.ToString() }, }; _client.TrackEvent("Change forecast mode", properties); _tracker.SendEvent("ui_action", "change_forecast_mode", mode?.ToString() + " > " + parkingLot.Id, 0); }
public void HandleApiExceptionForForecastData(ApiException e, MetaDataCityRow city, ParkingLot lot) { _tracking.TrackException(e, new Dictionary<string, string>() { { "handled", "true"}, { "type", "forecast"}, { "city", city?.Id }, { "lot", lot?.Id } }); var mailStr = string.Format(EmailFormat, ContactEmail, Uri.EscapeDataString(string.Format(_res.ExceptionMailForecastSubject, lot?.Name, city?.Name)), Uri.EscapeDataString(string.Format(_res.ExceptionMailForecastBody, lot?.Name, city?.Name, e.Message)) ); var content = new ToastContent { Launch = "handledForecastApiException", Visual = new ToastVisual { TitleText = new ToastText { Text = _res.ExceptionToastTitle }, BodyTextLine1 = new ToastText { Text = string.Format(_res.ExceptionToastForecastContent, lot?.Name, city?.Name) } }, Actions = new ToastActionsCustom { Buttons = { new ToastButton(_res.ExceptionToastShowInBrowserButton, city?.Url.ToString()) { ActivationType = ToastActivationType.Protocol, }, new ToastButton(_res.ExceptionToastContactDevButton, mailStr) { ActivationType = ToastActivationType.Protocol, } } } }; ShowToast(content); }
private int GetZIndexForParkingLot(ParkingLot lot) { if (_mainVm.SelectedParkingLot == lot) { return ZindexTopmostParkingLot; //100% * 1000 + 1 to be on top } var zIndex = ((double)lot.FreeLots / (double)lot.TotalLots); if (double.IsNaN(zIndex) || double.IsInfinity(zIndex)) { zIndex = 0; } else if (zIndex > 100) { zIndex = 100; } return (int)Math.Round(zIndex * 1000); }
private async void DrawParkingLot(MapControl map, Grid drawingContainer, ParkingLot lot) { if (lot?.Coordinates != null) { var icon = new MapIcon { Location = lot.Coordinates.Point, NormalizedAnchorPoint = new Point(0.5, 0.5), Title = lot.Name, CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible, Image = await GetMapIconDonutImage(drawingContainer, lot), ZIndex = GetZIndexForParkingLot(lot), }; if (_mapIconParkingLotDict.ContainsKey(lot.Id)) { map.MapElements.Remove(_mapIconParkingLotDict[lot.Id]); _mapIconParkingLotDict.Remove(lot.Id); } _mapIconParkingLotDict.Add(lot.Id, icon); map.MapElements.Add(icon); } }
public async void RedrawParkingLot(Grid drawingContainer, ParkingLot lot) { if (lot != null && _mapIconParkingLotDict != null) { await Task.Run(async () => { while (!_mapIconParkingLotDict.ContainsKey(lot.Id)) { await Task.Delay(500); } }); //catch errors because key can be not there anymore if user changed city meanwhile try { var icon = _mapIconParkingLotDict[lot.Id]; icon.Image = await GetMapIconDonutImage(drawingContainer, lot); icon.ZIndex = GetZIndexForParkingLot(lot); } catch (Exception) { //ignore } } }
public void TrackSelectParkingLotEvent(MetaDataCityRow city, ParkingLot parkingLot) { var properties = new Dictionary<string, string> { { "city", city?.Id }, { "parkingLot", parkingLot?.Id } }; _client.TrackEvent("Select parking lot", properties); _tracker.SendEvent("ui_action", "select_parking_lot", city?.Id + " > " + parkingLot?.Id, 0); }
public ParkingLotListGroup(string header, ParkingLot parkingLot) { Header = header; ParkingLots = new List<ParkingLot> { parkingLot }; }
private async void NavigateToParkingLot(ParkingLot lot) { const string launcherString = "bingmaps:?rtp=~{0}"; const string launcherPosString = "pos.{0}_{1}_{2}"; const string launcherAdrString = "adr.{0}"; if (lot == null) { return; } Uri launcherUri; _tracking.TrackNavigateToParkingLotEvent(SelectedCity, lot); if (lot.Coordinates != null) { launcherUri = new Uri( String.Format( launcherString, String.Format( launcherPosString, lot.Coordinates.Latitude.ToString(CultureInfo.InvariantCulture), lot.Coordinates.Longitude.ToString(CultureInfo.InvariantCulture), String.Format(ResourceService.Instance.DirectionsParkingLotLabel, lot.Name) ) ) ); }else if (!String.IsNullOrEmpty(lot.Address)) { launcherUri = new Uri( String.Format( launcherString, String.Format( launcherAdrString, Uri.EscapeDataString(lot.Address + ", " + SelectedCity.Name) ) ) ); } else { launcherUri = new Uri( String.Format( launcherString, String.Format( launcherAdrString, Uri.EscapeDataString(lot.Name + ", " + SelectedCity.Name) ) ) ); } if (launcherUri != null) { var launcherOptions = new LauncherOptions { TargetApplicationPackageFamilyName = "Microsoft.WindowsMaps_8wekyb3d8bbwe" }; await Launcher.LaunchUriAsync(launcherUri, launcherOptions); } }
private async void SetParkingLotListSelectionVisualState(ParkingLot selectedItem = null) { if (selectedItem == null) { selectedItem = Vm.SelectedParkingLot; } if (selectedItem != null) { ListViewItem listViewItem = null; var count = 0; while (listViewItem == null && count < 10) { var itemContainer = ParkingLotList.ContainerFromItem(selectedItem); listViewItem = itemContainer as ListViewItem; await Task.Delay(200); count++; } if (listViewItem != null) { Debug.WriteLine("[MainView] parking lot list: set selected visual state for " + selectedItem.Name); VisualStateManager.GoToState(listViewItem.ContentTemplateRoot as Control, "Selected", false); } else { Debug.WriteLine("[MainVm] parking lot list: list view item is null :/"); } ParkingLotList.ScrollIntoView(selectedItem); } else { Debug.WriteLine("[MainView] parking lot list: set selected index to -1"); ParkingLotList.SelectedIndex = -1; } }
private void RedrawOnPropertyChanged(ParkingLot lot, PropertyChangedEventArgs args) { if (lot != null) { if (args.PropertyName == nameof(lot.FreeLots) || args.PropertyName == nameof(lot.TotalLots)) { DrawingService.RedrawParkingLot(BackgroundDrawingContainer, lot); } } }
private async void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs args) { if (args.PropertyName == nameof(Vm.ParkingLots)) { FindName(nameof(BackgroundDrawingContainer)); DrawingService.DrawParkingLots(Map, BackgroundDrawingContainer); if (Vm.ParkingLots != null) { foreach (var selectableParkingLot in Vm.ParkingLots) { var lot = selectableParkingLot; lot.PropertyChanged += (sender1, changedEventArgs) => RedrawOnPropertyChanged(lot, changedEventArgs); } Vm.ParkingLots.CollectionChanged += (o, eventArgs) => { DrawingService.DrawParkingLots(Map, BackgroundDrawingContainer); if (eventArgs.NewItems != null) { foreach (var selectableParkingLot in eventArgs.NewItems.OfType<ParkingLot>()) { var lot = selectableParkingLot; lot.PropertyChanged += (sender1, changedEventArgs) => RedrawOnPropertyChanged(lot, changedEventArgs); } } }; } } else if (args.PropertyName == nameof(Vm.SelectedParkingLot)) { //don't change viewport or redraw something while the CVS is updated //the selection remains unchanged, whatever the ListView does (especially auto-selecting items...) if (Vm.UpdateFilterInProgress > 0) { return; } DrawingService.RedrawParkingLot(BackgroundDrawingContainer, Vm.SelectedParkingLot); DrawingService.RedrawParkingLot(BackgroundDrawingContainer, _selectedLot); _selectedLot = Vm.SelectedParkingLot; var selectedParkingLotPoint = Vm.SelectedParkingLot?.Coordinates?.Point; if (selectedParkingLotPoint != null) { Debug.WriteLine("[MainView] map: selected parking lot - wait until initial view was zoomed to (" + _selectedLot?.Id + ")"); await WaitForInitialMapZoom(); bool isParkingLotInView; Map.IsLocationInView(selectedParkingLotPoint, out isParkingLotInView); Debug.WriteLine("[MainView] map: selected parking lot - check (" + _selectedLot?.Id + ")"); if (Map.ZoomLevel < 14) { Debug.WriteLine("[MainView] map: selected parking lot, zoom level too high (" + _selectedLot?.Id + ")"); await Map.TrySetViewAsync(selectedParkingLotPoint, 14); } else if (!isParkingLotInView) { Debug.WriteLine("[MainView] map: selected parking lot, parking lot not in view (" + _selectedLot?.Id + ")"); await Map.TrySetViewAsync(selectedParkingLotPoint); } } } else if (args.PropertyName == nameof(Vm.ParkingLotFilterMode)) { UpdateParkingLotFilter(); } else if (args.PropertyName == nameof(Vm.ParkingLotsGroupedCollectionViewSource)) { var cvs = Resources["SelectedCityData"] as CollectionViewSource; cvs.IsSourceGrouped = true; cvs.Source = Vm.ParkingLotsGroupedCollectionViewSource; } else if (args.PropertyName == nameof(Vm.ParkingLotsListCollectionViewSource)) { var cvs = Resources["SelectedCityData"] as CollectionViewSource; cvs.IsSourceGrouped = false; cvs.Source = Vm.ParkingLotsListCollectionViewSource; } else if (args.PropertyName == nameof(Vm.UserLocation)) { DrawingService.DrawUserPosition(Map, Vm.UserLocation); } }
private async Task<IRandomAccessStreamReference> GetMapIconDonutImage(Grid drawingContainer, ParkingLot lot) { var drawDonut = new ParkingLotLoadDonut { Animate = false, ParkingLot = lot, Style = Application.Current.Resources["ParkingLotMapIconDonutStyle"] as Style }; drawingContainer.Children.Add(drawDonut); var rtb = new RenderTargetBitmap(); await rtb.RenderAsync(drawDonut); drawingContainer.Children.Remove(drawDonut); //TODO: take care of possible scaling issues var pixels = (await rtb.GetPixelsAsync()).ToArray(); var stream = new InMemoryRandomAccessStream(); var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream); encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)rtb.PixelWidth, (uint)rtb.PixelHeight, 96, 96, pixels); await encoder.FlushAsync(); stream.Seek(0); return RandomAccessStreamReference.CreateFromStream(stream.AsStream().AsRandomAccessStream()); }