/// <summary>
 /// Crates new MoveToRouteCommandOption. Initializes all main class fields.
 /// </summary>
 /// <param name="groupId">Option group ID (to set in separate group in UI).</param>
 /// <param name="targetRoute">Processed route.</param>
 public MoveToRouteCommandOption(int groupId, Route targetRoute)
 {
     GroupID = groupId;
     _targetRoute = targetRoute;
     EnabledTooltip = null;
     DisabledTooltip = null;
 }
        protected override List<Guid> GetRouteSpecIds(Route route)
        {
            List<Guid> specs = base.GetRouteSpecIds(route);

            if (_setAssignmentSpec && _unlockedTargetRoutes.Contains(route))
                specs.Add(ASSIGNMENT_SPEC_ID);

            return specs;
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="route">Route to show.</param>
        private RouteGraphicObject(Route route)
            : base(route)
        {
            _route = route;

            _InitEventHandlers();

            _CreateAndSetPolyline();
        }
        /// <summary>
        /// Gets assigned orders from route.
        /// </summary>
        /// <param name="route">Route as source for assigned orders.</param>
        /// <returns></returns>
        public static IEnumerable<Order> GetAssignedOrders(Route route)
        {
            Debug.Assert(route != null);

            var orders =
                from stop in route.Stops
                where stop.StopType == StopType.Order
                let order = stop.AssociatedObject as Order
                select order;

            return orders;
        }
        /// <summary>
        /// Initializes a new instance of the <c>StopGanttItem</c> class.
        /// </summary>
        public StopGanttItemElement(Stop stop, IGanttItem parent)
        {
            Debug.Assert(stop != null);
            Debug.Assert(parent != null);

            // Initialize stop.
            _stop = stop;
            _route = stop.Route;

            // Subscribe on stop and route changes to notify about updates.
            _route.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_RoutePropertyChanged);
            _stop.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_StopPropertyChanged);

            // Initialize parent.
            _parent = parent;
        }
        /// <summary>
        /// Method gets stops collection for route depots.
        /// </summary>
        /// <param name="depotVisits">Depots GP feature collection.</param>
        /// <param name="route">Route.</param>
        /// <param name="renewals">Renewals GP feature collection.</param>
        /// <returns>Collection of Stop data for depots.</returns>
        private List<StopData> _GetDepotStops(
              IEnumerable<GPFeature> depotVisits,
              Route route,
              IEnumerable<GPFeature> renewals)
        {
            Debug.Assert(depotVisits != null);
            Debug.Assert(route != null);
            Debug.Assert(renewals != null);

            var renewalsByID = renewals
                .GroupBy(feature => _AttrToObjectId(NAAttribute.DEPOT_NAME, feature.Attributes))
                .ToDictionary(group => group.Key, group => group.First());

            var stops = new List<StopData>();
            foreach (GPFeature depotVisitFeature in depotVisits)
            {
                // route id
                Guid depotRouteId = _AttrToObjectId(NAAttribute.ROUTE_NAME,
                    depotVisitFeature.Attributes);

                if (depotRouteId != route.Id)
                {
                    continue;
                }

                var depotID = default(string);
                // if not virtual depot
                if (!depotVisitFeature.Attributes.TryGet(NAAttribute.NAME, out depotID) ||
                    string.IsNullOrEmpty(depotID))
                {
                    continue;
                }

                // create/add stops
                stops.Add(_CreateStopFromDepot(depotVisitFeature, route, renewalsByID));
            }

            return stops;
        }
        /// <summary>
        /// Method gets stops collection from Breaks features collection for current route.
        /// </summary>
        /// <param name="breaks">Breaks feature collection.</param>
        /// <param name="route">Current route to get breaks.</param>
        /// <returns>Stops collection of Breaks for current route.</returns>
        private List<StopData> _GetBreakStops(IEnumerable<GPFeature> breaks, Route route)
        {
            // Sort breaks from route.
            Breaks breaksOnRoute = (Breaks)route.Breaks.Clone();
            breaksOnRoute.Sort();

            // Get all breaks from route.
            var routeBreaks = breaksOnRoute
                .OfType<Break>()
                .Where(item => item.Duration > 0.0)
                .ToList();

            // Find all break features for current route.
            var breakFeatures = (
                from feature in breaks
                where (route.Id == _AttrToObjectId(NAAttribute.ROUTE_NAME, feature.Attributes))
                select feature)
                .ToList();

            var stops = new List<StopData>();

            if (breakFeatures.Count <= routeBreaks.Count)
            {
                int breakIndex = 0;

                // Create stops from every break features.
                foreach (GPFeature feature in breakFeatures)
                {
                    // Get next break from route.
                    Break routeBreak = routeBreaks[breakIndex++];

                    StopData stopData = null;
                    if (_CreateStopFromBreak(feature, route, routeBreak, out stopData))
                        stops.Add(stopData);
                }
            }
            else
            {
                // Breaks count is incorrect.
                string message = Properties.Messages.Error_InvalidBreakGPFeatureCount;
                throw new RouteException(message);
            }

            return stops;
        }
