This sample demonstrates implementing a custom clusterer. The
clusterer in this sample aggregates the values of a specified field
for each feautre in a cluster and displays that value on the
cluster. In the sample XAML, the custom clusterer is used to
display aggregate population for each cluster.
      
      Download Sample Application 
      
     
      
< UserControl  x:Class = " ArcGISWPFSDK.LocalCustomClusterer " 
    xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "  
    xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml "  
    xmlns:esri = " http://schemas.esri.com/arcgis/client/2009 " 
    xmlns:samples = " clr-namespace:ArcGISWPFSDK " > 
    < Grid  x:Name = " LayoutRoot "  Background = " White "  > 
        < Grid.Resources > 
            < esri : SimpleRenderer  x:Key = " MySimpleRenderer " > 
                < esri : SimpleRenderer.Symbol > 
                    < esri : SimpleMarkerSymbol  Color = " #FF00BB00 " /> 
                </ esri : SimpleRenderer.Symbol > 
            </ esri : SimpleRenderer > 
            < LinearGradientBrush  x:Key = " PanelGradient "  EndPoint = " 0.5,1 "  StartPoint = " 0.5,0 " > 
                < LinearGradientBrush.RelativeTransform > 
                    < TransformGroup > 
                        < ScaleTransform  CenterY = " 0.5 "  CenterX = " 0.5 " /> 
                        < SkewTransform  CenterY = " 0.5 "  CenterX = " 0.5 " /> 
                        < RotateTransform  Angle = " 176 "  CenterY = " 0.5 "  CenterX = " 0.5 " /> 
                        < TranslateTransform /> 
                    </ TransformGroup > 
                </ LinearGradientBrush.RelativeTransform > 
                < GradientStop  Color = " #FF145787 "  Offset = " 0.16 " /> 
                < GradientStop  Color = " #FF3D7FAC "  Offset = " 0.502 " /> 
                < GradientStop  Color = " #FF88C5EF "  Offset = " 0.984 " /> 
            </ LinearGradientBrush > 
        </ Grid.Resources > 
        < esri : Map  x:Name = " MyMap "  Extent = " -15000000,2000000,-7000000,8000000 "  Background = " #FFE3E3E3 "  MinimumResolution = " 2445.98490512499 " > 
            < esri : ArcGISLocalTiledLayer  ID = " myBaseMap "  Path = " ..\\Data\\TPKs\\Topographic.tpk " /> 
            < esri : ArcGISLocalFeatureLayer  ID = " MyFeatureLayer "  LayerName = " Cities "  
                   Path = " ..\\Data\\MPKS\\USCitiesStates.mpk "       
                    Where = " POP2000 > 75000 " 
                    OutFields = " POP2000 "   Renderer = " {StaticResource MySimpleRenderer} " > 
                < esri : ArcGISLocalFeatureLayer.Clusterer > 
                    < samples : SumClusterer  AggregateColumn = " POP2000 "  SymbolScale = " 0.001 "  /> 
                </ esri : ArcGISLocalFeatureLayer.Clusterer > 
                < esri : ArcGISLocalFeatureLayer.MapTip > 
                    < Grid  Background = " LightYellow " > 
                        < StackPanel  Margin = " 5 " > 
                            < StackPanel  Orientation = " Horizontal " > 
                                < TextBlock  Foreground = " Black "  Text = " Population (2000):  "  /> 
                                < TextBlock  Foreground = " Black "  Text = " {Binding Path=.[POP2000]} "  /> 
                            </ StackPanel > 
                        </ StackPanel > 
                        < Border  BorderBrush = " Black "  BorderThickness = " 1 "  /> 
                    </ Grid > 
                </ esri : ArcGISLocalFeatureLayer.MapTip > 
            </ esri : ArcGISLocalFeatureLayer > 
        </ esri : Map > 
        < Grid  Margin = " 10 "  HorizontalAlignment = " Right "  VerticalAlignment = " Top " > 
            < Border  Background = " {StaticResource PanelGradient} "  CornerRadius = " 3 "  Padding = " 5 " > 
                < StackPanel  Orientation = " Vertical "  Margin = " 5 " > 
                    < TextBlock  Text = " Population density "  Foreground = " White "  FontWeight = " Bold "  FontSize = " 12 "  Margin = " 3 "  /> 
                    < CheckBox  Checked = " CheckBox_Checked "  Unchecked = " CheckBox_Unchecked "  IsChecked = " True "   
                        HorizontalAlignment = " Center "  Foreground = " Black "  Margin = " 0,0,5,0 "  > 
                        < TextBlock  Foreground = " White "  Text = " Enable Clustering " > </ TextBlock > 
                    </ CheckBox > 
                </ StackPanel > 
            </ Border > 
        </ Grid > 
    </ Grid > 
</ UserControl > 
 
