예제 #1
0
        /// <summary>
        /// Takes the symbol code and matches one of the stencils in the resource dictionary.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for which to look up the stencil.
        /// </param>
        /// <returns>
        /// The string that should be used to get the ResourceDictionary entry for this symbol.
        /// </returns>
        public static string CodeToStencil(string symbolCode)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            int schemeKey = CodingScheme.GetCode(symbolCode);

            // Weather short circuits most considerations, at least for now
            if (schemeKey == CodingScheme.Weather)
            {
                return(symbolCode);
            }

            string stencil = symbolCode.Substring(0, 10).ToUpperInvariant();

            int dash = stencil.IndexOf('-', 4);

            if (dash > 0)
            {
                stencil = stencil.Substring(0, dash);
            }

            // Replace remaining '-'s with '_'s
            stencil = stencil.Replace('-', '_');

            // Return one of the four (approximately) that we know about
            int identityKey = StandardIdentity.GetNormalizedStandardIdentity(symbolCode);

            // Need the battle dimension
            int dimensionKey = CategoryBattleDimension.GetCode(symbolCode);

            // If we have a Z battle dimension cut right to the chase.
            // Get a blank stencil so we can add a question mark.
            if (dimensionKey == CategoryBattleDimension.BdUnknown)
            {
                return("I" + StandardIdentity.ToChar(identityKey) + "ZP");
            }

            string tail = stencil.Substring(2, 1) + "P" + stencil.Substring(4);

            // If we have EmergenctManagement and a NaturalEvent, get rid of the standard identity
            // or if we have a tactical graphic, get rid of the standard identity
            if ((schemeKey == CodingScheme.EmergencyManagement &&
                 dimensionKey == CategoryBattleDimension.EmNaturalEvents) ||
                schemeKey == CodingScheme.TacticalGraphics)
            {
                return(stencil.Substring(0, 1) + "_" + tail);
            }

            // If framed, we'll include the base affiliation
            if (dimensionKey != CategoryBattleDimension.BdOther)
            {
                return(stencil.Substring(0, 1) + StandardIdentity.ToChar(identityKey) + tail);
            }

            // Otherwise, we're looking for an unframed element
            return(stencil.Substring(0, 1) + "." + tail);
        }
예제 #2
0
        /// <summary>
        /// Generate the top labels for the symbol.
        /// </summary>
        /// <param name="high">
        /// The height at which to generate the labels.
        /// </param>
        /// <param name="symbolCode">
        /// The symbol code for which to generate the labels.
        /// </param>
        /// <param name="labels">
        /// The dictionary of labels to generate.
        /// </param>
        /// <param name="style">
        /// The style with which to render the labels.
        /// </param>
        /// <returns>
        /// A TextBlock that represents the rendered labels.
        /// </returns>
        internal static TextBlock GenerateTop(double high, string symbolCode, IDictionary <string, string> labels, Style style)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            if (labels == null)
            {
                return(null);
            }

            var middle = new TextBlock {
                Style = style                          /*TopLabels*/
            };

            bool gotLine = false;

            ProcessLabels(labels, true, new[] { "C" }, middle, ref gotLine);
            var height = gotLine ? (double)middle.GetValue(TextBlock.LineHeightProperty) : 0.0;

            middle.FindTextExtent();

            // This positions the top line just above the symbol, I think
            SetTopLeft(middle, -middle.Width / 2.0, high - height);
            return(middle);
        }
