/// <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); }
/// <summary> /// When is the top of the symbol flat? /// Answer: /// 1. normalize StandardIdentity to 'F', 'H', 'N' or 'U' /// 2. return true when it is Subsurface /// 3. return true when it is Neutral /// 4. return true when it is Friendly Units, Installations, or SOF /// 5. return true when it is Friendly Emergency Operations /// a. technically, friendly emergency equipment is not flat /// </summary> /// <param name="symbolCode"> /// The symbol code to check for a flat top to the symbol. /// </param> /// <returns> /// Returns a boolean to indicate whether the top of the symbol is flat. /// </returns> internal static bool IsTopFlat(string symbolCode) { if (!Check(ref symbolCode)) { return(false); } int dimensionKey = CategoryBattleDimension.GetCode(symbolCode); if (dimensionKey == CategoryBattleDimension.BdSubsurface) { return(true); } int identityKey = StandardIdentity.GetNormalizedStandardIdentity(symbolCode); if (identityKey == StandardIdentity.Neutral) { return(true); } if (identityKey == StandardIdentity.Friend) { if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir || dimensionKey == CategoryBattleDimension.BdSeaSurface || dimensionKey == CategoryBattleDimension.BdUnknown) { return(false); } if (IsEquipment(symbolCode)) { return(false); } return(true); } return(false); }
/// <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); }
/// <summary> /// Generate the installation rendering for the passed in symbol. /// </summary> /// <param name="ms"> /// The military symbol for which to provide the installation rendering. /// </param> /// <param name="height"> /// The height at which to provide the installation rendering. /// </param> /// <returns> /// The graphics Shape object that represents the installation rendering. /// </returns> private static Shape GenerateInstallation(MilSymbol ms, out double height) { //// U&PGW ZSGF full unknown (flat) //// AP full air (not flat) //// U subsurface (flat) //// N&L ZSGF full neutral (flat) //// AP full air (flat) //// U subsurface (flat) //// H&S ZSGF full hostile (not flat) //// AP full air (not flat) //// U subsurface (flat) //// F&ADMJK Z(IG)S full friendly (not flat) //// F(~IG) full friendly (flat) //// AP full air (not flat) //// U subsurface (flat) height = -185; Brush br = new SolidColorBrush(Colors.Black); int si = StandardIdentity.GetNormalizedStandardIdentity(ms.SymbolCode); if (SymbolData.IsTopFlat(ms.SymbolCode)) { double t = ms.BaseRect.Top; if (si == StandardIdentity.Unknown) { t += SymbolData.HalfWidth; } height = t - 30; return(GenericInstallation(br, height, t)); } int bd = CategoryBattleDimension.GetCode(ms.SymbolCode); bool ap = bd == CategoryBattleDimension.BdSpace || bd == CategoryBattleDimension.BdAir; // The cases cover those surfaces which are flat on top versus those that are not switch (si) { case StandardIdentity.Unknown: // Outside for unknown space if (ap) { return(UnknownSpaceInstallation(br, height)); } return(UnknownGroundInstallation(br, height)); case StandardIdentity.Hostile: // Outside for hostile space if (ap) { height = -165; return(HostileSpaceInstallation(br, height)); } return(HostileGroundInstallation(br, height)); case StandardIdentity.Friend: height = -175; // Outside for friendly space if (ap) { return(FriendSpaceInstallation(br, height)); } return(FriendCircleInstallation(br, height)); } return(null); }
/// <summary> /// Generate the task force rendering for the passed in symbol. /// </summary> /// <param name="ms"> /// The military symbol for which to provide the task force rendering. /// </param> /// <param name="height"> /// The height at which to provide the task force rendering. /// </param> /// <returns> /// The graphics Path object that represents the task force rendering. /// </returns> private static Path GenerateTaskForce(MilSymbol ms, out double height) { height = -185; double bottom = 0; const double Wide = 54; int si = StandardIdentity.GetNormalizedStandardIdentity(ms.SymbolCode); if (SymbolData.IsTopFlat(ms.SymbolCode)) { bottom = ms.BaseRect.Top; if (si == StandardIdentity.Unknown) { bottom += SymbolData.HalfWidth; } height = bottom - 75; } else { int bd = CategoryBattleDimension.GetCode(ms.SymbolCode); bool ap = bd == CategoryBattleDimension.BdSpace || bd == CategoryBattleDimension.BdAir; // The cases cover those surfaces which are flat on top versus those that are not switch (si) { case StandardIdentity.Unknown: if (ap) { height = -230; // space bottom = -133; } else { height = -250; // ground bottom = -154; } break; case StandardIdentity.Hostile: if (ap) { height = -230; // space bottom = -107; } else { height = -253; // ground bottom = -119; } break; case StandardIdentity.Friend: height = -222; if (ap) { bottom = -121; // space } else { bottom = -137; // ground circles } break; } } return(new Path { Style = SymbolData.GetStyle("BS10"), Data = new PathGeometry { Figures = new PathFigureCollection { new PathFigure { StartPoint = new Point(Wide, bottom), Segments = new PathSegmentCollection { new LineSegment { Point = new Point(Wide, height) }, new LineSegment { Point = new Point(-Wide, height) }, new LineSegment { Point = new Point(-Wide, bottom) } } } } } }); }
/// <summary> /// Return the headquarters factor to help position the headquarters staff /// </summary> /// <param name="sc"> /// The symbol code for the headquarters. /// </param> /// <returns> /// A fractional offset as a double ranging from 0.0 to 1.0. /// </returns> internal static double GetHqFactor(string sc) { if (!Check(ref sc)) { return(0); } int identityKey = StandardIdentity.GetNormalizedStandardIdentity(sc); int dimensionKey = NormalizeBattleDimension(sc); switch (identityKey) { case StandardIdentity.Friend: if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir) { return(1.0); } if (dimensionKey == CategoryBattleDimension.BdSubsurface) { return(0.0); } if (dimensionKey == CategoryBattleDimension.BdSeaSurface || dimensionKey == CategoryBattleDimension.BdOther || IsEquipment(sc)) { return(0.5); // of course there is no headquarters that is also equipment } return(1.0); case StandardIdentity.Hostile: if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir) { return(1.0); } if (dimensionKey == CategoryBattleDimension.BdSubsurface) { return(0.0); } return(0.5); case StandardIdentity.Neutral: return(1.0); case StandardIdentity.Unknown: if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir) { return(0.7); } if (dimensionKey == CategoryBattleDimension.BdSubsurface) { return(0.3); } return(0.5); } return(0.0); }
/// <summary> /// This function returns the symbol bounds and some scaling factors /// (area and height) for the various standard symbol backgrounds. /// The exceptions to these sizes are the symbols that have headquarters /// or installations built-in. /// If that built-in is in the normal symbol code place (SymbolCode[10-11]) /// we're OK. /// But the designers threw in a few curveballs that we're going to special /// case for now. /// </summary> /// <param name="sc"> /// The symbol code. /// </param> /// <returns> /// A Scaling object representing the bounding rectangle and various scaling factors. /// </returns> public static Scaling GetScaling(string sc) { if (!Check(ref sc)) { return(new Scaling(Rect.Empty, 300.0 * 300.0, 300.0)); } int identityKey = StandardIdentity.GetNormalizedStandardIdentity(sc); int dimensionKey = NormalizeBattleDimension(sc); switch (identityKey) { case StandardIdentity.Friend: if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir) { return(Rects["F137149A"]); } if (dimensionKey == CategoryBattleDimension.BdSubsurface) { return(Rects["F137149U"]); } if (dimensionKey == CategoryBattleDimension.BdSeaSurface || dimensionKey == CategoryBattleDimension.BdOther || IsEquipment(sc)) { return(Rects["F149149G"]); } return(Rects["F185125G"]); case StandardIdentity.Hostile: if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir) { return(Rects["H137161A"]); } if (dimensionKey == CategoryBattleDimension.BdSubsurface) { return(Rects["H137161U"]); } return(Rects["H180180G"]); case StandardIdentity.Neutral: if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir) { return(Rects["N137149A"]); } if (dimensionKey == CategoryBattleDimension.BdSubsurface) { return(Rects["N137149U"]); } return(Rects["N137137G"]); case StandardIdentity.Unknown: if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir) { return(Rects["U183161A"]); } if (dimensionKey == CategoryBattleDimension.BdSubsurface) { return(Rects["U183161U"]); } return(Rects["U178178G"]); } return(new Scaling(Rect.Empty, 300.0 * 300.0, 300.0)); }