public TripLength CalculateDistance(Location startLocation, Location endLocation)
        {
            var result = TripLength.Zero;

            try
            {
                if (!startLocation.Equals(endLocation))
                {
                    var locationsTuple = GetLocationsTuple(startLocation, endLocation);
                    var hash           = locationsTuple.GetHashCode();

                    result = _dictionary.GetOrAdd(
                        hash, i => _distanceService.CalculateDistance(startLocation, endLocation));
                }
            }
            catch
            {
                result = TripLength.Zero;
            }

            return(result);
        }
        public TripLength CalculateDistance(Location startLocation, Location endLocation, TimeSpan startTime)
        {
            var startLocationDomain = _mapperService.MapModelToDomain(startLocation);

            startLocationDomain.Latitude  = startLocation.Latitude;
            startLocationDomain.Longitude = startLocation.Longitude;
            var endLocationDomain = _mapperService.MapModelToDomain(endLocation);

            endLocationDomain.Latitude  = endLocation.Latitude;
            endLocationDomain.Longitude = endLocation.Longitude;

            var locationDistance = _locationDistanceService.Get(startLocationDomain, endLocationDomain);

            TripLength result;

            if (locationDistance != null)
            {
                var hourIndex = (int)startTime.TotalHours;

                while (hourIndex >= 24)
                {
                    hourIndex = hourIndex - 24;
                }

                long travelTime = locationDistance.Hours[hourIndex].TravelTime.Value;
                if (travelTime == 0 && locationDistance.TravelTime.HasValue)
                {
                    travelTime = locationDistance.TravelTime.Value;
                }

                long distance = 0;
                if (locationDistance.Distance.HasValue)
                {
                    distance = (long)locationDistance.Distance.Value;
                }

                result = new TripLength(distance, TimeSpan.FromSeconds(travelTime));
            }
            else
            {
                // Use fallback service
                result = _fallbackDistanceService.CalculateDistance(startLocation, endLocation, startTime);
            }

            return(result);
        }
Esempio n. 3
0
 /// <summary>
 /// Calculates the trip length between two stops
 /// </summary>
 /// <param name="start"></param>
 /// <param name="end"></param>
 /// <returns></returns>
 public TripLength CalculateTripLength(RouteStop start, RouteStop end)
 {
     return(_distanceService.CalculateDistance(start.Location, end.Location));
 }
Esempio n. 4
0
        public JobNode CreateJobNode(Job job, TimeSpan?startTime = null, bool ignoreFirstStopExecutionTime = false)
        {
            var routeStops = FilterExtraniousFecMiamiTerminalStops(job.RouteStops.ToList()).ToList();

            job.RouteStops = routeStops;

            job.RouteSegmentStatisticses = new List <RouteSegmentStatistics>();

            _array = new double[11, routeStops.Count];

            if (job.RouteStops != null && job.RouteStops.Any())
            {
                SetTravelTimes(routeStops);
                SetTimeWindowValues(routeStops);
                SetServiceTimes(routeStops, startTime == null || ignoreFirstStopExecutionTime);
                SetSumValues(routeStops);
                SetResultTimeWindows(routeStops);

                SetDepartureTime(startTime, routeStops);
                //SetArrivalTime(routeStops);
                SetViolationsAndWait(routeStops);

                var result = new JobNode(job, _array)
                {
                    Priority = job.Priority > 0 && job.Priority < 4 ? job.Priority : 1
                };

                // TODO URGENT - use automapper to assure that future
                //  properties will be mapped automatically without needing to create a manual mapping

                try { result.Job.IsHazmat = job.IsHazmat; }
                catch (Exception e) { Console.WriteLine(e.ToString()); }

                try { result.WindowStart = TimeSpan.FromSeconds(_array[RowIndexResultTwl, 0]); }
                catch { result.WindowStart = TimeSpan.Zero; }

                try { result.WindowEnd = TimeSpan.FromSeconds(_array[RowIndexResultTwu, 0]); }
                catch { result.WindowEnd = _array[RowIndexResultTwu, 0] > 0 ? TimeSpan.MaxValue : result.WindowStart; }


                if (result.WindowEnd < result.WindowStart)
                {
                    result.WindowStart = result.WindowEnd;
                }

                if (DoesViolationExist(routeStops))
                {
                    result.IsInvalid = true;
                    //throw new Exception("Invalid Jobnode - violation detected");
                }

                for (var i = 1; i < routeStops.Count; i++)
                {
                    var distance = _distanceService.CalculateDistance(routeStops[i - 1].Location, routeStops[i].Location);
                    var rss      = new RouteSegmentStatistics()
                    {
                        StartStop         = routeStops[i - 1],
                        EndStop           = routeStops[i],
                        StartTime         = TimeSpan.FromSeconds(_array[RowIndexArrival, i]),
                        WhiffedTimeWindow = _array[RowIndexViolations, i] == 0,
                        Statistics        = new RouteStatistics
                        {
                            TotalExecutionTime  = TimeSpan.FromSeconds(_array[RowIndexServiceTime, i]),
                            TotalIdleTime       = TimeSpan.FromSeconds(_array[RowIndexWaitTime, i]),
                            TotalQueueTime      = TimeSpan.Zero,
                            TotalTravelTime     = distance.Time,
                            TotalTravelDistance = distance.Distance
                        }
                    };
                    job.RouteSegmentStatisticses.Add(rss);
                }

                return(result);
            }

            return(new JobNode(job)
            {
                IsInvalid = true
            });
        }