예제 #1
0
        private void CalcEndButton_Click(object sender, EventArgs e)
        {
            /// Summary
            /// "West is Best, East is least"
            /// To calculate true bearing from compass bearing (and known deviation and variation):
            ///     Compass bearing +deviation = magnetic bearing
            ///     Magnetic bearing + variation = true bearing
            /// To calculate compass bearing from true bearing(and known deviation and variation):
            ///     True bearing -variation = Magnetic bearing
            /// West Variations are negative
            /// In the US, the agonic line is roughly along the Mississippi river
            /// In aviation, maps, GPS and runways use true bearings
            double CalcTrueBrg = CalcBrg;

            if (MagBrgCheckBox.Checked)
            {
                CalcTrueBrg -= CalcMag;
            }
            double[] CalcLocation =
                LatLongCalc.Destination(StartLat, StartLon, DistanceAdjust(CalcDist, CalcType), CalcTrueBrg, CalcType);
            EndLat = CalcLocation[0];
            EndLon = CalcLocation[1];
            EndLatitudeTextBox.Text  = Conversions.Degrees2SCT(EndLat, true);
            EndLongitudeTextBox.Text = Conversions.Degrees2SCT(EndLon, false);
            EndFixTextBox.Text       = string.Empty;
            UpdateCopyButtons();
        }
예제 #2
0
        public static string WriteHF(string Message, double Lat, double Lon, int Angle = 0, float Scale = 1)
        {
            // Lat is 'Y'!! Lon is 'X'!!
            float  curLat = (float)Lat;
            float  curLon = (float)Lon;
            PointF origin = new PointF(curLon, curLat);
            PointF nextChar = origin;
            float  scale = Scale / 3600F;
            int    angle = (int)InfoSection.MagneticVariation + Angle;
            string space = new string(' ', 27);
            string cr = Environment.NewLine;
            int    AsciiC; int[] SmplxC;
            string Result = string.Empty;

            foreach (char c in Message)
            {
                AsciiC = c;
                if ((AsciiC - 32 >= 0) & (AsciiC - 32 < 95))
                {
                    AsciiC -= 32;
                }
                else
                {
                    AsciiC = 10;      // 10 is '*' for 'error'
                }
                SmplxC  = RomanSimplex.Simplex[AsciiC];
                Result += DrawChar(c, SmplxC, nextChar, Angle, Scale);
                // Use points to update here
                SizeF offset = new SizeF(SmplxC[1] * scale, 0);
                nextChar = PointF.Add(nextChar, offset);
                nextChar = LatLongCalc.RotatePoint(nextChar, origin, angle);
                origin   = nextChar;
            }
            return(space + "; Label " + Message + cr + Result);
        }
예제 #3
0
 private void UpdateDistBrg()
 {
     Distance             = LatLongCalc.Distance(StartLat, StartLon, EndLat, EndLon, 'N');
     DispDistTextBox.Text = decimal.Round(Convert.ToDecimal(Distance), 2, MidpointRounding.AwayFromZero).ToString();
     TrueBrg             = LatLongCalc.Bearing(StartLat, StartLon, EndLat, EndLon);
     DispBrgTextBox.Text = decimal.Round(Convert.ToDecimal(TrueBrg), 2, MidpointRounding.AwayFromZero).ToString();
 }
