Beispiel #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);
        }
Beispiel #2
0
        /// <summary>
        /// Process the given appendix.
        /// </summary>
        /// <param name="append">
        /// The name of the appendix.
        /// </param>
        /// <param name="framed">
        /// Whether or not the symbols are framed.
        /// </param>
        private void ProcessSymbolCollection(string append, bool framed)
        {
            const double Scale = 1.0;

            // Since some appendices cross reference symbols,
            // in other appendices, we'll check to make sure
            // we haven't already drawn a particular symbol code.
            IList <string> symList = new List <string>();

            var affiliations = new[] { "U", "F", "N", "H" };
            var keys         = MilAppendix.Keys(append);

            foreach (var ap in keys)
            {
                MilSymbol ms;
                var       sc = ap;
                if (symList.Contains(sc))
                {
                    continue;
                }

                symList.Add(sc);

                // There is no affiliation for weather
                var schemeKey = CodingScheme.GetCode(sc);
                if (schemeKey == CodingScheme.Weather)
                {
                    ms = new MilSymbol(sc, Scale, "X=67.8");
                    this.ProcessSymbol(ms, sc);
                    continue;
                }

                if (schemeKey == CodingScheme.TacticalGraphics)
                {
                    sc = sc.Substring(0, 1) + "H" + sc.Substring(2, 1) + "A" + sc.Substring(4);
                    ms = new MilSymbol(sc, Scale, "H=HH;H1=H1;W=W;W1=W1;T=TT;N=N;X=XX;V=VV;C=CC;Y=YY;Q=-60.0");
                    this.ProcessSymbol(ms, sc);
                    continue;
                }

                if (!framed)
                {
                    sc = sc.Substring(0, 2) + "X" + sc.Substring(3);
                }

                foreach (var c in affiliations)
                {
                    sc = sc[0] + c + sc[2] + "P" + sc.Substring(4, 10) + "E";

                    ms = new MilSymbol(sc, Scale, null, null);
                    this.ProcessSymbol(ms, sc);
                }
            }
        }
Beispiel #3
0
        public void CodingSchemeTest()
        {
            int gc = CodingScheme.GetCode(string.Empty);

            Assert.AreEqual(gc, 0);
            gc = CodingScheme.GetCode(null);
            Assert.AreEqual(gc, 0);
            gc = CodingScheme.GetCode("qqqqqqqqqqqqqqq");
            Assert.AreEqual(gc, 0);
            string str = CodingScheme.GetName(string.Empty);

            Assert.AreEqual(str, string.Empty);
            str = CodingScheme.GetName(null);
            Assert.AreEqual(str, string.Empty);
            str = CodingScheme.GetName("qqqqqqqqqqqqqqq");
            Assert.AreEqual(str, string.Empty);
            str = CodingScheme.GetName("gqpqqqqqqqqqqqq");
            Assert.AreEqual(str, "Tactical Graphics");
        }
