GpsLocationService.cs 3.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BLL.App.DTO;
using BLL.App.Mappers;
using BLL.Base.Services;
using Contracts.BLL.App.Mappers;
using Contracts.BLL.App.Services;
using Contracts.DAL.App;
using Contracts.DAL.App.Repositories;
12
using Microsoft.EntityFrameworkCore.Diagnostics;
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

namespace BLL.App.Services
{
    public class GpsLocationService :
        BaseEntityService<IAppUnitOfWork, IGpsLocationRepository, IGpsLocationServiceMapper, DAL.App.DTO.GpsLocation,
            BLL.App.DTO.GpsLocation>, IGpsLocationService
    {
        public GpsLocationService(IAppUnitOfWork uow) : base(uow, uow.GpsLocations, new GpsLocationServiceMapper())
        {
        }

        public virtual async Task<IEnumerable<GpsLocation>> GetAllAsync(Guid gpsSessionId, Guid? userId = null,
            bool noTracking = true)
        {
            return (await Repository.GetAllAsync(gpsSessionId, userId, noTracking)).Select(e => Mapper.Map(e));
        }
29
30
31
32
33
34
35
36
37
38


        public virtual async Task<GpsLocation> AddAndUpdateSessionAsync(GpsLocation gpsLocation)
        {
            // get the last location from uow
            // calculate updated metrics for session
            // update session
            // add location

            var gpsSession = await UOW.GpsSessions.FirstOrDefaultAsync(gpsLocation.GpsSessionId, gpsLocation.AppUserId);
Andres Käver's avatar
Andres Käver committed
39
40
            
            // last location, based on time
41
            var lastLocation = await UOW.GpsLocations.LastInSessionAsync(gpsSession.Id);
Andres Käver's avatar
Andres Käver committed
42
43
            
            
Andres Käver's avatar
bll    
Andres Käver committed
44
45
            // skip out of sync locations
            if (lastLocation != null && lastLocation.RecordedAt < gpsLocation.RecordedAt)
46
            {
Andres Käver's avatar
Andres Käver committed
47
48
49
50
51
52
53
54
55
                // calculate the metrics
                var distance = getDistance(gpsLocation, lastLocation);
                var vertical = getVerticalDistance(gpsLocation, lastLocation);
                gpsSession.Distance += distance;
                if (vertical < 0)
                {
                    gpsSession.Descent += Math.Abs(vertical);
                } else if (vertical > 0)
                {
Andres Käver's avatar
bll    
Andres Käver committed
56
                    gpsSession.Climb += vertical;
Andres Käver's avatar
Andres Käver committed
57
                }
Andres Käver's avatar
Andres Käver committed
58

Andres Käver's avatar
bll    
Andres Käver committed
59
                gpsSession.Duration = (lastLocation.RecordedAt - gpsSession.RecordedAt).TotalSeconds; 
Andres Käver's avatar
Andres Käver committed
60
                
Andres Käver's avatar
Andres Käver committed
61
62
                await UOW.GpsSessions.UpdateAsync(gpsSession);
            }
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
            
            return base.Add(gpsLocation);
        }

        private double getDistance(GpsLocation gpsLocation, DAL.App.DTO.GpsLocation lastLocation)
        {
            var d1 = gpsLocation.Latitude * (Math.PI / 180.0);
            var num1 = gpsLocation.Longitude * (Math.PI / 180.0);
            var d2 = lastLocation.Latitude * (Math.PI / 180.0);
            var num2 = lastLocation.Longitude * (Math.PI / 180.0) - num1;
            var d3 = Math.Pow(Math.Sin((d2 - d1) / 2.0), 2.0) + Math.Cos(d1) * Math.Cos(d2) * Math.Pow(Math.Sin(num2 / 2.0), 2.0);

            return Math.Abs(6376500.0 * (2.0 * Math.Atan2(Math.Sqrt(d3), Math.Sqrt(1.0 - d3))));
        }

        private double getVerticalDistance(GpsLocation gpsLocation, DAL.App.DTO.GpsLocation lastLocation)
        {
            return gpsLocation.Altitude - lastLocation.Altitude;
        }

83
84
    }
}