示例#1
0
        /// <summary>
        /// Calculate time range, when trip can be finished.
        /// </summary>
        /// <param name="tripTimeRange">TimeRange.</param>
        /// <returns>TimeRange.</returns>
        private TimeRange _GetTripPossibleFinishTimeRange(TimeRange tripTimeRange)
        {
            // Calculate route finish time window.
            TimeRange routeFinishTimeRange = new TimeRange();

            // If we have breaks that must be visited.
            if (_route.Breaks.Count != 0 && _route.Breaks[0] is TimeWindowBreak)
            {
                // Route finish time window will be from trip earliest possible finish
                // to time when trip can be finished.

                // Calculate last break finish time window.
                TimeWindowBreak lastBreak          = _GetSortedBreaks()[_route.Breaks.Count - 1] as TimeWindowBreak;
                TimeRange       lastBreakTimeRange =
                    new TimeRange(lastBreak.EffectiveFrom, lastBreak.EffectiveTo);
                TimeRange lastBreakFinishTimeRange = lastBreakTimeRange.Shift(
                    TimeSpan.FromMinutes(lastBreak.Duration));
                TimeRange lastBreakRealFinishTimeRange = lastBreakFinishTimeRange.Intersection(tripTimeRange);

                // Trip earliest finish is minimum time, when last break will be completed.
                var earliestTripFinish = lastBreakRealFinishTimeRange.From;

                routeFinishTimeRange = new TimeRange(earliestTripFinish, tripTimeRange.To);
            }
            // If we have no breaks to visit route finish time window will be equal to trip time window.
            else
            {
                routeFinishTimeRange = tripTimeRange;
            }

            return(routeFinishTimeRange);
        }
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Page loaded handler.
        /// </summary>
        private void fleetSetupWizardRoutesPage_Loaded(object sender, RoutedEventArgs e)
        {
            Debug.Assert(0 < DataKeeper.Locations.Count); // locations must present

            // If there are no default breaks - add default break to project configuration.
            if (DataKeeper.Project.BreaksSettings.BreaksType == null)
            {
                DataKeeper.Project.BreaksSettings.BreaksType = BreakType.TimeWindow;
                var timeWindowBreak = new TimeWindowBreak();
                DataKeeper.Project.BreaksSettings.DefaultBreaks.Add(timeWindowBreak);
            }

            // init controls
            if (!_isInited)
            {
                _InitControls();
            }

            _InitDataGridCollection();

            // validate controls
            _UpdatePageState();

            vehicleNumberTextBox.Focus();
            vehicleNumberTextBox.SelectAll();
        }
示例#3
0
        /// <summary>
        /// If we upgrading from old version of project we need to update breaks settings.
        /// So project's Breaks Type will be set to TimeWindowBreak and as a default break
        /// will be used default routes most popular break.
        /// </summary>
        private void _UpdateBreaksConfig()
        {
            // Check that we need to create default breaks.
            if (_projectCfg.BreaksSettings.BreaksType == null && DefaultRoutes.Count != 0)
            {
                var      breaks   = new List <MaxBreak>();
                MaxBreak breakObj = null;

                // Analyze each route in project.
                foreach (Route route in DefaultRoutes)
                {
                    // Check that route has break and this is TimeWindowBreak.
                    if (route.Breaks.Count == 1 && route.Breaks[0] is TimeWindowBreak)
                    {
                        // Get route's break.
                        TimeWindowBreak routeBreak = route.Breaks[0] as TimeWindowBreak;

                        // If break isn't first, try find same break in list.
                        if (breaks.Count != 0)
                        {
                            breakObj = breaks.FirstOrDefault(x => x.Break.To == routeBreak.To &&
                                                             x.Break.From == routeBreak.From && x.Break.Duration == routeBreak.Duration);
                        }

                        // If there is same break in a list - just increase records count.
                        if (breakObj != null)
                        {
                            breakObj.Count++;
                        }
                        // If there is no such break - add new record to list.
                        else
                        {
                            breaks.Add(new MaxBreak {
                                Count = 1, Break = routeBreak
                            });
                        }
                    }
                }

                // Try to find most popular break in list.
                MaxBreak mostPopularBreak = breaks.FirstOrDefault
                                                (x => x.Count == breaks.Max(br => br.Count));

                // Set default breaks type as timewindow break.
                _projectCfg.BreaksSettings.BreaksType = BreakType.TimeWindow;

                // If we found most popular break - set it as default, otherwise left default
                // breaks collection empty.
                if (mostPopularBreak != null)
                {
                    _projectCfg.BreaksSettings.DefaultBreaks.Add(
                        mostPopularBreak.Break.Clone() as TimeWindowBreak);
                }
            }
        }
