Welcome Guest, you are in: Login

FDOT Wiki

RSS RSS

GisFramework



Search the wiki
»

SymbolManager

RSS
Modified on Tuesday, 19 July 2011 08:54 AM by 156.75.200.64 Categorized as Uncategorized
Visual objects are placed on the map using two primary pieces of information - the geometry that defines their location and shape, and a symbol that defines their appearance. Symbols come in three basic types - point, line, and fill. The GIS Framework supports symbols via the SymbolManager and a set of pre-defined symbols specified in XAML. Of course, additional symbols can be defined in custom components as well.


The following are the default symbol definitions for the three types as implemented in the SymbolManager:

Example - Line Symbol (single-color line)


public static Symbol GetLineSymbol(Color color)
{ return new SimpleLineSymbol { Color = new SolidColorBrush(color), Width = 4 }; }

Example - Fill Symbol (diagonal hatch pattern with a border)


public static Symbol GetFillSymbol(Color[] colors)
{
    SimpleFillSymbol symbol = new SimpleFillSymbol();
    symbol.BorderBrush = new SolidColorBrush(colors[0]);
    symbol.Fill = new LinearGradientBrush(new GradientStopCollection { new GradientStop { Color = colors[1] }, new GradientStop { Color = colors[2], Offset = 0.526 }, new GradientStop { Color = Colors.Transparent, Offset = 0.544 }, new GradientStop { Color = Colors.Transparent, Offset = 1 } }, 0)
    {
        EndPoint = new Point(1.5, 1.5),
        MappingMode = BrushMappingMode.Absolute,
        SpreadMethod = GradientSpreadMethod.Repeat,
        StartPoint = new Point(0, 0)
    };
    symbol.BorderThickness = 4;

    return symbol;
}



Example - Default Point Symbol (loads a strobe symbol defined in XAML)


public static Symbol DefaultPointSymbol
{
    get { return (Symbol)Application.Current.Resources["CustomStrobeMarkerSymbol"]); }
}


<esriSymbols:MarkerSymbol x:Name="CustomStrobeMarkerSymbol">
    <esriSymbols:MarkerSymbol.ControlTemplate>
        <ControlTemplate>
            <Canvas>
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="MouseOver">
                            <Storyboard RepeatBehavior="ForEver">
                                <DoubleAnimation BeginTime="0" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" From="1" To="10" Duration="00:00:01" />
                                <DoubleAnimation BeginTime="0" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" From="1" To="10" Duration="00:00:01" />
                                <DoubleAnimation BeginTime="0" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.Opacity)" From="1" To="0" Duration="00:00:01" />
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Normal" />
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <Ellipse Height="10" Width="10" Canvas.Left="-5" Canvas.Top="-5" RenderTransformOrigin="0.5,0.5" x:Name="ellipse" IsHitTestVisible="False">
                    <Ellipse.RenderTransform>
                        <ScaleTransform />
                    </Ellipse.RenderTransform>
                    <Ellipse.Fill>
                        <RadialGradientBrush>
                            <GradientStop Color="#00FF0000" />
                            <GradientStop Color="#FFFF0000" Offset="0.25" />
                            <GradientStop Color="#00FF0000" Offset="0.5" />
                            <GradientStop Color="#FFFF0000" Offset="0.75" />
                            <GradientStop Color="#00FF0000" Offset="1" />
                        </RadialGradientBrush>
                    </Ellipse.Fill>
                </Ellipse>
                <Ellipse Height="10" Width="10" Canvas.Left="-5" Canvas.Top="-5" Fill="#FFFF0000" x:Name="ellipse1" />
            </Canvas>
        </ControlTemplate>
    </esriSymbols:MarkerSymbol.ControlTemplate>
</esriSymbols:MarkerSymbol>

Custom symbols can be added using the above approaches, or the symbols provided by the SymbolManager can simply be rendered in different colors. In the case of the point symbol, a number of different marker types with customizable colors are also provided (see DrawCommand for a list).