예제 #4
0
 private void Fix2CenterButton_Click(object sender, EventArgs e)
 {
     // East declination is positive; west is negative
     // True (map) Heading = Mag Bearing + Declination
     // Mag Hdg = True Brg - Declination
     // VOR headings are always magnetic (Hdg)
     if (FixListDataGridView.SelectedRows.Count > 0)
     {
         string   FixText = string.Empty;
         double[] Coords;
         double   Lat = Convert.ToDouble(FixListDataGridView.SelectedRows[0].Cells[1].Value);
         double   Lon = Convert.ToDouble(FixListDataGridView.SelectedRows[0].Cells[2].Value);
         // VORs are in bearings and need no adjustment
         //double MagVar = Convert.ToDouble(MagVarTextBox.Text);
         if (FixOffsetCheckBox.Checked)
         {
             double Dist = Convert.ToDouble(FixDistTextBox.Text);
             double Brg  = Convert.ToDouble(FixBrgNUD.Value);
             //if (FixListDataGridView.SelectedRows[0].Cells[3].Value != null)
             //MagVar = Convert.ToDouble(FixListDataGridView.SelectedRows[0].Cells[3].Value);
             Coords  = LatLongCalc.Destination(Lat, Lon, Dist, Brg, 'N');
             Lat     = Coords[0]; Lon = Coords[1];
             FixText = String.Format("{0:000}", FixBrgNUD.Value) +
                       String.Format("{0:000.0}", Convert.ToDouble(FixDistTextBox.Text));
         }
         CenterLatitudeTextBox.Text = Conversions.Degrees2SCT(Lat, true);
         CenterLat = Lat;
         CenterLongitudeTextBox.Text = Conversions.Degrees2SCT(Lon, false);
         CenterLon = Lon;
         //MagVarTextBox.Text = MagVar.ToString();
         CenterFixTextBox.Text = FixListDataGridView.SelectedRows[0].Cells[0].Value.ToString() + FixText;
         UpdateStats();
     }
 }
예제 #5
0
 private void ImportFixToHold()
 {
     // East declination is positive; west is negative
     // True (map) Heading = Mag Bearing + Declination
     // Mag Hdg = True Brg - Declination
     // VOR headings are always magnetic (Hdg)
     if (FixListDataGridView.SelectedRows.Count > 0)
     {
         string   FixText = string.Empty;
         double[] Coords;
         double   Lat = Convert.ToDouble(FixListDataGridView.SelectedRows[0].Cells[1].Value);
         double   Lon = Convert.ToDouble(FixListDataGridView.SelectedRows[0].Cells[2].Value);
         // VORs are in bearings and need no adjustment
         //double MagVar = Convert.ToDouble(MagVarTextBox.Text);
         if (FixOffsetCheckBox.Checked)
         {
             double Dist = Convert.ToDouble(FixOffsetDistTextBox.Text);
             double Brg  = Convert.ToDouble(FixOffsetBrgNUD.Value);
             //if (FixListDataGridView.SelectedRows[0].Cells[3].Value != null)
             //MagVar = Convert.ToDouble(FixListDataGridView.SelectedRows[0].Cells[3].Value);
             Coords  = LatLongCalc.Destination(Lat, Lon, Dist, Brg, 'N');
             Lat     = Coords[0]; Lon = Coords[1];
             FixText = String.Format("{0:000}", FixOffsetBrgNUD.Value) +
                       String.Format("{0:000.0}", Convert.ToDouble(FixOffsetDistTextBox.Text));
         }
         HoldLatitudeTextBox.Text = Conversions.Degrees2SCT(Lat, true);
         HoldLat = Lat;
         HoldLongitudeTextBox.Text = Conversions.Degrees2SCT(Lon, false);
         HoldLon = Lon;
         //MagVarTextBox.Text = MagVar.ToString();
         HoldFixTextBox.Text         = FixListDataGridView.SelectedRows[0].Cells[0].Value.ToString() + FixText;
         AddFixLabelCheckBox.Enabled = AddFixSymbolCheckBox.Enabled = (HoldFixTextBox.TextLength != 0);
     }
 }