예제 #3
0
        /// <summary>
        /// This is the current background color for this particular symbol
        /// </summary>
        /// <param name="symbolCode">The symbol code</param>
        /// <returns>A brush representing the current background color for the symbol code</returns>
        public static Brush FindColorScheme(string symbolCode)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            if (OrderOfBattle.GetCode(symbolCode) == OrderOfBattle.Civilian)
            {
                if (StandardIdentity.IsColorHostile(symbolCode))
                {
                    return(GetDefault(Reds, ColorScheme));
                }

                return(GetDefault(Purples, ColorScheme));
            }

            switch (StandardIdentity.GetCode(symbolCode))
            {
            case StandardIdentity.AssumedFriend:
            case StandardIdentity.ExerciseFriend:
            case StandardIdentity.Friend:
            case StandardIdentity.ExerciseAssumedFriend:
                return(GetDefault(Blues, ColorScheme));

            case StandardIdentity.Hostile:
            case StandardIdentity.Joker:
            case StandardIdentity.Faker:
            case StandardIdentity.Suspect:
                return(GetDefault(Reds, ColorScheme));

            case StandardIdentity.ExerciseNeutral:
            case StandardIdentity.Neutral:
                return(GetDefault(Greens, ColorScheme));

            case StandardIdentity.ExercisePending:
            case StandardIdentity.Pending:
            case StandardIdentity.Unknown:
            case StandardIdentity.ExerciseUnknown:
                return(GetDefault(Yellows, ColorScheme));

            default:
                return(null);
            }
        }
예제 #4
0
        /// <summary>
        /// Returns the arrow representing a direction of travel for a mil symbol
        /// </summary>
        /// <param name="symbolCode">Code for the mil symbol</param>
        /// <param name="labels">The labels for the symbol, we're looking for "Q"</param>
        /// <param name="extraOffset">An extra offset for tactical graphics</param>
        /// <returns>The arrow shape representing the direction of travel</returns>
        internal static Shape GenerateQ(
            string symbolCode,
            IDictionary <string, string> labels,
            double extraOffset)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            string q;

            if (!labels.TryGetValue("Q", out q))
            {
                return(null);
            }

            double angle;

            if (!double.TryParse(q, out angle))
            {
                return(null);
            }

            double off = 0.0;

            if (CategoryBattleDimension.GetCode(symbolCode) == CategoryBattleDimension.BdGround)
            {
                off = SymbolData.GetBounds(symbolCode).Bottom;
            }

            off += extraOffset;
            return(new Path
            {
                Style = SymbolData.GetStyle("BS10"),
                Data = new PathGeometry
                {
                    Figures = new PathFigureCollection
                    {
                        GenerateArrowPoints(off, angle)
                    }
                }
            });
        }
예제 #5
0
        /// <summary>
        /// Generate the left labels for the symbol.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for which to generate the labels.
        /// </param>
        /// <param name="labels">
        /// The dictionary of labels to generate.
        /// </param>
        /// <param name="style">
        /// The style with which to render the labels.
        /// </param>
        /// <returns>
        /// A TextBlock that represents the rendered labels.
        /// </returns>
        internal static TextBlock GenerateLeft(string symbolCode, IDictionary <string, string> labels, Style style)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            // Pick off the left-oriented strings and write them out
            if (labels == null)
            {
                return(null);
            }

            var left = new TextBlock {
                Style = style                        /*LeftLabels*/
            };

            bool gotLine = false;

            ProcessLabels(labels, false, new[] { "W" }, left, ref gotLine);
            var height = gotLine ? (double)left.GetValue(TextBlock.LineHeightProperty) : 0.0;

            // At this point we need to process the remaining labels as if each row has a label.
            // Otherwise some label lines may appear in the wrong position
            // if other label lines are empty.
            // Setting "gotLine" to true forces a new line for each of the label lines.
            // More complicated logic might consider the height of the text block, prior to
            // the elimination of the empty lines.
            gotLine = true;

            ProcessLabels(labels, false, new[] { "X", "Y" }, left, ref gotLine);
            ProcessLabels(labels, false, new[] { "V" }, left, ref gotLine);
            ProcessLabels(labels, false, new[] { "T" }, left, ref gotLine);
            ProcessLabels(labels, true, new[] { "Z" }, left, ref gotLine);
            TruncateNewLines(left);

            Rect b = SymbolData.GetBounds(symbolCode);

            left.FindTextExtent();
            SetTopLeft(left, b.Left - left.Width - 10, b.Top - height);
            return(left); // we're only doing this to support unit test
        }
