// 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); } }
// 1. Remove all "-VEC points from the end of the list // 2. Determine Lon/Lat of each -VEC point public void ParseTrajectoryList(ref List <Waypoint> T_List) { //////////////////////////////////////////////////////////////////////////////////////// // 1. Remove all "-VEC points from the end of the list //////////////////////////////////////////////////////////////////////////////////////// int LastKnownPointIndex = -1; for (int i = 0; i < T_List.Count; i++) { if (T_List[i].Name.Length == 6 && T_List[i].Name.Substring(0, 4) == "-VEC") { } else { LastKnownPointIndex = i; } } if (LastKnownPointIndex < (T_List.Count - 1)) { try { T_List.RemoveRange(LastKnownPointIndex + 1, T_List.Count - (LastKnownPointIndex + 1)); } catch (Exception e) { CBS_Main.WriteToLogFile("Exception removing VEC range: " + e.Message); } } //////////////////////////////////////////////////////////////////////////////////////////// // 2. Determine Lon/Lat of each -VEC point //////////////////////////////////////////////////////////////////////////////////////////// for (int i = 0; i < T_List.Count; i++) { // Check if this is a -VEC point if (T_List[i].Name.Length == 6 && T_List[i].Name.Substring(0, 4) == "-VEC") { // 1. YES, then LastKnownPointIndex is the index of the previous last known point // 2. Now determine the next known point int next_known_point = GetNextKnownPointIndex(i + 1, ref T_List); // Now we have two known points, so lets compute a new position representing // the percentage of the distance between two known points specifed in the -VEC // point. int percentage = int.Parse(T_List[i].Name.Substring(4, 2)); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); GlobalPosition Start_Pos = new GlobalPosition(new GlobalCoordinates(T_List[LastKnownPointIndex].Position.GetLatLongDecimal().LatitudeDecimal, T_List[LastKnownPointIndex].Position.GetLatLongDecimal().LongitudeDecimal)); GlobalPosition End_Pos = new GlobalPosition(new GlobalCoordinates(T_List[next_known_point].Position.GetLatLongDecimal().LatitudeDecimal, T_List[next_known_point].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)percentage; 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); // Assign new position to the -VEC point T_List[i].Position = new GeoCordSystemDegMinSecUtilities.LatLongClass(New_Position.GetLatLongDecimal().LatitudeDecimal, New_Position.GetLatLongDecimal().LongitudeDecimal); } else { LastKnownPointIndex = i; } } }
/// <summary> /// Calculate the three dimensional geodetic measurement between two positions /// measured in reference to a specified ellipsoid. /// /// This calculation is performed by first computing a new ellipsoid by expanding or contracting /// the reference ellipsoid such that the new ellipsoid passes through the average elevation /// of the two positions. A geodetic curve across the new ellisoid is calculated. The /// point-to-point distance is calculated as the hypotenuse of a right triangle where the length /// of one side is the ellipsoidal distance and the other is the difference in elevation. /// </summary> /// <param name="refEllipsoid">reference ellipsoid to use</param> /// <param name="start">starting position</param> /// <param name="end">ending position</param> /// <returns></returns> public GeodeticMeasurement CalculateGeodeticMeasurement(Ellipsoid refEllipsoid, GlobalPosition start, GlobalPosition end) { // get the coordinates GlobalCoordinates startCoords = start.Coordinates; GlobalCoordinates endCoords = end.Coordinates; // calculate elevation differences double elev1 = start.Elevation; double elev2 = end.Elevation; double elev12 = (elev1 + elev2) / 2.0; // calculate latitude differences double phi1 = startCoords.Latitude.Radians; double phi2 = endCoords.Latitude.Radians; double phi12 = (phi1 + phi2) / 2.0; // calculate a new ellipsoid to accommodate average elevation double refA = refEllipsoid.SemiMajorAxis; double f = refEllipsoid.Flattening; double a = refA + elev12 * (1.0 + f * Math.Sin(phi12)); Ellipsoid ellipsoid = Ellipsoid.FromAAndF(a, f); // calculate the curve at the average elevation GeodeticCurve averageCurve = CalculateGeodeticCurve(ellipsoid, startCoords, endCoords); // return the measurement return(new GeodeticMeasurement(averageCurve, elev2 - elev1)); }