示例#4
0
        /// <summary>
        /// Return index of break in original route collection.
        /// </summary>
        /// <param name="breakObj">Break which index must be detected.</param>
        /// <returns></returns>
        private int _IndexInUnsortedCollection(TimeWindowBreak breakObj)
        {
            for (int i = 0; i < _route.Breaks.Count; i++)
            {
                if ((_route.Breaks[i] as TimeWindowBreak).EffectiveFrom == breakObj.EffectiveFrom)
                {
                    return(i);
                }
            }

            return(-1);
        }
示例#5
0
        /// <summary>
        /// Comparison for two Brakes.
        /// </summary>
        /// <param name="break1">First <c>Brake</c>.</param>
        /// <param name="break2">Second <c>Brake</c>.</param>
        /// <returns>-1 if first break less then second, 0 if they are equal
        /// and 1 if first break more then second. </returns>
        public static int Compare(Break break1, Break break2)
        {
            // If first break == null.
            if (break1 == null)
            {
                if (break2 == null)
                {
                    return(0);
                }
                else
                {
                    return(-1);
                }
            }
            else if (break2 == null)
            {
                return(1);
            }

            // If both not null.
            if (break1.GetType() != break2.GetType())
            {
                return(0); // Breaks are not of the same type, cant compare.
            }
            else if (break1.GetType() == typeof(TimeWindowBreak))
            {
                TimeWindowBreak br1 = break1 as TimeWindowBreak;
                TimeWindowBreak br2 = break2 as TimeWindowBreak;

                return(_TimeWindowBreakComparer(br1, br2));
            }
            else if (break1.GetType() == typeof(WorkTimeBreak))
            {
                WorkTimeBreak br1 = break1 as WorkTimeBreak;
                WorkTimeBreak br2 = break2 as WorkTimeBreak;

                return(_WorkTimeBreakComparer(br1, br2));
            }
            else if (break1.GetType() == typeof(DriveTimeBreak))
            {
                DriveTimeBreak br1 = break1 as DriveTimeBreak;
                DriveTimeBreak br2 = break2 as DriveTimeBreak;

                return(_DriveTimeBreakComparer(br1, br2));
            }
            else
            {
                // Breaks are of unknown type, cant compare them.
                Debug.Assert(false);
                return(0);
            }
        }
        /// <summary>
        /// Does validation.
        /// </summary>
        /// <param name="objectToValidate">Object to validation.</param>
        /// <param name="currentTarget">Current target (expected only
        /// <see cref="T:ESRI.ArcLogistics.DomainObjects.TimeWindowBreak"/>).</param>
        /// <param name="key">Ignored.</param>
        /// <param name="validationResults">Validation results.</param>
        protected override void DoValidate(TimeSpan objectToValidate,
                                           object currentTarget,
                                           string key,
                                           ValidationResults validationResults)
        {
            // Input parametrs check.
            Debug.Assert(currentTarget != null);
            if ((currentTarget as TimeWindowBreak).Breaks == null)
            {
                return;
            }

            // Detecting index of TimeWindowBreak in Breaks collection.
            var timeWindowBreak = currentTarget as TimeWindowBreak;
            int index           = BreaksHelper.IndexOf(timeWindowBreak.Breaks, timeWindowBreak);

            // Detecting index of TimeWindowBreak in sorted collection.
            List <Break> sortedBreaks = BreaksHelper.GetSortedList(timeWindowBreak.Breaks);
            int          sortedIndex  = BreaksHelper.IndexOf(sortedBreaks, timeWindowBreak);

            // If it isn't last break in sorted collection, we can check it's
            // timewindow on intersection with next break.
            if (sortedIndex < sortedBreaks.Count - 1)
            {
                // Detecting index of next Break in input collection.
                TimeWindowBreak nextBreak    = sortedBreaks[sortedIndex + 1] as TimeWindowBreak;
                int             overlapIndex = BreaksHelper.IndexOf(timeWindowBreak.Breaks, nextBreak);

                // Checking next Break in collection on TimeWindow
                // intersection with current TimeWindowBreak.
                if (nextBreak.EffectiveFrom <= timeWindowBreak.EffectiveTo)
                {
                    // Breaks time windows overlap.
                    _AddString(Properties.Messages.Error_TimeWindowOverlap,
                               index, overlapIndex, currentTarget, key, validationResults);
                }
                else
                {
                    // Checking for time window + break time overlap.
                    TimeSpan duration = TimeSpan.FromMinutes(timeWindowBreak.Duration);
                    if (nextBreak.EffectiveFrom <= timeWindowBreak.EffectiveTo + duration)
                    {
                        // Break time window + duration overlap other break time window.
                        _AddString(Properties.Messages.Error_TimeWindowPlusDurationOverlap,
                                   index, overlapIndex, currentTarget, key, validationResults);
                    }
                }
            }
        }