예제 #6
0
        /// <summary>
        /// Generate the middle label for the symbol.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for which to generate the labels.
        /// </param>
        /// <param name="labels">
        /// The dictionary of labels to generate.
        /// </param>
        /// <returns>
        /// A TextBlock that represents the rendered labels.
        /// </returns>
        internal static TextBlock GenerateMiddle(string symbolCode, IDictionary <string, string> labels)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            if (labels == null)
            {
                return(null);
            }

            var middle = new TextBlock {
                Style = SymbolData.GetStyle("MiddleLabels")
            };

            bool gotLine = false;

            ProcessLabels(labels, true, new[] { "AA" }, middle, ref gotLine);
            middle.FindTextExtent();
            SetTopLeft(middle, -middle.Width / 2, -middle.Height / 2);
            return(middle);
        }
예제 #7
0
        /// <summary>
        /// Adds the black ribbon at the top of the symbol for the standard identity "Space".
        /// </summary>
        /// <param name="symbolCode">The symbol code for the space entity.</param>
        /// <returns>The shape representing the black ribbon overlay for a space entity.</returns>
        internal static Shape GenerateSpace(string symbolCode)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            if (CategoryBattleDimension.GetCode(symbolCode) != CategoryBattleDimension.BdSpace)
            {
                return(null);
            }

            // Handy points for future reference
            // Inside for unknown ground
            // <Path Data="F0 M-61,-140 C-30,-175 30,-175 61,-140" />
            // Inside for hostile ground
            // <Polygon Points="-61,-105 0,-166 61,-105" />
            switch (StandardIdentity.GetNormalizedStandardIdentity(symbolCode))
            {
            case StandardIdentity.Friend:
            {
                return(GenerateBlackSpline(
                           new Point(-61, -107), new Point(-23, -148), new Point(23, -148), new Point(61, -107)));
            }

            case StandardIdentity.Unknown:
            {
                return(GenerateBlackSpline(
                           new Point(-61, -117), new Point(-30, -160), new Point(30, -160), new Point(61, -117)));
            }

            case StandardIdentity.Hostile:
            {
                return(new Path
                    {
                        Fill = new SolidColorBrush(Colors.Black),
                        Data = new PathGeometry
                        {
                            Figures = new PathFigureCollection
                            {
                                new PathFigure
                                {
                                    StartPoint = new Point(-61, -93),
                                    Segments = new PathSegmentCollection
                                    {
                                        new LineSegment {
                                            Point = new Point(0, -149)
                                        },
                                        new LineSegment {
                                            Point = new Point(61, -93)
                                        }
                                    }
                                }
                            }
                        }
                    });
            }

            case StandardIdentity.Neutral:
            {
                return(new Path
                    {
                        Fill = new SolidColorBrush(Colors.Black),
                        Data = new PathGeometry
                        {
                            Figures = new PathFigureCollection
                            {
                                new PathFigure
                                {
                                    StartPoint = new Point(-127, -104),
                                    Segments = new PathSegmentCollection
                                    {
                                        new LineSegment {
                                            Point = new Point(127, -104)
                                        },
                                        new LineSegment {
                                            Point = new Point(127, -139)
                                        },
                                        new LineSegment {
                                            Point = new Point(-127, -139)
                                        }
                                    }
                                }
                            }
                        }
                    });
            }
            }

            return(null);
        }
