public static void ProcessRunwayOperations(List <SteerPoint> steerPoints) { for (int i = 1; i < steerPoints.Count(); i++) { if (steerPoints[i - 1] is RunwayPoint && steerPoints[i] is RunwayPoint) { RunwayPoint prev = steerPoints[i - 1] as RunwayPoint; RunwayPoint curr = steerPoints[i] as RunwayPoint; // When entering an active zone, mark it as hold short // When staying in the same active zone, mark it as 'on runway' // When switching to a new active zone, try to force a hold short // todo: will this work as intended? curr.OnRunway = (prev.Operations == curr.Operations); // Propagate IsExiting for as long as we are on a runway. if (curr.OnRunway && prev.IsExiting) { curr.IsExiting = true; } } } }
private IEnumerable <SteerPoint> BuildSteerPoints(ResultRoute route, TaxiNode runwayExitNode) { List <SteerPoint> steerPoints = new List <SteerPoint>(); // Route should start at the (displaced) threshold RunwayPoint threshold = new RunwayPoint(route.Runway.DisplacedNode, 55, $"{route.Runway.Designator} Threshold", route.RouteStart.Edge.ActiveForRunway(route.Runway.Designator)) { OnRunway = true, IsExiting = true }; steerPoints.Add(threshold); foreach (TaxiNode node in route.Runway.RunwayNodes) { int speed = (node == runwayExitNode) ? 35 : 55; steerPoints.Add(new RunwayPoint(node.Latitude, node.Longitude, speed, $"{route.Runway.Designator}", route.RouteStart.Edge.ActiveForRunway(route.Runway.Designator))); if (node == runwayExitNode) // Key of the dictionary is the last node on the runway centerline for this route { break; } } // This is the first node off the runway centerline steerPoints.Add(new RunwayPoint(route.StartNode, 30, route.RouteStart.Edge.LinkName, route.RouteStart.Edge.ActiveForRunway(route.Runway.Designator))); LinkedNode link = route.RouteStart; while (link.Node != null) { bool activeZone = false; string activeFor = ""; if (link.Edge.ActiveZone) { activeZone = true; activeFor = link.Edge.ActiveForRunway(""); } else if (link.Next.Edge != null && link.Next.Edge.ActiveZone) { activeZone = true; activeFor = link.Next.Edge.ActiveForRunway(""); } if (activeZone) { steerPoints.Add(new RunwayPoint(link.Node.Latitude, link.Node.Longitude, 15, $"{link.Edge.LinkName}", activeFor)); } else { steerPoints.Add(new SteerPoint(link.Node.Latitude, link.Node.Longitude, 15, $"{link.Edge.LinkName}")); } link = link.Next; } // remove last point if it takes us past the 'pushback point' if (steerPoints.Count > 1) { SteerPoint oneButLast = steerPoints.ElementAt(steerPoints.Count - 2); SteerPoint last = steerPoints.ElementAt(steerPoints.Count - 1); double lastBearing = VortexMath.BearingRadians(oneButLast, last); double bearingToPush = VortexMath.BearingRadians(last.Latitude, last.Longitude, Parking.PushBackLatitude, Parking.PushBackLongitude); double turnToPush = VortexMath.AbsTurnAngle(lastBearing, bearingToPush); if (turnToPush > VortexMath.Deg100Rad) { steerPoints.RemoveAt(steerPoints.Count - 1); } } // todo: how does this all work with freaky pushback points? // todo: tie downs steerPoints.Add(new SteerPoint(Parking.PushBackLatitude, Parking.PushBackLongitude, 5, Parking.Name)); steerPoints.Add(new ParkingPoint(Parking.Latitude, Parking.Longitude, 5, Parking.Name, Parking.Bearing, true)); //RouteProcessor.Smooth(steerPoints); RouteProcessor.ProcessRunwayOperations(steerPoints); if (MaxInPoints < steerPoints.Count) { MaxInPoints = steerPoints.Count; } return(steerPoints); }