Beispiel #8
0
        /// <summary>
        /// Compare two routes.
        /// </summary>
        /// <param name="route">Route to compare with this.</param>
        /// <returns>"True" if they are equal and false otherwise.</returns>
        internal bool EqualsByValue(Route route)
        {
            // If route to compare with is null - they are not equal.
            if (route == null)
                return false;

            // Compare properties of both routes.
            return Breaks.EqualsByValue(route.Breaks) && Name == route.Name &&
                Color == route.Color && Comment == route.Comment && route.HardZones == HardZones &&
                MaxOrders == route.MaxOrders && MaxTotalDuration == route.MaxTotalDuration &&
                MaxTravelDistance == route.MaxTravelDistance && TimeAtEnd == route.TimeAtEnd &&
                MaxTravelDuration == route.MaxTravelDuration &&
                StartTimeWindow.EqualsByValue(route.StartTimeWindow) &&
                TimeAtStart == route.TimeAtStart && TimeAtRenewal == route.TimeAtRenewal ;
        }
        /// <summary>
        /// Initializes a new instance of the <c>DriveTimeGanttItemElement</c> class.
        /// </summary>
        public DriveTimeGanttItemElement(Stop stop, IGanttItem parent)
        {
            // Creates route drive time as a gantt item element.
            _stop = stop;
            _route = stop.Route; // Cache route value.
            _parent = parent;

            // Subscribe on stop changes to notify about updates.
            _route.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_RoutePropertyChanged);
            _stop.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_StopPropertyChanged);
        }
        /// <summary>
        /// Method gets location of route.
        /// </summary>
        /// <param name="route">Route.</param>
        /// <param name="locId">Location id.</param>
        /// <returns>Start, End or renewal location - if found, otherwise - null.</returns>
        private static Location _GetRouteLocation(Route route, Guid locId)
        {
            Debug.Assert(route != null);

            Location loc = null;

            if (route.StartLocation != null &&
                route.StartLocation.Id == locId)
            {
                loc = route.StartLocation;
            }
            else if (route.EndLocation != null &&
                route.EndLocation.Id == locId)
            {
                loc = route.EndLocation;
            }
            else
            {
                loc = DataObjectHelper.FindObjectById<Location>(locId, route.RenewalLocations);
            }

            return loc;
        }
        private static void _SaveStops(
            XmlWriter writer,
            Route route,
            ICollection<Stop> stops,
            ICollection<string> orderPropertiesToExport,
            Project project,
            AddressField[] addressFields)
        {
            Debug.Assert(route != null);

            var sortedStops = new List<Stop>(stops);
            CommonHelpers.SortBySequence(sortedStops);

            var orderPropertiesTitlesToExport = new List<string>();
            var names = new List<string>(Order.GetPropertyNames(project.CapacitiesInfo,
                                         project.OrderCustomPropertiesInfo, addressFields));
            var titles = new List<string>(Order.GetPropertyTitles(project.CapacitiesInfo,
                                          project.OrderCustomPropertiesInfo, addressFields));

            foreach (string name in orderPropertiesToExport)
            {
                int index = names.IndexOf(name);
                string title = titles[index];
                orderPropertiesTitlesToExport.Add(title);
            }

            var routeStops = CommonHelpers.GetSortedStops(route);

            writer.WriteStartElement(STOPS_NODE_NAME);
            foreach (Stop stop in sortedStops)
            {
                string name = _GetStopName(stop, routeStops);

                var mapLocation = stop.MapLocation;
                if (!mapLocation.HasValue)
                {
                    if (stop.StopType != StopType.Lunch)
                    {
                        throw new InvalidOperationException(
                            Properties.Messages.Error_GrfExporterNoLocationForStop); // exception
                    }

                    var currentIndex = stop.SequenceNumber - 1;
                    var stopWithLocation = SolveHelper.GetActualLunchStop(routeStops, currentIndex);
                    if (!stopWithLocation.MapLocation.HasValue)
                    {
                        throw new InvalidOperationException(
                            Properties.Messages.Error_GrfExporterNoLocationForStop); // exception
                    }

                    mapLocation = stopWithLocation.MapLocation.Value;
                }

                writer.WriteStartElement(STOP_NODE_NAME);
                writer.WriteAttributeString(ENABLED_ATTR_NAME, TRUE_VALUE);

                string comments = _GetComments(stop, orderPropertiesToExport, orderPropertiesTitlesToExport);

                _SaveLocationNode(writer, mapLocation.Value, name, comments);
                writer.WriteStartElement(DURATION_NODE_NAME);
                double duration = stop.TimeAtStop * 60;
                writer.WriteValue(duration.ToString(DOUBLE_FORMAT, NumberFormatInfo.InvariantInfo));
                writer.WriteEndElement();

                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }
        private static void _SaveRouteResults(XmlWriter writer, Route route, ICollection<Stop> stops)
        {
            bool hasDirections = stops.Any(s => s.Directions != null);
            if (hasDirections)
            {
                writer.WriteStartElement(ROUTE_RESULT_NODE_NAME);

                List<Stop> routeStops = new List<Stop>(stops);
                CommonHelpers.SortBySequence(routeStops);

                double totalTimeInDays = route.TravelTime / (MINUTES_PER_HOUR * HOURS_PER_DAY);
                double serviceTimeSum = 0;
                double drivingTimeInDays = route.TravelTime / (MINUTES_PER_HOUR * HOURS_PER_DAY);
                foreach (Stop stop in routeStops)
                {
                    Order order = stop.AssociatedObject as Order;
                    if (order != null)
                        serviceTimeSum += order.ServiceTime;
                }
                totalTimeInDays += serviceTimeSum / (MINUTES_PER_HOUR * HOURS_PER_DAY);

                string totalsText = _GetTotalsText(route.TotalDistance, drivingTimeInDays);
                writer.WriteStartElement(TOTALS_TEXT_NODE_NAME);
                writer.WriteStartElement(TEXT_NODE_NAME);
                writer.WriteStartElement(STRING_NODE_NAME);
                writer.WriteValue(totalsText);
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteEndElement();

                writer.WriteStartElement(LENGTH_NODE_NAME);
                writer.WriteValue(route.TotalDistance.ToString(DOUBLE_FORMAT, NumberFormatInfo.InvariantInfo));
                writer.WriteEndElement();

                writer.WriteStartElement(TRAVELTIME_NODE_NAME);
                writer.WriteValue((totalTimeInDays).ToString(DOUBLE_FORMAT, NumberFormatInfo.InvariantInfo));
                writer.WriteEndElement();

                writer.WriteStartElement(DRIVINGTIME_NODE_NAME);
                writer.WriteValue((drivingTimeInDays).ToString(DOUBLE_FORMAT, NumberFormatInfo.InvariantInfo));
                writer.WriteEndElement();

                if (stops.Count > 0)
                    _SaveItems(writer, stops);

                writer.WriteEndElement();
            }
        }
        private static void _SaveRouteSettings(XmlWriter writer, Route route, IVrpSolver solver,
            GrfExportResult result )
        {
            SolverSettings settings = solver.SolverSettings;
            writer.WriteStartElement(ROUTE_SETTINGS_NODE_NAME);

            writer.WriteStartElement(UTURNPOLICY_NODE_NAME);
            string uTurnPolicy = "";
            switch (settings.GetUTurnPolicy())
            {
                case UTurnPolicy.Nowhere:
                    uTurnPolicy = UTurnNowhere;
                    break;
                case UTurnPolicy.AtDeadEnds:
                    uTurnPolicy = UTurnAtDeadEnds;
                    break;
                case UTurnPolicy.AtDeadEndsAndIntersections:
                    // GRF doesnt support "U-Turns at Dead Ends and Intersections" UTurnPolicy,
                    // so replace it with "U-Turns at Dead Ends".
                    uTurnPolicy = UTurnAtDeadEnds;

                    // Add warning message
                    result.Warnings.Add(Properties.Messages.Warning_UTurnPolicyNotSupported);
                    break;
                default:
                    Debug.Assert(false); // NOTE: not supported
                    break;
            }
            writer.WriteAttributeString(VALUE_ATTR_NAME, uTurnPolicy);
            writer.WriteEndElement();

            writer.WriteStartElement(IMPEDANCE_ATTR_NODE_NAME);
            writer.WriteAttributeString(NAME_ATTR_NAME, solver.NetworkDescription.ImpedanceAttributeName);
            writer.WriteEndElement();

            writer.WriteStartElement(RESTRICTIONS_ATTR_NODE_NAME);

            ICollection<string> restrictions = SolveHelper.GetEnabledRestrictionNames(
                solver.SolverSettings.Restrictions);

            foreach (string name in restrictions)
            {
                writer.WriteStartElement(RESTRICTION_NODE_NAME);
                writer.WriteAttributeString(NAME_ATTR_NAME, name);
                writer.WriteAttributeString(TYPE_ATTR_NAME, STRICT_ATTR_NAME);
                writer.WriteAttributeString(STATUS_ATTR_NAME, ON_ATTR);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();

            _SaveRouteAttributes(writer, route, solver);

            writer.WriteStartElement(TRIPPLANSETTINGS_NODE_NAME);
            writer.WriteStartElement(TRIP_START_NODE_NAME);
            string startTime = route.StartTime.Value.ToString("yyyy-MM-ddTHH:mm:ss");
            writer.WriteAttributeString(VALUE_ATTR_NAME, startTime);
            writer.WriteEndElement();
            writer.WriteEndElement();

            writer.WriteStartElement(DIRECTIONS_LENGTH_UNITS_NODE_NAME);
            string lengthUnits;
            RegionInfo ri = new RegionInfo(System.Threading.Thread.CurrentThread.CurrentCulture.LCID);
            if (ri.IsMetric)
                lengthUnits = KILOMETERS;
            else
                lengthUnits = MILES;
            writer.WriteAttributeString(VALUE_ATTR_NAME, lengthUnits);
            writer.WriteEndElement();

            writer.WriteStartElement(DIRECTIONS_CONTENT_NODE_NAME);
            writer.WriteAttributeString(VALUE_ATTR_NAME, "all");
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
        private static void _SaveRouteAttributes(XmlWriter writer, Route route, IVrpSolver solver)
        {
            bool attributesContainsParams = false;
            Debug.Assert(solver.NetworkDescription != null);
            foreach (NetworkAttribute attribute in solver.NetworkDescription.NetworkAttributes)
            {
                foreach (NetworkAttributeParameter parameter in attribute.Parameters)
                {
                    attributesContainsParams = true;
                    break;
                }
                if (attributesContainsParams)
                    break;
            }

            if (attributesContainsParams)
            {
                SolverSettings solverSettings = solver.SolverSettings;

                writer.WriteStartElement(ATTRIBUTE_PARAMS_NODE_NAME);
                foreach (NetworkAttribute attribute in solver.NetworkDescription.NetworkAttributes)
                {
                    bool containsParams = false;
                    foreach (NetworkAttributeParameter parameter in attribute.Parameters)
                    {
                        containsParams = true;
                        break;
                    }

                    if (containsParams)
                    {
                        writer.WriteStartElement(ATTRIBUTE_NODE_NAME);
                        writer.WriteAttributeString(NAME_ATTR_NAME, attribute.Name);
                        foreach (NetworkAttributeParameter parameter in attribute.Parameters)
                        {
                            writer.WriteStartElement(PARAM_NODE_NAME);
                            writer.WriteAttributeString(NAME_ATTR_NAME, parameter.Name);

                            object valueObj = null;
                            if (!solverSettings.GetNetworkAttributeParameterValue(attribute.Name,
                                                                                  parameter.Name,
                                                                                  out valueObj))
                                valueObj = null;

                            string value = _ConvertValue2String(valueObj);

                            writer.WriteAttributeString(VALUE_ATTR_NAME, value);
                            writer.WriteEndElement();
                        }
                        writer.WriteEndElement();
                    }
                }
                writer.WriteEndElement();
            }
        }
        /// <summary>
        /// Export route to GRF file.
        /// </summary>
        /// <param name="writer">XMLWriter.</param>
        /// <param name="route">Route to export.</param>
        /// <param name="stops">Route's stops.</param>
        /// <param name="project">Project, which contains this route.</param>
        /// <param name="geocoder">Geocoder.</param>
        /// <param name="solver">Solver.</param>
        /// <param name="orderPropertiesToExport">Collection of order properties, which must be
        /// exported.</param>
        /// <param name="compress">Flag, shows compress result file or not.</param>
        /// <returns>GrfExportResult which contains messages about exporting.</returns>
        public static GrfExportResult ExportToGRF(XmlWriter writer, Route route, ICollection<Stop> stops, Project project,
            IGeocoder geocoder, IVrpSolver solver, ICollection<string> orderPropertiesToExport, bool compress)
        {
            GrfExportResult result = new GrfExportResult();

            writer.WriteStartElement(GRF_DOC_NODE_NAME);
            writer.WriteAttributeString(VERSION_ATTR_NAME, VERSION_VALUE);

            writer.WriteStartElement(ROUTEINFO_NODE_NAME);
            if (stops.Count > 0)
            {
                _SaveStops(
                    writer,
                    route,
                    stops,
                    orderPropertiesToExport,
                    project,
                    geocoder.AddressFields);
            }

            IDataObjectCollection<Barrier> barriers =
                (IDataObjectCollection<Barrier>)project.Barriers.Search(route.StartTime.Value.Date, true);
            _SaveBarriers(writer, barriers, result);
            _SaveRouteResults(writer, route, stops);
            writer.WriteEndElement();
            _SaveRouteSettings(writer, route, solver, result);
            writer.WriteEndElement();

            return result;
        }
        /// <summary>
        /// Export route to GRF file.
        /// </summary>
        /// <param name="filePath">Path to grf file.</param>
        /// <param name="route">Route to export.</param>
        /// <param name="project">Project, which contains this route.</param>
        /// <param name="geocoder">Geocoder.</param>
        /// <param name="solver">Solver.</param>
        /// <param name="orderPropertiesToExport">Collection of order properties, which must be
        /// exported.</param>
        /// <param name="compress">Flag, shows compress result file or not.</param>
        /// <returns>GrfExportResult which contains messages about exporting.</returns>
        public static GrfExportResult ExportToGRF(string filePath, Route route, Project project,
            IGeocoder geocoder, IVrpSolver solver, ICollection<string> orderPropertiesToExport, bool compress)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = CommonHelpers.XML_SETTINGS_INDENT_CHARS;

            using (XmlWriter writer = XmlWriter.Create(filePath, settings))
            {
                var result = ExportToGRF(writer, route, route.Stops, project, geocoder, solver, orderPropertiesToExport, compress);
                writer.Flush();
                return result;
            }
        }
        /// <summary>
        /// Method gets stop data collection from Order features collection.
        /// </summary>
        /// <param name="orderFeatures">Order features collection.</param>
        /// <param name="route">Route.</param>
        /// <returns>Collection of stop data.</returns>
        private List<StopData> _GetOrderStops(IEnumerable<GPFeature> orderFeatures, Route route)
        {
            var stops = new List<StopData>();

            foreach (GPFeature feature in orderFeatures)
            {
                // route id
                Guid id = _AttrToObjectId(NAAttribute.ROUTE_NAME, feature.Attributes);

                if (id == route.Id)
                    stops.Add(_CreateStopFromOrder(feature, route));
            }

            return stops;
        }
        /// <summary>
        /// Get fill color for cluster graphics. OrdersColor in case of only orders.
        /// Route color in case of unique route. GrayColor otherwise.
        /// </summary>
        /// <param name="cluster"></param>
        /// <returns></returns>
        private SolidColorBrush _GetFillColor(IList<Graphic> cluster)
        {
            ClusterSymbol clusterSymbol = (ClusterSymbol)Symbol;
            SolidColorBrush brush = (SolidColorBrush)clusterSymbol.ControlTemplate.Resources["GrayColor"];

            bool isOrders = true;
            bool isUniqueRoute = true;

            foreach (Graphic graphic in cluster)
            {
                DataGraphicObject dataGraphic = (DataGraphicObject)graphic;
                if (dataGraphic.Data is Order)
                    isUniqueRoute = false;
                else
                    isOrders = false;

                if (isUniqueRoute)
                {
                    Stop stop = (Stop)dataGraphic.Data;
                    DataGraphicObject firstDataGraphic = (DataGraphicObject)cluster[0];
                    Stop firstStop = (Stop)firstDataGraphic.Data;
                    isUniqueRoute = stop.Route == firstStop.Route;
                }
            }

            if (isOrders)
            {
                Debug.Assert(!isUniqueRoute);
                brush = (SolidColorBrush)clusterSymbol.ControlTemplate.Resources["OrdersColor"];
            }

            if( isUniqueRoute)
            {
                Debug.Assert(!isOrders);
                DataGraphicObject firstDataGraphic = (DataGraphicObject)cluster[0];
                Stop firstStop = (Stop)firstDataGraphic.Data;
                Route route = firstStop.Route;

                // stop will not assign to route in case of not updated schedule
                if (route != null)
                {
                    Color mediaColor = System.Windows.Media.Color.FromArgb(route.Color.A,
                        route.Color.R, route.Color.G, route.Color.B);
                    brush = new SolidColorBrush(mediaColor);

                    _route = route;
                    route.PropertyChanged += new PropertyChangedEventHandler(route_PropertyChanged);
                }
            }

            return brush;
        }
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Method gets stops collection from features collection.
        /// </summary>
        /// <param name="gpResult">GP Route result from server.</param>
        /// <param name="route">Route to get route info.</param>
        /// <param name="request">Vrp request.</param>
        /// <returns></returns>
        private List<StopData> _GetRouteStops(
            GPRouteResult gpResult,
            Route route,
            SubmitVrpJobRequest request)
        {
            Debug.Assert(gpResult != null);
            Debug.Assert(route != null);

            var stopsByType = gpResult.Stops.Features
                .ToLookup(feature => feature.Attributes.Get<NAStopType>(NAAttribute.StopType));

            var stops = new List<StopData>();

            // process orders
            stops.AddRange(_GetOrderStops(stopsByType[NAStopType.Order], route));

            // process breaks
            stops.AddRange(_GetBreakStops(stopsByType[NAStopType.Break], route));

            var renewals = request.Renewals == null ?
                Enumerable.Empty<GPFeature>() : request.Renewals.Features;

            // process depots
            stops.AddRange(_GetDepotStops(
                stopsByType[NAStopType.Depot],
                route,
                renewals));

            SolveHelper.SortBySequence(stops);
            if (!stops.Any())
            {
                return stops;
            }

            var isDepot = Functional.MakeLambda(
                (StopData stop) => stop.StopType == StopType.Location);

            var startingDepot = stops.FirstOrDefault(isDepot);
            if (startingDepot != null)
            {
                startingDepot.TimeAtStop = route.TimeAtStart;
            }

            var endingDepot = stops.LastOrDefault(isDepot);
            if (endingDepot != null)
            {
                endingDepot.TimeAtStop = route.TimeAtEnd;
            }

            return stops;
        }
        /// <summary>
        /// Method route result.
        /// </summary>
        /// <param name="feature">GP feature.</param>
        /// <param name="route">Route.</param>
        /// <param name="stops">Stop data collection.</param>
        /// <returns>Route result.</returns>
        private RouteResult _CreateRouteResult(GPFeature feature,
                                               Route route,
                                               IList<StopData> stops)
        {
            RouteResult result = new RouteResult();

            // cost
            result.Cost = feature.Attributes.Get<double>(NAAttribute.TOTAL_COST, 0.0);

            // start time
            result.StartTime = _TryGet(feature.Attributes, NAAttribute.START_TIME);

            // end time
            result.EndTime = _TryGet(feature.Attributes, NAAttribute.END_TIME);

            // total time
            result.TotalTime = feature.Attributes.Get<double>(NAAttribute.TOTAL_TIME, 0.0);

            // total distance
            result.TotalDistance = feature.Attributes.Get<double>(NAAttribute.TOTAL_DISTANCE, 0.0);

            // total travel time
            result.TravelTime = feature.Attributes.Get<double>(NAAttribute.TOTAL_TRAVEL_TIME, 0.0);

            // total violation time
            result.ViolationTime =
                feature.Attributes.Get<double>(NAAttribute.TOTAL_VIOLATION_TIME, 0.0);

            // total wait time
            result.WaitTime = feature.Attributes.Get<double>(NAAttribute.TOTAL_WAIT_TIME, 0.0);

            // overtime
            double overtime = result.TotalTime - route.Driver.TimeBeforeOT;
            if (overtime > 0)
                result.Overtime = overtime;

            // capacities
            result.Capacities = _CreateCapacities(stops);

            // path
            // currently we use directions to get route geometry

            // route
            result.Route = route;

            // set stops
            var resStops = new List<StopData>();

            // When a break(s) has preassigned sequence, it could present alone in output
            // stops collection, so in this case there will be no stops at all.
            // Checks in stop sequence present at least one order
            if (stops.Any(stop => stop.StopType == StopType.Order))
                resStops.AddRange(stops);

            result.Stops = resStops;

            return result;
        }
        /// <summary>
        /// Method returns true if route found in collection and false otherwise
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="route"></param>
        /// <returns></returns>
        private bool _IsRouteFound(IList<Route> collection, Route defaultRoute)
        {
            bool isFound = false;

            foreach (Route collectionRoute in collection)
            {
                if (collectionRoute.DefaultRouteID.Equals(defaultRoute.Id))
                    isFound = true;
            }
            return isFound;
        }
        /// <summary>
        /// Check that routes links are equal.
        /// </summary>
        /// <param name="Id">Previously saved route identificator.</param>
        /// <param name="newRoute">Corresponding route, which links will be checked on equality.</param>
        /// <returns>'True' if routes links are equal, 'false' otherwise.</returns>
        private bool RouteLinksAreEqual(Guid id, Route newRoute)
        {
            // Find RouteLink, corresponding to old route.
            var oldRouteLink = _oldDefaultRouteLinks.Find(x => x.savedRouteID == id);

            // It must exist.
            Debug.Assert(_oldDefaultRouteLinks != null);

            // Compare fields of structure and new route.
            return oldRouteLink.Vehicle == newRoute.Vehicle &&
                oldRouteLink.StartLocation == newRoute.StartLocation &&
                oldRouteLink.EndLocation == newRoute.EndLocation &&
                oldRouteLink.Driver == newRoute.Driver &&
                DataObjectCollectionsComparer<Zone>.AreEqual(oldRouteLink.Zones, newRoute.Zones) &&
                DataObjectCollectionsComparer<Location>.AreEqual
                    (oldRouteLink.RenewalLocations, newRoute.RenewalLocations);
        }
 public SentRouteConfig(Route route)
 {
     Route = route;
 }
 /// <summary>
 /// Remove route from inner collection and unsubscribe from route property changed.
 /// </summary>
 /// <param name="route">Route to remove.</param>
 private void _DeleteRouteFromInnerCollection(Route route)
 {
     if (_routes.Contains(route))
     {
         _routes.Remove(route);
         route.PropertyChanged -= new PropertyChangedEventHandler(_RoutePropertyChanged);
     }
     else
     {
         Debug.Assert(false);
     }
 }
        /// <summary>
        /// Method creates stop from break GP feature.
        /// </summary>
        /// <param name="feature">Break GP feature</param>
        /// <param name="route">Route.</param>
        /// <param name="routeBreak">Break from route.</param>
        /// <param name="stop">Stop data to fill.</param>
        /// <returns>True - if successfully created, otherwise - False.</returns>
        private bool _CreateStopFromBreak(GPFeature feature, Route route,
            Break routeBreak, out StopData stop)
        {
            Debug.Assert(feature != null);
            Debug.Assert(route != null);
            Debug.Assert(routeBreak != null);

            // Check sequence number.
            int sequenceNumber = 0;

            if (!feature.Attributes.TryGet<int>(NAAttribute.SEQUENCE, out sequenceNumber)
                // Sequence always starts from 1. Otherwise: this is empty break.
                || sequenceNumber == 0)
            {
                stop = null;
                return false;
            }

            stop = new StopData();
            stop.SequenceNumber = sequenceNumber;

            // Distance.
            stop.Distance = feature.Attributes.Get<double>(NAAttribute.FROM_PREV_DISTANCE);

            // Wait time.
            stop.WaitTime = feature.Attributes.Get<double>(NAAttribute.WAIT_TIME, 0.0);

            // Service time.
            stop.TimeAtStop = routeBreak.Duration;

            // Travel time.
            stop.TravelTime =
                feature.Attributes.Get<double>(NAAttribute.FROM_PREV_TRAVEL_TIME, 0.0);

            // Time Windows for break stop.
            var breakTimeWindow = _GetBreakTimeWindow(routeBreak);
            var plannedDate = route.Schedule.PlannedDate.Value;

            var timeWindow = breakTimeWindow.ToDateTime(plannedDate);
            stop.TimeWindowStart1 = timeWindow.Item1;
            stop.TimeWindowEnd1 = timeWindow.Item2;

            // Arrive time.
            var arriveTime = _TryGet(feature.Attributes, NAAttribute.ARRIVE_TIME);

            if (!arriveTime.HasValue)
            {
                arriveTime = stop.TimeWindowStart1;
            }

            arriveTime = arriveTime.AddMinutes(stop.WaitTime);

            stop.ArriveTime = arriveTime.Value;

            // Route id.
            stop.RouteId = _AttrToObjectId(NAAttribute.ROUTE_NAME, feature.Attributes);

            // Geometry:
            // There is no geometry for breaks.

            // Curb approach.
            stop.NACurbApproach = NACurbApproachType.esriNAEitherSideOfVehicle;

            // Stop type.
            stop.StopType = StopType.Lunch;

            // Break stop does not have an associated object.
            stop.AssociatedObject = null;

            return true;
        }
Beispiel #26
0
 /// <summary>
 /// Method clones all route properties except results.
 /// </summary>
 /// <returns>Clone of this object without build results.</returns>
 public object CloneNoResults()
 {
     Route obj = new Route(_capacitiesInfo);
     _CopyNoResults(obj);
     return obj;
 }
 /// <summary>
 /// Add route to inner collection and subscribe to route property changed.
 /// </summary>
 /// <param name="route">Route to add.</param>
 private void _AddRouteToInnerCollection(Route route)
 {
     _routes.Add(route);
     route.PropertyChanged += new PropertyChangedEventHandler(_RoutePropertyChanged);
 }
        /// <summary>
        /// Method creates stop from depot.
        /// </summary>
        /// <param name="depotVisitFeature">Depot GP feature.</param>
        /// <param name="route">Route.</param>
        /// <param name="renewalsByID">Renewals collection associated with its Id.</param>
        /// <returns>Stop data.</returns>
        private StopData _CreateStopFromDepot(
            GPFeature depotVisitFeature,
            Route route,
            IDictionary<Guid, GPFeature> renewalsByID)
        {
            Debug.Assert(depotVisitFeature != null);
            Debug.Assert(route != null);
            Debug.Assert(renewalsByID != null);

            StopData stop = new StopData();

            // Distance.
            stop.Distance = depotVisitFeature.Attributes.Get<double>(NAAttribute.FROM_PREV_DISTANCE);

            // Sequence number.
            stop.SequenceNumber = depotVisitFeature.Attributes.Get<int>(NAAttribute.SEQUENCE);

            // Wait time.
            stop.WaitTime = depotVisitFeature.Attributes.Get<double>(NAAttribute.WAIT_TIME, 0.0);

            // Travel time.
            stop.TravelTime =
                depotVisitFeature.Attributes.Get<double>(NAAttribute.FROM_PREV_TRAVEL_TIME, 0.0);

            // Arrive time.
            stop.ArriveTime = _Get(depotVisitFeature.Attributes, NAAttribute.ARRIVE_TIME);

            // Associated object.
            Guid assocObjectId =
                _AttrToObjectId(NAAttribute.NAME, depotVisitFeature.Attributes);

            Location loc = _GetRouteLocation(route, assocObjectId);
            if (loc == null)
            {
                string message = Properties.Messages.Error_InvalidGPFeatureMapping;
                throw new RouteException(message); // exception
            }

            stop.AssociatedObject = loc;

            var renewalFeature = default(GPFeature);
            if (renewalsByID.TryGetValue(assocObjectId, out renewalFeature))
            {
                stop.TimeAtStop = renewalFeature.Attributes.Get<double>(
                    NAAttribute.SERVICE_TIME,
                    0.0);
            }

            var plannedDate = route.Schedule.PlannedDate.Value;
            var timeWindow = loc.TimeWindow.ToDateTime(plannedDate);
            stop.TimeWindowStart1 = timeWindow.Item1;
            stop.TimeWindowEnd1 = timeWindow.Item2;

            // Curb approach.
            stop.NACurbApproach = CurbApproachConverter.ToNACurbApproach(
                _settings.GetDepotCurbApproach());

            // Route id.
            stop.RouteId = route.Id;

            // Geometry.
            if (loc.GeoLocation != null)
            {
                stop.Geometry = GPObjectHelper.PointToGPPoint(loc.GeoLocation.Value);
            }

            // Stop type.
            stop.StopType = StopType.Location;

            return stop;
        }
        /// <summary>
        /// Check routes, assigned to zone.
        /// </summary>
        private void _SetAssignedRoute()
        {
            _assignedRoute = null;
            _multiRoute = false;

            foreach (Route route in _schedule.Routes)
            {
                if (route.Zones.Contains(_zone))
                {
                    if (_assignedRoute == null)
                    {
                        _assignedRoute = route;
                    }
                    else
                    {
                        _multiRoute = true;
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Method creates stop from order GP feature.
        /// </summary>
        /// <param name="feature">Order GP feature</param>
        /// <param name="route">Route.</param>
        /// <returns>Stop data.</returns>
        private StopData _CreateStopFromOrder(GPFeature feature, Route route)
        {
            var stop = new StopData();

            // distance
            stop.Distance = feature.Attributes.Get<double>(NAAttribute.FROM_PREV_DISTANCE);

            // sequence number
            stop.SequenceNumber = feature.Attributes.Get<int>(NAAttribute.SEQUENCE);

            // wait time
            stop.WaitTime = feature.Attributes.Get<double>(NAAttribute.WAIT_TIME, 0.0);

            // service time
            stop.TimeAtStop = feature.Attributes.Get<double>(NAAttribute.SERVICE_TIME, 0.0);

            // travel time
            stop.TravelTime =
                feature.Attributes.Get<double>(NAAttribute.FROM_PREV_TRAVEL_TIME, 0.0);

            // arrive time
            var arriveTime = _Get(feature.Attributes, NAAttribute.ARRIVE_TIME);

            // set stop arrive time = real arrive time + wait time
            stop.ArriveTime = arriveTime.AddMinutes(stop.WaitTime);

            // TW1
            stop.TimeWindowStart1 = _TryGet(feature.Attributes, NAAttribute.TW_START1);
            stop.TimeWindowEnd1 = _TryGet(feature.Attributes, NAAttribute.TW_END1);

            // TW2
            stop.TimeWindowStart2 = _TryGet(feature.Attributes, NAAttribute.TW_START2);
            stop.TimeWindowEnd2 = _TryGet(feature.Attributes, NAAttribute.TW_END2);

            // curbapproach
            stop.NACurbApproach =
                (NACurbApproachType)feature.Attributes.Get<int>(NAAttribute.ArriveCurbApproach);

            // associated object
            Guid assocObjectId = _AttrToObjectId(NAAttribute.NAME, feature.Attributes);

            Order order = _project.Orders.SearchById(assocObjectId);
            if (order == null)
            {
                string message = Properties.Messages.Error_InvalidGPFeatureMapping;
                throw new RouteException(message); // exception
            }

            stop.AssociatedObject = order;

            stop.TimeAtStop = order.ServiceTime;

            var plannedDate = route.Schedule.PlannedDate.Value;
            var timeWindow = order.TimeWindow.ToDateTime(plannedDate);
            stop.TimeWindowStart1 = timeWindow.Item1;
            stop.TimeWindowEnd1 = timeWindow.Item2;

            timeWindow = order.TimeWindow2.ToDateTime(plannedDate);
            stop.TimeWindowStart2 = timeWindow.Item1;
            stop.TimeWindowEnd2 = timeWindow.Item2;

            // route id
            stop.RouteId = _AttrToObjectId(NAAttribute.ROUTE_NAME, feature.Attributes);

            // geometry
            if (order.GeoLocation != null)
            {
                stop.Geometry = GPObjectHelper.PointToGPPoint(order.GeoLocation.Value);
            }

            // stop type
            stop.StopType = StopType.Order;

            return stop;
        }