예제 #8
0
파일: MilHats.cs 프로젝트: HillHouse/MilSym
        /// <summary>
        /// Generates the correct combination of task force, installation, and feint dummy for a symbol.
        /// </summary>
        /// <param name="ms">
        /// The symbol to which the generated rendering is attached.
        /// </param>
        /// <param name="symbolCode">
        /// The symbol code for the given symbol
        /// </param>
        /// <returns>
        /// The maximum height of the generated rendering.
        /// </returns>
        internal static double Generate(MilSymbol ms, string symbolCode)
        {
            // This is the maximum height generated by this combination of pieces
            Rect r = ms.BaseRect;

            if (r.IsEmpty)
            {
                return(0);
            }

            double height = r.Top;

            if (!SymbolData.Check(ref symbolCode))
            {
                return(height);
            }

            char code = ModifierCode.GetCode(symbolCode);

            switch (code)
            {
            case ModifierCode.Headquarters:     // headquarters
                ms.AddChild("HQ", GenerateHeadquarters(ms));
                break;

            case ModifierCode.TaskForceHeadquarters:     // task force, headquarters
                ms.AddChild("TF", GenerateTaskForce(ms, out height));
                ms.AddChild("HQ", GenerateHeadquarters(ms));
                break;

            case ModifierCode.FeintDummyHeadquarters:     // feint dummy, headquarters
                ms.AddChild("FD", GenerateFeintDummy(ms, ref height));
                ms.AddChild("HQ", GenerateHeadquarters(ms));
                break;

            case ModifierCode.FeintDummyTaskForceHeadquarters:     // feint dummy, task force, headquarters
                ms.AddChild("TF", GenerateTaskForce(ms, out height));
                ms.AddChild("FD", GenerateFeintDummy(ms, ref height));
                ms.AddChild("HQ", GenerateHeadquarters(ms));
                break;

            case ModifierCode.TaskForce:     // task force
                ms.AddChild("TF", GenerateTaskForce(ms, out height));
                break;

            case ModifierCode.FeintDummy:     // feint dummy
                ms.AddChild("FD", GenerateFeintDummy(ms, ref height));
                break;

            case ModifierCode.FeintDummyTaskForce:     // feint dummy/task force
                ms.AddChild("TF", GenerateTaskForce(ms, out height));
                ms.AddChild("FD", GenerateFeintDummy(ms, ref height));
                break;

            case ModifierCode.Installation:     // installation
                ms.AddChild("Installation", GenerateInstallation(ms, out height));

                // There is an unfortunate overloading of the echelon character in the standard
                if (Echelon.GetCode(symbolCode) == 'B')
                {
                    ms.AddChild("FD", GenerateFeintDummy(ms, ref height));
                }

                break;

            case ModifierCode.Mobility:  // mobility
            case ModifierCode.Towed:     // towed
                break;
            }

            return(height);
        }
