Beispiel #1
0
        public void GetDistance()
        {
            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, 6));
            pkt.Add(new GPSPoint(50.933815f, 17.3040714f, 35, 45, 7));

            var distance = GPSTrackerHelper.GetDistance(pkt);

            Assert.AreEqual(574.84724282491675, distance);
        }
Beispiel #2
0
        public void GetDistance_WithPausePoint()
        {
            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(GPSPoint.CreatePause(5.1f));
            pkt.Add(new GPSPoint(50.9329834f, 17.3020668f, 35, 45, 6));
            pkt.Add(new GPSPoint(50.933815f, 17.3040714f, 35, 45, 7));

            var distance = GPSTrackerHelper.GetDistance(pkt);

            Assert.AreEqual(296.89223243105414, distance);
        }
        public void TestAltitudeCorrection()
        {
            IList <GPSPoint> pkt = new List <GPSPoint>();

            pkt.Add(new GPSPoint(50.9313049f, 17.2975941f, 10, 4, 1));
            pkt.Add(new GPSPoint(50.9311333f, 17.29805f, 31, 41, 2));
            pkt.Add(new GPSPoint(50.9310341f, 17.2986717f, 38, 42, 3));
            pkt.Add(new GPSPoint(50.9312172f, 17.2992649f, 33, 44, 5));
            pkt.Add(new GPSPoint(50.9329834f, 17.3020668f, 35, 45, 43));
            pkt.Add(new GPSPoint(50.933815f, 17.3040714f, 35, 62, 60));
            GPSTrackerHelper.CorrectGpsData(pkt);
            Assert.AreEqual(10, pkt[0].Altitude);
            Assert.AreEqual(20.5f, pkt[1].Altitude);
            Assert.AreEqual(22.833334f, pkt[2].Altitude);
            Assert.AreEqual(21.583334f, pkt[3].Altitude);
            Assert.AreEqual(24.9791679f, pkt[4].Altitude);
            Assert.AreEqual(26.098959f, pkt[5].Altitude);
        }
        public void TestAltitudeCorrection_WithPause()
        {
            IList <GPSPoint> pkt = new List <GPSPoint>();

            pkt.Add(new GPSPoint(50.9313049f, 17.2975941f, 10, 4, 1));
            pkt.Add(new GPSPoint(50.9311333f, 17.29805f, 31, 41, 2));
            pkt.Add(new GPSPoint(50.9310341f, 17.2986717f, 38, 42, 3));
            pkt.Add(GPSPoint.CreatePause(42.1f));
            pkt.Add(new GPSPoint(50.9312172f, 17.2992649f, 33, 44, 5));
            pkt.Add(new GPSPoint(50.9329834f, 17.3020668f, 35, 45, 43));
            pkt.Add(new GPSPoint(50.933815f, 17.3040714f, 35, 62, 60));
            GPSTrackerHelper.CorrectGpsData(pkt);
            Assert.AreEqual(10, pkt[0].Altitude);
            Assert.AreEqual(20.5f, pkt[1].Altitude);
            Assert.AreEqual(22.833334f, pkt[2].Altitude);
            Assert.AreEqual(true, float.IsNaN(pkt[3].Altitude));
            Assert.AreEqual(33, pkt[4].Altitude);
            Assert.AreEqual(34, pkt[5].Altitude);
            Assert.AreEqual(34, pkt[6].Altitude);
        }
        private static void performGpsPointsCalculations(GPSTrackerEntry res, List <GPSPoint> points, Profile dbProfile)
        {
            if (res.Status == EntryObjectStatus.Planned)
            {
                res.Status = EntryObjectStatus.Done;
            }
            //perform calculation based on gps coordinates
            res.Distance = (decimal?)GPSTrackerHelper.GetDistance(points);
            var pointsWithSpeed = points.Where(x => !float.IsNaN(x.Speed) && x.Speed > -1).ToList();

            if (pointsWithSpeed.Count > 0)
            {
                res.MaxSpeed = (decimal?)pointsWithSpeed.Max(x => x.Speed);
            }
            //res.AvgSpeed = (decimal?) points.Average(x => x.Speed);
            var pointsWithAltitude = points.Where(x => !float.IsNaN(x.Altitude) && x.Altitude > -1).ToList();

            if (pointsWithAltitude.Count > 0)
            {
                res.MaxAltitude  = (decimal?)pointsWithAltitude.Max(x => x.Altitude);
                res.MinAltitude  = (decimal?)pointsWithAltitude.Min(x => x.Altitude);
                res.TotalAscent  = (decimal?)GPSTrackerHelper.GetTotalAscents(pointsWithAltitude);
                res.TotalDescent = (decimal?)GPSTrackerHelper.GetTotalDescends(pointsWithAltitude);
            }

            if (res.Duration == null || res.Duration == 0)
            {
                res.Duration = (decimal?)points.Last().Duration;
            }
            if (res.Calories == null || res.Calories == 0)
            {
                TrainingDayService.CalculateCaloriesBurned(res,
                                                           res.TrainingDay.Customer != null
                                                               ? (IPerson)res.TrainingDay.Customer
                                                               : dbProfile);
            }
            if (res.Duration.Value > 0)
            {
                res.AvgSpeed = res.Distance.Value / res.Duration.Value;
            }
        }
        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);
        }
        //http://stackoverflow.com/questions/472906/net-string-to-byte-array-c-sharp
        //public PagedResult<GPSPoint> GetGPSCoordinates(Guid entryId,PartialRetrievingInfo pageInfo)
        //{
        //    Log.WriteWarning("GetGPSCoordinates:Username={0},gpsTrackerEntryId={1}", SecurityInfo.SessionData.Profile.UserName, entryId);

        //    using (var transactionScope = Session.BeginGetTransaction())
        //    {
        //        var res = Session.QueryOver<GPSTrackerEntry>().Fetch(x => x.Coordinates).Eager.Where(x => x.GlobalId == entryId).SingleOrDefault();
        //        if (res.Coordinates == null)
        //        {
        //            return new PagedResult<GPSPoint>(new List<GPSPoint>(),0,0 );
        //        }
        //        char[] chars = new char[res.Coordinates.Content.Length / sizeof(char)];
        //        System.Buffer.BlockCopy(res.Coordinates.Content, 0, chars, 0, res.Coordinates.Content.Length);

        //        var pointsCollection = JsonConvert.DeserializeObject<IList<GPSPoint>>(new string(chars));

        //        transactionScope.Commit();
        //        return pointsCollection.ToPagedResult(pageInfo);
        //    }
        //}

        //public GPSTrackerEntryDTO GPSCoordinatesOperation(GPSCoordinatesOperationParam param)
        //{
        //    Log.WriteWarning("GPSCoordinatesOperation:Username={0},gpsTrackerEntryId={1}", SecurityInfo.SessionData.Profile.UserName, param.GPSTrackerEntryId);

        //    using (var transactionScope = Session.BeginGetTransaction())
        //    {
        //        var res = Session.QueryOver<GPSTrackerEntry>().Fetch(x => x.Coordinates).Eager.SingleOrDefault();

        //        if(param.Operation==GPSCoordinatesOperationType.DeleteCoordinates)
        //        {
        //            var coordinates = res.Coordinates;
        //            res.Coordinates = null;
        //            if(coordinates!=null)
        //            {
        //                Session.Delete(coordinates);
        //            }
        //        }
        //        else
        //        {
        //            string output = JsonConvert.SerializeObject(param.Coordinates);
        //            var bytes = UTF8Encoding.UTF8.GetBytes(output);
        //            if (res.Coordinates == null)
        //            {
        //                res.Coordinates = new GPSCoordinates();
        //            }
        //            res.Coordinates.Content = bytes.ToZip();
        //        }

        //        Session.SaveOrUpdate(res);
        //        transactionScope.Commit();
        //        return res.Map<GPSTrackerEntryDTO>();
        //    }


        //}

        public GPSCoordinatesOperationResult GPSCoordinatesOperation(GPSOperationParam param)
        {
            Log.WriteWarning("GPSCoordinatesOperation:Username={0},gpsTrackerEntryId={1}", SecurityInfo.SessionData.Profile.UserName, param.Params.GPSTrackerEntryId);

            using (var transactionScope = Session.BeginGetTransaction())
            {
                var dbProfile = Session.Load <Profile>(SecurityInfo.SessionData.Profile.GlobalId);

                var res = Session.QueryOver <GPSTrackerEntry>().Fetch(x => x.Coordinates).Eager.Where(x => x.GlobalId == param.Params.GPSTrackerEntryId).SingleOrDefault();
                if (res == null)
                {
                    throw new ObjectNotFoundException();
                }
                if (res.TrainingDay.Profile != dbProfile)
                {
                    throw new CrossProfileOperationException();
                }
                if (param.Params.Operation == GPSCoordinatesOperationType.DeleteCoordinates)
                {
                    deletesCoordinates(res);
                }
                else
                {
                    try
                    {
                        MemoryStream zippedStream = new MemoryStream();
                        param.CoordinatesStream.CopyTo(zippedStream);
                        zippedStream.Seek(0, SeekOrigin.Begin);
                        if (zippedStream.Length == 0)
                        {
                            deletesCoordinates(res);
                        }
                        else
                        {
                            int maxPointNumber = 21600;//points after 24h, one point every 4 sec
                            var unzippedData   = zippedStream.FromZip();
                            var json           = UTF8Encoding.UTF8.GetString(unzippedData);
                            var points         = JsonConvert.DeserializeObject <IList <GPSPoint> >(json).OrderBy(x => x.Duration).ToList();
                            if (points.Count == 0)
                            {
                                deletesCoordinates(res);
                            }
                            else if (points.Count > maxPointNumber)
                            {
                                throw new ArgumentOutOfRangeException("You can upload max " + maxPointNumber + " points");
                            }
                            else
                            {
                                if (param.Params.Operation == GPSCoordinatesOperationType.UpdateCoordinatesWithCorrection)
                                {//correct altitude data
                                    GPSTrackerHelper.CorrectGpsData(points);
                                }
                                performGpsPointsCalculations(res, points, dbProfile);

                                if (SecurityInfo.Licence.IsPremium)
                                {//for premium account store coordinates in the db
                                    if (res.Coordinates == null)
                                    {
                                        res.Coordinates = new GPSCoordinates();
                                    }
                                    if (param.Params.Operation == GPSCoordinatesOperationType.UpdateCoordinatesWithCorrection)
                                    {
//now zip corrected data again and save them to the db
                                        var settings = new JsonSerializerSettings();
                                        settings.NullValueHandling     = NullValueHandling.Ignore;
                                        settings.MissingMemberHandling = MissingMemberHandling.Ignore;
                                        json = JsonConvert.SerializeObject(points, settings);
                                        var bytes = UTF8Encoding.UTF8.GetBytes(json);
                                        res.Coordinates.Content = bytes.ToZip();
                                    }
                                    else
                                    {
                                        res.Coordinates.Content = zippedStream.ToArray();
                                    }
                                }
                            }
                        }
                    }
                    catch (ZipException ex)
                    {
                        throw new ConsistencyException(ex.Message, ex);
                    }
                    catch (JsonSerializationException ex)
                    {
                        throw  new ConsistencyException(ex.Message, ex);
                    }
                }

                Session.SaveOrUpdate(res);
                transactionScope.Commit();
                return(new GPSCoordinatesOperationResult()
                {
                    GPSTrackerEntry = res.Map <GPSTrackerEntryDTO>()
                });
            }
        }