示例#7
0
 /// <summary>
 /// Comparer for two <c>TimeWindowBrakes</c>.
 /// </summary>
 /// <param name="break1">First <c>Brake</c>.</param>
 /// <param name="break2">Second <c>Brake</c>.</param>
 /// <returns>Result of comparing. Breaks are compared by EffectiveFrom property.</returns>
 private static int _TimeWindowBreakComparer(TimeWindowBreak break1, TimeWindowBreak break2)
 {
     if (break1.EffectiveFrom > break2.EffectiveFrom)
     {
         return(1);
     }
     else if (break1.EffectiveFrom < break2.EffectiveFrom)
     {
         return(-1);
     }
     else
     {
         return(0);
     }
 }
示例#8
0
        /// <summary>
        /// Check that all route's breaks can be visited.
        /// For invalid breaks add error messages.
        /// </summary>
        /// <param name="tripTimeRange">Trip start time window.</param>
        /// <rereturns>'True' if all breaks can be visited, 'false' otherwise.</rereturns>
        private bool _CheckBreaksCanBeVisited(TimeRange tripTimeRange)
        {
            var result = true;

            // Prepare breaks for validation.
            Breaks sortedBreaks = _GetSortedBreaks();

            // Collection with breaks, which cannot be completed at time.
            Breaks invalidBreaks = new Breaks();

            // Check that all breaks can be completed in time.
            for (int i = 0; i < sortedBreaks.Count; i++)
            {
                TimeWindowBreak breakToCheck = sortedBreaks[i] as TimeWindowBreak;

                // Try to calculate break start.
                var breakStart = tripTimeRange.Intersection(breakToCheck.EffectiveFrom,
                                                            breakToCheck.EffectiveTo);

                // If break cannot be started - it is invalid. Check next break.
                if (breakStart == null)
                {
                    invalidBreaks.Add(breakToCheck);
                }
                // Check that break can be finished.
                else
                {
                    // Try calculate break finish.
                    var breakFinish = breakStart.Shift(TimeSpan.FromMinutes(breakToCheck.Duration));
                    breakFinish = breakFinish.Intersection(tripTimeRange);

                    // If break cannot be finished - it is invalid.
                    if (breakFinish == null)
                    {
                        invalidBreaks.Add(breakToCheck);
                    }
                }
            }

            // If there was invalid breaks - show error messages.
            if (invalidBreaks.Count != 0)
            {
                _AddErrorMessages(invalidBreaks);
                result = false;
            }

            return(result);
        }
示例#9
0
        /// <summary>
        /// Get the time span when route must start to satisfy first break.
        /// </summary>
        /// <param name="startTimeRange">TimeRange in which route can left start location.</param>
        /// <param name="firstBreak">TimeWindowBreak.</param>
        /// <param name="tripMaxDuration">Max trip duration.</param>
        /// <returns>TimeSpan?.</returns>
        private TimeSpan?_GetRealStart(TimeRange startTimeRange,
                                       TimeWindowBreak firstBreak, TimeSpan tripMaxDuration)
        {
            // Calculate trip possible time range.
            var tripPossibleTimeRange = startTimeRange.Clone() as TimeRange;

            tripPossibleTimeRange.To += tripMaxDuration;

            // Get finishTimeRange of trip and break time ranges.
            var intersection = tripPossibleTimeRange.Intersection(
                new TimeRange(firstBreak.EffectiveFrom, firstBreak.EffectiveFrom));

            // If they intersects - calculate trip start.
            if (intersection != null)
            {
                return(_MinTimeSpan(startTimeRange.To, intersection.To));
            }
            else
            {
                return(null);
            }
        }