예제 #9
0
        /// <summary>
        /// Generate the labels for single point technical graphics.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for the technical graphic.
        /// </param>
        /// <param name="labels">
        /// The dictionary of labels for the technical graphic.
        /// </param>
        /// <param name="style">
        /// The style for the labels.
        /// </param>
        /// <param name="addChild">
        /// The delegate that actually adds the label to the UIElement.
        /// </param>
        internal static void GenerateTacticalGraphics(
            string symbolCode, IDictionary <string, string> labels, Style style, AddChild addChild)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return;
            }

            if (labels == null)
            {
                return;
            }

            string stencil = MilSymbolBase.CodeToStencil(symbolCode);

            double    extraOffset;
            TextBlock tb;

            // These are special case codes that require labels
            switch (stencil)
            {
            case "G_MPNDP":
            case "G_MPNDA":
            case "G_MPNDT":
            case "G_MPNDE":
            case "G_MPNDB":
            case "G_MPNDO":
            case "G_MPNDD":
            case "G_FPPCS":
            case "G_FPPCB":
            case "G_FPPCR":
            case "G_FPPCH":
            case "G_FPPCL":
                TacticalGraphicsPointLabels(labels, addChild, new[] { "H", "N", "T", "W" }, style);
                break;

            case "G_GPGPP":
                TacticalGraphicsPointLabels(labels, addChild, new[] { "H", "H1", "N", "T", "W-" }, style);
                break;

            case "G_GPGPPK":
            case "G_GPGPPL":
            case "G_GPGPPP":
            case "G_GPGPPR":
            case "G_GPGPPE":
            case "G_GPGPPS":
            case "G_GPGPPA":
            case "G_GPOPP":
            case "G_MPBCP":
            case "G_SPPX":
            case "G_SPPC":
            case "G_SPPY":
            case "G_SPPT":
            case "G_SPPD":
            case "G_SPPE":
            case "G_SPPL":
            case "G_SPPM":
            case "G_SPPR":
            case "G_SPPU":
            case "G_SPPO":
            case "G_SPPI":
            case "G_SPPN":
            case "G_SPPSZ":
            case "G_SPPSA":
            case "G_SPPSB":
            case "G_SPPSC":
            case "G_SPPSD":
            case "G_SPPSE":
            case "G_SPPSF":
            case "G_SPPSG":
            case "G_SPPSH":
            case "G_SPPSI":
            case "G_SPPSJ":
            case "G_SPPAS":
            case "G_SPPAT":
                TacticalGraphicsPointLabels(labels, addChild, new[] { "H", "N", "T", "W-" }, style);
                break;

            case "G_GPGPRI":
                GenerateSingleLabel(labels, "T", 0, -246, 0.5, 0.5, style, addChild);
                break;

            case "G_GPGPH":
                GenerateSingleLabel(labels, "H", 0, 0, 0.5, 0.5, style, addChild);
                break;

            case "G_GPGPPC":
                GenerateSingleLabel(labels, "T", 0, -175, 0.5, 0.5, style, addChild);
                break;

            case "G_GPGPPD":
                GenerateSingleLabel(labels, "T", 0, 0, 0.5, 0.25, style, addChild);
                break;

            case "G_GPGPPW":
                GenerateSingleLabel(labels, "T", 50, 0, 0.0, 0.5, style, addChild);
                break;

            case "G_GPAPP":
            case "G_GPAPC":
                GenerateSingleLabel(labels, "T", 0, 0, 0.5, 0.25, style, addChild);
                break;

            case "G_GPDPT":
                GenerateSingleLabel(labels, "T", 87, -87, 0.5, 0.5, style, addChild);
                break;

            case "G_MPOHTL":
                GenerateSingleLabel(labels, "X", 50, -250, 0.0, 0.0, style, addChild);
                break;

            case "G_MPOHTH":
                GenerateSingleLabel(labels, "X", 50, -230, 0.0, 0.0, style, addChild);
                break;

            case "G_MPNZ":
                GenerateSingleLabel(labels, "W", -110, -300, 1.0, 0.0, style, addChild);
                GenerateSingleLabel(labels, "V", -110, -200, 1.0, 0.0, style, addChild);
                GenerateSingleLabel(labels, "T", -110, -100, 1.0, 0.0, style, addChild);
                GenerateSingleLabel(labels, "H", 110, -300, 0.0, 0.0, style, addChild);
                GenerateSingleLabel(labels, "N", 110, -100, 0.0, 0.0, style, addChild);
                GenerateSingleLabel(labels, "C", 0, -300, 0.5, 1.0, style, addChild);
                tb = GenerateSingleLabel(labels, "Y", 0, 0, 0.5, 0.0, style, addChild);
                tb.FindTextExtent();
                extraOffset = tb != null ? tb.Height : 0.1;
                addChild("Q", GenerateQ(symbolCode, labels, extraOffset));
                break;

            case "G_MPNEB":
                GenerateSingleLabel(labels, "W", -110, -300, 1.0, 0.0, style, addChild);
                GenerateSingleLabel(labels, "T", -110, -100, 1.0, 0.0, style, addChild);
                GenerateSingleLabel(labels, "H", 110, -300, 0.0, 0.0, style, addChild);
                GenerateSingleLabel(labels, "N", 110, -100, 0.0, 0.0, style, addChild);
                tb = GenerateSingleLabel(labels, "Y", 0, 0, 0.5, 0.0, style, addChild);
                tb.FindTextExtent();
                extraOffset = tb != null ? tb.Height : 0.1;
                addChild("Q", GenerateQ(symbolCode, labels, extraOffset));
                break;

            case "G_MPNEC":
                GenerateSingleLabel(labels, "W", -94, -300, 1.0, 0.0, style, addChild);
                GenerateSingleLabel(labels, "T", -94, -100, 1.0, 0.0, style, addChild);
                GenerateSingleLabel(labels, "H", 94, -300, 0.0, 0.0, style, addChild);
                GenerateSingleLabel(labels, "N", 94, -100, 0.0, 0.0, style, addChild);
                tb = GenerateSingleLabel(labels, "Y", 0, 0, 0.5, 0.0, style, addChild);
                tb.FindTextExtent();
                extraOffset = tb != null ? tb.Height : 0.1;
                addChild("Q", GenerateQ(symbolCode, labels, extraOffset));
                break;

            case "G_FPPTS":
                GenerateSingleLabel(labels, "H", 50, 75, 0.0, 0.5, style, addChild);
                GenerateSingleLabel(labels, "H1", -50, 75, 1.0, 0.5, style, addChild);
                GenerateSingleLabel(labels, "T", 50, -75, 0.0, 0.5, style, addChild);
                break;

            case "G_FPPTN":
                GenerateSingleLabel(labels, "T", 50, -75, 0.0, 0.5, style, addChild);
                break;

            case "G_FPPCF":
                GenerateSingleLabel(labels, "T", 50, 0, 0.0, 0.5, style, addChild);
                break;
            }
        }