Beispiel #4
0
        /// <summary>
        /// Determine once and for all if a symbol code is for a piece of equipment.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code.
        /// </param>
        /// <returns>
        /// A boolean indicating if the symbol code represents equipment.
        /// </returns>
        internal static bool IsEquipment(string symbolCode)
        {
            if (!Check(ref symbolCode))
            {
                return(false);
            }

            var schemeKey = CodingScheme.GetCode(symbolCode);

            if (schemeKey == CodingScheme.Intelligence)
            {
                return(true);
            }

            var func = symbolCode.Substring(4, 6).Trim(new[] { '-' });

            if (schemeKey == CodingScheme.Warfighting &&
                !string.IsNullOrEmpty(func) &&
                func[0] == 'E')
            {
                return(true);
            }

            if (schemeKey == CodingScheme.EmergencyManagement)
            {
                var catKey = CategoryBattleDimension.GetCode(symbolCode);
                if (catKey == CategoryBattleDimension.EmOperations &&
                    EmOperationsEquipment.Contains(func))
                {
                    return(true);
                }

                if (catKey == CategoryBattleDimension.EmInfrastructure &&
                    EmInfrastructureEquipment.Contains(func))
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #5
0
        /// <summary>
        /// Writes out the CXML file.
        /// </summary>
        /// <param name="ms">
        /// The symbol for which to generate the CXML.
        /// </param>
        /// <param name="rootName">
        /// The name to use for the symbol.
        /// </param>
        private void WriteCxml(MilSymbol ms, string rootName)
        {
            var symbolCode = (CodingScheme.GetCode(ms.SymbolCode) != CodingScheme.Weather) ? rootName + "*****" : ms.SymbolCode;

            var description = MilAppendix.Description(symbolCode);
            var lines       = description.Split(new[] { '\n' });
            var lineCount   = lines.Length - 1; // the last line is empty

            var sb = new StringBuilder();

            sb.AppendFormat(@"<Item Id=""{0}"" Name=""{1}"" Img=""Symbols\{1}.png"" Href="""">", this.index++, rootName);
            sb.AppendLine();
            if (lineCount > 0)
            {
                sb.AppendFormat(@" <Description>""{0}""</Description>", lines[lineCount - 1].Trim(new[] { ' ', '\n', '\r' }));
                sb.AppendLine();
            }
            else
            {
                sb.AppendFormat(@" <Description>""""</Description>");
                sb.AppendLine();
            }

            sb.AppendLine(@" <Facets>");
            sb.AppendLine(@"  <Facet Name=""Affiliation"">");
            sb.AppendFormat(@"   <String Value=""{0}"" />", StandardIdentity.GetName(symbolCode));
            sb.AppendLine();
            sb.AppendLine(@"  </Facet>");
            sb.AppendLine(@"  <Facet Name=""Battle Dimension"">");
            sb.AppendFormat(@"   <String Value=""{0}"" />", CategoryBattleDimension.GetName(symbolCode));
            sb.AppendLine();
            sb.AppendLine(@"  </Facet>");
            if (lineCount > 2)
            {
                sb.AppendLine(@"  <Facet Name=""Type"">");
                sb.AppendFormat(@"   <String Value=""{0}"" />", lines[2].Trim(new[] { ' ', '\n', '\r' }));
                sb.AppendLine();
                sb.AppendLine(@"  </Facet>");
            }

            sb.AppendLine(@"  <Facet Name=""Coding Scheme"">");
            sb.AppendFormat(@"   <String Value=""{0}"" />", CodingScheme.GetName(symbolCode));
            sb.AppendLine();
            sb.AppendLine(@"  </Facet>");
            if (lineCount - 1 > 3)
            {
                sb.AppendLine(@"  <Facet Name=""Key Phrases"">");
                for (var i = 3; i < lineCount - 1; i++)
                {
                    sb.AppendFormat(@"   <String Value=""{0}"" />", lines[i].Trim(new[] { ' ', '\n', '\r' }));
                    sb.AppendLine();
                }

                sb.AppendLine(@"  </Facet>");
            }

            sb.AppendLine(@" </Facets>");
            sb.AppendLine(@"</Item>");

#if DO_WRITES
            this.cxmlStream.Write(sb.ToString());
#endif
        }
Beispiel #6
0
        /// <summary>
        /// Always generates the entire symbol.
        /// The symbol code should not change very often.
        /// </summary>
        private void GenerateSymbol()
        {
            try
            {
                // Only draw after we have the symbol code, if drawing via method call
                if (this.suppressRefresh)
                {
                    return;
                }

                string symbolCode = this.SymbolCode;

                // Reinitialize
                this.IsDirty  = true;       // set a dirty flag to indicate the symbol needs updating
                this.bounds   = Rect.Empty;
                this.BaseRect = Rect.Empty;
                this.Children.Clear();      // tried to cheap this one out - but that doesn't work well
                this.elements.Clear();

                // Get the base symbol from "the" resource dictionary
                var baseSymbol = new MilSymbolBase(symbolCode, this.LineBrush, this.FillBrush);
                if (baseSymbol.Empty)
                {
                    return;
                }

                this.AddChild("Base", baseSymbol);

                var styles = MilLabels.GetStyles(this.LabelStyle);

                // There is only label decoration for weather codes
                int schemeKey = CodingScheme.GetCode(symbolCode);
                if (schemeKey == CodingScheme.Weather || schemeKey == CodingScheme.TacticalGraphics)
                {
                    this.GenerateLabels(styles);
                    return;
                }

                // Add in the echelon marking.
                // "high" is the maximum height from the decoration
                this.high = Echelon.Generate(this, symbolCode);

                // Draw headquarters, feint dummy, task force, and installation.
                // "high" is the maximum height from the decoration
                this.high = MilHats.Generate(this, symbolCode);

                // Take care of any Joker, Faker, or Exercise character
                this.AddChild(
                    "JFE", MilLabels.GenerateJokerFakerExercise(symbolCode, this.labels, styles[MilLabels.BigLabels]));

                // Add the black ribbon on the base symbol for space
                this.AddChild("Space", MilSymbolBase.GenerateSpace(symbolCode));

                // Indicate whether the entity is damaged or destroyed
                this.AddChild("OC", StatusOperationalCapacity.Generate(symbolCode));

                // Add the mobility to the base of the symbol
                this.AddChild("Mobility", DrawMobility.GenerateMobility(symbolCode));

                // We have to (re)generate the labels because the symbol code extent may be different
                this.GenerateLabels(styles);
            }
            catch (Exception ex)
            {
                Log.WriteMessage(LogLevel.Error, "Unable to construct military symbol", ex);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Selectively (re)generates labels.
        /// </summary>
        /// <param name="styles">
        /// An optional list of styles to apply to the labels.
        /// </param>
        private void GenerateLabels(IList <Style> styles)
        {
            try
            {
                if (this.suppressRefresh)
                {
                    return;
                }

                string symbolCode = this.SymbolCode;
                if (symbolCode == null)
                {
                    return;
                }

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

                if (styles == null)
                {
                    styles = MilLabels.GetStyles(this.LabelStyle);
                }

                this.IsDirty = true;

                int schemeKey = CodingScheme.GetCode(symbolCode);
                if (schemeKey == CodingScheme.Weather)
                {
                    // All extraneous information for weather is in the labels.
                    MilLabels.GenerateWeather(symbolCode, this.labels, this.AddChild);
                    return;
                }

                if (schemeKey == CodingScheme.TacticalGraphics)
                {
                    MilLabels.GenerateTacticalGraphics(
                        symbolCode, this.labels, styles[MilLabels.TacticalGraphicsLabels], this.AddChild);
                    return;
                }

                // Generate labels to the left of the symbol
                this.AddChild("Left", MilLabels.GenerateLeft(symbolCode, this.labels, styles[MilLabels.LeftLabels]));

                // Generate labels to the right of the symbol
                this.AddChild("Right", MilLabels.GenerateRight(symbolCode, this.labels, styles[MilLabels.RightLabels]));

                // This is just the quantity, if specified
                this.AddChild("Top", MilLabels.GenerateTop(this.high, symbolCode, this.labels, styles[MilLabels.TopLabels]));

                // This is just the C2 headquarters label
                this.AddChild("Middle", MilLabels.GenerateMiddle(symbolCode, this.labels));

                // This is the direction of movement (which apparently requires a label value)
                this.AddChild("Q", MilLabels.GenerateQ(symbolCode, this.labels, 0.0));
            }
            catch (Exception ex)
            {
                Log.WriteMessage(LogLevel.Error, "Unable to add labels to symbol", ex);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MilSymbolBase"/> class.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for this symbol.
        /// </param>
        /// <param name="lineBrush">
        /// An optional line brush for outlining the symbol.
        /// </param>
        /// <param name="fillBrush">
        /// An optional fill brush for filling the symbol's background.
        /// </param>
        public MilSymbolBase(string symbolCode, Brush lineBrush, Brush fillBrush)
        {
            if (symbolCode == null)
            {
                this.empty = true;
                return;
            }

            string stencil = CodeToStencil(symbolCode);

            if (MilAppendix.NoTemplate(stencil))
            {
                this.empty = true;
                return;
            }

            this.DataContext = this;

            // Will need to treat weather and tactical graphics carefully
            int schemeKey = CodingScheme.GetCode(symbolCode);

            if (schemeKey == CodingScheme.Weather)
            {
                // These symbols can change color - so we bind to Line and Fill
                if (symbolCode.StartsWith("WAS-WSTS"))
                {
                    if (lineBrush == null)
                    {
                        lineBrush = MilBrush.Rust;
                    }

                    if (fillBrush == null)
                    {
                        fillBrush = MilBrush.Rust;
                    }

                    this.SetLines(lineBrush);
                    this.SetLineFills(lineBrush, fillBrush);
                }

                this.Template = SymbolData.GetControlTemplate(stencil); // gets the template - the main thing
                this.empty    = this.Template == null;
                if (!this.empty)
                {
                    this.SetLimits(symbolCode);
                }

                return;
            }

            // If the standard identity (StandardIdentity) is some type of pending, we'll need the
            // anticipated (dashhed) outline for the frame.
            this.needDashed = SymbolData.IsDashed(symbolCode);

            // There are occasions when we need a line style that matches affiliation and present
            int  dimensionKey = CategoryBattleDimension.GetCode(symbolCode);
            bool needUnframed =
                schemeKey == CodingScheme.TacticalGraphics ||
                dimensionKey == CategoryBattleDimension.BdOther ||
                (schemeKey == CodingScheme.Warfighting &&
                 dimensionKey == CategoryBattleDimension.BdSubsurface);

            if (needUnframed)
            {
                this.unframedLine = MilBrush.GetLinePresent(MilBrush.FindColorScheme(symbolCode));
                this.SetUnframedLines(lineBrush);
            }

            this.SetLines(lineBrush);

            // Get a brush style if user didn't specify
            if (fillBrush == null)
            {
                fillBrush = MilBrush.FindColorScheme(symbolCode);
            }

            if (needUnframed)
            {
                this.SetUnframedLineFills(fillBrush);
            }

            this.SetLineFills(lineBrush, fillBrush);

            this.Template = SymbolData.GetControlTemplate(stencil); // gets the template - the main thing
            this.empty    = this.Template == null;
            if (!this.empty)
            {
                this.SetLimits(symbolCode);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Plots all of the core symbols that are in Appendix D.
        /// Since not all symbol codes are non-blank, there are some blanks in the output.
        /// Refer to MIL-STD 2525C for comparison.
        /// </summary>
        /// <param name="append">
        /// The appendix from which to get the symbols.
        /// </param>
        /// <param name="framed">
        /// Whether or not the symbols are framed.
        /// </param>
        private static void PlotAllSymbols(string append, bool framed)
        {
            Canvas cv = GetCanvas();

            if (cv == null)
            {
                return;
            }

            // Since some appendices cross reference symbols,
            // in other appendices, we'll check to make sure
            // we haven't already drawn a particular symbol code.
            IList <string> symList = new List <string>();

            double x = Edge;
            double y = Edge;

            var  affiliations = new[] { "U", "F", "N", "H" };
            bool first        = true;

            var keys = MilAppendix.Keys(append);

            foreach (string ap in keys)
            {
                string sc = ap;
                if (symList.Contains(sc))
                {
                    continue;
                }

                symList.Add(sc);

                // There is no affiliation for weather
                int schemeKey = CodingScheme.GetCode(sc);
                if (schemeKey == CodingScheme.Weather)
                {
                    // Check centering
                    // var ls1 = new Line { X1 = x + 5, Y1 = y + 5, X2 = x - 5, Y2 = y - 5, Stroke = new SolidColorBrush(Colors.Red), StrokeThickness = 1 };
                    // var ls2 = new Line { X1 = x - 5, Y1 = y + 5, X2 = x + 5, Y2 = y - 5, Stroke = new SolidColorBrush(Colors.Red), StrokeThickness = 1 };
                    // cv.Children.Add(ls1);
                    // cv.Children.Add(ls2);
                    var ms = new MilSymbol(sc, Scale, "X=67.8");
                    DrawSymbol(cv, ms, x, y);
                    if ((x += Tight) > 12 * Tight)
                    {
                        x  = Edge;
                        y += Tight;
                    }

                    continue;
                }

                if (schemeKey == CodingScheme.TacticalGraphics)
                {
                    // Check centering
                    // var ls1 = new Line { X1 = x + 5, Y1 = y + 5, X2 = x - 5, Y2 = y - 5, Stroke = new SolidColorBrush(Colors.Red), StrokeThickness = 1 };
                    // var ls2 = new Line { X1 = x - 5, Y1 = y + 5, X2 = x + 5, Y2 = y - 5, Stroke = new SolidColorBrush(Colors.Red), StrokeThickness = 1 };
                    // cv.Children.Add(ls1);
                    // cv.Children.Add(ls2);
                    sc = sc.Substring(0, 1) + "H" + sc.Substring(2, 1) + "A" + sc.Substring(4);
                    var ms = new MilSymbol(sc, Scale, "H=HH;H1=H1;W=W;W1=W1;T=TT;N=N;X=XX;V=VV;C=CC;Y=YY;Q=-60.0");
                    DrawSymbol(cv, ms, x, y);
                    if ((x += Tight) > 12 * Tight)
                    {
                        x  = Edge;
                        y += Tight + 25;
                    }

                    continue;
                }

                if (!framed)
                {
                    sc = sc.Substring(0, 2) + "X" + sc.Substring(3);
                }

                foreach (string c in affiliations)
                {
                    sc = sc[0] + c + sc[2] + "C" + sc.Substring(4, 10) + "E";

                    var ms = new MilSymbol(sc, Scale, null, null);
                    if (first && ms.Empty)
                    {
                        continue;
                    }

                    first = false;
                    DrawSymbol(cv, ms, x, y);

                    if ((x += Tight) > 12 * Tight)
                    {
                        x  = Edge;
                        y += Tight;
                    }
                }
            }
        }