예제 #6
0
 private void InsertCoordsButton_Click(object sender, EventArgs e)
 {
     if ((CenterLat == -1) || (CenterLon == -1))
     {
         SCTcommon.SendMessage("First select the center point of the arc.");
         return;
     }
     if ((CalcDistanceTextBox.TextLength == 0) || (Convert.ToDouble(CalcDistanceTextBox.Text) < 1))
     {
         SCTcommon.SendMessage("Radius of arc must be at least 1 NM");
         return;
     }
     else
     {
         double[] Coords;
         double   CenterLat = Conversions.DMS2Degrees(CenterLatitudeTextBox.Text);
         double   CenterLon = Conversions.DMS2Degrees(CenterLongitudeTextBox.Text);
         double   Dist = Convert.ToDouble(CalcDistanceTextBox.Text);
         double   BrgStart = Convert.ToDouble(StartRadialNUD.Value);
         double   BrgEnd = Convert.ToDouble(EndRadialNUD.Value);
         double   MagVar = Convert.ToDouble(MagVarTextBox.Text);
         double   Lat; double Lon;
         if (CircleCheckBox.Checked)
         {
             Coords = LatLongCalc.Destination(CenterLat, CenterLon, Dist, 90, 'N');
             Lat    = Coords[0];
             Lon    = Coords[1];
             StartLatitudeTextBox.Text  = Conversions.Degrees2SCT(Lat, true);
             StartLongitudeTextBox.Text = Conversions.Degrees2SCT(Lon, false);
             StartLat = Lat;
             StartLon = Lon;
             EndLatitudeTextBox.Text  = Conversions.Degrees2SCT(Lat, true);
             EndLongitudeTextBox.Text = Conversions.Degrees2SCT(Lon, false);
             EndLat = Lat;
             EndLon = Lon;
         }
         else
         {
             if (MagBrgCheckBox.Checked == true)
             {
                 BrgStart -= MagVar; BrgEnd -= MagVar;
             }
             Coords = LatLongCalc.Destination(CenterLat, CenterLon, Dist, BrgStart, 'N');
             Lat    = Coords[0];
             Lon    = Coords[1];
             StartLatitudeTextBox.Text  = Conversions.Degrees2SCT(Lat, true);
             StartLongitudeTextBox.Text = Conversions.Degrees2SCT(Lon, false);
             StartLat = Lat;
             StartLon = Lon;
             Coords   = LatLongCalc.Destination(CenterLat, CenterLon, Dist, BrgEnd, 'N');
             Lat      = Coords[0];
             Lon      = Coords[1];
             EndLatitudeTextBox.Text  = Conversions.Degrees2SCT(Lat, true);
             EndLongitudeTextBox.Text = Conversions.Degrees2SCT(Lon, false);
             EndLat = Lat;
             EndLon = Lon;
         }
         UpdateStats();
     }
 }
예제 #7
0
 private void FixToEndButton_Click(object sender, EventArgs e)
 {
     if (FixListDataGridView.SelectedRows.Count > 0)
     {
         string   FixText = string.Empty;
         double[] Coords;
         double   Lat = Convert.ToDouble(FixListDataGridView.SelectedRows[0].Cells[1].Value);
         double   Lon = Convert.ToDouble(FixListDataGridView.SelectedRows[0].Cells[2].Value);
         // VORs are in bearings and need no adjustment
         //double MagVar = Convert.ToDouble(MagVarTextBox.Text);
         if (FixOffsetCheckBox.Checked)
         {
             double Dist = Convert.ToDouble(FixDistTextBox.Text);
             double Brg  = Convert.ToDouble(FixBrgNUD.Value);
             //if (FixListDataGridView.SelectedRows[0].Cells[3].Value != null)
             //MagVar = Convert.ToDouble(FixListDataGridView.SelectedRows[0].Cells[3].Value);
             Coords  = LatLongCalc.Destination(Lat, Lon, Dist, Brg, 'N');
             Lat     = Coords[0]; Lon = Coords[1];
             FixText = String.Format("{0:000}", FixBrgNUD.Value) +
                       String.Format("{0:000.0}", Convert.ToDouble(FixDistTextBox.Text));
         }
         EndLatitudeTextBox.Text = Conversions.Degrees2SCT(Lat, true);
         EndLat = Lat;
         EndLongitudeTextBox.Text = Conversions.Degrees2SCT(Lon, false);
         EndLon = Lon;
         //MagVarTextBox.Text = MagVar.ToString();
         EndFixTextBox.Text = FixListDataGridView.SelectedRows[0].Cells[0].Value.ToString() + FixText;
         UpdateStats();
     }
 }
