public async Task <IActionResult> RouteRequest(string startNode, string endNode, string routeType, TimeSpan startingTime) { try { // Get all student routes. AllStudentRoutes = await CongestionHelper.GenerateAllStudentRoutes(DissDatabaseContext, Pathfinder, MemoryCache, AppSettings.Accommodations); RouteRequestResponse response = new RouteRequestResponse(); // If start and end are the same, return empty response. if (startNode == endNode) { return(Ok(response)); } // Get a list of possible start and end nodes that fulfil this request. List <string> starts = await RoutingHelper.GetMatchingIds(DissDatabaseContext, startNode, routeType[0].ToString()); List <string> ends = await RoutingHelper.GetMatchingIds(DissDatabaseContext, endNode, routeType.Last().ToString()); // Check we have a start location. if (starts.Count == 0) { return(BadRequest("Could not find start points.")); } // Check we have an end location. if (ends.Count == 0) { return(BadRequest("Could not find end points")); } // Calculate all possible routes between all starts and all ends. // There is more than one start or end point - probably more efficient to calculate in parallel. if (starts.Count > 1 || ends.Count > 1) { ConcurrentBag <Route> possibleRoutes = new ConcurrentBag <Route>(); ConcurrentBag <Route> possibleAdjustedRoutes = new ConcurrentBag <Route>(); Parallel.ForEach(starts, startPoint => { Parallel.ForEach(ends, destination => { // Calculate route and add to possible. possibleRoutes.Add(Pathfinder.BuildAStar(startPoint, destination)); possibleAdjustedRoutes.Add(Pathfinder.BuildAStar(startPoint, destination, AllStudentRoutes, startingTime)); }); }); // Find the shortest route from the possible routes. response.NormalRoute = RoutingHelper.FindTheBestRouteFromPossibleRoutes(possibleRoutes.ToList()); response.AdjustedRoute = RoutingHelper.FindTheBestRouteFromPossibleRoutes(possibleAdjustedRoutes.ToList()); } else { // Only one start and end point - only need to do this once, so avoid parallel overheads. response.NormalRoute = Pathfinder.BuildAStar(starts[0], ends[0]); response.AdjustedRoute = Pathfinder.BuildAStar(starts[0], ends[0], AllStudentRoutes, startingTime); } // Adjust walking times based on congestion values. response.NormalRoute.CalculateAdjustedWalkingTime(AllStudentRoutes, startingTime); response.AdjustedRoute.CalculateAdjustedWalkingTime(AllStudentRoutes, startingTime); if (response.AdjustedRoute.WalkingTimeSeconds == response.NormalRoute.WalkingTimeSeconds) { // Both routes are the same, remove the adjusted route - there was likely no congestion. response.AdjustedRoute = new Route(); } return(Ok(response)); } catch (Exception exception) { return(StatusCode(500, exception.Message)); } }