private void ReadStartPoint(string line) { string[] tokens = line.Split(_splitters, StringSplitOptions.RemoveEmptyEntries); string[] xpTypes = tokens[5].Split('|'); Parking sp = new Parking(this) { Latitude = VortexMath.ParseDegreesToRadians(tokens[1]), Longitude = VortexMath.ParseDegreesToRadians(tokens[2]), Bearing = ((VortexMath.Parse(tokens[3]) + 540) * VortexMath.Deg2Rad) % (VortexMath.PI2) - Math.PI, LocationType = StartUpLocationTypeConverter.FromString(tokens[4]), XpTypes = AircraftTypeConverter.XPlaneTypesFromStrings(xpTypes), Name = string.Join(" ", tokens.Skip(6)) }; if (Settings.FixDuplicateParkingNames) { if (_parkings.Count(p => p.Name == sp.Name) > 0) { if (!_parkingNameDuplicates.ContainsKey(sp.Name)) { _parkingNameDuplicates.Add(sp.Name, 1); } _parkingNameDuplicates[sp.Name]++; sp.Name += $" - {_parkingNameDuplicates[sp.Name]}"; Logger.Log($"Renamed a parking to: {sp.Name}"); } } _parkings.Add(sp); }
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); } }
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"); } }
public void ParseRunwayUse(string line, List <Runway> runways) { string[] tokens = line.Split(_splitters, StringSplitOptions.RemoveEmptyEntries); RunwayUse ru = GetUse(tokens[1]); ru.Arrivals |= (tokens[3].Contains("arr")); ru.Departures |= (tokens[3].Contains("dep")); ru.XpTypes.AddRange(AircraftTypeConverter.XPlaneTypesFromStrings(tokens[4].Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries))); Runway r = runways.SingleOrDefault(rw => rw.Designator == ru.Designator); if (r != null) { if (ru.Arrivals) { r.AvailableForLanding = true; } if (ru.Departures) { r.AvailableForTakeOff = true; } } }
internal void DetermineWtTypes() { PossibleWtTypes = AircraftTypeConverter.WTTypesFromXPlaneLimits(XPlaneAircraftCategory.A, MaxSize, Operation); }