예제 #8
0
 private void ChordStats()
 {
     ChordLength                = LatLongCalc.Distance(EndLat, EndLon, StartLat, StartLon);
     ChordArcAngle              = LatLongCalc.Deg2Rad(Math.Abs(StartBrg = EndBrg));
     ChordArcLength             = ChordArcAngle * ArcRadius;
     ChordRadius                = ChordArcLength / 2;
     ChordLengthTextBox.Text    = ChordLength.ToString("F3");
     ChordRadiusTextBox.Text    = ChordRadius.ToString("F3");
     ChordArcLengthTextBox.Text = ChordArcLength.ToString("F3");
 }
예제 #9
0
 private void FixEndCoordButton_Click(object sender, EventArgs e)
 {
     double[] coords =
         LatLongCalc.Destination(CenterLat, CenterLon, ArcRadius, Convert.ToDouble(EndRadialNUD.Value), 'N');
     EndLat = coords[0];
     EndLon = coords[1];
     EndLatitudeTextBox.Text  = Conversions.Degrees2SCT(EndLat, true);
     EndLongitudeTextBox.Text = Conversions.Degrees2SCT(EndLon, false);
     UpdateStats();
 }
예제 #10
0
 private void RadBrgStartButton_Click(object sender, EventArgs e)
 {
     double[] coords = new double[2];
     if ((CenterLat != -1) && (CenterLon != -1))
     {
         coords   = LatLongCalc.Destination(CenterLat, CenterLon, ArcRadius, Convert.ToDouble(StartRadialNUD.Value), 'N');
         StartLat = coords[0];
         StartLon = coords[1];
         StartLatitudeTextBox.Text  = Conversions.Degrees2SCT(StartLat, true);
         StartLongitudeTextBox.Text = Conversions.Degrees2SCT(StartLon, false);
     }
 }
예제 #11
0
 private void UpdateStats()
 {
     if ((CenterLat != -1) && (CenterLon != -1))
     {
         if ((StartLat != -1) && (StartLon != -1))
         {
             StartBrg = LatLongCalc.Bearing(CenterLat, CenterLon, StartLat, StartLon);
             if (StartBrg == 0)
             {
                 StartBrg = 360;
             }
             StartRadialNUD.Value     = Convert.ToInt32(StartBrg);
             ArcRadius                = LatLongCalc.Distance(CenterLat, CenterLon, StartLat, StartLon);
             CalcDistanceTextBox.Text = ArcRadius.ToString("F3");
         }
         else
         {
             ArcRadius                = -1;
             StartBrg                 = -1;
             StartRadialNUD.Value     = 1;
             CalcDistanceTextBox.Text = string.Empty;
         }
         if ((EndLat != -1) && (EndLon != -1))
         {
             EndBrg = LatLongCalc.Bearing(CenterLat, CenterLon, EndLat, EndLon);
             if (EndBrg == 0)
             {
                 EndBrg = 360;
             }
             EndRadialNUD.Value  = Convert.ToInt32(EndBrg);
             EndDistTextBox.Text = LatLongCalc.Distance(CenterLat, CenterLon, EndLat, EndLon).ToString("F3");
             if (ArcRadius != -1)
             {
                 ChordStats();
             }
         }
         else
         {
             EndBrg              = -1;
             EndRadialNUD.Value  = 1;
             EndDistTextBox.Text = string.Empty;
         }
     }
     else
     {
         ArcRadius = EndBrg = StartBrg - 1;
     }
     CheckArcButton();
 }
예제 #12
0
        public static float[] Adjust(float lat, float lon,
                                     float LeftRightSeconds, float UpDownSeconds, int Angle = 0, float Scale = 1)
        {
            // X and Y are Hershey units (one char is 30 x 30)
            // Latitude is Y and Longitude is X
            float[] result = new float[2];
            PointF  Origin = new PointF(lon, lat);
            SizeF   Offset = new SizeF(LeftRightSeconds / 3600, UpDownSeconds / 3600);
            PointF  Coord  = PointF.Add(Origin, Offset);
            int     angle  = (int)InfoSection.MagneticVariation + Angle;

            Coord     = LatLongCalc.RotatePoint(Coord, Origin, angle);
            result[0] = Coord.Y; result[1] = Coord.X;
            return(result);
        }
