//// This method is to be called once Sector and Trajectory //// lists are populated (upon comleting EFD message extraction) //public void CalculateSectorEntry_Exit_Times(ref List<Sector> Sector_List) //{ // // Loop through the sector list and calculate // // entry/exit levels // for (int i = 0; i < Sector_List.Count; i++) // { // // First take care of the sector entry FL // int Start_Index = 0; // int End_Index = 0; // bool Start_End_WPT_Search_Status = false; // int Start_FL; // int End_FL; // int FL_DIFFERENCE; // TimeSpan Start_To_Sector; // TimeSpan Start_To_End; // double Time_Factor; // double Sector_Crossing_FL; // // Get indexes of WPT before and after sector crossing border // Get_Start_End_WPT_Index(Sector_List[i].SECTOR_ENTRY_TIME, out Start_Index, out End_Index, out Start_End_WPT_Search_Status); // if (Start_End_WPT_Search_Status == true) // { // Start_FL = int.Parse(TrajectoryPoints[Start_Index].Flight_Level); // End_FL = int.Parse(TrajectoryPoints[End_Index].Flight_Level); // FL_DIFFERENCE = End_FL - Start_FL; // Start_To_Sector = Sector_List[i].SECTOR_ENTRY_TIME - CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[Start_Index].ETO); // Start_To_End = CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[End_Index].ETO) - CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[Start_Index].ETO); // Time_Factor = Start_To_Sector.TotalSeconds / Start_To_End.TotalSeconds; // Sector_Crossing_FL = Start_FL + (FL_DIFFERENCE * Time_Factor); // Sector_List[i].EFL = Math.Round(Sector_Crossing_FL).ToString(); // } // // Now calculate sector exit FL // // Get indexes of WPT before and after sector crossing border // Get_Start_End_WPT_Index(Sector_List[i].SECTOR_EXIT_TIME, out Start_Index, out End_Index, out Start_End_WPT_Search_Status); // if (Start_End_WPT_Search_Status == true) // { // Start_FL = int.Parse(TrajectoryPoints[Start_Index].Flight_Level); // End_FL = int.Parse(TrajectoryPoints[End_Index].Flight_Level); // FL_DIFFERENCE = End_FL - Start_FL; // Start_To_Sector = Sector_List[i].SECTOR_EXIT_TIME - CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[Start_Index].ETO); // Start_To_End = CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[End_Index].ETO) - CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[Start_Index].ETO); // Time_Factor = Start_To_Sector.TotalSeconds / Start_To_End.TotalSeconds; // Sector_Crossing_FL = Start_FL + (FL_DIFFERENCE * Time_Factor); // Sector_List[i].XFL = Math.Round(Sector_Crossing_FL).ToString(); // } // } //} // This method returns the indexes of the two WPT points (before and after) given time. // Intended use is to obtain points before and after expected sector crossing. The points // have expected FL and times and based on that it is possible to calculate sector crossing FL private void Get_Start_End_WPT_Index(DateTime TimeAtPoint, out int Start, out int End, out bool Succefull) { Start = 0; End = 0; Succefull = false; for (int i = 0; i < TrajectoryPoints.Count; i++) { TimeSpan Time = CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[i].ETO) - TimeAtPoint; if (Time.TotalSeconds > 0) { Start = i - 1; End = i; // Check for the special case when the first points in the // list is also sector entry point. if (Start < 0) { Start = 0; } Succefull = true; break; } } }
public EFD_Msg(StreamReader Reader) { string OneLine; char[] delimiterChars = { ' ' }; // Parse the file and extract all data needed by EFD while (Reader.Peek() >= 0) { OneLine = Reader.ReadLine(); string[] Words = OneLine.Split(delimiterChars); Waypoint WPT = new Waypoint(); try { switch (Words[0]) { case "-IFPLID": IFPLID = Words[1]; break; case "-ARCID": ACID = Words[1]; break; case "-FLTSTATE": FLTSTATE = Words[1]; break; case "-ARCTYP": ARCTYP = Words[1]; break; case "-ADEP": ADEP = Words[1]; break; case "-ADES": ADES = Words[1]; break; case "-EOBT": EOBT = Words[1]; break; case "-EOBD": EOBD = Words[1]; break; case "-GEO": try { string LAT = Words[4]; string LON = Words[6]; // -LATTD 550302N -LONGTD 1070037W int LAT_DEG = int.Parse(LAT.Substring(0, 2)); int LAT_MIN = int.Parse(LAT.Substring(2, 2)); int LAT_SEC = int.Parse(LAT.Substring(4, 2)); GeoCordSystemDegMinSecUtilities.LatLongPrefix LAT_Prefix = GeoCordSystemDegMinSecUtilities.LatLongPrefix.Not_Valid; if (LAT[6] == 'N') { LAT_Prefix = GeoCordSystemDegMinSecUtilities.LatLongPrefix.N; } else { LAT_Prefix = GeoCordSystemDegMinSecUtilities.LatLongPrefix.S; } int LON_DEG = int.Parse(LON.Substring(0, 3)); int LON_MIN = int.Parse(LON.Substring(3, 2)); int LON_SEC = int.Parse(LON.Substring(5, 2)); GeoCordSystemDegMinSecUtilities.LatLongPrefix LON_Prefix = GeoCordSystemDegMinSecUtilities.LatLongPrefix.Not_Valid; if (LON[7] == 'W') { LON_Prefix = GeoCordSystemDegMinSecUtilities.LatLongPrefix.W; } else { LON_Prefix = GeoCordSystemDegMinSecUtilities.LatLongPrefix.E; } WPT.Name = Words[2]; WPT.Position = new GeoCordSystemDegMinSecUtilities.LatLongClass(LAT_DEG, LAT_MIN, LAT_SEC, LAT_Prefix, LON_DEG, LON_MIN, LON_SEC, LON_Prefix); WPT.Position_Determined = true; GEO_Artifical_List.Add(WPT); } catch (Exception e) { CBS_Main.WriteToLogFile("Exception in EFD_Msg.cs, -GEP Parsing: " + e.Message); } break; case "-BEGIN": if (Words[1] == "RTEPTS") { } else if (Words[1] == "ASPLIST") { } else { } break; // Maastricht UAC Entry and Exit Times // -ASP -AIRSPDES EDYYAOI -ETI 130404091206 -XTI 130404095840 case "": if ((Words.Length == 8) && (Words[1] == "-ASP")) { // Always extract UAC Entry and Exit Times if ((Words[2] == "-AIRSPDES") && (Words[3] == "EDYYAOI")) { AOI_ENTRY_TIME = CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + Words[5]); AOI_ENTRY_TIME_YYMMDDHHMMSS = "20" + Words[5]; AOI_EXIT_TIME = CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + Words[7]); AOI_EXIT_TIME_YYMMDDHHMMSS = "20" + Words[7]; } //// Now extract all MUAC sectors and sector entry/exit times //// Always extract UAC Entry and Exit Times //if ((Words[2] == "-AIRSPDES") && (Words[3].Substring(0, 4) == "EDYY")) //{ // string Sector_ID = Words[3].Substring(4, (Words[3].Length - 4)); // // FOX,FOX1,FOX2,UAC,UACX,AOI // if (Sector_ID != "FOX" && Sector_ID != "FOX1" && Sector_ID != "FOX2" && // Sector_ID != "UAC" && Sector_ID != "UACX" && Sector_ID != "AOI") // { // Sector Sector = new Sector(); // Sector.ID = Sector_ID; // Sector.SECTOR_ENTRY_TIME = CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + Words[5]); // Sector.SECTOR_EXIT_TIME = CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + Words[7]); // Sector_List.Add(Sector); // } //} } else if (Words.Length > 1) { if (Words[1] == "-AD" || Words[1] == "-VEC" || Words[1] == "-PT") { FIX_TO_LATLNG.FIXPOINT_TYPE FIX = new FIX_TO_LATLNG.FIXPOINT_TYPE(); switch (Words[1]) { // -AD -ADID OMDB -ETO 130404033500 -PTRTE DCT case "-AD": break; // -VEC -RELDIST 01 -FL F010 -ETO 130404034715 case "-VEC": // Extract data from -PT line WPT.Name = "-VEC" + Words[3]; WPT.Flight_Level = Words[5].Substring(1); // Remove F at the beggining. WPT.ETO = Words[7]; if (TrajectoryPoints.Count > 0) { // Add a new point to the list // Only add position that are known // as defined in the fixpoint table. TrajectoryPoints.Add(WPT); } break; // -PT -PTID GEO01 -FL F300 -ETO 130404041754 case "-PT": // Extract data from -PT line WPT.Name = Words[4]; WPT.Flight_Level = Words[6].Substring(1); // Remove F at the beggining. WPT.ETO = Words[8]; FIX = FIX_TO_LATLNG.Get_LATLNG(WPT.Name); if (FIX.Is_Found == true) { WPT.Position = FIX.Position; WPT.Position_Determined = true; // Add a new point to the list // Only add position that are known // as defined in the fixpoint table. TrajectoryPoints.Add(WPT); } else { // Lets check if the point is in the artifical EFD message // provided list. If so extract the position and assign it to // the main trajectory WPT list foreach (Waypoint GEO_WPT in GEO_Artifical_List) { if (WPT.Name == GEO_WPT.Name) { WPT.Position = new GeoCordSystemDegMinSecUtilities.LatLongClass(GEO_WPT.Position.GetLatLongDecimal().LatitudeDecimal, GEO_WPT.Position.GetLatLongDecimal().LongitudeDecimal); WPT.Position_Determined = true; TrajectoryPoints.Add(WPT); break; } } } break; default: break; } } } break; default: break; } } catch (Exception e) { CBS_Main.WriteToLogFile("Exception in EFD_Msg.cs, Instantiation: " + e.Message); } } ///////////////////////////////////////////////////////////////////////// // DO NOT CHANGE THE ORDER OF THE FOLLOWING CALLS ///////////////////////////////////////////////////////////////////////// // Here parse the list and // 1. Remove all "-VEC points from the end of the list // 2. Determine Lon/Lat of each -VEC point ParseTrajectoryList(ref TrajectoryPoints); // Iterate through the sector lists and // calculate sector entry/exit levels based on the // extrapolation data calculated from the main trajectory // WPT list // CalculateSectorEntry_Exit_Times(ref Sector_List); ///////////////////////////////// // Now set AOI Entry/Exit Points CalculateAOI_Entry_Exit_Times(); Reader.Close(); Reader.Dispose(); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// }
// This method is to be called once TrajectoryPoints // list has been populated and parsed so only known // points are left in the list (The route has been extracted) private void CalculateAOI_Entry_Exit_Times() { // First take care of the sector entry FL int Start_Index = 0; int End_Index = 0; bool Start_End_WPT_Search_Status = false; // FL int Start_FL; int End_FL; int FL_DIFFERENCE; TimeSpan Start_To_Sector; TimeSpan Start_To_End; double Time_Factor; double Sector_Crossing_FL; // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // Get indexes of WPT before and after AOI ENTRY crossing crossing border Get_Start_End_WPT_Index(AOI_ENTRY_TIME, out Start_Index, out End_Index, out Start_End_WPT_Search_Status); if (Start_End_WPT_Search_Status == true) { // First take care of the FL Start_FL = int.Parse(TrajectoryPoints[Start_Index].Flight_Level); End_FL = int.Parse(TrajectoryPoints[End_Index].Flight_Level); FL_DIFFERENCE = End_FL - Start_FL; if (Start_Index != End_Index) { Start_To_Sector = AOI_ENTRY_TIME - CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[Start_Index].ETO); Start_To_End = CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[End_Index].ETO) - CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[Start_Index].ETO); Time_Factor = Start_To_Sector.TotalSeconds / Start_To_End.TotalSeconds; Sector_Crossing_FL = Start_FL + (FL_DIFFERENCE * Time_Factor); } else { Sector_Crossing_FL = Start_FL; Time_Factor = 0.0; } AOI_ENTRY_FL = Math.Round(Sector_Crossing_FL).ToString(); GlobalPosition Start_Pos = new GlobalPosition(new GlobalCoordinates(TrajectoryPoints[Start_Index].Position.GetLatLongDecimal().LatitudeDecimal, TrajectoryPoints[Start_Index].Position.GetLatLongDecimal().LongitudeDecimal)); GlobalPosition End_Pos = new GlobalPosition(new GlobalCoordinates(TrajectoryPoints[End_Index].Position.GetLatLongDecimal().LatitudeDecimal, TrajectoryPoints[End_Index].Position.GetLatLongDecimal().LongitudeDecimal)); // Get the distance and conver it to NM double distance = geoCalc.CalculateGeodeticMeasurement(reference, Start_Pos, End_Pos).PointToPointDistance; if (distance > 0) { distance = (distance / 100.0) * (double)Time_Factor; distance = 0.00053996 * distance; //////////////////////////////////////////////////////////// // Calculate the azimuth between two known points Angle Azimuth = geoCalc.CalculateGeodeticMeasurement(reference, Start_Pos, End_Pos).Azimuth; // Calculate new position GeoCordSystemDegMinSecUtilities.LatLongClass New_Position = GeoCordSystemDegMinSecUtilities.CalculateNewPosition(new GeoCordSystemDegMinSecUtilities.LatLongClass(Start_Pos.Latitude.Degrees, Start_Pos.Longitude.Degrees), distance, Azimuth.Degrees); ENTRY_AOI_POINT = new GeoCordSystemDegMinSecUtilities.LatLongClass(New_Position.GetLatLongDecimal().LatitudeDecimal, New_Position.GetLatLongDecimal().LongitudeDecimal); } else { ENTRY_AOI_POINT = new GeoCordSystemDegMinSecUtilities.LatLongClass(Start_Pos.Latitude.Radians, Start_Pos.Longitude.Radians); } } // Get indexes of WPT before and after AOI EXIT crossing crossing border Get_Start_End_WPT_Index(AOI_EXIT_TIME, out Start_Index, out End_Index, out Start_End_WPT_Search_Status); if (Start_End_WPT_Search_Status == true) { // First take care of the FL Start_FL = int.Parse(TrajectoryPoints[Start_Index].Flight_Level); End_FL = int.Parse(TrajectoryPoints[End_Index].Flight_Level); FL_DIFFERENCE = End_FL - Start_FL; Start_To_Sector = AOI_EXIT_TIME - CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[Start_Index].ETO); Start_To_End = CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[End_Index].ETO) - CBS_Main.GetDate_Time_From_YYYYMMDDHHMMSS("20" + TrajectoryPoints[Start_Index].ETO); Time_Factor = Start_To_Sector.TotalSeconds / Start_To_End.TotalSeconds; Sector_Crossing_FL = Start_FL + (FL_DIFFERENCE * Time_Factor); AOI_EXIT_FL = Math.Round(Sector_Crossing_FL).ToString(); GlobalPosition Start_Pos = new GlobalPosition(new GlobalCoordinates(TrajectoryPoints[Start_Index].Position.GetLatLongDecimal().LatitudeDecimal, TrajectoryPoints[Start_Index].Position.GetLatLongDecimal().LongitudeDecimal)); GlobalPosition End_Pos = new GlobalPosition(new GlobalCoordinates(TrajectoryPoints[End_Index].Position.GetLatLongDecimal().LatitudeDecimal, TrajectoryPoints[End_Index].Position.GetLatLongDecimal().LongitudeDecimal)); // Get the distance and conver it to NM double distance = geoCalc.CalculateGeodeticMeasurement(reference, Start_Pos, End_Pos).PointToPointDistance; distance = (distance / 100.0) * (double)Time_Factor; distance = 0.00053996 * distance; //////////////////////////////////////////////////////////// // Calculate the azimuth between two known points Angle Azimuth = geoCalc.CalculateGeodeticMeasurement(reference, Start_Pos, End_Pos).Azimuth; // Calculate new position GeoCordSystemDegMinSecUtilities.LatLongClass New_Position = GeoCordSystemDegMinSecUtilities.CalculateNewPosition(new GeoCordSystemDegMinSecUtilities.LatLongClass(Start_Pos.Latitude.Degrees, Start_Pos.Longitude.Degrees), distance, Azimuth.Degrees); EXIT_AOI_POINT = new GeoCordSystemDegMinSecUtilities.LatLongClass(New_Position.GetLatLongDecimal().LatitudeDecimal, New_Position.GetLatLongDecimal().LongitudeDecimal); } }