Symbols and renderers
Symbols define the non-geographic aspects of a graphic's appearance, including color, border width, transparency, and so on. The ArcGIS API for WPF includes many symbol classes, each of which allows you to specify symbology in a unique way. Each symbol type is also specific to one geometry type (that is, point, line, or polygon).
Renderers define one or more symbols to apply to a graphics layer. The symbol applied to each graphic depends on the graphic's attributes. The renderer specifies the attribute values that correspond to a particular symbol.
Symbol types
The available symbols and the geometries to which they apply are summarized in the following table:
Symbol | Geometry | Description |
---|---|---|
SimpleMarkerSymbol | Point | Symbolizes points with simple shapes. |
PictureMarkerSymbol | Point | Symbolizes points with images. |
SimpleLineSymbol | Polyline | Symbolizes lines with pre-defined styles. |
CartographicLineSymbol | Polyline | Symbolizes lines with custom styles. |
SimpleFillSymbol | Polygon | Fills polygons with a WPF Brush. |
PictureFillSymbol | Polygon | Fills polygons with images. |
Creating symbols
In many applications, the same symbol is used many times. Consider, for instance, an application that uses the Find task to allow users to search for counties. In this situation, it makes sense to apply the same symbology to the task's results every time the task is executed. In such cases, you should define a symbol in the application's XAML. This is the best place for the symbol's definition because, in WPF, an application's visual components should be specified in XAML, while its execution logic should be defined in .NET code. This makes for a distinct separation between presentation layer and business logic, which makes applications easier to develop, maintain, and enhance.
All the symbol classes are defined in the ESRI.ArcGIS.Client.Symbols namespace in the ESRI.ArcGIS.Client assembly. Using symbol classes requires the project to have a reference to the ESRI.ArcGIS.Client assembly. The XAML must include the following XML namespace declaration:
xmlns:esri="http://schemas.esri.com/arcgis/client/2009"
The use of Microsoft's System namespace in the mscorlib assembly in the sample code in this topic also requires the following XML namespace declaration:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Declare a static symbol and a renderer in the resources of the root layout element. The following code declares a SimpleFillSymbol with a semitransparent red fill and a red outline that is two pixels wide, and a SimpleRenderer that uses that symbol. The x:Key attribute defines the name you'll use to reference the symbol either from XAML or in the window's code-behind. The root element is assumed to be a Grid.
<Grid.Resources>
<esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" />
<esri:SimpleRenderer x:Key="MySimpleRenderer" Symbol="{StaticResource MyRedFillSymbol}" />
</Grid.Resources>
Now that the renderer is declared, it can be applied to a feature layer by binding to the Renderer property. This applies the symbol associated with the renderer to all the features in the layer. See the following code:
<esri:FeatureLayer ID="MyFeatureLayer" Where="1 = 1"
Renderer="{StaticResource MySimpleRenderer}"
Url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5" >
<esri:FeatureLayer.OutFields>
<sys:String>POP07_SQMI</sys:String>
</esri:FeatureLayer.OutFields>
</esri:FeatureLayer>
Alternatively, when a dynamically-generated symbol is required, you can create and apply the symbol to graphics individually in the window's code-behind. The following code initializes a fill symbol with the fill color based on variables for the color's alpha, red, green, and blue values. The symbol is then applied to each Graphic in the GraphicsLayer.
SimpleFillSymbol fillSymbol = new SimpleFillSymbol()
{
BorderBrush = new SolidColorBrush(Color.FromArgb(0, 255, 0, 0)),
BorderThickness = 2,
Fill = new SolidColorBrush(Color.FromArgb(alphaVal, redVal, greenVal, blueVal))
};
GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
foreach (Graphic graphic in graphicsLayer.Graphics)
graphic.Symbol = fillSymbol;
If you have a renderer set on your GraphicsLayer, and the GraphicsLayer.RendererTakesPrecedence property is set to true (which is the default), the symbols set on individual graphics will be overwritten by the renderer. Set RendererTakesPrecedence to false to use the symbols set on individual graphics, and only apply the renderer on the graphics without a symbol set.
Creating a unique value renderer
With the unique value renderer, you can define symbols for graphics with specific attribute values. This section describes the steps for defining a simple unique value renderer.
- Create an application with a Map, base layer, and FeatureLayer. Set the FeatureLayer to use the states layer of the ESRI_Census_USA map service as shown in the following code:
<Grid x:Name="LayoutRoot" Background="White" > <esri:Map x:Name="MyMap" Extent="-130,10,-70,60" > <esri:Map.Layers> <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/> <esri:FeatureLayer ID="MyFeatureLayer" Url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5" > </esri:FeatureLayer> </esri:Map.Layers> </esri:Map> </Grid>
- In the FeatureLayer, specify a filter so that only California, New York, and Kansas are drawn. Also specify that the STATE_NAME field be included with the layer's graphics.
<esri:FeatureLayer ID="MyFeatureLayer" Where="(STATE_NAME = 'California') OR (STATE_NAME = 'New York') OR (STATE_NAME = 'Kansas')" Url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5" > <esri:FeatureLayer.OutFields> <sys:String>STATE_NAME</sys:String> </esri:FeatureLayer.OutFields> </esri:FeatureLayer>
- In the Grid containing the Map, declare three fill symbols as static resources.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> </Grid.Resources>
- Declare a unique value renderer as a resource.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:UniqueValueRenderer x:Key="MyUniqueValueRenderer" > </esri:UniqueValueRenderer> </Grid.Resources>
- In the UniqueValueRenderer element, specify the Attribute property as STATE_NAME (the name of the field holding the state name). This uses the renderer to symbolize state graphics based on the state's name.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:UniqueValueRenderer x:Key="MyUniqueValueRenderer" Attribute="STATE_NAME" > </esri:UniqueValueRenderer> </Grid.Resources>
- The symbol-value mappings for unique value renderers are specified in a collection of UniqueValueInfo objects that are stored in the UniqueValueRenderer's Infos property. In the UniqueValueRenderer element, specify another element, UniqueValueRenderer.Infos, to hold this collection.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:UniqueValueRenderer x:Key="MyUniqueValueRenderer" Attribute="STATE_NAME" > <esri:UniqueValueRenderer.Infos> </esri:UniqueValueRenderer.Infos> </esri:UniqueValueRenderer> </Grid.Resources>
- Specify a UniqueValueInfo element in the collection.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:UniqueValueRenderer x:Key="MyUniqueValueRenderer" Attribute="STATE_NAME" > <esri:UniqueValueRenderer.Infos> <esri:UniqueValueInfo /> </esri:UniqueValueRenderer.Infos> </esri:UniqueValueRenderer> </Grid.Resources>
- Map California to the green fill symbol by specifying the element's value as California and its symbol as the desired fill symbol.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:UniqueValueRenderer x:Key="MyUniqueValueRenderer" Attribute="STATE_NAME" > <esri:UniqueValueRenderer.Infos> <esri:UniqueValueInfo Value="California" Symbol="{StaticResource MyGreenFillSymbol}" /> </esri:UniqueValueRenderer.Infos> </esri:UniqueValueRenderer> </Grid.Resources>
- Add UniqueValueInfos to symbolize New York with the yellow fill symbol and Kansas with the red fill symbol.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:UniqueValueRenderer x:Key="MyUniqueValueRenderer" Attribute="STATE_NAME" > <esri:UniqueValueRenderer.Infos> <esri:UniqueValueInfo Value="California" Symbol="{StaticResource MyGreenFillSymbol}" /> <esri:UniqueValueInfo Value="New York" Symbol="{StaticResource MyYellowFillSymbol}" /> <esri:UniqueValueInfo Value="Kansas" Symbol="{StaticResource MyRedFillSymbol}" /> </esri:UniqueValueRenderer.Infos> </esri:UniqueValueRenderer> </Grid.Resources>
- The renderer needs to be associated with the FeatureLayer. Along with the other elements you've specified in the application, this will appear as shown in the following code.
<Grid x:Name="LayoutRoot" Background="White" > <Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:UniqueValueRenderer x:Key="MyUniqueValueRenderer" Attribute="STATE_NAME" > <esri:UniqueValueRenderer.Infos> <esri:UniqueValueInfo Value="California" Symbol="{StaticResource MyGreenFillSymbol}" /> <esri:UniqueValueInfo Value="New York" Symbol="{StaticResource MyYellowFillSymbol}" /> <esri:UniqueValueInfo Value="Kansas" Symbol="{StaticResource MyRedFillSymbol}" /> </esri:UniqueValueRenderer.Infos> </esri:UniqueValueRenderer> </Grid.Resources> <esri:Map x:Name="MyMap" Extent="-130,10,-70,60" > <esri:Map.Layers> <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/> <esri:FeatureLayer ID="MyFeatureLayer" Where="(STATE_NAME = 'California') OR (STATE_NAME = 'New York') OR (STATE_NAME = 'Kansas')" Renderer="{StaticResource MyUniqueValueRenderer}" Url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5" > <esri:FeatureLayer.OutFields> <sys:String>STATE_NAME</sys:String> </esri:FeatureLayer.OutFields> </esri:FeatureLayer> </esri:Map.Layers> </esri:Map> </Grid>
Creating a class breaks renderer
The class breaks renderer allows you to apply symbols to groups of graphics that have attribute values within specified ranges. The steps to define such a renderer are described in this section.
- Start with the same application that you used at the start of the unique value renderer definition. In this case, you'll symbolize the states based on their population density. Define a filter on the FeatureLayer so that all states are displayed and the POP07_SQMI field is returned as shown in the following code:
<esri:FeatureLayer ID="MyFeatureLayer" Where="1 = 1" Url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5" > <esri:FeatureLayer.OutFields> <sys:String>POP07_SQMI</sys:String> </esri:FeatureLayer.OutFields> </esri:FeatureLayer>
- Use the same symbols as you did for the unique value renderer.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> </Grid.Resources>
- Declare a ClassBreaksRenderer. Specify that the renderer apply symbols based on population density by setting the Attribute property to POP07_SQMI. This is the population density field in the map service layer used by the application's FeatureLayer.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:ClassBreaksRenderer x:Key="MyClassBreaksRenderer" Attribute="POP07_SQMI" > </esri:ClassBreaksRenderer> </Grid.Resources>
- The mapping between symbols and values is defined in a collection of ClassBreakInfo objects. The renderer stores this in its Classes property. Declare an element to hold this collection in the Class Beaks Renderer element.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:ClassBreaksRenderer x:Key="MyClassBreaksRenderer" Attribute="POP07_SQMI" > <esri:ClassBreaksRenderer.Classes> </esri:ClassBreaksRenderer.Classes> </esri:ClassBreaksRenderer> </Grid.Resources>
- In the Classes collection, declare a ClassBreakInfo element to specify a mapping between a symbol and a range of values. Define the relationship so that values between 0 and 50 are symbolized with the green fill symbol.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:ClassBreaksRenderer x:Key="MyClassBreaksRenderer" Attribute="POP07_SQMI" > <esri:ClassBreaksRenderer.Classes> <esri:ClassBreakInfo MinimumValue="0" MaximumValue="50" Symbol="{StaticResource MyGreenFillSymbol}" /> </esri:ClassBreaksRenderer.Classes> </esri:ClassBreaksRenderer> </Grid.Resources>
- Map value ranges of 51 to 125 and 126 to 2000 to the yellow and red fill symbols, respectively.
<Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:ClassBreaksRenderer x:Key="MyClassBreaksRenderer" Attribute="POP07_SQMI" > <esri:ClassBreaksRenderer.Classes> <esri:ClassBreakInfo MinimumValue="0" MaximumValue="50" Symbol="{StaticResource MyGreenFillSymbol}" /> <esri:ClassBreakInfo MinimumValue="51" MaximumValue="125" Symbol="{StaticResource MyYellowFillSymbol}" /> <esri:ClassBreakInfo MinimumValue="126" MaximumValue="2000" Symbol="{StaticResource MyRedFillSymbol}" /> </esri:ClassBreaksRenderer.Classes> </esri:ClassBreaksRenderer> </Grid.Resources>
- Associate the renderer with the FeatureLayer. The following is the XAML for the Grid:
<Grid x:Name="LayoutRoot" Background="White" > <Grid.Resources> <esri:SimpleFillSymbol x:Key="MyGreenFillSymbol" Fill="#6600FF00" BorderBrush="Green" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyYellowFillSymbol" Fill="#66FFFF00" BorderBrush="Yellow" BorderThickness="2" /> <esri:SimpleFillSymbol x:Key="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> <esri:ClassBreaksRenderer x:Key="MyClassBreaksRenderer" Attribute="POP07_SQMI" > <esri:ClassBreaksRenderer.Classes> <esri:ClassBreakInfo MinimumValue="0" MaximumValue="50" Symbol="{StaticResource MyGreenFillSymbol}" /> <esri:ClassBreakInfo MinimumValue="51" MaximumValue="125" Symbol="{StaticResource MyYellowFillSymbol}" /> <esri:ClassBreakInfo MinimumValue="125" MaximumValue="2000" Symbol="{StaticResource MyRedFillSymbol}" /> </esri:ClassBreaksRenderer.Classes> </esri:ClassBreaksRenderer> </Grid.Resources> <esri:Map x:Name="MyMap" Extent="-130,10,-70,60" > <esri:Map.Layers> <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/> <esri:FeatureLayer ID="MyFeatureLayer" Where="1 = 1" Renderer="{StaticResource MyClassBreaksRenderer}" Url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5" > <esri:FeatureLayer.OutFields> <sys:String>POP07_SQMI</sys:String> </esri:FeatureLayer.OutFields> </esri:FeatureLayer> </esri:Map.Layers> </esri:Map> </Grid>