Пример #1
0
        public void Preprocess()
        {
            // Filter out nodes with links (probably nodes for the vehicle network)
            _taxiNodes = _nodeDict.Values.Where(v => v.IncomingEdges.Count > 0);

            // Filter out parkings with operation type none.
            _parkings = _parkings.Where(p => p.Operation != OperationType.None).ToList();

            // With unneeded nodes gone, parse the lat/lon string and convert the values to radians
            foreach (TaxiNode v in _taxiNodes)
            {
                v.ComputeLonLat();
            }

            // Compute distance and bearing of each edge
            foreach (TaxiEdge edge in _edges)
            {
                edge.Compute();
            }

            Dictionary <XPlaneAircraftCategory, int> numberOfParkingsPerCategory = new Dictionary <XPlaneAircraftCategory, int>();

            for (XPlaneAircraftCategory cat = XPlaneAircraftCategory.A; cat < XPlaneAircraftCategory.Max; cat++)
            {
                numberOfParkingsPerCategory[cat] = 0;
            }

            Dictionary <WorldTrafficAircraftType, int> numberOfParkingsPerWTType = new Dictionary <WorldTrafficAircraftType, int>();

            for (WorldTrafficAircraftType cat = WorldTrafficAircraftType.Fighter; cat <= WorldTrafficAircraftType.Max; cat++)
            {
                numberOfParkingsPerWTType[cat] = 0;
            }

            foreach (Parking parking in _parkings)
            {
                parking.DetermineWtTypes();
                parking.DetermineTaxiOutLocation(_taxiNodes); // Move this to first if we need pushback info in the parking def
                numberOfParkingsPerCategory[parking.MaxSize]++;

                foreach (XPlaneAircraftType wtt in parking.XpTypes)
                {
                    WorldTrafficAircraftType t = AircraftTypeConverter.WTTypeFromXPlaneTypeAndCat(parking.MaxSize, wtt);
                    numberOfParkingsPerWTType[t]++;
                }
                //parking.FindNearestLine(_lines);
            }

            Log($"Parkings by Category: {string.Join(" ", numberOfParkingsPerCategory.Select(kvp => kvp.Key.ToString() + ": " + kvp.Value.ToString()))}");
            Log($"Parkings by WorldTraffic type:\n\t{string.Join("\n\t", numberOfParkingsPerWTType.Select(kvp => $"{kvp.Key.ToString(),-15}: {kvp.Value.ToString()}"))}".Replace("Max", "Undefined"));

            StringBuilder sb = new StringBuilder();

            _flows.Analyze(sb);

            foreach (Runway r in _runways)
            {
                r.Analyze(_taxiNodes, _edges);
            }
        }
Пример #2
0
        internal void Write(string icao)
        {
            string operationFile = Path.Combine(Settings.WorldTrafficOperations, $"{icao}.txt");

            using (InvariantWriter sw = new InvariantWriter(operationFile, Encoding.ASCII))
            {
                sw.WriteLine("                                                                            Start  End");
                sw.WriteLine("INDEX   Low Wind Speed    High Wind Speed    Low Wind Dir   High Wind Dir   Time   Time  Comments (not parsed)");
                sw.WriteLine("---------------------------------------------------------------------------------------------------------------------");
                sw.WriteLine("START_OPERATIONS");
                foreach (string op in _operations)
                {
                    sw.WriteLine(op);
                }
                sw.WriteLine("END_OPERATIONS\n\n");

                sw.WriteLine("Ops                           1   2     Start End");
                sw.WriteLine("Index    Active Runway       Arr Dep    Time   Time   Comments (not parsed)");
                sw.WriteLine("-------------------------------------------------------------------------------------------------");
                sw.WriteLine("START_RUNWAY_OPS");
                foreach (string rwop in _runwayOps)
                {
                    sw.WriteLine(rwop);
                }
                sw.WriteLine("END_RUNWAY_OPS\n\n");

                sw.WriteLine("        Supported AC Types    Supported Approaches");
                sw.WriteLine("Runway  0 1 2 3 4 5 6 7 8 9     1 2 3 4 5 6 7 8");
                sw.WriteLine("---------------------------------------------------------------------------");
                sw.WriteLine("START_RUNWAYS");


                IEnumerable <IGrouping <string, RunwayUse> > uses = TrafficRules.SelectMany(tr => tr.RunwayUses).GroupBy(ru => ru.Designator);
                foreach (IGrouping <string, RunwayUse> use in uses)
                {
                    IEnumerable <XPlaneAircraftType>       types   = use.SelectMany(u => u.XpTypes).Distinct();
                    IEnumerable <WorldTrafficAircraftType> wtTypes = AircraftTypeConverter.WTTypesFromXPlaneTypes(types);
                    List <int> onOffs = new List <int>();
                    for (WorldTrafficAircraftType t = WorldTrafficAircraftType.Fighter; t < WorldTrafficAircraftType.Ground; t++)
                    {
                        onOffs.Add(wtTypes.Contains(t) ? 1 : 0);
                    }

                    sw.WriteLine($"{use.Key,-7} {string.Join(" ", onOffs)}     1 1 1 1 1 1 1 0");
                }

                sw.WriteLine("END_RUNWAYS");
            }
        }
