private IList <GPSPointViewModel> processGPSPoints(IList <GPSPoint> points) { var viewModels = new List <GPSPointViewModel>(); decimal distance = 0; GPSPoint previousPoint = null; for (int index = 0; index < points.Count; index++) { var gpsPoint = points[index]; if (gpsPoint.IsPause()) { previousPoint = null; } if (gpsPoint.IsPoint() && previousPoint != null) { var coordinate1 = previousPoint.ToCoordinates(); var coordinate2 = gpsPoint.ToCoordinates(); distance += (decimal)coordinate2.GetDistanceTo(coordinate1); } GPSPointViewModel pointViewModel = new GPSPointViewModel(gpsPoint); pointViewModel.Distance = distance; viewModels.Add(pointViewModel); if (gpsPoint.IsPoint()) { previousPoint = gpsPoint; } } return(viewModels); }
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 void ProcessGPSPoints() { decimal lapLength = 200; IList <GPSPoint> pkt = new List <GPSPoint>(); pkt.Add(new GPSPoint(50.9313049f, 17.2975941f, 3, 4, 1)); pkt.Add(new GPSPoint(50.9311333f, 17.29805f, 31, 41, 2)); pkt.Add(new GPSPoint(50.9310341f, 17.2986717f, 32, 42, 3)); pkt.Add(new GPSPoint(50.9312172f, 17.2992649f, 34, 44, 5)); pkt.Add(new GPSPoint(50.9329834f, 17.3020668f, 35, 45, 43)); pkt.Add(new GPSPoint(50.933815f, 17.3040714f, 35, 62, 60)); GPSPointsProcessor processor = new GPSPointsProcessor(pkt, lapLength); var points = processor.Points; IList <LapViewModel> laps = processor.Laps; Assert.AreEqual(8, points.Count); foreach (var info in laps) { var lapDistance = info.EndPoint.Distance - info.StartPoint.Distance; Assert.IsTrue(lapDistance % 200 == 0 || !info.FullLap); } for (int i = 1; i < points.Count; i++) { Assert.Less(points[i - 1].Point.Duration, points[i].Point.Duration); Assert.Less(points[i - 1].Distance, points[i].Distance); } for (int i = 0; i < laps.Count; i++) { var startIndex = points.IndexOf(laps[i].StartPoint); var endIndex = points.IndexOf(laps[i].EndPoint); var lapPoints = points.Skip(startIndex).Take(endIndex - (startIndex - 1)).ToList(); GPSPointViewModel previousPoint = null; decimal distance = 0; for (int index = 0; index < lapPoints.Count; index++) { var gpsPoint = lapPoints[index]; if (previousPoint != null) { var coordinate1 = previousPoint.Point.ToCoordinates(); var coordinate2 = gpsPoint.Point.ToCoordinates(); distance += (decimal)coordinate2.GetDistanceTo(coordinate1); } previousPoint = gpsPoint; } Assert.IsTrue(lapLength == (int)distance || !laps[i].FullLap); } //check laps Assert.AreEqual(200, laps[0].Distance); Assert.AreEqual(400, laps[1].Distance); Assert.AreEqual(574.847243m, Math.Round(laps[2].Distance, 6)); Assert.AreEqual(true, laps[0].FullLap); Assert.AreEqual(true, laps[1].FullLap); Assert.AreEqual(false, laps[2].FullLap); Assert.AreEqual(true, laps[0].BestLap); Assert.AreEqual(false, laps[1].BestLap); Assert.AreEqual(false, laps[2].BestLap); Assert.AreEqual(13.766d, laps[0].LapTime.TotalSeconds); Assert.AreEqual(27.343d, laps[1].LapTime.TotalSeconds); Assert.AreEqual(17.890999999999998d, laps[2].LapTime.TotalSeconds); Assert.AreEqual(13.766d, laps[0].TotalTime.TotalSeconds); Assert.AreEqual(41.108999999999995d, laps[1].TotalTime.TotalSeconds); Assert.AreEqual(59.0d, laps[2].TotalTime.TotalSeconds); //check added points (virtual) Assert.AreEqual(true, points[4].IsVirtual); Assert.AreEqual(200, points[4].Distance); Assert.AreEqual(34, points[4].Point.Altitude); Assert.AreEqual(14.766058f, points[4].Point.Duration); Assert.AreEqual(50.93167f, points[4].Point.Latitude); Assert.AreEqual(17.2999859f, points[4].Point.Longitude); Assert.AreEqual(true, points[5].IsVirtual); Assert.AreEqual(400, points[5].Distance); Assert.AreEqual(34, points[5].Point.Altitude); Assert.AreEqual(42.1086121f, points[5].Point.Duration); Assert.AreEqual(50.9329453f, points[5].Point.Latitude); Assert.AreEqual(17.3020039f, points[5].Point.Longitude); }