///////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////
 protected override void SetOrderAssignment(AttrDictionary attrs,
     AssignedOrder assignedOrder)
 {
     if (assignedOrder.Route.IsLocked)
     {
         // order is assigned to a locked route
         attrs.Set(NAAttribute.ASSIGNMENT_RULE,
             (int)NAOrderAssignmentRule.esriNAOrderExcludeFromSolve);
     }
     else if (assignedOrder.Stop.IsLocked)
     {
         // order is locked itself
         attrs.Set(NAAttribute.ROUTE_NAME, assignedOrder.Route.Id.ToString());
         attrs.Set(NAAttribute.SEQUENCE, assignedOrder.SequenceNumber);
         attrs.Set(NAAttribute.ASSIGNMENT_RULE,
             (int)NAOrderAssignmentRule.esriNAOrderPreserveRouteAndRelativeSequence);
     }
     else
     {
         attrs.Set(NAAttribute.ROUTE_NAME, "");
         attrs.Set(NAAttribute.SEQUENCE, null);
         attrs.Set(NAAttribute.ASSIGNMENT_RULE,
             (int)NAOrderAssignmentRule.esriNAOrderOverride);
     }
 }
Beispiel #2
0
        /// <summary>
        /// Converts the specified attributes dictionary into a collection of name/value pairs.
        /// </summary>
        /// <param name="properties">The reference to the attributes dictionary object to be
        /// converted.</param>
        /// <returns>A reference to the collection of name/value pairs for all dictionary
        /// items.</returns>
        private static IEnumerable <NameValuePair> _ToCollection(AttrDictionary properties)
        {
            Debug.Assert(properties != null);

            return(properties
                   .Select(item => new NameValuePair
            {
                Name = item.Key,
                Value = item.Value.ToString(),
            })
                   .ToArray());
        }
 ///////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////
 protected override void SetOrderAssignment(AttrDictionary attrs,
     AssignedOrder assignedOrder)
 {
     if (assignedOrder.Route.IsLocked ||
         assignedOrder.Stop.IsLocked)
     {
         attrs.Set(NAAttribute.ROUTE_NAME, assignedOrder.Route.Id.ToString());
         attrs.Set(NAAttribute.SEQUENCE, assignedOrder.SequenceNumber);
         attrs.Set(NAAttribute.ASSIGNMENT_RULE,
             (int)NAOrderAssignmentRule.esriNAOrderPreserveRouteAndRelativeSequence);
     }
     else
     {
         attrs.Set(NAAttribute.ROUTE_NAME, assignedOrder.Route.Id.ToString());
         attrs.Set(NAAttribute.SEQUENCE, assignedOrder.SequenceNumber);
         attrs.Set(NAAttribute.ASSIGNMENT_RULE,
             (int)NAOrderAssignmentRule.esriNAOrderPreserveRoute);
     }
 }
        /// <summary>
        /// Tries to get <see cref="T:System.DateTime"/> value from the attribute
        /// dictionary for the specified key.
        /// </summary>
        /// <param name="dictionary">The reference to the attribute dictionary
        /// to get value from.</param>
        /// <param name="key">The key to get value for.</param>
        /// <returns><see cref="T:System.DateTime"/> value for the specified
        /// key or null if there is no value for the key.</returns>
        private DateTime? _TryGet(AttrDictionary dictionary, string key)
        {
            Debug.Assert(dictionary != null);
            Debug.Assert(key != null);

            var dateTime = dictionary.TryGet<DateTime>(key);
            if (dateTime.HasValue)
            {
                return dateTime;
            }

            // assume it's either ArcgGIS 10.0 server returning milliseconds or
            // there is no any value for this key.
            var milliseconds = dictionary.TryGet<long>(key);
            var ticks = milliseconds * TICKS_IN_MILLISECOND;

            return ticks.Select(value => START_DATE.AddTicks(value));
        }
        /// <summary>
        /// Gets <see cref="T:System.DateTime"/> value from the attribute
        /// dictionary for the specified key.
        /// </summary>
        /// <param name="dictionary">The reference to the attribute dictionary
        /// to get value from.</param>
        /// <param name="key">The key to get value for.</param>
        /// <returns>see cref="T:System.DateTime"/> value for the specified
        /// key.</returns>
        /// <exception cref="ESRI.ArcLogistics.Routing.RouteException">There
        /// is no value for the specified key in the dictionary.</exception>
        private DateTime _Get(AttrDictionary dictionary, string key)
        {
            Debug.Assert(dictionary != null);
            Debug.Assert(key != null);

            var result = _TryGet(dictionary, key);
            if (!result.HasValue)
            {
                string message = Properties.Messages.Error_GetAttributeByKeyFailed;
                throw new RouteException(message); // exception
            }

            return result.Value;
        }