예제 #13
0
        private string BuildArcString(double StartBrg, double EndBrg, double StartLat, double StartLon)
        {
            string Lat0 = string.Empty; string Lon0 = string.Empty; string Lat1; string Lon1;
            string output = string.Empty;

            double[] Coords;
            // Make sure we aren't crossing 360...
            if ((StartBrg + Math.Abs(EndBrg - StartBrg)) > 360)
            {
                for (double i = StartBrg; i < 360; i++)
                {
                    Coords  = LatLongCalc.Destination(StartLat, StartLon, ArcRadius, i, 'N');
                    Lat1    = Conversions.Degrees2SCT(Coords[0], true);
                    Lon1    = Conversions.Degrees2SCT(Coords[1], false);
                    output += OutputText(Lat0, Lon0, Lat1, Lon1);
                    Lat0    = Lat1; Lon0 = Lon1;
                }
                for (double i = 1; i < EndBrg; i++)
                {
                    Coords  = LatLongCalc.Destination(StartLat, StartLon, ArcRadius, i, 'N');
                    Lat1    = Conversions.Degrees2SCT(Coords[0], true);
                    Lon1    = Conversions.Degrees2SCT(Coords[1], false);
                    output += OutputText(Lat0, Lon0, Lat1, Lon1);
                    Lat0    = Lat1; Lon0 = Lon1;
                }
            }
            else
            {
                for (double i = StartBrg; i < EndBrg; i++)
                {
                    Coords  = LatLongCalc.Destination(StartLat, StartLon, ArcRadius, i, 'N');
                    Lat1    = Conversions.Degrees2SCT(Coords[0], true);
                    Lon1    = Conversions.Degrees2SCT(Coords[1], false);
                    output += OutputText(Lat0, Lon0, Lat1, Lon1);
                    Lat0    = Lat1; Lon0 = Lon1;
                }
            }
            // Draw last segment
            Coords   = LatLongCalc.Destination(StartLat, StartLon, ArcRadius, EndBrg, 'N');
            PasteLat = Coords[0]; PasteLon = Coords[1];
            Lat1     = Conversions.Degrees2SCT(Coords[0], true);
            Lon1     = Conversions.Degrees2SCT(Coords[1], false);
            output  += OutputText(Lat0, Lon0, Lat1, Lon1);
            return(output);
        }
예제 #14
0
        private void CenterFromChord()
        {
            // The center is perpendicular to the midpoint of the start/end chord
            // Since I'm always turning to the right, perpendicular is always +90
            double Lat0 = (StartLat + EndLat) / 2.0;
            double Lon0 = (StartLon + EndLon) / 2.0;
            double Brg  = (LatLongCalc.Bearing(StartLat, StartLon, EndLat, EndLon) + 90) % 360;

            double[] Coords = LatLongCalc.Destination(Lat0, Lon0, RadiusFromChordArc(), Brg, 'N');
            CenterLat = Coords[0]; CenterLon = Coords[1];
            CenterLatitudeTextBox.Text  = Conversions.Degrees2SCT(CenterLat, true);
            CenterLongitudeTextBox.Text = Conversions.Degrees2SCT(CenterLon, false);
            CenterFixTextBox.Text       = "<calculated from chord>";
            StartBrg             = (LatLongCalc.Bearing(CenterLat, CenterLon, StartLat, StartLon) + 90) % 360;
            StartRadialNUD.Value = (int)StartBrg;
            EndBrg             = (LatLongCalc.Bearing(CenterLat, CenterLon, EndLat, EndLon) + 90) % 360;
            EndRadialNUD.Value = (int)EndBrg;
        }
