private void SetBestLapSectorsFromLap(LapViewModel bestLap) { foreach (var sectorCoordinate in trackSectors ?? Enumerable.Empty <TrackSectorViewModel>()) { if (bestLap != null && bestLap.DataPoints != null) { TimeSpan?sectorSplit = null; if (sectorCoordinate.IsFinishLine) { sectorSplit = bestLap.LapTime; } else { var lastLapCoordinate = bestLap.DataPoints.LastOrDefault(lc => lc.SectorNumber == sectorCoordinate.SectorNumber); if (lastLapCoordinate != null) { sectorSplit = lastLapCoordinate.ElapsedTime - bestLap.StartElapsedTime; } } bestLapSectors[sectorCoordinate.SectorNumber] = sectorSplit; } else { bestLapSectors[sectorCoordinate.SectorNumber] = null; } } }
public void SetUp() { _factory = new MockRepository(MockBehavior.Default); _fakeTelemetryViewModel = _factory.Create <ITelemetryViewModel>(); _fakeTelemetryViewModel.SetupGet(x => x.Chone).Returns(It.IsAny <IEnumerable <SelectListItem> >()); _fakeTelemetryViewModel.SetupGet(x => x.Chtwo).Returns(It.IsAny <IEnumerable <SelectListItem> >()); _fakeTelemetryViewModel.SetupGet(x => x.SelectedCh1).Returns("20"); _fakeTelemetryViewModel.SetupGet(x => x.SelectedCh2).Returns("17"); MapperConfig.RegisterMapping(); _kernel = new StandardKernel(new RepositoryModule()); _controller = _kernel.Get <HomeController>(); _lapvm = new LapViewModel() { TelemetryModel = new TelemetryViewModel() { Chone = _fakeTelemetryViewModel.Object.Chone, Chtwo = _fakeTelemetryViewModel.Object.Chtwo, SelectedCh1 = _fakeTelemetryViewModel.Object.SelectedCh1, SelectedCh2 = _fakeTelemetryViewModel.Object.SelectedCh2 } }; }
public static double ProjectedLength(this LapViewModel lap) { var geographicLapDataPoints = lap.DataPoints.Where(dp => dp.Latitude.HasValue && dp.Longitude.HasValue); if (!geographicLapDataPoints.Any()) { return(0d); } GeographyPoint firstGeographyPoint = null; GeographyPoint lastGeographyPoint = null; double length = geographicLapDataPoints.Aggregate(Tuple.Create(0d, (GeographyPoint)null), (a, b) => { var currentGeoPoint = b.AsGeographyPoint(); if (firstGeographyPoint == null) { firstGeographyPoint = currentGeoPoint; } lastGeographyPoint = currentGeoPoint; double distance = a.Item2 == null || (a.Item2.Latitude == currentGeoPoint.Latitude && a.Item2.Longitude == currentGeoPoint.Longitude) ? a.Item1 : a.Item1 + a.Item2.Distance(currentGeoPoint); return(Tuple.Create(distance, currentGeoPoint)); }, a => a.Item1); // Add distance between last and first points to complete circuit if (lastGeographyPoint != null) { length += lastGeographyPoint.Distance(firstGeographyPoint); } return(length); }
public async Task <ActionResult> Comparelaps(LapViewModel model) { if (ModelState.IsValid) { var ch1 = int.Parse(model.TelemetryModel.SelectedCh1); var ch2 = int.Parse(model.TelemetryModel.SelectedCh2); if (ch1 != 0 && ch2 != 0) { return(PartialView("_lapcomparison", new LapViewModel { LapModel = new List <TelemetryDto>() { await GenerateComparisonFromFormDataAsync(ch1, "CH1"), await GenerateComparisonFromFormDataAsync(ch2, "CH2") } })); } else { return(RedirectToAction("Compare")); } } return(RedirectToAction("Compare")); }
public static LapViewModel AsViewModel(this Lap lap, TimeSpan?bestLapTime, bool isMetricUnits) { var lapViewModel = new LapViewModel { LapNumber = lap.LapNumber, StartElapsedTime = new TimeSpan(lap.StartTicks), EndElapsedTime = new TimeSpan(lap.EndTicks), // IsComplete is a new field, assume it is true if it hasn't been set IsComplete = lap.IsComplete ?? true, DataPoints = new ObservableCollection <LapDataPointViewModel>(), Timestamp = lap.Timestamp.ToLocalTime() }; if (bestLapTime.HasValue && bestLapTime > TimeSpan.Zero) { lapViewModel.DifferenceToBest = lapViewModel.LapTime - bestLapTime.Value; } else { lapViewModel.DifferenceToBest = TimeSpan.Zero; } double maximumSpeed = 0; foreach (var dataPoint in lap.DataPoints) { double?speedInUserUnits = isMetricUnits ? dataPoint.Speed * Constants.KMH_TO_METRES_PER_SECOND : dataPoint.Speed * Constants.KMH_TO_METRES_PER_SECOND / Constants.MILES_TO_KILOMETRES; lapViewModel.DataPoints.Add(new LapDataPointViewModel { SectorNumber = dataPoint.SectorNumber, ElapsedTime = new TimeSpan(dataPoint.ElapsedTimeTicks), AccelerationX = dataPoint.AccelerationX, AccelerationY = dataPoint.AccelerationY, AccelerationZ = dataPoint.AccelerationZ, Altitude = dataPoint.Altitude, Heading = dataPoint.Heading, Latitude = dataPoint.Latitude, Longitude = dataPoint.Longitude, IsEndOfLap = dataPoint.IsEndOfLap, Speed = speedInUserUnits, Timestamp = dataPoint.Timestamp.ToLocalTime() }); if (speedInUserUnits.HasValue && speedInUserUnits.Value > maximumSpeed) { maximumSpeed = speedInUserUnits.Value; } } lapViewModel.MaximumSpeed = maximumSpeed; return(lapViewModel); }
public static Lap AsModel(this LapViewModel lapViewModel, bool isMetricUnits) { return(new Lap { LapNumber = lapViewModel.LapNumber, DataPoints = lapViewModel.DataPoints.Select(p => p.AsLapDataPoint(isMetricUnits)), StartTicks = lapViewModel.StartElapsedTime.Ticks, EndTicks = lapViewModel.EndElapsedTime.Ticks, Timestamp = lapViewModel.Timestamp.ToUniversalTime(), IsComplete = lapViewModel.IsComplete }); }
public override void ViewDidLoad() { base.ViewDidLoad(); _viewModel = new LapViewModel(UIApplication.SharedApplication.Delegate as IModelPool); // ListView(listLaps, ArrayAdapter) のバインド // 番号付きのリストに変換 var numberedLaps = _viewModel.FormattedLaps.ToNumberedLaps(); tableLaps .SetBindingToSource(numberedLaps) .AddTo(_subscriptionOnLoad); }
public override void ViewDidLoad() { base.ViewDidLoad(); _viewModel = new LapViewModel(UIApplication.SharedApplication.Delegate as IModelPool); // ListView(listLaps, ArrayAdapter) のバインド // フォーマットされた経過時間群を表す Observable(time と timeFormat のどちらかが変更されたら更新) var formattedLaps = _viewModel.Laps.CombineLatest( _viewModel.TimeFormat, (laps, f) => laps.Select((x, i) => $"{i+1}. {TimeSpan.FromMilliseconds(x).ToString(f)}")) .ToReactiveProperty(); tableLaps.SetBindingToSource(formattedLaps) .AddTo(_subscriptionOnLoad); }
public TimerViewModel(LiveClient liveClient, LapViewModel bestLap, IEnumerable <TrackSectorViewModel> trackSectors, GeolocatorFactory geolocatorFactory, ICamera camera, Dispatcher dispatcher) { Dispatcher = dispatcher; LapCount = 1; CurrentLapTime = TimeSpan.Zero; CurrentLapStatus = TimeSpan.Zero; GpsStatusText = AppResources.Text_Unit_InternalGps; Laps = new ObservableCollection <LapViewModel>(); this.trackSectors = trackSectors; bestLapSectors = new Dictionary <int, TimeSpan?>(); SetBestLapSectorsFromLap(bestLap); this.geolocatorFactory = geolocatorFactory; this.camera = camera; lapTimer = new LapTimer(geolocatorFactory, App.ViewModel.Settings.IsMetricUnits); lapTimer.GeolocatorStatusChanged += lapTimer_GeolocatorStatusChanged; lapTimer.GeolocatorUnrecoverableError += lapTimer_GeolocatorUnrecoverableError; }
public static double ActualLength(this LapViewModel lap) { var geographicLapDataPoints = lap.DataPoints.Where(dp => dp.Latitude.HasValue && dp.Longitude.HasValue); if (!geographicLapDataPoints.Any()) { return(0d); } double length = geographicLapDataPoints.Aggregate(Tuple.Create(0d, (GeographyPoint)null), (a, b) => { var currentGeoPoint = b.AsGeographyPoint(); double distance = a.Item2 == null ? 0 : a.Item1 + a.Item2.Distance(currentGeoPoint); return(Tuple.Create(distance, currentGeoPoint)); }, a => a.Item1); return(length); }
private void EndSector(LapDataPointViewModel sectorEndDataPoint, int currentSectorNumber) { if (SectorComplete == null) { return; } var lap = new LapViewModel { StartElapsedTime = lapStartElapsedTime, EndElapsedTime = sectorEndDataPoint.ElapsedTime, MaximumSpeed = sectorEndDataPoint.Speed ?? 0, Timestamp = sectorEndDataPoint.Timestamp, SectorNumber = currentSectorNumber, IsComplete = false }; SectorComplete(this, new LapEventArgs(lap)); }
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); _viewModel = new LapViewModel(this.Application as IModelPool); // Set our view from the "main" layout resource SetContentView(Resource.Layout.activity_lap); // ListView(listLaps, ArrayAdapter) のバインド // 番号付きのリストに変換 var numberedLaps = _viewModel.FormattedLaps.ToNumberedLaps(); var listLaps = FindViewById <ListView>(Resource.Id.listLaps); var listAdapter = new ArrayAdapter(this, global::Android.Resource.Layout.SimpleListItem1); listLaps.Adapter = listAdapter; listAdapter .SetBinding(numberedLaps) .AddTo(_subscriptionOnCreate); }
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); _viewModel = new LapViewModel(this.Application as IModelPool); // Set our view from the "main" layout resource SetContentView(Resource.Layout.activity_lap); // ListView(listLaps, ArrayAdapter) のバインド // フォーマットされた経過時間群を表す Observable(time と timeFormat のどちらかが変更されたら更新) var formattedLaps = _viewModel.Laps.CombineLatest( _viewModel.TimeFormat, (laps, f) => laps.Select((x, i) => $"{i+1}. {TimeSpan.FromMilliseconds(x).ToString(f)}")) .ToReactiveProperty(); var listLaps = FindViewById <ListView>(Resource.Id.listLaps); var listAdapter = new ArrayAdapter(this, global::Android.Resource.Layout.SimpleListItem1); listLaps.Adapter = listAdapter; listAdapter .SetBinding(formattedLaps) .AddTo(_subscriptionOnCreate); }
public static BestLapViewModel AsViewModel(this LapViewModel lap, bool isMetricUnits, bool lapIsUnofficial = false) { var bestLapViewModel = new BestLapViewModel { DataPoints = new ObservableCollection <LapDataPointViewModel>(), StartElapsedTime = TimeSpan.Zero, EndElapsedTime = lap.LapTime, MaximumSpeed = lap.MaximumSpeed, SectorNumber = lap.SectorNumber, Timestamp = lap.Timestamp.ToLocalTime(), TotalLaps = lap.TotalLaps, IsUnofficial = lapIsUnofficial, IsComplete = lap.IsComplete }; foreach (var dataPoint in lap.DataPoints) { bestLapViewModel.DataPoints.Add(new LapDataPointViewModel { SectorNumber = dataPoint.SectorNumber, ElapsedTime = dataPoint.ElapsedTime - lap.StartElapsedTime, AccelerationX = dataPoint.AccelerationX, AccelerationY = dataPoint.AccelerationY, AccelerationZ = dataPoint.AccelerationZ, Altitude = dataPoint.Altitude, Heading = dataPoint.Heading, Latitude = dataPoint.Latitude, Longitude = dataPoint.Longitude, IsEndOfLap = dataPoint.IsEndOfLap, Speed = dataPoint.Speed, Timestamp = dataPoint.Timestamp.ToLocalTime() }); } return(bestLapViewModel); }
private IList <LapViewModel> fillLapsInfo(IList <GPSPointViewModel> points, decimal lapLength) { IList <LapViewModel> laps = new List <LapViewModel>(); var veryFirst = points.FirstOrDefault(); GPSPointViewModel start = veryFirst; LapViewModel bestLap = null; decimal lapDistance = 0; for (int i = 1; i < points.Count; i++) { lapDistance = points[i].Distance - start.Distance; bool isLastPoint = i == points.Count - 1; if (lapDistance >= lapLength || isLastPoint) { var endLapPoint = points[i]; //if distance is higher than exact lap length then create virtual gps point and calculate speed and duration if (lapDistance > lapLength) { var above = lapDistance - lapLength; var twoLastPointTime = (decimal)(points[i].Point.Duration - points[i - 1].Point.Duration); var twoLastPointsDistance = points[i].Distance - points[i - 1].Distance; var midDuration = twoLastPointTime - ((twoLastPointTime * above) / twoLastPointsDistance) + (decimal)points[i - 1].Point.Duration; var bearing = GPSTrackerHelper.CalculateInitialBearing(points[i - 1].Point, points[i].Point); var midPoint = GPSTrackerHelper.CalculateDestination(points[i - 1].Point, bearing, (double)((laps.Count * lapLength + (lapDistance - above)) - points[i - 1].Distance)); midPoint.Duration = (float)midDuration; midPoint.Speed = points[i].Point.Speed; GPSPointViewModel midPointViewModel = new GPSPointViewModel(midPoint); midPointViewModel.Distance = (laps.Count + 1) * lapLength; midPointViewModel.IsVirtual = true; endLapPoint = midPointViewModel;//inject new virtual point as a end lap point //now we should insert mid point between two points points.Insert(i, midPointViewModel); } var lapViewModel = new LapViewModel(start, endLapPoint); lapViewModel.LapTime = TimeSpan.FromSeconds(lapViewModel.EndPoint.Point.Duration - lapViewModel.StartPoint.Point.Duration); lapViewModel.TotalTime = TimeSpan.FromSeconds(lapViewModel.EndPoint.Point.Duration - veryFirst.Point.Duration); lapViewModel.Speed = lapViewModel.LapTime.TotalSeconds > 0 ? (lapDistance / (decimal)lapViewModel.LapTime.TotalSeconds): 0; laps.Add(lapViewModel); lapViewModel.Nr = laps.Count; lapViewModel.Distance = lapViewModel.EndPoint.Distance; start = endLapPoint; if (isLastPoint && lapDistance < lapLength) {//if last lap is smaller than lap length lapViewModel.FullLap = false; } if (bestLap == null || (bestLap.LapTime > lapViewModel.LapTime && lapViewModel.FullLap)) { bestLap = lapViewModel; } } } if (bestLap != null) { bestLap.BestLap = true; } return(laps); }
public LapEventArgs(LapViewModel lap) { this.Lap = lap; }
private void EndLap(LapDataPointViewModel lapEndDataPoint, int lapEndDataPointIndex, int currentSectorNumber) { if (!lapCoordinates.Any(lc => lc.Latitude.HasValue && lc.Longitude.HasValue && lc.Heading.HasValue)) { return; } var lapStartTime = lapStartElapsedTime; var lapTime = lapStartElapsedTime = lapEndDataPoint.ElapsedTime; lapEndDataPoint.IsEndOfLap = true; int currentLapEndCoordinate = lapEndDataPointIndex; var allCoordinates = lapCoordinates.ToList(); var currentLapCoordinates = allCoordinates.Skip(previousLapEndCoordinateIndex + 1).Take(currentLapEndCoordinate - previousLapEndCoordinateIndex).ToList(); if (!currentLapCoordinates.Any()) { return; } var lap = new LapViewModel { StartElapsedTime = lapStartTime, EndElapsedTime = lapTime, MaximumSpeed = currentLapCoordinates.Max(c => c.Speed) ?? 0, Timestamp = currentLapCoordinates.First().Timestamp, SectorNumber = currentSectorNumber, LapNumber = lapNumber, IsComplete = true }; previousLapEndCoordinateIndex = currentLapEndCoordinate; if (generateSectors) { if (currentLapCoordinates.Count() < 3) { return; } lap.DataPoints = new ObservableCollection <LapDataPointViewModel>(currentLapCoordinates); var sectors = currentLapCoordinates.ToTrackSectors(); if (sectors.Count < 3) { return; } currentSector = sectors[1]; sectorCoordinates = sectors.Select(s => s.Value); lastSectorNumber = 3; } else { // Some accelerometer readings in this lap but received before currentSector changed will have the last SectorNumber // so change them to be the first sector foreach (var coordinate in currentLapCoordinates) { if (coordinate.SectorNumber == 1) { break; } coordinate.SectorNumber = 1; } lap.DataPoints = new ObservableCollection <LapDataPointViewModel>(currentLapCoordinates); } lapNumber++; if (LapComplete != null) { LapComplete(this, new LapEventArgs(lap)); } }