Beispiel #6
0
        /// <summary>
        /// Converts the specified attributes dictionary into a collection of name/value pairs.
        /// </summary>
        /// <param name="properties">The reference to the attributes dictionary object to be
        /// converted.</param>
        /// <returns>A reference to the collection of name/value pairs for all dictionary
        /// items.</returns>
        private static IEnumerable<NameValuePair> _ToCollection(AttrDictionary properties)
        {
            Debug.Assert(properties != null);

            return properties
                .Select(item => new NameValuePair
                {
                    Name = item.Key,
                    Value = item.Value.ToString(),
                })
                .ToArray();
        }
        /// <summary>
        /// Method converts order into GPFeature.
        /// </summary>
        /// <param name="unassignedOrder">Unassigned order to convert.</param>
        /// <param name="assignedOrder">Assigned order to convert.</param>
        /// <returns>Orders GPFeature.</returns>
        /// <exception cref="RouteException">If unassigned order is not geocoded.</exception>
        private GPFeature _ConvertOrder(Order unassignedOrder, AssignedOrder assignedOrder)
        {
            Debug.Assert(unassignedOrder != null);

            GPFeature feature = new GPFeature();

            // Geometry.
            IGeocodable gc = unassignedOrder as IGeocodable;
            Debug.Assert(gc != null);

            if (!gc.IsGeocoded)
            {
                throw new RouteException(String.Format(
                    Properties.Messages.Error_OrderIsUngeocoded, unassignedOrder.Id));
            }

            Debug.Assert(gc.GeoLocation != null);
            feature.Geometry = new GeometryHolder();
            feature.Geometry.Value = GPObjectHelper.PointToGPPoint((Point)gc.GeoLocation);

            // Attributes.
            AttrDictionary attrs = new AttrDictionary();

            // Name.
            attrs.Add(NAAttribute.NAME, unassignedOrder.Id.ToString());

            // Curb approach.
            attrs.Add(NAAttribute.CURB_APPROACH,
                (int)CurbApproachConverter.ToNACurbApproach(
                _context.SolverSettings.GetOrderCurbApproach()));

            // Service time.
            attrs.Add(NAAttribute.SERVICE_TIME, unassignedOrder.ServiceTime);

            // Time windows.
            TimeWindow timeWindow1 = unassignedOrder.TimeWindow;
            TimeWindow timeWindow2 = unassignedOrder.TimeWindow2;

            _SetTimeWindowsAttributes(attrs, ref timeWindow1, ref timeWindow2);

            // Max Violation Time 1.
            attrs.Add(NAAttribute.MAX_VIOLATION_TIME1,
                timeWindow1.IsWideOpen ? (double?)null : unassignedOrder.MaxViolationTime);

            // Max Violation Time 2.
            attrs.Add(NAAttribute.MAX_VIOLATION_TIME2,
                timeWindow2.IsWideOpen ? (double?)null : unassignedOrder.MaxViolationTime);

            // PickUp or DropOff quantities.
            string capacities = _FormatCapacities(unassignedOrder.Capacities);

            if (unassignedOrder.Type == OrderType.Delivery)
            {
                attrs.Add(NAAttribute.DELIVERY, capacities);
                attrs.Add(NAAttribute.PICKUP, null);
            }
            else
            {
                attrs.Add(NAAttribute.PICKUP, capacities);
                attrs.Add(NAAttribute.DELIVERY, null);
            }

            // Revenue.
            attrs.Add(NAAttribute.REVENUE,
                unassignedOrder.Priority == OrderPriority.Normal ? 0 : (long)_orderRevenue);

            // Specialties.
            List<Guid> specIds = GetOrderSpecIds(unassignedOrder);
            if (specIds.Count > 0)
                attrs.Add(NAAttribute.SPECIALTY_NAMES, _FormatSpecList(specIds));

            if (assignedOrder != null)
                SetOrderAssignment(attrs, assignedOrder);
            else
                SetOrderAssignment(attrs, unassignedOrder);

            // Status.
            attrs.Add(NAAttribute.STATUS, (int)NAObjectStatus.esriNAObjectStatusOK);

            feature.Attributes = attrs;

            return feature;
        }
        /// <summary>
        /// Gets properties dictionary for the specified stop built of the specified order property
        /// info objects.
        /// </summary>
        /// <param name="stop">The reference to the stop object to get properties for.</param>
        /// <param name="orderPropertiesToExport">The reference to the collection
        /// of custom order properties to be exported.</param>
        /// <returns>A dictionary with properties for an order associated with the specified
        /// stop.</returns>
        private static AttrDictionary _GetOrderProperties(
            Stop stop,
            IEnumerable<OrderPropertyInfo> orderPropertiesToExport)
        {
            Debug.Assert(stop != null);
            Debug.Assert(orderPropertiesToExport != null);
            Debug.Assert(orderPropertiesToExport.All(info => info != null));

            var properties = new AttrDictionary();
            var order = stop.AssociatedObject as Order;
            if (order == null)
            {
                return properties;
            }

            object value = null;

            foreach (var info in orderPropertiesToExport)
            {
                if (info.Name == Order.PropertyNamePlannedDate)
                    value = stop.ArriveTime;
                else
                    value = Order.GetPropertyValue(order, info.Name);

                if (value != null && value.ToString().Length > 0)
                {
                    properties.Add(info.Title, value);
                }
            }

            return properties;
        }
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Method set assigned order attributes.
        /// </summary>
        /// <param name="attrs">Attributes to set.</param>
        /// <param name="assignedOrder">Assigned order to get attribute values.</param>
        protected virtual void SetOrderAssignment(AttrDictionary attrs, AssignedOrder assignedOrder)
        {
            Debug.Assert(attrs != null);

            // Route name.
            attrs.Set(NAAttribute.ROUTE_NAME, assignedOrder.Route.Id.ToString());
            // Sequence.
            attrs.Set(NAAttribute.SEQUENCE, assignedOrder.SequenceNumber);
            // Assignment rule.
            attrs.Set(NAAttribute.ASSIGNMENT_RULE,
                (int)NAOrderAssignmentRule.esriNAOrderPreserveRouteAndRelativeSequence);
        }
        /// <summary>
        /// Method set attributes for both time windows.
        /// </summary>
        /// <param name="attributes">Attributes.</param>
        /// <param name="timeWindow1">Time window 1.</param>
        /// <param name="timeWindow2">Time window 2.</param>
        private void _SetTimeWindowsAttributes(AttrDictionary attributes,
            ref TimeWindow timeWindow1, ref TimeWindow timeWindow2)
        {
            Debug.Assert(attributes != null);
            Debug.Assert(timeWindow1 != null);
            Debug.Assert(timeWindow2 != null);

            // Swap time windows in case first is Wideopen but second isn't.
            if (timeWindow1.IsWideOpen && !timeWindow2.IsWideOpen)
            {
                var temp = timeWindow1;
                timeWindow1 = timeWindow2;
                timeWindow2 = temp;
            }

            // Time window 1.
            _SetTimeWindowAttribute(timeWindow1, NAAttribute.TW_START1, NAAttribute.TW_END1,
                attributes);

            // Time window 2.
            _SetTimeWindowAttribute(timeWindow2, NAAttribute.TW_START2, NAAttribute.TW_END2,
                attributes);
        }
 /// <summary>
 /// Method fills TimeWindow attributes in correct format.
 /// </summary>
 /// <param name="timeWindow">TimeWindow value.</param>
 /// <param name="attrNameStart">Format string for Start TimeWindow.</param>
 /// <param name="attrNameEnd">Format string for End TimeWindow</param>
 /// <param name="attributes">Attributes to fill in.</param>
 private void _SetTimeWindowAttribute(TimeWindow timeWindow,
     string attrNameStart,
     string attrNameEnd,
     AttrDictionary attributes)
 {
     attributes.SetTimeWindow(timeWindow, _plannedDate, attrNameStart, attrNameEnd);
 }
        /// <summary>
        /// Method converts route into GPFeature.
        /// </summary>
        /// <param name="route">Route.</param>
        /// <returns>Routes GPFeature.</returns>
        /// <exception cref="RouteException">If Fuel Economy in routes is 0.0.</exception>
        private GPFeature _ConvertRoute(Route route)
        {
            Debug.Assert(route != null);

            // Attributes.
            AttrDictionary attrs = new AttrDictionary();

            // Name.
            attrs.Add(NAAttribute.NAME, route.Id.ToString());

            // Start depot.
            attrs.Add(NAAttribute.START_DEPOT_NAME,
                route.StartLocation == null ? null : route.StartLocation.Id.ToString());

            // End depot.
            attrs.Add(NAAttribute.END_DEPOT_NAME,
                route.EndLocation == null ? null : route.EndLocation.Id.ToString());

            // Depot service times.
            attrs.Add(NAAttribute.START_DEPOT_SERVICE_TIME,
                route.StartLocation == null ? null : (object)route.TimeAtStart);
            attrs.Add(NAAttribute.END_DEPOT_SERVICE_TIME,
                route.EndLocation == null ? null : (object)route.TimeAtEnd);

            // Grace period.
            _SetTimeWindowAttribute(route.StartTimeWindow,
                NAAttribute.EARLIEST_START_TIME,
                NAAttribute.LATEST_START_TIME,
                attrs);

            // Capacities.
            attrs.Add(NAAttribute.CAPACITIES,
                _FormatCapacities(route.Vehicle.Capacities));

            // Costs.
            attrs.Add(NAAttribute.FIXED_COST, route.Driver.FixedCost + route.Vehicle.FixedCost);
            attrs.Add(NAAttribute.COST_PER_UNIT_TIME, route.Driver.PerHourSalary / 60);
            attrs.Add(NAAttribute.COST_PER_UNIT_OVERTIME, route.Driver.PerHourOTSalary / 60);
            attrs.Add(NAAttribute.OVERTIME_START_TIME, route.Driver.TimeBeforeOT);

            if (route.Vehicle.FuelEconomy == 0.0)
                throw new RouteException(Properties.Messages.Error_InvalidFuelConsumptionValue);

            attrs.Add(NAAttribute.COST_PER_UNIT_DISTANCE,
                route.Vehicle.FuelType.Price / route.Vehicle.FuelEconomy);

            // Order constraints.
            attrs.Add(NAAttribute.MAX_ORDERS, route.MaxOrders);

            // Max drive duration.
            attrs.Add(NAAttribute.MAX_TOTAL_TRAVEL_TIME,
                route.MaxTravelDuration == 0.0 ? null : (object)route.MaxTravelDuration);

            // Max total duration.
            attrs.Add(NAAttribute.MAX_TOTAL_TIME,
                route.MaxTotalDuration == 0.0 ? null : (object)route.MaxTotalDuration);

            // Max drive distance.
            attrs.Add(NAAttribute.MAX_TOTAL_DISTANCE,
                route.MaxTravelDistance == 0.0 ? null : (object)route.MaxTravelDistance);

            // Arrive and depart delay.
            attrs.Add(NAAttribute.ARRIVE_DEPART_DELAY,
                _context.SolverSettings.ArriveDepartDelay);

            // Specialties.
            List<Guid> specIds = GetRouteSpecIds(route);
            if (specIds.Count > 0)
                attrs.Add(NAAttribute.SPECIALTY_NAMES, _FormatSpecList(specIds));

            // assignment rule.
            attrs.Add(NAAttribute.ASSIGNMENT_RULE,
                (int)NARouteAssignmentRule.esriNARouteIncludeInSolve);

            // TODO: dynamic point zones.

            GPFeature feature = new GPFeature();
            feature.Attributes = attrs;

            return feature;
        }
        /// <summary>
        /// Method converts renewal location from route into GPFeature.
        /// </summary>
        /// <param name="loc">Location to convert.</param>
        /// <param name="route">Route on which location assigned.</param>
        /// <returns>Renewals GPFeature.</returns>
        private GPFeature _ConvertRenewal(Location loc, Route route)
        {
            Debug.Assert(loc != null);
            Debug.Assert(route != null);

            GPFeature feature = new GPFeature();

            // Attributes.
            AttrDictionary attrs = new AttrDictionary();

            // Route name.
            attrs.Add(NAAttribute.ROUTE_NAME, route.Id.ToString());
            // Depot name.
            attrs.Add(NAAttribute.DEPOT_NAME, loc.Id.ToString());
            // Service time.
            attrs.Add(NAAttribute.SERVICE_TIME, route.TimeAtRenewal);

            // Sequences: currently sequences are not used.

            feature.Attributes = attrs;

            return feature;
        }
        /// <summary>
        /// Method converts pickup and delivery orders into GPFeature.
        /// </summary>
        /// <param name="pickupOrder">Order.</param>
        /// <param name="deliveryOrder">Order.</param>
        /// <returns>OrderPair GPFeature.</returns>
        private GPFeature _ConvertOrderPair(Order pickupOrder, Order deliveryOrder)
        {
            Debug.Assert(pickupOrder != null && deliveryOrder != null);

            GPFeature feature = new GPFeature();

            // Attributes.
            AttrDictionary attrs = new AttrDictionary();

            // Pickup Name.
            attrs.Add(NAAttribute.FIRST_ORDER_NAME, pickupOrder.Id.ToString());

            // Delivery Name.
            attrs.Add(NAAttribute.SECOND_ORDER_NAME, deliveryOrder.Id.ToString());

            // not using MaxTransitTime

            feature.Attributes = attrs;

            return feature;
        }
        /// <summary>
        /// Method gets object Id for attribute by its name.
        /// </summary>
        /// <param name="attrName">Attribute name.</param>
        /// <param name="attrs">Collection of attributes.</param>
        /// <returns>Object id.</returns>
        private static Guid _AttrToObjectId(string attrName, AttrDictionary attrs)
        {
            Debug.Assert(attrName != null);
            Debug.Assert(attrs != null);

            return _StringToObjectId(attrs.Get<string>(attrName));
        }
        /// <summary>
        /// Gets comments for the specified stop built of the specified custom order properties.
        /// </summary>
        /// <param name="stop">The reference to the stop object to get comments for.</param>
        /// <param name="orderPropertiesToExport">The reference to the collection
        /// of custom order properties to be exported.</param>
        /// <returns>A string with comments for the specified stop or empty string if
        /// stop is not associated with an order.</returns>
        private static string _GetOrderComments(AttrDictionary commentsProperties)
        {
            Debug.Assert(commentsProperties != null);

            StringBuilder comments = new StringBuilder();
            foreach (var item in commentsProperties)
            {
                var value = item.Value;
                if (value != null && !string.IsNullOrEmpty(value.ToString()))
                {
                    comments.AppendLine(string.Format("{0}: {1}", item.Key, value));
                }
            }

            return comments.ToString();
        }
        /// <summary>
        /// Method set unassigned order attributes.
        /// </summary>
        /// <param name="attrs">Attributes to set.</param>
        /// <param name="unassignedOrder">Unassigned order to get attribute values.</param>
        protected virtual void SetOrderAssignment(AttrDictionary attrs, Order unassignedOrder)
        {
            Debug.Assert(attrs != null);

            // Route name.
            attrs.Set(NAAttribute.ROUTE_NAME, "");
            // Sequence.
            attrs.Set(NAAttribute.SEQUENCE, null);
            // Assignment rule.
            attrs.Set(NAAttribute.ASSIGNMENT_RULE,
                (int)NAOrderAssignmentRule.esriNAOrderOverride);
        }
 ///////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////
 protected override void SetOrderAssignment(AttrDictionary attrs,
     AssignedOrder assignedOrder)
 {
     if (!_unlockedOrdersToAssign.Contains(assignedOrder.Order))
     {
         attrs.Set(NAAttribute.ROUTE_NAME, assignedOrder.Route.Id.ToString());
         attrs.Set(NAAttribute.SEQUENCE, assignedOrder.SequenceNumber);
         attrs.Set(NAAttribute.ASSIGNMENT_RULE,
             (int)NAOrderAssignmentRule.esriNAOrderPreserveRouteAndRelativeSequence);
     }
     else
     {
         attrs.Set(NAAttribute.ROUTE_NAME, "");
         attrs.Set(NAAttribute.SEQUENCE, null);
         attrs.Set(NAAttribute.ASSIGNMENT_RULE,
             (int)NAOrderAssignmentRule.esriNAOrderOverride);
     }
 }
        /// <summary>
        /// Method converts location into GPFeature.
        /// </summary>
        /// <param name="loc">Location to convert.</param>
        /// <returns>Locations GPFeature.</returns>
        /// <exception cref="RouteException">If location is not geocoded.</exception>
        private GPFeature _ConvertDepot(Location loc)
        {
            Debug.Assert(loc != null);

            GPFeature feature = new GPFeature();

            // Geometry.
            feature.Geometry = new GeometryHolder();
            feature.Geometry.Value = GPObjectHelper.PointToGPPoint(_GetLocationPoint(loc));

            // Attributes.
            AttrDictionary attrs = new AttrDictionary();

            // Name.
            attrs.Add(NAAttribute.NAME, loc.Id.ToString());

            // Curb approach.
            attrs.Add(NAAttribute.CURB_APPROACH,
                (int)CurbApproachConverter.ToNACurbApproach(
                _context.SolverSettings.GetDepotCurbApproach()));

            // Set Time Windows attributes.
            TimeWindow timeWindow1 = loc.TimeWindow;
            TimeWindow timeWindow2 = loc.TimeWindow2;

            _SetTimeWindowsAttributes(attrs, ref timeWindow1, ref timeWindow2);

            feature.Attributes = attrs;

            return feature;
        }