Example - Returns the default point symbol


public static Symbol GetMarkerSymbol()
{ return Controls.MarkerSymbol.CreateSymbol(); }

Example - Returns the specified symbol with custom fill color


public static Symbol GetMarkerSymbol(string symbolType, string color)
{ return Controls.MarkerSymbol.CreateSymbol(symbolType, color); }

Example - Returns the specified symbol with custom fill and stroke colors


public static Symbol GetMarkerSymbol(string symbolType, string color, string stroke)
{ return Controls.MarkerSymbol.CreateSymbol(symbolType, color, stroke); }

Customized line and fill symbols are also supported by the SymbolManager by specifying one or more colors for the symbol, shifting the SymbolManager's color palette, or specifying an amount by which to shift the palette when drawing a given object. Each option has a case for which it's best suited. The method calls and parameters for line and fill symbols are similar, so the following examples will look at the fill symbol. Note that fill symbols can be customized with a single color, though they use three for the hatch pattern - the SymbolManager uses the single color to create a hue shift on the other two to preserve the hatch. Alternatively, all three colors can be specified.

Example - red hatch fill


Symbol symbol = SymbolManager.GetFillSymbol("#FF0000");

Hue shifting is a way of getting a customized symbol based on the SymbolManager's current palette. It's primarily intended for cases where multiple objects are to be drawn and a different color is desired for each object or group of objects. By using a hue shift, the items can be drawn in a loop and the hue value incremented, as opposed to specifying exact colors. The hue shift value is technically a decimal number from 0.0 to 1.0, though it's based on a color wheel, so higher or lower values simply continue clockwise or counter-clockwise around the wheel, respectively.

Example - fill based on a hue shift


double hueShift = 0.0; // no shift, starts at the palette base color
foreach(DataContracts.Geometry geometry in myDrawingObjects)
{
   graphicsManager.AddGraphic(geometry, SymbolManager.GetFillSymbol(hueShift), null, null);
   hueShift += 0.1;
}

Finally, the SymbolManager's palette can be shifted, causing any objects drawn after the shift to be rendered with, or shifted from, the new palette. The palette can be set using either a base color or hue shift. In the case of a hue shift, the shift is based on the current palette so the entire palette can be shifted by increments. Setting the palette is the ideal means by which a virtual application can set default colors different from the framework defaults without having to customize every symbol individually. It's also recommended for drawing objects interactively, where the final object rendered will have a custom fill. Without doing a palette shift, the active selection will use the palette default and the final object will use the custom color. Finally, palette shifts can be used for customizing colors for groups of objects, similar to the previous example.

Example - setting the palette to red


SymbolManager.SetPalette("#FF0000");

Example - shifting the palette for groups of objects


double hueShift = 0.0; // no shift, starts at the palette base color
foreach(IEnumerable<DataContracts.Geometry> myDrawingObjects in myDrawingObjectGroups)
{
   SymbolManager.ShiftPalette(hueShift);
   foreach(DataContracts.Geometry geometry in myDrawingObjects)
   {
      // null symbol uses default based on current palette
      graphicsManager.AddGraphic(geometry, null, null, null); 
   }
   hueShift += 0.1;
}
SetDefaultPalette();   // return the palette to the framework default

The following is an adaptation from DrawingGeometry using a palette change to ensure that the active drawing selection and final rendered object will have the same color. If using this approach, it's important to ensure that cancelling the drawing or closing the drawing dialog also restore the palette.

Example - drawing geometry with a palette shift

SymbolManager.SetPalette("#FF0000"); geometryService.SelectGeometry(GeometryType.Polyline, g => { isDrawing = false; graphicsManager.AddGraphic(g, null, null, null); SetDefaultPalette(); });

See Also





Any Questions or Comments? Email
Some of the icons created by FamFamFam.