using  System;
using  System.Windows;
using  System.Windows.Controls;
using  System.Windows.Media;
using  ESRI.ArcGIS.Client;
using  ESRI.ArcGIS.Client.Geometry;
namespace  ArcGISWPFSDK
{
    public  partial  class  LocalCustomClusterer : UserControl
    {
        public  LocalCustomClusterer()
        {
            InitializeComponent();
        }
        private  void  CheckBox_Checked(object  sender, RoutedEventArgs e)
        {
            if  (MyMap == null ) return ;
            GraphicsLayer layer = MyMap.Layers["MyFeatureLayer" ] as  GraphicsLayer;
            layer.Clusterer = new  SumClusterer2() { AggregateColumn = "POP2000" , SymbolScale = 0.001 };
        }
        private  void  CheckBox_Unchecked(object  sender, RoutedEventArgs e)
        {
            if  (MyMap == null ) return ;
            GraphicsLayer layer = MyMap.Layers["MyFeatureLayer" ] as  GraphicsLayer;
            layer.Clusterer = null ;
        }
    }
    public  class  SumClusterer2 : GraphicsClusterer
    {
        public  SumClusterer2()
        {
            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  ClusterSymbol2() { 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));
        }
    }
    internal  class  ClusterSymbol2 : ESRI.ArcGIS.Client.Symbols.MarkerSymbol
    {
        public  ClusterSymbol2()
        {
            string  template = "<ControlTemplate "  +
            "xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\""  + ">"  +
            @"<Grid IsHitTestVisible=""False"">
            <Ellipse
                Fill=""{Binding Attributes[Color]}"" 
                Width=""{Binding Attributes[Size]}""
                Height=""{Binding Attributes[Size]}"" />
            <Grid HorizontalAlignment=""Center"" VerticalAlignment=""Center"">
            <TextBlock 
                Text=""{Binding Attributes[Count]}"" 
                FontSize=""9"" Margin=""1,1,0,0"" FontWeight=""Bold""
                Foreground=""#99000000"" />
            <TextBlock
                Text=""{Binding Attributes[Count]}"" 
                FontSize=""9"" Margin=""0,0,1,1"" FontWeight=""Bold""
                Foreground=""White"" />
            </Grid>
            </Grid>
            </ControlTemplate>" ;
            System.IO.MemoryStream templateStream = new  System.IO.MemoryStream(System.Text.UTF8Encoding.Default.GetBytes(template));
            ControlTemplate = System.Windows.Markup.XamlReader.Load(templateStream) as  ControlTemplate;
        }
        public  double  Size { get ; set ; }
        public  override  double  OffsetX
        {
            get 
            {
                return  Size / 2;
            }
            set 
            {
                throw  new  NotSupportedException();
            }
        }
        public  override  double  OffsetY
        {
            get 
            {
                return  Size / 2;
            }
            set 
            {
                throw  new  NotSupportedException();
            }
        }
    }
}
 
