dot
Working with Clustering

When rendering a large number of points in a map, symbolizing each point individually is often unhelpful since symbols will frequently overlap one another making it difficult to distinguish between points. Symbolizing multiple points with a single symbol is often used to resolve this issue by providing a more aesthetic, efficient, and usable rendering solution. This process is termed clustering. Clustering identifies groups of points in a layer that are within a given cluster distance. The cluster distance is dependent on the scale at which the map is displayed; so as you zoom in fewer points are clustered and as you zoom out, more points are clustered. Note, clustering can be applied to a GraphicsLayer or FeatureLayer.

There are two techniques for clustering graphics:

Both techniques can be used with a GraphicsLayer or FeatureLayer.

Use the FlareClusterer

The flare clusterer can be added to a GraphicsLayer or FeatureLayer using the following XAML:

<esri:GraphicsLayer ID="MyGraphicsLayer">
   <esri:GraphicsLayer.Clusterer>
      <esri:FlareClusterer />
   </esri:GraphicsLayer.Clusterer>
</esri:GraphicsLayer>

Groups of points that form a cluster are symbolized using either a flare cluster or large cluster symbol. The default flare cluster symbol consists of a red circle with a white border and a number representing the number of clustered points. The symbol is also animated. Mouse over the feature in the map and the symbol will flare out to display each point as a single red circle attached to the cluster.

The default large cluster symbol is rendered using a gradient color between red and yellow and the feature count the cluster represents is drawn on top of the symbol. The large cluster symbol is not interactive. The MaximumFlareCount property on the FlareClusterer determines when a flare or large cluster symbol is used (see the table below).
fc
You can modify the FlareClusterer in XAML using the following properties; default values are listed:

FlareClusterer
properties
Description
FlareBackground
Background color (fill) of the flare symbol. Default = Red.

FlareForeground

Text and boundary color of the flare symbol. Default = White.

MaximumFlareCount

The maximum number of clustered features to be represented by a flare cluster. If the number of features is greater than this value, a large cluster is used to render the features. The large cluster displays the number of features it represents. It's size is scaled to the number of features and the color is defined by a gradient (see Gradient property below). Default = 10.

Radius

The radius within which features will be clustered. Defined in pixels. Default = 20.

Gradient

The LinearGradientBrush used to render large clusters. Default = LinearGradientBrush; MappingMode = RelativeToBoundingBox; GradientStop1: Offset = 0, Argb=127,255,255,0, GradientStop2: Offset = 1, Argb=127,255,0,0.


The following code example illustrates how to modify FlareClusterer properties in XAML. The result will generate flare symbols with a yellow background with gray border and text, and a blue gradient symbol for the large clusters. Flare symbols represent at a maximum 5 features within a 15 pixel radius. A green circle symbol has been applied to single graphic features. To see a functional example, view the Simple Clusterer sample in the Interactive SDK.

fcc

<Grid x:Name="LayoutRoot" Background="White">
 <Grid.Resources>
    <LinearGradientBrush x:Name="BlueGradient" MappingMode="RelativeToBoundingBox" >
		<GradientStop Color="#990011FF" Offset="0"/>
		<GradientStop Color="#990055FF" Offset="0.25"/>
		<GradientStop Color="#990099FF" Offset="0.5"/>
		<GradientStop Color="#9900CCFF" Offset="0.75"/>
		<GradientStop Color="#9900FFFF" Offset="1"/>
    </LinearGradientBrush>
 </Grid.Resources>
 <esri:Map x:Name="MyMap">
    <esri:Map.Layers>
	   <esri:GraphicsLayer ID="MyGraphicsLayer">
	    <esri:GraphicsLayer.Clusterer>
		<esri:FlareClusterer 
			FlareBackground="Yellow"
			FlareForeground="#99000000"
			MaximumFlareCount="5" Radius="15" 
			Gradient="{StaticResource BlueGradient}" />
	    </esri:GraphicsLayer.Clusterer>
	   </esri:GraphicsLayer>
    </esri:Map.Layers>
 </esri:Map>
</Grid>

Extend the GraphicsClusterer

To customize the look, feel, and behavior of clustering, you need to create a custom cluster class that derives from ESRI.ArcGIS.Client.GraphicsClusterer. Override the OnCreateGraphic() method to return a cluster graphic. The clustered features are passed to the OnCreateGraphic method in a graphic collection. Interrogate the collection and graphic features to determine how to create a clustered graphic with a symbol. The FlareClusterer returns either a flare cluster symbol or a large cluster symbol. The example code below generates a single symbol for any graphic collection that have more than 1 feature. The cluster symbol size and color are calculated, and values in a attribute column in the GraphicsLayer or FeatureLayer on which the custom clusterer is applied will be aggregated. The sum total of te values will be displayed on the cluster symbol. For brevity,only the custom cluster class source is provided below. To view the complete example, see the Custom Clusterer sample in the Interactive SDK.

public class SumClusterer : GraphicsClusterer
    {
        public SumClusterer()
        {
            MinimumColor = Colors.Red;
            MaximumColor = Colors.Yellow;
            SymbolScale = 1;
            base.Radius = 50;
        }

public string AggregateColumn { get; set; } public double SymbolScale { get; set; } public Color MinimumColor { get; set; } public Color MaximumColor { get; set; }

protected override Graphic OnCreateGraphic(GraphicCollection cluster,
MapPoint point, int maxClusterCount) { if (cluster.Count == 1) return cluster[0]; Graphic graphic = null; double sum = 0; foreach (Graphic g in cluster) { if (g.Attributes.ContainsKey(AggregateColumn)) { try { sum += Convert.ToDouble(g.Attributes[AggregateColumn]); } catch { } } } double size = (sum + 450) / 30; size = (Math.Log(sum * SymbolScale / 10) * 10 + 20); if (size < 12) size = 12; graphic = new Graphic() { Symbol = new ClusterSymbol() { Size = size },
Geometry = point }; graphic.Attributes.Add("Count", sum); graphic.Attributes.Add("Size", size); graphic.Attributes.Add("Color", InterpolateColor(size - 12, 100)); return graphic; }

private static Brush InterpolateColor(double value, double max) { value = (int)Math.Round(value * 255.0 / max); if (value > 255) value = 255; else if (value < 0) value = 0; return new SolidColorBrush(Color.FromArgb(127, 255, (byte)value, 0)); } }