Пример #3
0
        private void button2_Click(object sender, EventArgs e)
        {
            string aircraftFolder             = Path.Combine(Settings.XPlaneLocation, "ClassicJetSimUtils", "WorldTraffic", "AircraftTypes");
            IEnumerable <string> baseAircraft = Directory.EnumerateFiles(aircraftFolder, "*_BASE.txt");

            rtbAircraft.Clear();
            rtbAircraft.AppendText($"Found {baseAircraft.Count()} 'base' aircraft.\n\n");

            WorldTrafficAircraftType currentType = WorldTrafficAircraftType.Fighter;

            Dictionary <WorldTrafficAircraftType, List <AircraftBase> > aircraft = new Dictionary <WorldTrafficAircraftType, List <AircraftBase> >();

            for (WorldTrafficAircraftType wat = WorldTrafficAircraftType.Fighter; wat < WorldTrafficAircraftType.Max; wat++)
            {
                aircraft[wat] = new List <AircraftBase>();
            }


            foreach (string basecraft in baseAircraft)
            {
                AircraftBase aircraftBase = null;
                string[]     lines        = File.ReadAllLines(basecraft);
                bool         startFound   = false;
                string       nameCache    = "";

                foreach (string line in lines)
                {
                    string[] tokens = line.ToLower().Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                    if (tokens.Length < 1)
                    {
                        continue;
                    }

                    if (!startFound)
                    {
                        if (tokens[0] != "start")
                        {
                            continue;
                        }
                        else
                        {
                            startFound = true;
                            continue;
                        }
                    }

                    if (tokens.Length < 2)
                    {
                        continue;
                    }

                    switch (tokens[0])
                    {
                    case "type":
                        currentType  = (WorldTrafficAircraftType)int.Parse(tokens[1]);
                        aircraftBase = new AircraftBase
                        {
                            Name = nameCache.ToUpper()
                        };
                        break;

                    case "name":
                        nameCache = tokens[1];
                        break;

                    case "wingspan":
                        aircraftBase.WingSpan = VortexMath.Parse(tokens[1]);
                        break;

                    case "takeoffdistatmtow":
                        aircraftBase.TakeOffDist = VortexMath.Parse(tokens[1]);
                        break;

                    case "landingdist":
                        aircraftBase.LandingDist = VortexMath.Parse(tokens[1]);
                        break;

                    case "minlandingdist":
                        aircraftBase.MinLandingDist = VortexMath.Parse(tokens[1]);
                        break;

                    default:
                        break;
                    }
                }

                aircraft[currentType].Add(aircraftBase);
            }

            for (WorldTrafficAircraftType wat = WorldTrafficAircraftType.Fighter; wat < WorldTrafficAircraftType.Max; wat++)
            {
                if (aircraft[wat].Count > 0)
                {
                    rtbAircraft.AppendText($"World Traffic Type {(int)wat} <{wat}> {aircraft[wat].Count} base aircraft\n");

                    var byCat     = aircraft[wat].GroupBy(ac => SpanToCat(ac.WingSpan));
                    var catCounts = byCat.ToDictionary(ca => ca.Key, ca => ca.ToList().Count);


                    double minLandingDist = aircraft[wat].Min(ac => ac.LandingDist);
                    double maxLandingDist = aircraft[wat].Max(ac => ac.LandingDist);

                    var    withMLD           = aircraft[wat].Where(ac => ac.MinLandingDist > 0);
                    double minMinLandingDist = withMLD.Count() > 0 ? withMLD.Min(ac => ac.MinLandingDist) : 0.0;
                    int    noMinLandingDist  = aircraft[wat].Count(ac => ac.MinLandingDist == 0);
                    double maxMinLandingDist = aircraft[wat].Max(ac => ac.MinLandingDist);

                    double minWingSpan = aircraft[wat].Min(ac => ac.WingSpan);
                    double maxWingSpan = aircraft[wat].Max(ac => ac.WingSpan);

                    double minTakeOff = aircraft[wat].Min(ac => ac.TakeOffDist);
                    double maxTakeOff = aircraft[wat].Max(ac => ac.TakeOffDist);

                    string Name = aircraft[wat].First(ac => ac.WingSpan == maxWingSpan).Name;
                    rtbAircraft.AppendText($" Required Gate/Taxiway Size:  <{SpanToCat(maxWingSpan)}>  ({Name} has wingspan {maxWingSpan,4:0.0})\n");

                    foreach (var group in byCat)
                    {
                        rtbAircraft.AppendText($" Number of cat {group.Key}           : {catCounts[group.Key],5} {string.Join(", ", group)}\n");
                    }

                    Name = aircraft[wat].First(ac => ac.TakeOffDist == minTakeOff).Name;
                    rtbAircraft.AppendText($" Shortest Takeoff possible : {minTakeOff,5} ({Name})\n");
                    Name = aircraft[wat].First(ac => ac.TakeOffDist == maxTakeOff).Name;
                    rtbAircraft.AppendText($" Max Takeoff required      : {maxTakeOff,5} ({Name})\n");

                    Name = aircraft[wat].First(ac => ac.LandingDist == minLandingDist).Name;
                    rtbAircraft.AppendText($" Shortest Landing Distance : {minLandingDist,5} ({Name})\n");
                    Name = aircraft[wat].First(ac => ac.LandingDist == maxLandingDist).Name;
                    rtbAircraft.AppendText($" Longest Landing Distance  : {maxLandingDist,5} ({Name})\n");

                    Name = aircraft[wat].First(ac => ac.MinLandingDist == minMinLandingDist).Name;
                    rtbAircraft.AppendText($" Shortest Min Ldg Dist.    : {minMinLandingDist,5} ({Name})\n");
                    Name = aircraft[wat].First(ac => ac.MinLandingDist == maxMinLandingDist).Name;
                    rtbAircraft.AppendText($" Longest Min Ldg Dist.     : {maxMinLandingDist,5} ({Name})\n");
                    rtbAircraft.AppendText($" Without Min Ldg Dist.     : {noMinLandingDist,5}\n");

                    //rtbAircraft.AppendText($"{wat,-10} {aircraft[wat].Count(),2} {minLandingDist,5} {maxLandingDist,5}  {minMinLandingDist,5}  {maxMinLandingDist,5} {minTakeOff,5} {maxTakeOff,5} {minWingSpan,4:0.0} <{SpanToCat(minWingSpan)}> {maxWingSpan,4:0.0} <{SpanToCat(maxWingSpan)}>\n");
                    rtbAircraft.AppendText("\n");
                }
            }


            //foreach (KeyValuePair<int, List<AircraftBase>> details in aircraft.OrderBy(ac => ac.Key))
            //{
            //    double averageWingSpan = details.Value.Average(a => a.WingSpan);
            //    double minWingSpan = details.Value.Min(a => a.WingSpan);
            //    double maxWingSpan = details.Value.Max(a => a.WingSpan);

            //    rtbAircraft.AppendText($"{details.Key} Wingspan: mn {minWingSpan:0.0} <{SpanToCat(minWingSpan)}> av {averageWingSpan:0.0} mx: {maxWingSpan:0.0} <{SpanToCat(maxWingSpan)}>\n");
            //}

            //foreach (KeyValuePair<int, List<AircraftBase>> details in aircraft.OrderBy(ac => ac.Key))
            //{
            //    double averageLength = details.Value.Average(a => a.TakeOffDist);
            //    double minLength = details.Value.Min(a => a.TakeOffDist);
            //    double maxLength = details.Value.Max(a => a.TakeOffDist);

            //    rtbAircraft.AppendText($"{details.Key} TakeOffDist: mn {minLength:0} av {averageLength:0} mx: {maxLength:0}\n");
            //}

            //foreach (KeyValuePair<int, List<AircraftBase>> details in aircraft.OrderBy(ac => ac.Key))
            //{
            //    double averageLength = details.Value.Average(a => a.LandingDist);
            //    double minLength = details.Value.Min(a => a.LandingDist);
            //    double maxLength = details.Value.Max(a => a.LandingDist);

            //    rtbAircraft.AppendText($"{details.Key} LandingDist: mn {minLength:0} av {averageLength:0} mx: {maxLength:0}\n");
            //}
        }