Imports  System.Windows
Imports  System.Windows.Controls
Imports  System.Windows.Media
Imports  ESRI.ArcGIS.Client
Imports  ESRI.ArcGIS.Client.Geometry
Namespace  ArcGISWPFSDKVB
    Partial  Public  Class  LocalCustomClusterer
        Inherits  UserControl
        Public  Sub  New ()
            InitializeComponent()
        End  Sub 
        Private  Sub  CheckBox_Checked(sender As  Object , e As  RoutedEventArgs)
            If  MyMap Is  Nothing  Then 
                Return 
            End  If 
            Dim  layer As  GraphicsLayer = TryCast(MyMap.Layers("MyFeatureLayer" ), GraphicsLayer)
            layer.Clusterer = New  SumClusterer2() With  { _
             .AggregateColumn = "POP2000" , _
             .SymbolScale = 0.001 _
            }
        End  Sub 
        Private  Sub  CheckBox_Unchecked(sender As  Object , e As  RoutedEventArgs)
            If  MyMap Is  Nothing  Then 
                Return 
            End  If 
            Dim  layer As  GraphicsLayer = TryCast(MyMap.Layers("MyFeatureLayer" ), GraphicsLayer)
            layer.Clusterer = Nothing 
        End  Sub 
    End  Class 
    Public  Class  SumClusterer2
        Inherits  GraphicsClusterer
        Public  Sub  New ()
            MinimumColor = Colors.Red
            MaximumColor = Colors.Yellow
            SymbolScale = 1
            MyBase .Radius = 50
        End  Sub 
        Public  Property  AggregateColumn() As  String 
            Get 
                Return  m_AggregateColumn
            End  Get 
            Set (value As  String )
                m_AggregateColumn = value
            End  Set 
        End  Property 
        Private  m_AggregateColumn As  String 
        Public  Property  SymbolScale() As  Double 
            Get 
                Return  m_SymbolScale
            End  Get 
            Set (value As  Double )
                m_SymbolScale = value
            End  Set 
        End  Property 
        Private  m_SymbolScale As  Double 
        Public  Property  MinimumColor() As  Color
            Get 
                Return  m_MinimumColor
            End  Get 
            Set (value As  Color)
                m_MinimumColor = value
            End  Set 
        End  Property 
        Private  m_MinimumColor As  Color
        Public  Property  MaximumColor() As  Color
            Get 
                Return  m_MaximumColor
            End  Get 
            Set (value As  Color)
                m_MaximumColor = value
            End  Set 
        End  Property 
        Private  m_MaximumColor As  Color
        Protected  Overrides  Function  OnCreateGraphic(cluster As  GraphicCollection, point As  MapPoint, maxClusterCount As  Integer ) As  Graphic
            If  cluster.Count  = 1 Then 
                Return  cluster(0)
            End  If 
            Dim  graphic As  Graphic = Nothing 
            Dim  sum  As  Double  = 0
            For  Each  g As  Graphic In  cluster
                If  g.Attributes.ContainsKey(AggregateColumn) Then 
                    Try 
                        sum  += Convert.ToDouble(g.Attributes(AggregateColumn))
                    Catch 
                    End  Try 
                End  If 
            Next 
            Dim  size As  Double  = (sum  + 450) / 30
            size = (Math.Log(sum  * SymbolScale / 10) * 10 + 20)
            If  size < 12 Then 
                size = 12
            End  If 
            graphic = New  Graphic() With  { _
             .Symbol = New  ClusterSymbol2() With  { _
              .Size = size _
             }, _
             .Geometry = point _
            }
            graphic.Attributes.Add("Count" , sum )
            graphic.Attributes.Add("Size" , size)
            graphic.Attributes.Add("Color" , InterpolateColor(size - 12, 100))
            Return  graphic
        End  Function 
        Private  Shared  Function  InterpolateColor(value As  Double , max  As  Double ) As  Brush
            value = CInt (Math.Truncate(Math.Round(value * 255.0 / max )))
            If  value > 255 Then 
                value = 255
            ElseIf  value < 0 Then 
                value = 0
            End  If 
            Return  New  SolidColorBrush(Color.FromArgb(127, 255, CByte (Math.Truncate(value)), 0))
        End  Function 
    End  Class 
    Friend  Class  ClusterSymbol2
        Inherits  ESRI.ArcGIS.Client.Symbols.MarkerSymbol
        Public  Sub  New ()
            Dim  template As  String  = "<ControlTemplate "  & "xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"""  & ">"  & "<Grid IsHitTestVisible=""False"">"  & vbCr & vbLf & "            <Ellipse"  & vbCr & vbLf & "                Fill=""{Binding Attributes[Color]}"" "  & vbCr & vbLf & "                Width=""{Binding Attributes[Size]}"""  & vbCr & vbLf & "                Height=""{Binding Attributes[Size]}"" />"  & vbCr & vbLf & "            <Grid HorizontalAlignment=""Center"" VerticalAlignment=""Center"">"  & vbCr & vbLf & "            <TextBlock "  & vbCr & vbLf & "                Text=""{Binding Attributes[Count]}"" "  & vbCr & vbLf & "                FontSize=""9"" Margin=""1,1,0,0"" FontWeight=""Bold"""  & vbCr & vbLf & "                Foreground=""#99000000"" />"  & vbCr & vbLf & "            <TextBlock"  & vbCr & vbLf & "                Text=""{Binding Attributes[Count]}"" "  & vbCr & vbLf & "                FontSize=""9"" Margin=""0,0,1,1"" FontWeight=""Bold"""  & vbCr & vbLf & "                Foreground=""White"" />"  & vbCr & vbLf & "            </Grid>"  & vbCr & vbLf & "            </Grid>"  & vbCr & vbLf & "            </ControlTemplate>" 
            Dim  templateStream As  New  System.IO.MemoryStream(System.Text.UTF8Encoding.[Default ].GetBytes(template))
            ControlTemplate = TryCast(System.Windows.Markup.XamlReader.Load(templateStream), ControlTemplate)
        End  Sub 
        Public  Property  Size() As  Double 
            Get 
                Return  m_Size
            End  Get 
            Set (value As  Double )
                m_Size = value
            End  Set 
        End  Property 
        Private  m_Size As  Double 
        Public  Overrides  Property  OffsetX() As  Double 
            Get 
                Return  Size / 2
            End  Get 
            Set (value As  Double )
                Throw  New  NotSupportedException()
            End  Set 
        End  Property 
        Public  Overrides  Property  OffsetY() As  Double 
            Get 
                Return  Size / 2
            End  Get 
            Set (value As  Double )
                Throw  New  NotSupportedException()
            End  Set 
        End  Property 
    End  Class 
End  Namespace 
 
5/16/2014