예제 #10
0
        /// <summary>
        /// Generate the labels for the single point weather symbology.
        /// </summary>
        /// <param name="symbolCode">
        /// The weather symbol code.
        /// </param>
        /// <param name="labels">
        /// The dictionary of labels to be displayed with the weather symbology.
        /// </param>
        /// <param name="addChild">
        /// The delegate that will actually add the child to the UIElement.
        /// </param>
        internal static void GenerateWeather(string symbolCode, IDictionary <string, string> labels, AddChild addChild)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return;
            }

            if (labels == null)
            {
                return;
            }

            // There are very few weather codes that require labels - so we'll handle them via a case statement
            string label;

            switch (symbolCode)
            {
            case "WOS-HDS---P----":                // X - altitude
            {
                double depth  = 0.0;
                var    ok     = labels.ContainsKey("X") && double.TryParse(labels["X"], out depth);
                var    splits = (ok ? depth.ToString(Culture) : "6.3").Split('.');
                var    meters = IntegerLabel(0, -100, splits[0], "MeterDepthLabel");
                addChild("Meters", meters);

                // Plot the first fractional digit offset
                if (splits.Length > 1)
                {
                    meters.FindTextExtent();
                    addChild(
                        "Decimeters",
                        IntegerLabel(meters.Width / 2, -25, splits[1].Substring(0, 1), "DecimeterDepthLabel"));
                }

                return;
            }

            case "WAS-WSF-LVP----":                // X - altitude
            {
                label = labels.ContainsKey("X") ? labels["X"] : "100";
                addChild("Altitude", IntegerLabel(63, -55, label, "FreezeLabel"));
                return;
            }

            case "WAS-WST-LVP----":                // X - altitude
            {
                label = labels.ContainsKey("X") ? labels["X"] : "380";
                addChild("Altitude", IntegerLabel(0, -61, label, "TropoLabel"));
                return;
            }

            case "WAS-PLT---P----":                // low pressure
            {
                label = labels.ContainsKey("X") ? labels["X"] : "270";
                addChild("Altitude", IntegerLabel(0, -136, label, "PressureLabel"));
                return;
            }

            case "WAS-PHT---P----":                // high pressure
            {
                label = labels.ContainsKey("X") ? labels["X"] : "460";
                addChild("Altitude", IntegerLabel(0, 2, label, "PressureLabel"));
                return;
            }

            case "WAS-WC----P----":
            {
                int cloudCover;     // 0 through 9}
                if (labels.ContainsKey("AA") &&
                    int.TryParse(labels["AA"], out cloudCover))
                {
                    addChild("CloudCover", WindBarb.GenerateCloudCover(2, cloudCover));
                }

                return;
            }

            case "WAS-WP----P----": // wind barb
            {
                int cloudCover;     // 0 through 9}
                if (labels.ContainsKey("AA") &&
                    int.TryParse(labels["AA"], out cloudCover))
                {
                    addChild("CloudCover", WindBarb.GenerateCloudCover(1, cloudCover));
                }

                double speed;            // in knots
                double?speedIn = null;
                if (labels.ContainsKey("Z") &&
                    double.TryParse(labels["Z"], out speed))
                {
                    speedIn = speed;
                }

                bool southernHemisphere = labels.ContainsKey("Y") && labels["Y"].ToUpper() == "S";

                double direction;        // in degrees
                if (labels.ContainsKey("Q") &&
                    double.TryParse(labels["Q"], out direction))
                {
                    addChild("Wind", WindBarb.GenerateWind(speedIn, direction, southernHemisphere));
                }

                return;
            }
            }
        }