예제 #15
0
        private string BuildArcString()
        {
            string Lat0 = string.Empty; string Lon0 = string.Empty; string Lat1; string Lon1;
            string output = string.Empty;

            double[] Coords;
            if (CircleCheckBox.Checked)
            {
                StartBrg = 0; EndBrg = 360;
            }
            // Make sure we aren't crossing 360...
            if ((StartBrg + (EndBrg - StartBrg)) > 360)
            {
                for (double i = StartBrg; i < 360; i++)
                {
                    Coords  = LatLongCalc.Destination(StartLat, StartLon, ArcRadius, i, 'N');
                    Lat1    = Conversions.Degrees2SCT(Coords[0], true);
                    Lon1    = Conversions.Degrees2SCT(Coords[1], false);
                    output += OutputText(Lat0, Lon0, Lat1, Lon1);
                    Lat0    = Lat1; Lon0 = Lon1;
                }
                for (double i = 1; i < EndBrg; i++)
                {
                    Coords  = LatLongCalc.Destination(StartLat, StartLon, ArcRadius, i, 'N');
                    Lat1    = Conversions.Degrees2SCT(Coords[0], true);
                    Lon1    = Conversions.Degrees2SCT(Coords[1], false);
                    output += OutputText(Lat0, Lon0, Lat1, Lon1);
                    Lat0    = Lat1; Lon0 = Lon1;
                }
            }
            else
            {
                for (double i = StartBrg; i < EndBrg; i++)
                {
                    Coords  = LatLongCalc.Destination(StartLat, StartLon, ArcRadius, i, 'N');
                    Lat1    = Conversions.Degrees2SCT(Coords[0], true);
                    Lon1    = Conversions.Degrees2SCT(Coords[1], false);
                    output += OutputText(Lat0, Lon0, Lat1, Lon1);
                    Lat0    = Lat1; Lon0 = Lon1;
                }
            }
            return(output);
        }
예제 #16
0
        public static double NMperLongDegree()
        {
            // Assumes all Lat/Longs are in Decimal degrees
            double DegPerNMequator = 69.172;
            double radCenterLat;

            // Use the user's desired center if possible
            if (InfoSection.CenterLatitude_Dec == 0)
            {
                radCenterLat =
                    LatLongCalc.Deg2Rad((FilterBy.NorthLimit + FilterBy.SouthLimit) / 2);
            }
            else
            {
                radCenterLat = LatLongCalc.Deg2Rad(InfoSection.CenterLatitude_Dec);
            }
            double result = Math.Cos(radCenterLat) * DegPerNMequator;

            return(result);
        }
예제 #17
0
        public static PointF RotatePoint(PointF pointToRotate, PointF centerPoint, double angleInDegrees)
        {
            // Given a center point and point to rotate (aka a line), rotate the line X degrees
            double radians = LatLongCalc.Deg2Rad(angleInDegrees);
            double sin     = Math.Sin(radians);
            double cos     = Math.Cos(radians);

            // Translate point back to origin
            pointToRotate.X -= centerPoint.X;
            pointToRotate.Y -= centerPoint.Y;

            // Rotate point
            double xnew = pointToRotate.X * cos - pointToRotate.Y * sin;
            double ynew = pointToRotate.X * sin + pointToRotate.Y * cos;

            // Translate point back
            PointF newPoint = new PointF((float)xnew + centerPoint.X, (float)ynew + centerPoint.Y);

            return(newPoint);
        }
