English

How To: Replace a PictureMarkerSymbol with an ImageBrush to enhance graphic display performance

Summary

The ArcGIS API for Microsoft Silverlight/WPF includes a PictureMarkerSymbol type to render graphic points using an image icon. Like other symbols in the API, its content is defined by a control template.

The PictureMarkerSymbol control template is provided below:


Code:

<ControlTemplate xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Image Source="{Binding Symbol.Source}"
Opacity="{Binding Symbol.Opacity}"
Stretch="Fill"
Width="{Binding Symbol.Width}"
Height="{Binding Symbol.Height}" />
</ControlTemplate>



When assigned to a graphic (e.g., Graphic.Symbol), an Image control instance is created. If the same picture marker symbol is assigned to 500 graphic points, the image is decoded 500 times. As a result, initial graphic rendering will be relatively slow. Even though the symbol is bound to one image source and thus shared between the 500 graphics (downloaded only once), the decoded image is not shared.

To reduce the overhead associated the PictureMarkerSymbol's use of the Image control, create a custom control template for a symbol and use an ImageBrush.

Instructions provided describe how to replace a PictureMarkerSymbol with an ImageBrush to enhance graphic display performance.

Procedure

Start with a container (e.g., Rectangle) that has a Fill property that can be set to any type of brush. Use an ImageBrush to reference the desired picture (image) to use to symbolize the graphics. The ImageBrush is responsible for decoding the image, therefore it can be shared among all graphic features that use it. So, when a custom symbol is assigned to 500 graphic points, 500 rectangle instances are created (as defined by the template), but only one image brush is generated. Here is the basic control template for the symbol:

Code:

<ControlTemplate
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Rectangle Fill="{Binding Symbol.Fill}"
Opacity="{Binding Symbol.Opacity}"
Width="{Binding Symbol.Width}"
Height="{Binding Symbol.Height}" />
</ControlTemplate>


Start by using the MarkerSymbol class included with the ArcGIS API for Microsoft Silverlight/WPF, or create a new custom symbol from scratch. In both cases, the custom marker symbol class should have a public Fill property, which can be used to bind to a brush. Here is an example that shows how to define a custom control template for the MarkerSymbol class:

Code:

<Grid.Resources>
<ImageBrush ImageSource="/images/i_pushpin.png" x:Name="MyImageBrush" />
<esriSymbols:MarkerSymbol x:Name="MyPictureMarker" OffsetX="10" OffsetY="10">
<esriSymbols:MarkerSymbol.ControlTemplate>
<ControlTemplate>
<Rectangle Fill="{StaticResource MyImageBrush}"
Opacity="0.75" Width="20" Height="20" />
</ControlTemplate>
</esriSymbols:MarkerSymbol.ControlTemplate>
</esriSymbols:MarkerSymbol>
</Grid.Resources>