示例#10
0
        /// <summary>
        /// Method gets stops date from route.
        /// </summary>
        /// <param name="route">Route to get information.</param>
        /// <returns>Collection of stops data.</returns>
        private List <StopData> _GetStops(Route route)
        {
            Debug.Assert(route != null);

            IDataObjectCollection <Stop> stops = route.Stops;
            int stopsCount = stops.Count;

            var stopDatas = new List <StopData>(stopsCount);

            for (int index = 0; index < stopsCount; ++index)
            {
                Stop stop = stops[index];

                StopData sd = new StopData();
                sd.SequenceNumber = stop.SequenceNumber;
                sd.Distance       = stop.Distance;
                sd.WaitTime       = stop.WaitTime;
                sd.TimeAtStop     = stop.TimeAtStop;
                sd.TravelTime     = stop.TravelTime;
                sd.ArriveTime     = (DateTime)stop.ArriveTime;

                if (stop.StopType == StopType.Lunch)
                {
                    // Break.

                    // ToDo - need update logic - now find only first TWBreak.
                    var twBreaks =
                        from currBreak in route.Breaks
                        where
                        currBreak is TimeWindowBreak
                        select currBreak;

                    TimeWindowBreak rtBreak = twBreaks.FirstOrDefault() as TimeWindowBreak;
                    if (rtBreak != null && rtBreak.Duration > 0.0)
                    {
                        // TODO Break

                        //// Time window.
                        //DateTime? twStart = null;
                        //DateTime? twEnd = null;
                        //if (rtBreak.TimeWindow != null)
                        //    _ConvertTW(rtBreak.TimeWindow, out twStart, out twEnd);
                        sd.TimeWindowStart1 = _TSToDate(rtBreak.From);
                        sd.TimeWindowEnd1   = _TSToDate(rtBreak.To);
                    }
                }
                else
                {
                    Debug.Assert(stop.AssociatedObject != null);

                    // Associated object id.
                    sd.AssociatedObject = stop.AssociatedObject;

                    // Geometry.
                    Point pt = _GetStopPoint(stop);
                    sd.Geometry = GPObjectHelper.PointToGPPoint(pt);

                    // Time windows.
                    DateTime?twStart1 = null;
                    DateTime?twStart2 = null;
                    DateTime?twEnd1   = null;
                    DateTime?twEnd2   = null;

                    // Type-specific data.
                    if (stop.StopType == StopType.Order)
                    {
                        Order order = stop.AssociatedObject as Order;
                        Debug.Assert(order != null);

                        // Curbapproach.
                        sd.NACurbApproach =
                            CurbApproachConverter.ToNACurbApproach(
                                _context.SolverSettings.GetDepotCurbApproach());

                        // Time window 1.
                        if (order.TimeWindow != null)
                        {
                            _ConvertTW(order.TimeWindow, out twStart1, out twEnd1);
                        }

                        // Time window 2.
                        if (order.TimeWindow2 != null)
                        {
                            _ConvertTW(order.TimeWindow2, out twStart2, out twEnd2);
                        }
                    }
                    else if (stop.StopType == StopType.Location)
                    {
                        Location loc = stop.AssociatedObject as Location;
                        Debug.Assert(loc != null);

                        // Time window.
                        if (loc.TimeWindow != null)
                        {
                            _ConvertTW(loc.TimeWindow, out twStart1, out twEnd1);
                        }
                    }

                    sd.TimeWindowStart1 = twStart1;
                    sd.TimeWindowStart2 = twStart2;
                    sd.TimeWindowEnd1   = twEnd1;
                    sd.TimeWindowEnd2   = twEnd2;
                }

                sd.RouteId  = route.Id;
                sd.StopType = stop.StopType;
                stopDatas.Add(sd);
            }

            SolveHelper.ConsiderArrivalDelayInStops(
                _context.SolverSettings.ArriveDepartDelay, stopDatas);

            return(stopDatas);
        }