////////////////////////////////////////////////////////////////////////////////////// // This method takes in present position (LatLongClass) and range/bearing from the // present position. It returns a new position (LatLongClass) // // Distance is IN // Azimuth in degrees public static LatLongClass CalculateNewPosition(LatLongClass PresentPosition, double Distance, double Azimuth) { LatLongClass NewPosition = new LatLongClass(); // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set Lincoln Memorial coordinates GlobalCoordinates Present_Pos; Present_Pos = new GlobalCoordinates(new Angle(PresentPosition.GetLatLongDecimal().LatitudeDecimal), new Angle(PresentPosition.GetLatLongDecimal().LongitudeDecimal)); // now, plug the result into to direct solution GlobalCoordinates dest; Angle endBearing = new Angle(); double Distance_In_Meeters = (Distance * NMtoKM * 1000.0); dest = geoCalc.CalculateEndingGlobalCoordinates(reference, Present_Pos, Azimuth, Distance_In_Meeters, out endBearing); NewPosition.SetPosition(new LatLongDecimal(dest.Latitude.Degrees, dest.Longitude.Degrees)); return NewPosition; }
////////////////////////////////////////////////////////////////////////////////////// // This method takes in present position (LatLongClass) and range/bearing from the // present position. It returns a new position (LatLongClass) // // Distance is IN // Azimuth in degrees public static LatLongClass CalculateNewPosition(LatLongClass PresentPosition, double Distance, double Azimuth) { LatLongClass NewPosition = new LatLongClass(); // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set Lincoln Memorial coordinates GlobalCoordinates Present_Pos; Present_Pos = new GlobalCoordinates(new Angle(PresentPosition.GetLatLongDecimal().LatitudeDecimal), new Angle(PresentPosition.GetLatLongDecimal().LongitudeDecimal)); // now, plug the result into to direct solution GlobalCoordinates dest; Angle endBearing = new Angle(); double Distance_In_Meeters = (Distance * NMtoKM * 1000.0); dest = geoCalc.CalculateEndingGlobalCoordinates(reference, Present_Pos, Azimuth, Distance_In_Meeters, out endBearing); NewPosition.SetPosition(new LatLongDecimal(dest.Latitude.Degrees, dest.Longitude.Degrees)); return(NewPosition); }
public OutData GetResult() { // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // Used to calculate the time to the min distance GlobalPosition Orig_Track_1_Pos = new GlobalPosition(new GlobalCoordinates(Track_1_Pos.Latitude, Track_1_Pos.Longitude)); int UpdateStep = 60 / Properties.Settings.Default.SEepToolUpdateRate; for (int LookAheadIndex = 1; LookAheadIndex <= ((MaxLookAheadTimeInMinutes * 60) / UpdateStep); LookAheadIndex++) { // Calculate new position X seconds ahead for track 1 double Range = (Track_1_SPD / 60) / UpdateStep; GeoCordSystemDegMinSecUtilities.LatLongClass ResultPosition_1 = GeoCordSystemDegMinSecUtilities.CalculateNewPosition(new GeoCordSystemDegMinSecUtilities.LatLongClass(Track_1_Pos.Latitude.Degrees, Track_1_Pos.Longitude.Degrees), (double)Range, (double)Track_1_TRK); GPoint MarkerPositionLocal = FormMain.gMapControl.FromLatLngToLocal(new PointLatLng(ResultPosition_1.GetLatLongDecimal().LatitudeDecimal, ResultPosition_1.GetLatLongDecimal().LongitudeDecimal)); ReturnData.Track_1_Pos_Min.X = MarkerPositionLocal.X; ReturnData.Track_1_Pos_Min.Y = MarkerPositionLocal.Y; // Calculate new position X seconds ahead for track 2 Range = (Track_2_SPD / 60) / 15; GeoCordSystemDegMinSecUtilities.LatLongClass ResultPosition_2 = GeoCordSystemDegMinSecUtilities.CalculateNewPosition(new GeoCordSystemDegMinSecUtilities.LatLongClass(Track_2_Pos.Latitude.Degrees, Track_2_Pos.Longitude.Degrees), (double)Range, (double)Track_2_TRK); MarkerPositionLocal = FormMain.gMapControl.FromLatLngToLocal(new PointLatLng(ResultPosition_2.GetLatLongDecimal().LatitudeDecimal, ResultPosition_2.GetLatLongDecimal().LongitudeDecimal)); ReturnData.Track_2_Pos_Min.X = MarkerPositionLocal.X; ReturnData.Track_2_Pos_Min.Y = MarkerPositionLocal.Y; double distance1 = geoCalc.CalculateGeodeticMeasurement(reference, Track_1_Pos, Track_2_Pos).PointToPointDistance; double distance2 = geoCalc.CalculateGeodeticMeasurement(reference, new GlobalPosition(new GlobalCoordinates(ResultPosition_1.GetLatLongDecimal().LatitudeDecimal, ResultPosition_1.GetLatLongDecimal().LongitudeDecimal)), new GlobalPosition(new GlobalCoordinates(ResultPosition_2.GetLatLongDecimal().LatitudeDecimal, ResultPosition_2.GetLatLongDecimal().LongitudeDecimal))).PointToPointDistance; // Calculate distance between present and new position if ((distance1 < distance2) && (LookAheadIndex != 1)) { ReturnData.Is_Converging = true; ReturnData.MinDistance = distance2 * 0.00053996; // Convert to nautical miles double DistanceToTravel = geoCalc.CalculateGeodeticMeasurement(reference, Orig_Track_1_Pos, new GlobalPosition(new GlobalCoordinates(ResultPosition_1.GetLatLongDecimal().LatitudeDecimal, ResultPosition_1.GetLatLongDecimal().LongitudeDecimal))).PointToPointDistance; DistanceToTravel = DistanceToTravel * 0.00053996; // Convert to nautical miles ReturnData.SecondsToMinimum = (int)((DistanceToTravel / Track_1_SPD) * 60.0 * 60.0); // We have reached the minimum distance break; } else if ((distance1 < distance2) && (LookAheadIndex == 1)) { ReturnData.Is_Converging = false; break; } Track_1_Pos = new GlobalPosition(new GlobalCoordinates(ResultPosition_1.GetLatLongDecimal().LatitudeDecimal, ResultPosition_1.GetLatLongDecimal().LongitudeDecimal)); Track_2_Pos = new GlobalPosition(new GlobalCoordinates(ResultPosition_2.GetLatLongDecimal().LatitudeDecimal, ResultPosition_2.GetLatLongDecimal().LongitudeDecimal)); } return(ReturnData); }
public OutData GetResult() { // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // Used to calculate the time to the min distance GlobalPosition Orig_Track_1_Pos = new GlobalPosition(new GlobalCoordinates(Track_1_Pos.Latitude, Track_1_Pos.Longitude)); int UpdateStep = 60 / Properties.Settings.Default.SEepToolUpdateRate; for (int LookAheadIndex = 1; LookAheadIndex <= ((MaxLookAheadTimeInMinutes * 60) / UpdateStep); LookAheadIndex++) { // Calculate new position X seconds ahead for track 1 double Range = (Track_1_SPD / 60) / UpdateStep; GeoCordSystemDegMinSecUtilities.LatLongClass ResultPosition_1 = GeoCordSystemDegMinSecUtilities.CalculateNewPosition(new GeoCordSystemDegMinSecUtilities.LatLongClass(Track_1_Pos.Latitude.Degrees, Track_1_Pos.Longitude.Degrees), (double)Range, (double)Track_1_TRK); GPoint MarkerPositionLocal = FormMain.gMapControl.FromLatLngToLocal(new PointLatLng(ResultPosition_1.GetLatLongDecimal().LatitudeDecimal, ResultPosition_1.GetLatLongDecimal().LongitudeDecimal)); ReturnData.Track_1_Pos_Min.X = MarkerPositionLocal.X; ReturnData.Track_1_Pos_Min.Y = MarkerPositionLocal.Y; // Calculate new position X seconds ahead for track 2 Range = (Track_2_SPD / 60) / 15; GeoCordSystemDegMinSecUtilities.LatLongClass ResultPosition_2 = GeoCordSystemDegMinSecUtilities.CalculateNewPosition(new GeoCordSystemDegMinSecUtilities.LatLongClass(Track_2_Pos.Latitude.Degrees, Track_2_Pos.Longitude.Degrees), (double)Range, (double)Track_2_TRK); MarkerPositionLocal = FormMain.gMapControl.FromLatLngToLocal(new PointLatLng(ResultPosition_2.GetLatLongDecimal().LatitudeDecimal, ResultPosition_2.GetLatLongDecimal().LongitudeDecimal)); ReturnData.Track_2_Pos_Min.X = MarkerPositionLocal.X; ReturnData.Track_2_Pos_Min.Y = MarkerPositionLocal.Y; double distance1 = geoCalc.CalculateGeodeticMeasurement(reference, Track_1_Pos, Track_2_Pos).PointToPointDistance; double distance2 = geoCalc.CalculateGeodeticMeasurement(reference, new GlobalPosition(new GlobalCoordinates(ResultPosition_1.GetLatLongDecimal().LatitudeDecimal, ResultPosition_1.GetLatLongDecimal().LongitudeDecimal)), new GlobalPosition(new GlobalCoordinates(ResultPosition_2.GetLatLongDecimal().LatitudeDecimal, ResultPosition_2.GetLatLongDecimal().LongitudeDecimal))).PointToPointDistance; // Calculate distance between present and new position if ((distance1 < distance2) && (LookAheadIndex != 1)) { ReturnData.Is_Converging = true; ReturnData.MinDistance = distance2 * 0.00053996; // Convert to nautical miles double DistanceToTravel = geoCalc.CalculateGeodeticMeasurement(reference, Orig_Track_1_Pos, new GlobalPosition(new GlobalCoordinates(ResultPosition_1.GetLatLongDecimal().LatitudeDecimal, ResultPosition_1.GetLatLongDecimal().LongitudeDecimal))).PointToPointDistance; DistanceToTravel = DistanceToTravel * 0.00053996; // Convert to nautical miles ReturnData.SecondsToMinimum = (int)((DistanceToTravel / Track_1_SPD) * 60.0 * 60.0); // We have reached the minimum distance break; } else if ((distance1 < distance2) && (LookAheadIndex == 1)) { ReturnData.Is_Converging = false; break; } Track_1_Pos = new GlobalPosition(new GlobalCoordinates(ResultPosition_1.GetLatLongDecimal().LatitudeDecimal, ResultPosition_1.GetLatLongDecimal().LongitudeDecimal)); Track_2_Pos = new GlobalPosition(new GlobalCoordinates(ResultPosition_2.GetLatLongDecimal().LatitudeDecimal, ResultPosition_2.GetLatLongDecimal().LongitudeDecimal)); } return ReturnData; }
public override void OnRender(Graphics g) { g.DrawLine(new Pen(Brush_To_Use), StartPosition, EndPosition); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); GlobalPosition Start = new GlobalPosition(new GlobalCoordinates(this.Position.Lat, this.Position.Lng)); PointLatLng End_LatLng = FormMain.FromLocalToLatLng(EndPosition.X, EndPosition.Y); GlobalPosition End = new GlobalPosition(new GlobalCoordinates(End_LatLng.Lat, End_LatLng.Lng)); GeodeticMeasurement GM = geoCalc.CalculateGeodeticMeasurement(reference, Start, End); // Now compute position half way between two points. double distance = GM.PointToPointDistance / 2.0; if (distance > 0.0) { GlobalCoordinates GC = geoCalc.CalculateEndingGlobalCoordinates(reference, new GlobalCoordinates(this.Position.Lat, this.Position.Lng), GM.Azimuth, distance); GPoint GP = FormMain.FromLatLngToLocal(new PointLatLng(GC.Latitude.Degrees, GC.Longitude.Degrees)); double Distane_NM = 0.00053996 * GM.PointToPointDistance; g.DrawString(Math.Round(GM.Azimuth.Degrees).ToString() + "°/" + Math.Round(Distane_NM, 1).ToString() + "nm", new Font(FontFamily.GenericSansSerif, 9), Brush_To_Use, new PointF(GP.X, GP.Y)); } }
public override void OnRender(Graphics g) { Pen MyPen = new Pen(new SolidBrush(LabelAttributes.TargetColor), LabelAttributes.TargetSize); MyPen.DashStyle = LabelAttributes.TargetStyle; // Draw AC Symbol g.DrawRectangle(MyPen, LocalPosition.X - 5, LocalPosition.Y - 5, 10, 10); AC_SYMB_START_X = LocalPosition.X - 5; AC_SYMB_START_Y = LocalPosition.Y - 5; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // Here handle drawing of Range/Bearing & SEP tool if (TargetToMonitor != -1) { Point StartPosition = new Point(LocalPosition.X, LocalPosition.Y); Point EndPosition = DynamicDisplayBuilder.GetTargetPositionByIndex(TargetToMonitor); g.DrawLine(new Pen(Brushes.Yellow, 1), StartPosition, EndPosition); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); GlobalPosition Start = new GlobalPosition(new GlobalCoordinates(this.Position.Lat, this.Position.Lng)); PointLatLng End_LatLng = FormMain.FromLocalToLatLng(EndPosition.X, EndPosition.Y); GlobalPosition End = new GlobalPosition(new GlobalCoordinates(End_LatLng.Lat, End_LatLng.Lng)); GeodeticMeasurement GM = geoCalc.CalculateGeodeticMeasurement(reference, End, Start); //////////////////////////////////////////////////////////////////////////////////////////// // Handle SEP Tool double TRK1_SPD = 0.0, TRK2_SPD = 0.0; double TRK1_AZ = 0.0, TRK2_AZ = 0.0; bool Sep_Data_Is_Valid = true; if (!double.TryParse(CALC_GSPD_STRING, out TRK1_SPD)) { if (!double.TryParse(DAP_GSPD, out TRK1_SPD)) { Sep_Data_Is_Valid = false; } } if (!double.TryParse(DynamicDisplayBuilder.GetTarget_CALC_GSPD_ByIndex(TargetToMonitor), out TRK2_SPD)) { if (!double.TryParse(DynamicDisplayBuilder.GetTarget_DAP_GSPD_ByIndex(TargetToMonitor), out TRK2_SPD)) { Sep_Data_Is_Valid = false; } } if (!double.TryParse(CALC_HDG_STRING, out TRK1_AZ)) { if (!double.TryParse(TRK, out TRK1_AZ)) { if (!double.TryParse(DAP_HDG, out TRK1_AZ)) { Sep_Data_Is_Valid = false; } } } if (!double.TryParse(DynamicDisplayBuilder.GetTarget_CALC_HDG_ByIndex(TargetToMonitor), out TRK2_AZ)) { if (!double.TryParse(DynamicDisplayBuilder.GetTargetTRKByIndex(TargetToMonitor), out TRK2_AZ)) { if (!double.TryParse(DynamicDisplayBuilder.GetTargetM_HDGByIndex(TargetToMonitor), out TRK2_AZ)) { Sep_Data_Is_Valid = false; } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // If all the necessary data is avilable // then pass it on to the SEP tool calculator // and then draw the result string SepToolActive = "N/A"; if (Sep_Data_Is_Valid) { SEP_Tool_Calculator SepTool = new SEP_Tool_Calculator(Start, End, TRK1_SPD, TRK2_SPD, TRK1_AZ, TRK2_AZ, 20); SEP_Tool_Calculator.OutData Sep_Tool_Data = SepTool.GetResult(); if (Sep_Tool_Data.Is_Converging) { g.DrawRectangle(new Pen(Brushes.Yellow, LabelAttributes.TargetSize), Sep_Tool_Data.Track_1_Pos_Min.X - 5, Sep_Tool_Data.Track_1_Pos_Min.Y - 5, 10, 10); g.DrawRectangle(new Pen(Brushes.Yellow, LabelAttributes.TargetSize), Sep_Tool_Data.Track_2_Pos_Min.X - 5, Sep_Tool_Data.Track_2_Pos_Min.Y - 5, 10, 10); g.DrawLine(new Pen(Brushes.Yellow, LabelAttributes.TargetSize), new Point(Sep_Tool_Data.Track_1_Pos_Min.X, Sep_Tool_Data.Track_1_Pos_Min.Y), new Point(StartPosition.X, StartPosition.Y)); g.DrawLine(new Pen(Brushes.Yellow, LabelAttributes.TargetSize), new Point(Sep_Tool_Data.Track_2_Pos_Min.X, Sep_Tool_Data.Track_2_Pos_Min.Y), new Point(EndPosition.X, EndPosition.Y)); TimeSpan T = TimeSpan.FromSeconds(Sep_Tool_Data.SecondsToMinimum); SepToolActive = "min d:" + Math.Round(Sep_Tool_Data.MinDistance, 1).ToString() + "/" + T.Minutes.ToString() + ":" + T.Seconds.ToString(); } } // Now compute position half way between two points. double distance = GM.PointToPointDistance / 2.0; if (distance > 0.0) { GlobalCoordinates GC = geoCalc.CalculateEndingGlobalCoordinates(reference, new GlobalCoordinates(End_LatLng.Lat, End_LatLng.Lng), GM.Azimuth, distance); GPoint GP = FormMain.FromLatLngToLocal(new PointLatLng(GC.Latitude.Degrees, GC.Longitude.Degrees)); double Distane_NM = 0.00053996 * GM.PointToPointDistance; g.DrawString(Math.Round(GM.Azimuth.Degrees).ToString() + "°/" + Math.Round(Distane_NM, 1).ToString() + "nm", new Font(FontFamily.GenericSansSerif, 9), Brushes.Yellow, new PointF(GP.X, GP.Y)); if (Sep_Data_Is_Valid && SepToolActive != "N/A") { g.DrawString(SepToolActive, new Font(FontFamily.GenericSansSerif, 9), Brushes.Yellow, new PointF(GP.X, GP.Y + 15)); } } } // Here handle history points // First draw all previous history points int Number_of_Points_Drawn = 0; for (int Index = HistoryPoints.Count - 2; Index >= 0; Index--) { if (Number_of_Points_Drawn < Properties.Settings.Default.HistoryPoints) { HistoryPointsType I = HistoryPoints.ElementAt(Index); GPoint MarkerPositionLocal = FormMain.gMapControl.FromLatLngToLocal(new PointLatLng(I.LatLong.Lat, I.LatLong.Lng)); g.DrawEllipse(MyPen, MarkerPositionLocal.X, MarkerPositionLocal.Y, 3, 3); Number_of_Points_Drawn++; } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Here draw speed vector // // Find out what data should be used for speed vector? IAS, TAS, GSPD, MACH? if ((DataItemValidator(CALC_HDG_STRING) || DataItemValidator(DAP_HDG) || DataItemValidator(TRK)) && (DataItemValidator(DAP_GSPD) || DataItemValidator(CALC_GSPD_STRING))) { double Azimuth = 0.0; double Range = 0.0; if (DataItemValidator(CALC_GSPD_STRING)) { Range = double.Parse(CALC_GSPD_STRING); } else { Range = double.Parse(DAP_GSPD); } if (DataItemValidator(CALC_HDG_STRING)) { Azimuth = double.Parse(CALC_HDG_STRING); } else if (DataItemValidator(TRK)) { Azimuth = double.Parse(TRK); } else { Azimuth = double.Parse(DAP_HDG); } Range = (Range / 60) * (double)Properties.Settings.Default.SpeedVector; GeoCordSystemDegMinSecUtilities.LatLongClass ResultPosition = GeoCordSystemDegMinSecUtilities.CalculateNewPosition(new GeoCordSystemDegMinSecUtilities.LatLongClass(Position.Lat, Position.Lng), (double)Range, (double)Azimuth); GPoint MarkerPositionLocal = FormMain.gMapControl.FromLatLngToLocal(new PointLatLng(ResultPosition.GetLatLongDecimal().LatitudeDecimal, ResultPosition.GetLatLongDecimal().LongitudeDecimal)); g.DrawLine(MyPen, new Point(LocalPosition.X, LocalPosition.Y), new Point(MarkerPositionLocal.X, MarkerPositionLocal.Y)); } else { int T = 9; int r = T; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MyPen = new Pen(new SolidBrush(LabelAttributes.LineColor), LabelAttributes.LineWidth); MyPen.DashStyle = LabelAttributes.LineStyle; // Draw leader line g.DrawLine(MyPen, new Point(LocalPosition.X, LocalPosition.Y), new Point(LocalPosition.X - LabelOffset.X, LocalPosition.Y - LabelOffset.Y)); // Draw label box Point LabelStartPosition = GetLabelStartingPoint(); // Recalculate Label Width each cycle to adjust for the possible changes in the number of lines // and changes in the text size LabelHeight = 0; // Draw ModeA and coast indicator g.DrawString(ModeA_CI_STRING, ModeA_CI_FONT, ModeA_CI_BRUSH, LabelStartPosition.X + ModeA_CI_OFFSET.X, LabelStartPosition.Y + SpacingIndex); LabelHeight = LabelHeight + (int)ModeA_CI_FONT.Size + SpacingIndex * 2; if (CALLSIGN_STRING != "--------") { // Draw CALLSIGN g.DrawString(CALLSIGN_STRING, CALLSIGN_FONT, CALLSIGN_BRUSH, LabelStartPosition.X + CALLSIGN_OFFSET.X, LabelStartPosition.Y + LabelHeight); LabelHeight = LabelHeight + (int)CALLSIGN_FONT.Size + SpacingIndex * 2; } // Draw ModeC g.DrawString(ModeC_STRING, ModeC_FONT, ModeC_BRUSH, LabelStartPosition.X + ModeC_OFFSET.X, LabelStartPosition.Y + LabelHeight); // Draw CFL on the same line if (ModeC_STRING == null) { ModeC_STRING = "---"; } CFL_OFFSET.X = ModeC_STRING.Length * (int)ModeC_FONT.Size; CFL_OFFSET.Y = LabelStartPosition.Y + LabelHeight; g.DrawString(CFL_STRING, CFL_FONT, CFL_BRUSH, LabelStartPosition.X + CFL_OFFSET.X, CFL_OFFSET.Y); CFL_START_X = LabelStartPosition.X + CFL_OFFSET.X; CFL_START_Y = CFL_OFFSET.Y; // Draw GSPD on the same line GSPD_OFFSET.X = (ModeC_STRING.Length * (int)ModeC_FONT.Size) + (CFL_STRING.Length * (int)CFL_FONT.Size); GSPD_OFFSET.Y = LabelStartPosition.Y + LabelHeight; if (CALC_GSPD_STRING != " ---") { g.DrawString(CALC_GSPD_STRING, GSPD_FONT, GSPD_BRUSH, LabelStartPosition.X + GSPD_OFFSET.X, GSPD_OFFSET.Y); } else if (DAP_GSPD != "N/A") { g.DrawString(DAP_GSPD, GSPD_FONT, GSPD_BRUSH, LabelStartPosition.X + GSPD_OFFSET.X, GSPD_OFFSET.Y); } else { g.DrawString(" ---", GSPD_FONT, GSPD_BRUSH, LabelStartPosition.X + GSPD_OFFSET.X, GSPD_OFFSET.Y); } GSPD_START_X = LabelStartPosition.X + GSPD_OFFSET.X; GSPD_START_Y = GSPD_OFFSET.Y; LabelHeight = LabelHeight + (int)GSPD_FONT.Size + SpacingIndex * 2; if (ShowLabelBox == true) { ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // DRAW Assigned HDG, SPD and ROC ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // HDG g.DrawString(A_HDG_STRING, A_HDG_FONT, A_HDG_BRUSH, LabelStartPosition.X + A_HDG_OFFSET.X, LabelStartPosition.Y + LabelHeight); HDG_START_X = LabelStartPosition.X + A_HDG_OFFSET.X; HDG_START_Y = LabelStartPosition.Y + LabelHeight; // SPD A_SPD_OFFSET.X = A_HDG_STRING.Length * (int)A_HDG_FONT.Size; A_SPD_OFFSET.Y = LabelStartPosition.Y + LabelHeight; g.DrawString(A_SPD_STRING, A_SPD_FONT, A_SPD_BRUSH, LabelStartPosition.X + A_SPD_OFFSET.X, A_SPD_OFFSET.Y); SPD_START_X = LabelStartPosition.X + A_SPD_OFFSET.X; SPD_START_Y = A_SPD_OFFSET.Y; // ROC //A_ROC_OFFSET.X = A_SPD_OFFSET.X + A_SPD_OFFSET.X + A_SPD_STRING.Length * (int)A_SPD_FONT.Size; //A_ROC_OFFSET.Y = LabelStartPosition.Y + LabelHeight; // g.DrawString(A_ROC_STRING, A_ROC_FONT, A_ROC_BRUSH, LabelStartPosition.X + A_ROC_OFFSET.X, A_ROC_OFFSET.Y); LabelHeight = LabelHeight + (int)A_SPD_FONT.Size + SpacingIndex * 2; // Add the final spacing index and draw the box LabelHeight = LabelHeight + SpacingIndex * 2; g.DrawRectangle(MyPen, LabelStartPosition.X, LabelStartPosition.Y, LabelWidth, LabelHeight); } }
// This method takes in two Target Positions and determines if horizontal // separation is infringed. The first parameter is passed by reference as // the method will, in the case it determines that separation is infringed // set appropriate inication in the passed in Target. It actually sets all // items in the STCA_List private static void Check_And_Set_Horizontal_Infringed(ref DynamicDisplayBuilder.TargetType T1, DynamicDisplayBuilder.TargetType T2) { //////////////////////////////////////////////////////////////////////////////////////////////// // First extract and validate all the data // GlobalPosition Track_1_Pos = new GlobalPosition(new GlobalCoordinates(T1.Lat, T1.Lon)); GlobalPosition Track_2_Pos = new GlobalPosition(new GlobalCoordinates(T2.Lat, T2.Lon)); bool DataValid = false; double Track_1_SPD; double Track_2_SPD; double Track_1_TRK; double Track_2_TRK; if (!double.TryParse(T1.CALC_GSPD, out Track_1_SPD)) { DataValid = false; } if (!double.TryParse(T2.CALC_GSPD, out Track_2_SPD)) { DataValid = false; } if (!double.TryParse(T1.TRK, out Track_1_TRK)) { if (!double.TryParse(T1.DAP_HDG, out Track_1_TRK)) { DataValid = false; } } if (!double.TryParse(T2.TRK, out Track_2_TRK)) { if (!double.TryParse(T2.DAP_HDG, out Track_2_TRK)) { DataValid = false; } } // Data validated if (DataValid) { // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // Used to calculate the time to the min distance GlobalPosition Track_1 = new GlobalPosition(new GlobalCoordinates(Track_1_Pos.Latitude, Track_1_Pos.Longitude)); GlobalPosition Track_2 = new GlobalPosition(new GlobalCoordinates(Track_2_Pos.Latitude, Track_2_Pos.Longitude)); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // First check if the two targets are already in separation violation status. // If so, then add the STCA items to the STCA pair target double DistanceToTravel = geoCalc.CalculateGeodeticMeasurement(reference, Track_1, Track_2).PointToPointDistance; DistanceToTravel = DistanceToTravel * 0.00053996; // Convert to nautical miles if (DistanceToTravel < Min_Horizontal_Separation_Nm) { STCA_Target_Item STCA_Item = new STCA_Target_Item(); STCA_Item.CurrentDistance = DistanceToTravel; STCA_Item.STCA_Partner = T2.TrackNumber; STCA_Item.STCA_Status = STCA_Status_Type.Violation; STCA_Item.TimeToImpact_Sec = 10; STCA_Item.TimeToConflictSec = 0; T1.STCA_List.Add(STCA_Item); } // No they are not, then check if the two targets are going to be in // the separation violation status a parameter set time in the future // This is so called "violation prediction status" } }
public override void OnRender(Graphics g) { Pen MyPen = new Pen(new SolidBrush(LabelAttributes.TargetColor), LabelAttributes.TargetSize); MyPen.DashStyle = LabelAttributes.TargetStyle; // Draw AC Symbol g.DrawRectangle(MyPen, LocalPosition.X - 5, LocalPosition.Y - 5, 10, 10); AC_SYMB_START_X = LocalPosition.X - 5; AC_SYMB_START_Y = LocalPosition.Y - 5; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // Here handle drawing of Range/Bearing & SEP tool if (TargetToMonitor != -1) { Point StartPosition = new Point(LocalPosition.X, LocalPosition.Y); Point EndPosition = DynamicDisplayBuilder.GetTargetPositionByIndex(TargetToMonitor); g.DrawLine(new Pen(Brushes.Yellow, 1), StartPosition, EndPosition); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); GlobalPosition Start = new GlobalPosition(new GlobalCoordinates(this.Position.Lat, this.Position.Lng)); PointLatLng End_LatLng = FormMain.FromLocalToLatLng(EndPosition.X, EndPosition.Y); GlobalPosition End = new GlobalPosition(new GlobalCoordinates(End_LatLng.Lat, End_LatLng.Lng)); GeodeticMeasurement GM = geoCalc.CalculateGeodeticMeasurement(reference, End, Start); //////////////////////////////////////////////////////////////////////////////////////////// // Handle SEP Tool double TRK1_SPD = 0.0, TRK2_SPD = 0.0; double TRK1_AZ = 0.0, TRK2_AZ = 0.0; bool Sep_Data_Is_Valid = true; if (!double.TryParse(CALC_GSPD_STRING, out TRK1_SPD)) { if (!double.TryParse(DAP_GSPD, out TRK1_SPD)) Sep_Data_Is_Valid = false; } if (!double.TryParse(DynamicDisplayBuilder.GetTarget_CALC_GSPD_ByIndex(TargetToMonitor), out TRK2_SPD)) { if (!double.TryParse(DynamicDisplayBuilder.GetTarget_DAP_GSPD_ByIndex(TargetToMonitor), out TRK2_SPD)) Sep_Data_Is_Valid = false; } if (!double.TryParse(CALC_HDG_STRING, out TRK1_AZ)) { if (!double.TryParse(TRK, out TRK1_AZ)) { if (!double.TryParse(DAP_HDG, out TRK1_AZ)) Sep_Data_Is_Valid = false; } } if (!double.TryParse(DynamicDisplayBuilder.GetTarget_CALC_HDG_ByIndex(TargetToMonitor), out TRK2_AZ)) { if (!double.TryParse(DynamicDisplayBuilder.GetTargetTRKByIndex(TargetToMonitor), out TRK2_AZ)) { if (!double.TryParse(DynamicDisplayBuilder.GetTargetM_HDGByIndex(TargetToMonitor), out TRK2_AZ)) Sep_Data_Is_Valid = false; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // If all the necessary data is avilable // then pass it on to the SEP tool calculator // and then draw the result string SepToolActive = "N/A"; if (Sep_Data_Is_Valid) { SEP_Tool_Calculator SepTool = new SEP_Tool_Calculator(Start, End, TRK1_SPD, TRK2_SPD, TRK1_AZ, TRK2_AZ, 20); SEP_Tool_Calculator.OutData Sep_Tool_Data = SepTool.GetResult(); if (Sep_Tool_Data.Is_Converging) { g.DrawRectangle(new Pen(Brushes.Yellow, LabelAttributes.TargetSize), Sep_Tool_Data.Track_1_Pos_Min.X - 5, Sep_Tool_Data.Track_1_Pos_Min.Y - 5, 10, 10); g.DrawRectangle(new Pen(Brushes.Yellow, LabelAttributes.TargetSize), Sep_Tool_Data.Track_2_Pos_Min.X - 5, Sep_Tool_Data.Track_2_Pos_Min.Y - 5, 10, 10); g.DrawLine(new Pen(Brushes.Yellow, LabelAttributes.TargetSize), new Point(Sep_Tool_Data.Track_1_Pos_Min.X, Sep_Tool_Data.Track_1_Pos_Min.Y), new Point(StartPosition.X, StartPosition.Y)); g.DrawLine(new Pen(Brushes.Yellow, LabelAttributes.TargetSize), new Point(Sep_Tool_Data.Track_2_Pos_Min.X, Sep_Tool_Data.Track_2_Pos_Min.Y), new Point(EndPosition.X, EndPosition.Y)); TimeSpan T = TimeSpan.FromSeconds(Sep_Tool_Data.SecondsToMinimum); SepToolActive = "min d:" + Math.Round(Sep_Tool_Data.MinDistance, 1).ToString() + "/" + T.Minutes.ToString() + ":" + T.Seconds.ToString(); } } // Now compute position half way between two points. double distance = GM.PointToPointDistance / 2.0; if (distance > 0.0) { GlobalCoordinates GC = geoCalc.CalculateEndingGlobalCoordinates(reference, new GlobalCoordinates(End_LatLng.Lat, End_LatLng.Lng), GM.Azimuth, distance); GPoint GP = FormMain.FromLatLngToLocal(new PointLatLng(GC.Latitude.Degrees, GC.Longitude.Degrees)); double Distane_NM = 0.00053996 * GM.PointToPointDistance; g.DrawString(Math.Round(GM.Azimuth.Degrees).ToString() + "°/" + Math.Round(Distane_NM, 1).ToString() + "nm", new Font(FontFamily.GenericSansSerif, 9), Brushes.Yellow, new PointF(GP.X, GP.Y)); if (Sep_Data_Is_Valid && SepToolActive != "N/A") { g.DrawString(SepToolActive, new Font(FontFamily.GenericSansSerif, 9), Brushes.Yellow, new PointF(GP.X, GP.Y + 15)); } } } // Here handle history points // First draw all previous history points int Number_of_Points_Drawn = 0; for (int Index = HistoryPoints.Count - 2; Index >= 0; Index--) { if (Number_of_Points_Drawn < Properties.Settings.Default.HistoryPoints) { HistoryPointsType I = HistoryPoints.ElementAt(Index); GPoint MarkerPositionLocal = FormMain.gMapControl.FromLatLngToLocal(new PointLatLng(I.LatLong.Lat, I.LatLong.Lng)); g.DrawEllipse(MyPen, MarkerPositionLocal.X, MarkerPositionLocal.Y, 3, 3); Number_of_Points_Drawn++; } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Here draw speed vector // // Find out what data should be used for speed vector? IAS, TAS, GSPD, MACH? if ((DataItemValidator(CALC_HDG_STRING) || DataItemValidator(DAP_HDG) || DataItemValidator(TRK)) && (DataItemValidator(DAP_GSPD) || DataItemValidator(CALC_GSPD_STRING))) { double Azimuth = 0.0; double Range = 0.0; if (DataItemValidator(CALC_GSPD_STRING)) Range = double.Parse(CALC_GSPD_STRING); else Range = double.Parse(DAP_GSPD); if (DataItemValidator(CALC_HDG_STRING)) Azimuth = double.Parse(CALC_HDG_STRING); else if (DataItemValidator(TRK)) Azimuth = double.Parse(TRK); else Azimuth = double.Parse(DAP_HDG); Range = (Range / 60) * (double)Properties.Settings.Default.SpeedVector; GeoCordSystemDegMinSecUtilities.LatLongClass ResultPosition = GeoCordSystemDegMinSecUtilities.CalculateNewPosition(new GeoCordSystemDegMinSecUtilities.LatLongClass(Position.Lat, Position.Lng), (double)Range, (double)Azimuth); GPoint MarkerPositionLocal = FormMain.gMapControl.FromLatLngToLocal(new PointLatLng(ResultPosition.GetLatLongDecimal().LatitudeDecimal, ResultPosition.GetLatLongDecimal().LongitudeDecimal)); g.DrawLine(MyPen, new Point(LocalPosition.X, LocalPosition.Y), new Point(MarkerPositionLocal.X, MarkerPositionLocal.Y)); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MyPen = new Pen(new SolidBrush(LabelAttributes.LineColor), LabelAttributes.LineWidth); MyPen.DashStyle = LabelAttributes.LineStyle; // Draw leader line g.DrawLine(MyPen, new Point(LocalPosition.X, LocalPosition.Y), new Point(LocalPosition.X - LabelOffset.X, LocalPosition.Y - LabelOffset.Y)); // Draw label box Point LabelStartPosition = GetLabelStartingPoint(); // Recalculate Label Width each cycle to adjust for the possible changes in the number of lines // and changes in the text size LabelHeight = 0; // Draw ModeA and coast indicator g.DrawString(ModeA_CI_STRING, ModeA_CI_FONT, ModeA_CI_BRUSH, LabelStartPosition.X + ModeA_CI_OFFSET.X, LabelStartPosition.Y + SpacingIndex); LabelHeight = LabelHeight + (int)ModeA_CI_FONT.Size + SpacingIndex * 2; if (CALLSIGN_STRING != "--------") { // Draw CALLSIGN g.DrawString(CALLSIGN_STRING, CALLSIGN_FONT, CALLSIGN_BRUSH, LabelStartPosition.X + CALLSIGN_OFFSET.X, LabelStartPosition.Y + LabelHeight); LabelHeight = LabelHeight + (int)CALLSIGN_FONT.Size + SpacingIndex * 2; } // Draw ModeC g.DrawString(ModeC_STRING, ModeC_FONT, ModeC_BRUSH, LabelStartPosition.X + ModeC_OFFSET.X, LabelStartPosition.Y + LabelHeight); // Draw CFL on the same line if (ModeC_STRING == null) ModeC_STRING = "---"; CFL_OFFSET.X = ModeC_STRING.Length * (int)ModeC_FONT.Size; CFL_OFFSET.Y = LabelStartPosition.Y + LabelHeight; g.DrawString(CFL_STRING, CFL_FONT, CFL_BRUSH, LabelStartPosition.X + CFL_OFFSET.X, CFL_OFFSET.Y); CFL_START_X = LabelStartPosition.X + CFL_OFFSET.X; CFL_START_Y = CFL_OFFSET.Y; // Draw GSPD on the same line GSPD_OFFSET.X = (ModeC_STRING.Length * (int)ModeC_FONT.Size) + (CFL_STRING.Length * (int)CFL_FONT.Size); GSPD_OFFSET.Y = LabelStartPosition.Y + LabelHeight; if (CALC_GSPD_STRING != " ---") g.DrawString(CALC_GSPD_STRING, GSPD_FONT, GSPD_BRUSH, LabelStartPosition.X + GSPD_OFFSET.X, GSPD_OFFSET.Y); else if (DAP_GSPD != "N/A") g.DrawString(DAP_GSPD, GSPD_FONT, GSPD_BRUSH, LabelStartPosition.X + GSPD_OFFSET.X, GSPD_OFFSET.Y); else g.DrawString(" ---", GSPD_FONT, GSPD_BRUSH, LabelStartPosition.X + GSPD_OFFSET.X, GSPD_OFFSET.Y); GSPD_START_X = LabelStartPosition.X + GSPD_OFFSET.X; GSPD_START_Y = GSPD_OFFSET.Y; LabelHeight = LabelHeight + (int)GSPD_FONT.Size + SpacingIndex * 2; if (ShowLabelBox == true) { ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // DRAW Assigned HDG, SPD and ROC ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // HDG g.DrawString(A_HDG_STRING, A_HDG_FONT, A_HDG_BRUSH, LabelStartPosition.X + A_HDG_OFFSET.X, LabelStartPosition.Y + LabelHeight); HDG_START_X = LabelStartPosition.X + A_HDG_OFFSET.X; HDG_START_Y = LabelStartPosition.Y + LabelHeight; // SPD A_SPD_OFFSET.X = A_HDG_STRING.Length * (int)A_HDG_FONT.Size; A_SPD_OFFSET.Y = LabelStartPosition.Y + LabelHeight; g.DrawString(A_SPD_STRING, A_SPD_FONT, A_SPD_BRUSH, LabelStartPosition.X + A_SPD_OFFSET.X, A_SPD_OFFSET.Y); SPD_START_X = LabelStartPosition.X + A_SPD_OFFSET.X; SPD_START_Y = A_SPD_OFFSET.Y; // ROC //A_ROC_OFFSET.X = A_SPD_OFFSET.X + A_SPD_OFFSET.X + A_SPD_STRING.Length * (int)A_SPD_FONT.Size; //A_ROC_OFFSET.Y = LabelStartPosition.Y + LabelHeight; // g.DrawString(A_ROC_STRING, A_ROC_FONT, A_ROC_BRUSH, LabelStartPosition.X + A_ROC_OFFSET.X, A_ROC_OFFSET.Y); LabelHeight = LabelHeight + (int)A_SPD_FONT.Size + SpacingIndex * 2; // Add the final spacing index and draw the box LabelHeight = LabelHeight + SpacingIndex * 2; g.DrawRectangle(MyPen, LabelStartPosition.X, LabelStartPosition.Y, LabelWidth, LabelHeight); } }
/// <summary> /// ////////////////////////////////////////////////////////////////////////////////////// /// DO NOT CHANGE THE ORDER OF CALLS BELOW !!! /// /// </summary> private static void UpdateGlobalList() { foreach (TargetType CurrentTarget in CurrentTargetList) { CurrentTarget.TrackTerminateTreshold = 0; if (CurrentTarget.TrackNumber != -1) { GlobalTargetList[CurrentTarget.TrackNumber].ModeA = CurrentTarget.ModeA; GlobalTargetList[CurrentTarget.TrackNumber].ModeC_Previous_Cycle = ""; if (GlobalTargetList[CurrentTarget.TrackNumber].ModeC != null) GlobalTargetList[CurrentTarget.TrackNumber].ModeC_Previous_Cycle = "" + GlobalTargetList[CurrentTarget.TrackNumber].ModeC; GlobalTargetList[CurrentTarget.TrackNumber].ModeC = CurrentTarget.ModeC; GlobalTargetList[CurrentTarget.TrackNumber].CALC_GSPD = CurrentTarget.CALC_GSPD; if (CurrentTarget.DAP_GSPD != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].DAP_GSPD = CurrentTarget.DAP_GSPD; GlobalTargetList[CurrentTarget.TrackNumber].ACID_Mode_S = CurrentTarget.ACID_Mode_S; if (CurrentTarget.Mode_S_Addr != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].Mode_S_Addr = CurrentTarget.Mode_S_Addr; if (CurrentTarget.DAP_HDG != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].DAP_HDG = CurrentTarget.DAP_HDG; GlobalTargetList[CurrentTarget.TrackNumber].CALC_HDG = CurrentTarget.CALC_HDG; if (CurrentTarget.IAS != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].IAS = CurrentTarget.IAS; if (CurrentTarget.TRK != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].TRK = CurrentTarget.TRK; if (CurrentTarget.MACH != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].MACH = CurrentTarget.MACH; if (CurrentTarget.TAS != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].TAS = CurrentTarget.TAS; if (CurrentTarget.Roll_Ang != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].Roll_Ang = CurrentTarget.Roll_Ang; if (CurrentTarget.SelectedAltitude_ShortTerm != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].SelectedAltitude_ShortTerm = CurrentTarget.SelectedAltitude_ShortTerm; if (CurrentTarget.SelectedAltitude_LongTerm != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].SelectedAltitude_LongTerm = CurrentTarget.SelectedAltitude_LongTerm; if (CurrentTarget.Rate_Of_Climb != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].Rate_Of_Climb = CurrentTarget.Rate_Of_Climb; if (CurrentTarget.Barometric_Setting != "N/A") GlobalTargetList[CurrentTarget.TrackNumber].Barometric_Setting = CurrentTarget.Barometric_Setting; GlobalTargetList[CurrentTarget.TrackNumber].Lat = CurrentTarget.Lat; GlobalTargetList[CurrentTarget.TrackNumber].Lon = CurrentTarget.Lon; GlobalTargetList[CurrentTarget.TrackNumber].TimeSinceMidnight = CurrentTarget.TimeSinceMidnight; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Handle history points if (GlobalTargetList[CurrentTarget.TrackNumber].MyMarker.HistoryPoints.Count > 0) { // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); GlobalPosition Track_1 = new GlobalPosition(new GlobalCoordinates(CurrentTarget.Lat, CurrentTarget.Lon)); GlobalPosition Track_2 = new GlobalPosition(new GlobalCoordinates(GlobalTargetList[CurrentTarget.TrackNumber].MyMarker.HistoryPoints.Last().LatLong.Lat, GlobalTargetList[CurrentTarget.TrackNumber].MyMarker.HistoryPoints.Last().LatLong.Lng)); // Calculate distance traveled double DistanceTraveled = geoCalc.CalculateGeodeticMeasurement(reference, Track_1, Track_2).PointToPointDistance; DistanceTraveled = DistanceTraveled * 0.00053996; // Convert to nautical miles double BetweenTwoUpdates = CurrentTarget.TimeSinceMidnight - GlobalTargetList[CurrentTarget.TrackNumber].MyMarker.HistoryPoints.Last().TimeSinceMidnight; int Miliseconds = (int)(((BetweenTwoUpdates - Math.Floor(BetweenTwoUpdates)) * 10.0)); TimeSpan TimeDifference = new TimeSpan(0, 0, 0, (int)Math.Floor(BetweenTwoUpdates), Miliseconds); // Only update history position if there was actually a change in the distance if (DistanceTraveled > 0) { if (GlobalTargetList[CurrentTarget.TrackNumber].MyMarker.HistoryPoints.Count > Max_History_Points) GlobalTargetList[CurrentTarget.TrackNumber].MyMarker.HistoryPoints.Dequeue(); GMapTargetandLabel.HistoryPointsType HP = new GMapTargetandLabel.HistoryPointsType(); HP.LatLong = new PointLatLng(CurrentTarget.Lat, CurrentTarget.Lon); HP.TimeSinceMidnight = CurrentTarget.TimeSinceMidnight; GlobalTargetList[CurrentTarget.TrackNumber].MyMarker.HistoryPoints.Enqueue(HP); } } else { GMapTargetandLabel.HistoryPointsType HP = new GMapTargetandLabel.HistoryPointsType(); HP.LatLong = new PointLatLng(CurrentTarget.Lat, CurrentTarget.Lon); HP.TimeSinceMidnight = CurrentTarget.TimeSinceMidnight; GlobalTargetList[CurrentTarget.TrackNumber].MyMarker.HistoryPoints.Enqueue(HP); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// GlobalTargetList[CurrentTarget.TrackNumber].TrackNumber = CurrentTarget.TrackNumber; GlobalTargetList[CurrentTarget.TrackNumber].TrackTerminateTreshold = CurrentTarget.TrackTerminateTreshold; } else { int ModeAIndex = int.Parse(CurrentTarget.ModeA.ToString()); GlobalTargetList[ModeAIndex].ModeA = CurrentTarget.ModeA; GlobalTargetList[ModeAIndex].ModeC_Previous_Cycle = ""; if (GlobalTargetList[ModeAIndex].ModeC != null) GlobalTargetList[ModeAIndex].ModeC_Previous_Cycle = "" + GlobalTargetList[ModeAIndex].ModeC; GlobalTargetList[ModeAIndex].ModeC = CurrentTarget.ModeC; if (CurrentTarget.DAP_GSPD != "N/A") GlobalTargetList[ModeAIndex].DAP_GSPD = CurrentTarget.DAP_GSPD; GlobalTargetList[ModeAIndex].CALC_GSPD = CurrentTarget.CALC_GSPD; GlobalTargetList[ModeAIndex].ACID_Mode_S = CurrentTarget.ACID_Mode_S; if (CurrentTarget.Mode_S_Addr != "N/A") GlobalTargetList[ModeAIndex].Mode_S_Addr = CurrentTarget.Mode_S_Addr; if (CurrentTarget.DAP_HDG != "N/A") GlobalTargetList[ModeAIndex].DAP_HDG = CurrentTarget.DAP_HDG; GlobalTargetList[ModeAIndex].CALC_HDG = CurrentTarget.CALC_HDG; if (CurrentTarget.IAS != "N/A") GlobalTargetList[ModeAIndex].IAS = CurrentTarget.IAS; if (CurrentTarget.TRK != "N/A") GlobalTargetList[ModeAIndex].TRK = CurrentTarget.TRK; if (CurrentTarget.MACH != "N/A") GlobalTargetList[ModeAIndex].MACH = CurrentTarget.MACH; if (CurrentTarget.TAS != "N/A") GlobalTargetList[ModeAIndex].TAS = CurrentTarget.TAS; if (CurrentTarget.Roll_Ang != "N/A") GlobalTargetList[ModeAIndex].Roll_Ang = CurrentTarget.Roll_Ang; if (CurrentTarget.SelectedAltitude_ShortTerm != "N/A") GlobalTargetList[ModeAIndex].SelectedAltitude_ShortTerm = CurrentTarget.SelectedAltitude_ShortTerm; if (CurrentTarget.SelectedAltitude_LongTerm != "N/A") GlobalTargetList[ModeAIndex].SelectedAltitude_LongTerm = CurrentTarget.SelectedAltitude_LongTerm; if (CurrentTarget.Rate_Of_Climb != "N/A") GlobalTargetList[ModeAIndex].Rate_Of_Climb = CurrentTarget.Rate_Of_Climb; if (CurrentTarget.Barometric_Setting != "N/A") GlobalTargetList[ModeAIndex].Barometric_Setting = CurrentTarget.Barometric_Setting; GlobalTargetList[ModeAIndex].Lat = CurrentTarget.Lat; GlobalTargetList[ModeAIndex].Lon = CurrentTarget.Lon; GlobalTargetList[ModeAIndex].TimeSinceMidnight = CurrentTarget.TimeSinceMidnight; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Handle history points if (GlobalTargetList[ModeAIndex].MyMarker.HistoryPoints.Count > 0) { // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); GlobalPosition Track_1 = new GlobalPosition(new GlobalCoordinates(CurrentTarget.Lat, CurrentTarget.Lon)); GlobalPosition Track_2 = new GlobalPosition(new GlobalCoordinates(GlobalTargetList[ModeAIndex].MyMarker.HistoryPoints.Last().LatLong.Lat, GlobalTargetList[ModeAIndex].MyMarker.HistoryPoints.Last().LatLong.Lng)); // Calculate distance traveled double DistanceTraveled = geoCalc.CalculateGeodeticMeasurement(reference, Track_1, Track_2).PointToPointDistance; DistanceTraveled = DistanceTraveled * 0.00053996; // Convert to nautical miles double BetweenTwoUpdates = CurrentTarget.TimeSinceMidnight - GlobalTargetList[ModeAIndex].MyMarker.HistoryPoints.Last().TimeSinceMidnight; int Miliseconds = (int)(((BetweenTwoUpdates - Math.Floor(BetweenTwoUpdates)) * 10.0)); TimeSpan TimeDifference = new TimeSpan(0, 0, 0, (int)Math.Floor(BetweenTwoUpdates), Miliseconds); // Only update history position if there was actually a change in the distance if (DistanceTraveled > 0) { if (GlobalTargetList[ModeAIndex].MyMarker.HistoryPoints.Count > Max_History_Points) GlobalTargetList[ModeAIndex].MyMarker.HistoryPoints.Dequeue(); GMapTargetandLabel.HistoryPointsType HP = new GMapTargetandLabel.HistoryPointsType(); HP.LatLong = new PointLatLng(CurrentTarget.Lat, CurrentTarget.Lon); HP.TimeSinceMidnight = CurrentTarget.TimeSinceMidnight; GlobalTargetList[ModeAIndex].MyMarker.HistoryPoints.Enqueue(HP); } } else { GMapTargetandLabel.HistoryPointsType HP = new GMapTargetandLabel.HistoryPointsType(); HP.LatLong = new PointLatLng(CurrentTarget.Lat, CurrentTarget.Lon); HP.TimeSinceMidnight = CurrentTarget.TimeSinceMidnight; GlobalTargetList[ModeAIndex].MyMarker.HistoryPoints.Enqueue(HP); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// GlobalTargetList[ModeAIndex].TrackNumber = ModeAIndex; GlobalTargetList[ModeAIndex].TrackTerminateTreshold = CurrentTarget.TrackTerminateTreshold; } } CurrentTargetList.Clear(); foreach (TargetType GlobalTarget in GlobalTargetList) { if (GlobalTarget.TrackTerminateTreshold < Properties.Settings.Default.TrackCoast) { TargetType NewTarget = new TargetType(); GlobalTarget.TrackTerminateTreshold++; NewTarget.ModeA = GlobalTarget.ModeA; NewTarget.ModeC_Previous_Cycle = GlobalTarget.ModeC_Previous_Cycle; NewTarget.ModeC = GlobalTarget.ModeC; NewTarget.CALC_GSPD = GlobalTarget.CALC_GSPD; NewTarget.DAP_GSPD = GlobalTarget.DAP_GSPD; NewTarget.ACID_Mode_S = GlobalTarget.ACID_Mode_S; NewTarget.Mode_S_Addr = GlobalTarget.Mode_S_Addr; NewTarget.TRK = GlobalTarget.TRK; NewTarget.TAS = GlobalTarget.TAS; NewTarget.Roll_Ang = GlobalTarget.Roll_Ang; NewTarget.SelectedAltitude_ShortTerm = GlobalTarget.SelectedAltitude_ShortTerm; NewTarget.SelectedAltitude_LongTerm = GlobalTarget.SelectedAltitude_LongTerm; NewTarget.Rate_Of_Climb = GlobalTarget.Rate_Of_Climb; NewTarget.MACH = GlobalTarget.MACH; NewTarget.DAP_HDG = GlobalTarget.DAP_HDG; NewTarget.CALC_HDG = GlobalTarget.CALC_HDG; NewTarget.IAS = GlobalTarget.IAS; NewTarget.Barometric_Setting = GlobalTarget.Barometric_Setting; NewTarget.Lat = GlobalTarget.Lat; NewTarget.Lon = GlobalTarget.Lon; NewTarget.TimeSinceMidnight = GlobalTarget.TimeSinceMidnight; NewTarget.TrackNumber = GlobalTarget.TrackNumber; NewTarget.TrackTerminateTreshold = GlobalTarget.TrackTerminateTreshold; NewTarget.MyMarker = GlobalTarget.MyMarker; CurrentTargetList.Add(NewTarget); } else { if (GlobalTarget.MyMarker != null) GlobalTarget.MyMarker.TerminateTarget(); } } if (Properties.Settings.Default.DisplayPSR == true) { // Now append all the PSR tracks to the end of the display list foreach (TargetType PSRTgtList in PSRTargetList) { TargetType NewTarget = new TargetType(); NewTarget.ModeC_Previous_Cycle = PSRTgtList.ModeC_Previous_Cycle; NewTarget.Lat = PSRTgtList.Lat; NewTarget.Lon = PSRTgtList.Lon; NewTarget.TrackNumber = PSRTgtList.TrackNumber; NewTarget.TrackTerminateTreshold = 0; NewTarget.MyMarker = PSRTgtList.MyMarker; CurrentTargetList.Add(NewTarget); } } }
// This method takes in two Target Positions and determines if horizontal // separation is infringed. The first parameter is passed by reference as // the method will, in the case it determines that separation is infringed // set appropriate inication in the passed in Target. It actually sets all // items in the STCA_List private static void Check_And_Set_Horizontal_Infringed(ref DynamicDisplayBuilder.TargetType T1, DynamicDisplayBuilder.TargetType T2) { //////////////////////////////////////////////////////////////////////////////////////////////// // First extract and validate all the data // GlobalPosition Track_1_Pos = new GlobalPosition(new GlobalCoordinates(T1.Lat, T1.Lon)); GlobalPosition Track_2_Pos = new GlobalPosition(new GlobalCoordinates(T2.Lat, T2.Lon)); bool DataValid = false; double Track_1_SPD; double Track_2_SPD; double Track_1_TRK; double Track_2_TRK; if (!double.TryParse(T1.CALC_GSPD, out Track_1_SPD)) DataValid = false; if (!double.TryParse(T2.CALC_GSPD, out Track_2_SPD)) DataValid = false; if (!double.TryParse(T1.TRK, out Track_1_TRK)) { if (!double.TryParse(T1.DAP_HDG, out Track_1_TRK)) DataValid = false; } if (!double.TryParse(T2.TRK, out Track_2_TRK)) { if (!double.TryParse(T2.DAP_HDG, out Track_2_TRK)) DataValid = false; } // Data validated if (DataValid) { // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // Used to calculate the time to the min distance GlobalPosition Track_1 = new GlobalPosition(new GlobalCoordinates(Track_1_Pos.Latitude, Track_1_Pos.Longitude)); GlobalPosition Track_2 = new GlobalPosition(new GlobalCoordinates(Track_2_Pos.Latitude, Track_2_Pos.Longitude)); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // First check if the two targets are already in separation violation status. // If so, then add the STCA items to the STCA pair target double DistanceToTravel = geoCalc.CalculateGeodeticMeasurement(reference, Track_1, Track_2).PointToPointDistance; DistanceToTravel = DistanceToTravel * 0.00053996; // Convert to nautical miles if (DistanceToTravel < Min_Horizontal_Separation_Nm) { STCA_Target_Item STCA_Item = new STCA_Target_Item(); STCA_Item.CurrentDistance = DistanceToTravel; STCA_Item.STCA_Partner = T2.TrackNumber; STCA_Item.STCA_Status = STCA_Status_Type.Violation; STCA_Item.TimeToImpact_Sec = 10; STCA_Item.TimeToConflictSec = 0; T1.STCA_List.Add(STCA_Item); } // No they are not, then check if the two targets are going to be in // the separation violation status a parameter set time in the future // This is so called "violation prediction status" } }