예제 #18
0
        private static string DrawChar(char c, int[] hFont, PointF origin, int Angle, float Scale)
        {
            // Each vector needs to be (a) rotate to the angle of the line of text and (b) Scaled
            // One unit vector = 1 second or 90-100 feet.  Use the Scale function to adjust.
            string result = string.Empty; float X; float Y;
            bool   isFirst = true; string cr = Environment.NewLine;
            int    angle = (int)InfoSection.MagneticVariation + Angle;
            float  scale = Scale / 3600F;
            PointF end; PointF start = PointF.Empty;

            // Rotate through vectors in usual manner
            for (int i = 2; i < hFont.Length; i += 2)
            {
                Y = hFont[i + 1]; X = hFont[i];                     // X-Lon, Y-Lat
                if ((X == -1) || (Y == -1))                         // Next point is a break
                {
                    end = PointF.Empty;
                }
                else                                                // Get next vector (which will get moved to Start)
                {
                    SizeF vector = new SizeF(X * scale, Y * scale);
                    end = PointF.Add(origin, vector);
                    end = LatLongCalc.RotatePoint(end, origin, angle);
                }
                if (!(start.IsEmpty) && !(end.IsEmpty))
                {
                    result +=
                        SCTstrings.CharOut(Conversions.DecDeg2SCT(start.Y, true), Conversions.DecDeg2SCT(start.X, false),
                                           Conversions.DecDeg2SCT(end.Y, true), Conversions.DecDeg2SCT(end.X, false));
                    if (isFirst)
                    {
                        result += ";" + c.ToString();
                        isFirst = false;
                    }
                    result += cr;
                }
                start = end;                            // No matter what happened, move End to Start
            }
            return(result);                             // Lat Long string to draw ONE character!  (Sheesh)
        }
예제 #19
0
        public static string DrawSymbol(object[] FixData)
        {
            // FixData contains: ID(opt), FacilityID, Frequency(opt), Latitude, Longitude, NameOrUse, FixType
            string Lat0; string Lon0; string Lat1; string Lon1;
            string cr = Environment.NewLine; string space = new string(' ', 27);
            int    angle   = (int)InfoSection.MagneticVariation;
            string Fix     = FixData[1].ToString();
            string FixType = FixData[6].ToString();

            if (FixType == "FIX")
            {
                FixType = FixData[5].ToString();
            }
            float lat = Convert.ToSingle(FixData[3]);
            float lon = Convert.ToSingle(FixData[4]);

            int[] Symbol = SymbolRef(FixType);
            // Declare values used in loop below
            PointF[] Coords = new PointF[Symbol[0]];
            float    myX; float myY;
            // Loop through the symbol points, creating the initial pattern
            int Counter = 0;

            for (int i = 2; i <= Symbol[0] * 2; i += 2)
            {
                myX = Symbol[i + 1]; myY = Symbol[i];           // Lat is Y, Lon is X
                if ((myY != -1) && (myX != -1))
                {
                    Coords[Counter] = new PointF(myX /= 3600F, myY /= 3600F);
                }
                else
                {
                    Coords[Counter] = new PointF(-1F, -1F);
                }
                Counter++;
            }
            // Rotate the symbol to True North - with the first point as the origin (skip breaks)
            // WHY is Mag Var correct, but rotation is NOT?
            PointF PenUp = new PointF(-1, -1);

            for (int i = 0; i < Coords.Length; i++)
            {
                if (Coords[i] != PenUp)
                {
                    Coords[i] = LatLongCalc.RotatePoint(Coords[i], Coords[0], angle);
                }
            }
            // Get the centroid
            PointF centroid = LatLongCalc.Centroid(Coords);
            // Find the offset of the centroid from the FIX
            SizeF CentOffset = new SizeF(lon - centroid.X, lat - centroid.Y);

            // Move the symbol so it appears over the FIX
            for (int i = 0; i < Coords.Length; i++)
            {
                if (Coords[i] != PenUp)
                {
                    Coords[i] = PointF.Add(Coords[i], CentOffset);
                }
            }
            // Now write out the symbol strings in typical end-to-start rotation
            PointF start = PointF.Empty; PointF end;
            string Result = space + "; Symbol for " + FixType + " " + Fix + cr;

            foreach (PointF pointF in Coords)
            {
                if (pointF != PenUp)
                {
                    end = pointF;
                }
                else
                {
                    end = PointF.Empty;
                }
                if (!(start.IsEmpty) && !(end.IsEmpty))
                {
                    Lat0    = Conversions.DecDeg2SCT(start.Y, true);
                    Lat1    = Conversions.DecDeg2SCT(end.Y, true);
                    Lon0    = Conversions.DecDeg2SCT(start.X, false);
                    Lon1    = Conversions.DecDeg2SCT(end.X, false);
                    Result += SCTstrings.SSDout(Lat0, Lon0, Lat1, Lon1) + cr;
                }
                start = end;
            }
            return(Result);
        }