예제 #11
0
        /// <summary>
        /// Generates barge mobility object.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code containing the mobility indicator for which to create a mobility Shape.
        /// </param>
        /// <returns>
        /// A Shape object representing the mobility object.
        /// </returns>
        public static Shape GenerateMobility(string symbolCode)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            if (!Mobility.IsMobility(symbolCode))
            {
                return(null);
            }

            Rect         b      = SymbolData.GetBounds(symbolCode);
            double       bottom = b.Bottom + HalfWidth;
            bool         flat   = SymbolData.IsBaseFlat(symbolCode);
            const double X      = End - Rad;

            switch (Mobility.GetCode(symbolCode))
            {
            case Mobility.WheeledLimited:
                return(GenerateWheels(new[] { -X, X }, bottom));

            case Mobility.WheeledCrossCountry:
                return(GenerateWheels(new[] { -X, 0, X }, bottom));

            case Mobility.Tracked:
                return(GenerateTracked(bottom));

            case Mobility.WheeledTracked:
                return(GenerateWheeledTracked(bottom));

            case Mobility.Towed:
                if (flat)
                {
                    bottom += Rad;
                }

                return(GenerateTowed(bottom));

            case Mobility.Railway:
                return(GenerateWheels(new[] { -X, -X + TwoRad, X - TwoRad, X }, bottom));

            case Mobility.OverSnow:
                if (flat)
                {
                    bottom += TwoRad;
                }

                return(GenerateOverSnow(bottom));

            case Mobility.Sled:
                if (!flat)
                {
                    bottom -= TwoRad;
                }

                return(GenerateSled(bottom));

            case Mobility.PackAnimals:
                return(GeneratePackAnimals(bottom));

            case Mobility.Barge:
                return(GenerateBarge(bottom));

            case Mobility.Amphibious:
                return(GenerateAmphibious(bottom));

            case Mobility.TowedArrayShort:
                return(GenerateArray(new[] { -End - TwoSqr, 0.0, End + TwoSqr }, bottom + ThreeSqr - HalfWidth));

            case Mobility.TowedArrayLong:
                if (!flat)
                {
                    bottom -= Sqr + HalfWidth;
                }

                return(GenerateArray(
                           new[]
                {
                    -End - TwoSqr, -HalfEnd - Sqr, 0.0, HalfEnd + Sqr, End + TwoSqr
                },
                           bottom + ThreeSqr - HalfWidth));
            }

            return(null);
        }