/// <summary> /// /// </summary> /// <param name="locations"></param> /// <param name="vehicle"></param> /// <param name="optimize"></param> /// <param name="calcPoints"></param> /// <param name="pointsEncoded"></param> /// <returns></returns> public Tuple <List <Activity>, List <RoutePoint> > Calculate(List <Location> locations , Vehicle vehicle , bool optimize = false , bool calcPoints = true , bool pointsEncoded = true) { var traceMsg = new List <string>(); try { if (optimize) { traceMsg.Add(string.Format("Calculate:", "OPTIMIZE")); // remove origin and final points as we only // need to optimize the job sites in between. locations.RemoveAt(0); locations.RemoveAt(locations.Count - 1); var response = CalculateRouteOptimize(locations , vehicle , pointsEncoded , calcPoints); var route = (((response ?? throw new InvalidOperationException("Response is null. No route solution returned."))?.Solution ?? throw new InvalidOperationException("No route solution returned.")).Routes ?? throw new InvalidOperationException("No route solution returned.")).FirstOrDefault() ?? throw new InvalidOperationException("No route solution returned."); var wpCoords = route.Points; return(new Tuple <List <Activity>, List <RoutePoint> >(route.Activities, wpCoords)); } else { traceMsg.Add(string.Format("Calculate:", "NON-OPTIMIZE")); Exception ex = null; RouteResponse response = null; RetryCodeKit.LoopAction(() => { traceMsg.Add(string.Format("Calculate:", "BEFORE_CalculateRoute")); response = CalculateRoute(locations , vehicle: vehicle.VehicleType.Profile?.ToString() ?? "car" , pointsEncoded: pointsEncoded , calcPoints: calcPoints , details: "time"); traceMsg.Add(string.Format("Calculate:", "AFTER_CalculateRoute")); return(response != null); }, ref ex, true, 10, 5000); if (response == null) { throw new Exception("GHRouteNonOptim> For some reason GH fails to cater to route request.", ex); } else if (ex != null) { throw ex; } else { try { traceMsg.Add(string.Format("Calculate:", "BEFORE_GettingRouteData")); var actvAndWpCoords = CalculateActivitiesAndWpCoords(response.Paths[0], locations); var activities = actvAndWpCoords.Item1.ToList(); var routePoints = actvAndWpCoords.Item2; //rtngResponse.Paths[0].Points.ToRoutePoints(); return(new Tuple <List <Activity>, List <RoutePoint> >(activities, routePoints)); } catch (Exception e) { Console.WriteLine(e); throw; } } } } catch (Exception exception) { //var xMsg = "Exception when calling SolutionApi.GetSolution: " + exception.Message; //var auditDat = new //{ // /* // List<Location> locations // , Vehicle vehicle // , bool optimize = false // , bool calcPoints = true // , bool pointsEncoded = true // */ //}; //var ghCalcEx = new GHCalculationException(xMsg, exception, auditDat); //throw ghCalcEx; exception.Data.Add("Trace", traceMsg); throw new Exception("Exception when calling SolutionApi.GetSolution", exception); } }
/// <summary> /// /// </summary> /// <param name="locations"></param> /// <param name="vehicle"></param> /// <param name="pointsEncoded"></param> /// <param name="calcPoints"></param> /// <returns></returns> private Response CalculateRouteOptimize(List <Location> locations , Vehicle vehicle , bool pointsEncoded = true , bool calcPoints = true) { // comnpose the body for the request var clientServices = new List <Service>(); try { locations.ForEach(loc => { var address = new Address(loc.LocationId, $"servicing-{loc.LocationId}", loc.Lon, loc.Lat); var srvc = new Service(Id: address.LocationId, Name: address.Name, Type: loc.ServiceType, Address: address); clientServices.Add(srvc); }); var routingCfg = new Model.Configuration() { Routing = new Routing(calcPoints: calcPoints, considerTraffic: true, networkDataProvider: Routing.NetworkDataProviderEnum.Openstreetmap) }; var body = new Request(Vehicles: new List <Vehicle>() { vehicle }, VehicleTypes: new List <VehicleType>() { vehicle.VehicleType }, Configuration: routingCfg, Services: clientServices); // Request | Request object that contains the problem to be solved var jobId = _vrpApiInstance.PostVrp(_apiKey, body); // Return the solution associated to the jobId Exception ex = null; Response response = null; RetryCodeKit.LoopAction(() => { response = _slnApiInstance.GetSolution(_apiKey, jobId._JobId); return(response?.Status != null && response.Solution?.Routes != null && response.Solution.Routes.Any() && (response != null && response?.Status.Value != Response.StatusEnum.Finished)); }, ref ex, true, 10, 5000); if (ex != null) { throw ex; } return(response); } catch (Exception ex) { throw; } }