예제 #20
0
        private string BuildRaceTrack()
        {
            string output = string.Empty;
            // Step 1  - build leg away from hold fix
            double StartLat = HoldLat;
            double StartLon = HoldLon;
            double StartBrg; double EndBrg;
            double EndLat; double EndLon; double[] Coords;
            string Lat0; string Lon0; string Lat1; string Lon1;
            double OutTrack = Track;

            if (InboundTrackRadioButton.Checked)
            {
                OutTrack = Track + 540 % 360;                                   // Reverse track to outbnd
            }
            Coords  = LatLongCalc.Destination(StartLat, StartLon, LegLnthDist, OutTrack, 'N');
            EndLat  = Coords[0]; EndLon = Coords[1];
            Lat0    = Conversions.Degrees2SCT(PasteLat, true);
            Lon0    = Conversions.Degrees2SCT(PasteLon, false);
            Lat1    = Conversions.Degrees2SCT(EndLat, true);
            Lon1    = Conversions.Degrees2SCT(EndLon, false);
            output += OutputText(Lat0, Lon0, Lat1, Lon1);
            // Step 2 - Enter first turn
            StartLat = EndLat; StartLon = EndLon;   // This is start of turn
            if (TurnRight)
            {
                StartBrg = (OutTrack + 270) % 360;
                EndBrg   = (OutTrack + 90) % 360;
            }
            else
            {
                EndBrg   = (OutTrack + 270) % 360;
                StartBrg = (OutTrack + 90) % 360;
            }
            Coords = LatLongCalc.Destination(StartLat, StartLon, ArcRadius, EndBrg, 'N');
            double CenterLat = Coords[0]; double CenterLon = Coords[1];                     // Center of arc

            output += BuildArcString(StartBrg, EndBrg, CenterLat, CenterLon);               // Build Arc 1
            // Step 3 - Return leg
            // Need to close the end of arc with next line
            Coords   = LatLongCalc.Destination(StartLat, StartLon, ArcRadius * 2, EndBrg, 'N');
            StartLat = Coords[0]; StartLon = Coords[1];
            Lat0     = Conversions.Degrees2SCT(PasteLat, true);
            Lon0     = Conversions.Degrees2SCT(PasteLon, false);
            Lat1     = Conversions.Degrees2SCT(StartLat, true);
            Lon1     = Conversions.Degrees2SCT(StartLon, false);
            output  += OutputText(Lat0, Lon0, Lat1, Lon1);
            // Now draw the leg line
            double InTrack = (OutTrack + 180) % 360;

            Coords  = LatLongCalc.Destination(StartLat, StartLon, LegLnthDist, InTrack, 'N');
            EndLat  = Coords[0]; EndLon = Coords[1];
            Lat0    = Conversions.Degrees2SCT(StartLat, true);
            Lon0    = Conversions.Degrees2SCT(StartLon, false);
            Lat1    = Conversions.Degrees2SCT(EndLat, true);
            Lon1    = Conversions.Degrees2SCT(EndLon, false);
            output += OutputText(Lat0, Lon0, Lat1, Lon1);
            // Step 4 - Return arc
            if (TurnRight)
            {
                EndBrg   = (OutTrack + 270) % 360;
                StartBrg = (OutTrack + 90) % 360;
            }
            else
            {
                StartBrg = (OutTrack + 270) % 360;
                EndBrg   = (OutTrack + 90) % 360;
            }
            StartLat  = EndLat; StartLon = EndLon;
            Coords    = LatLongCalc.Destination(StartLat, StartLon, ArcRadius, EndBrg, 'N');
            CenterLat = Coords[0]; CenterLon = Coords[1];
            output   += BuildArcString(StartBrg, EndBrg, CenterLat, CenterLon);
            if (DrawFixSymbol)
            {
                output += DrawFix_Symbol();
            }
            if (DrawFixLabel)
            {
                output += DrawFix_Label();
            }
            return(output);
        }