/// <summary>
        /// Method searches Depot GP feature by its ID in GP record set layer.
        /// </summary>
        /// <param name="depots">Depots GP record set layer.</param>
        /// <param name="id">Depot id to find.</param>
        /// <returns>Depot GP feature.</returns>
        private GPFeature _FindDepotById(GPFeatureRecordSetLayer depots, Guid id)
        {
            GPFeature res = null;
            foreach (GPFeature feature in depots.Features)
            {
                Guid locId = _AttrToObjectId(NAAttribute.NAME, feature.Attributes);

                if (locId == id)
                {
                    res = feature;
                    break;
                }
            }

            return res;
        }
        public IList<Violation> GetRouteViolations(GPFeatureRecordSetLayer layer, int solveHR)
        {
            Debug.Assert(layer != null);

            var violations = new List<Violation>();
            foreach (GPFeature feature in layer.Features)
            {
                int vc;
                if (_GetViolatedConstraint(feature, out vc))
                {
                    // route id
                    Guid routeId = _AttrToObjectId(NAAttribute.NAME, feature.Attributes);

                    // find route
                    Route route = DataObjectHelper.FindObjectById<Route>(routeId, _schedule.Routes);
                    if (route == null)
                    {
                        string message = Properties.Messages.Error_InvalidGPFeatureMapping;
                        throw new RouteException(message); // exception
                    }

                    // create violation objects
                    violations.AddRange(_CreateViolations(vc, solveHR, route, ROUTE_VC));
                }
            }

            return violations;
        }
        /// <summary>
        /// Method converts depots into GPFeatureRecordSetLayer.
        /// </summary>
        /// <returns>Depots GPFeatureRecordSetLayer.</returns>
        /// <exception cref="RouteException">If location is not geocoded.</exception>
        private GPFeatureRecordSetLayer _ConvertDepots()
        {
            GPFeatureRecordSetLayer layer = new GPFeatureRecordSetLayer();
            layer.GeometryType = NAGeometryType.esriGeometryPoint;
            layer.SpatialReference = solverSR;

            List<GPFeature> features = new List<GPFeature>();
            foreach (Location loc in _depotsAll)
                features.Add(_ConvertDepot(loc));

            layer.Features = features.ToArray();

            return layer;
        }
 /// <summary>
 /// Initializes a new instance of the ZoneInfo class.
 /// </summary>
 /// <param name="useSpatialClustering">The value indicating if spatial clustering
 /// should be used.</param>
 /// <param name="zones">The reference to route zones.</param>
 private ZoneInfo(bool useSpatialClustering, GPFeatureRecordSetLayer zones)
 {
     this.UseSpatialClustering = useSpatialClustering;
     this.Zones = zones;
 }
 /// <summary>
 /// Initializes a new instance of the ZoneInfo class.
 /// </summary>
 /// <param name="zones">The reference to route zones.</param>
 public ZoneInfo(GPFeatureRecordSetLayer zones)
     : this(false, zones)
 {
 }
        /// <summary>
        /// Method converts zones from routes collection into GPFeatureRecordSetLayer.
        /// </summary>
        /// <param name="routes">Routes collection to get zones.</param>
        /// <returns>Zones information object with route zones settings.</returns>
        private ZoneInfo _ConvertZones(ICollection<Route> routes)
        {
            RouteZoneType type = _GetRoutesZonesType(routes);
            if (type == RouteZoneType.None && _context.SolverSettings.UseDynamicPoints)
            {
                return new ZoneInfo(useSpatialClustering: true);
            }

            List<GPFeature> zoneFeatures = new List<GPFeature>();
            List<GPFeature> seedPointFeatures = new List<GPFeature>();

            foreach (Route route in routes)
            {
                _ConvertRouteZones(route, type, zoneFeatures,
                    seedPointFeatures);
            }

            // We should have either route zones or seed points, but not both.
            Debug.Assert(zoneFeatures.Count == 0 || seedPointFeatures.Count == 0);

            var zones = default(GPFeatureRecordSetLayer);
            if (zoneFeatures.Count > 0)
            {
                zones = new GPFeatureRecordSetLayer
                {
                    SpatialReference = solverSR,
                    Features = zoneFeatures.ToArray(),
                    GeometryType = type == RouteZoneType.Point ?
                        NAGeometryType.esriGeometryPoint : NAGeometryType.esriGeometryPolygon,
                };
            }
            else if (seedPointFeatures.Count > 0)
            {
                zones = new GPFeatureRecordSetLayer
                {
                    GeometryType = NAGeometryType.esriGeometryPoint,
                    SpatialReference = solverSR,
                    Features = seedPointFeatures.ToArray(),
                };
            }

            return new ZoneInfo(zones);
        }
        /// <summary>
        /// Method converts orders collection into GPFeatureRecordSetLayer.
        /// </summary>
        /// <param name="orders">Orders collection to convert.</param>
        /// <param name="routes">Routes to determine which orders are assigned.</param>
        /// <param name="convertUnassigned">Is need to convert unassigned orders.</param>
        /// <returns>Orders GPFeatureRecordSetLayer.</returns>
        /// <exception cref="RouteException">If unassigned order is not geocoded.</exception>
        private GPFeatureRecordSetLayer _ConvertOrders(ICollection<Order> orders,
            ICollection<Route> routes, bool convertUnassigned)
        {
            Debug.Assert(orders != null);

            GPFeatureRecordSetLayer layer = new GPFeatureRecordSetLayer();
            layer.GeometryType = NAGeometryType.esriGeometryPoint;
            layer.SpatialReference = solverSR;

            List<AssignedOrder> assignedOrders = _GetAssignedOrders(
                routes);

            List<GPFeature> features = new List<GPFeature>();
            foreach (Order order in orders)
            {
                GPFeature feature = null;

                AssignedOrder assignedOrder = null;
                if (_FindAssignedOrder(order, assignedOrders,
                    out assignedOrder))
                {
                    // Convert assigned order.
                    feature = _ConvertOrder(order, assignedOrder);
                }
                else if (convertUnassigned)
                {
                    // Convert unassigned order.
                    feature = _ConvertOrder(order, null);
                }

                if (feature != null)
                    features.Add(feature);
            }

            layer.Features = features.ToArray();

            return layer;
        }