public TaxiInstructions GetTaxiInstructions(Point callerPosition) { TaxiPoint source; try { source = _airfield.TaxiPoints.OrderBy(taxiPoint => taxiPoint.DistanceTo(callerPosition.Coordinate)) .First(); } catch (NullReferenceException) { throw new TaxiPathNotFoundException($"Taxi path not available because no TaxiPoints found"); } Logger.Debug($"Player is at {callerPosition.Coordinate}, nearest Taxi point is {source}"); var runways = ActiveRunwayDecider.GetActiveRunways(_airfield); return(runways.Count == 1 ? GetTaxiInstructionsWhenSingleRunway(source, runways.First()) : GetTaxiInstructionsWhenMultipleRunways(source, runways)); }
private List <List <TaggedEdge <NavigationPoint, string> > > GetPathsToActiveRunways() { // First we get a list of active runway(s) var activeRunways = ActiveRunwayDecider.GetActiveRunways(_airfield); // Then we get a list of all the entry Waypoints var entryPoints = _airfield.WayPoints.Where(x => x.Name.ToLower().Contains("entry")); var paths = new List <KeyValuePair <double, List <TaggedEdge <NavigationPoint, string> > > >(); // Get all the paths from all the entry waypoints to the active runway(s) foreach (var entryPoint in entryPoints) { var tryGetPaths = _airfield.NavigationGraph.ShortestPathsDijkstra(_airfield.NavigationCostFunction, entryPoint); foreach (var runway in activeRunways) { if (!tryGetPaths(runway, out var path)) { continue; } var taggedEdges = path.ToList(); var pathCost = PathCost(taggedEdges); var pathWithCost = new KeyValuePair <double, List <TaggedEdge <NavigationPoint, string> > >(pathCost, taggedEdges); paths.Add(pathWithCost); } } // Sort so that we get the cheapest ones first var cheapestPathsByCost = paths.OrderBy(pair => pair.Key).ToList(); // This is the cheapest one, so we want this one and any that have the same cost // since there could be multiple entry points for a given active runway(s). var cheapestCost = cheapestPathsByCost.First().Key; cheapestPathsByCost.RemoveAll(pair => pair.Key > cheapestCost); // And finally return the paths so the caller can find the one with the closest // start point to the player, which will be the actual approach path. return(cheapestPathsByCost.Select(pathPair => pathPair.Value).ToList()); }