This is a migrated thread and some comments may be shown as answers.

Adding a field to "ClusterItem"

1 Answer 74 Views
Map
This is a migrated thread and some comments may be shown as answers.
Derek
Top achievements
Rank 1
Derek asked on 19 Dec 2013, 07:01 PM
I am using pushpins on the RadMap control to represent buildings, and each push-pin has a double sqFeet value representing the internal square footage of the building.

The example shows how to bind to the "Count" field of a ClusterItem
http://demos.telerik.com/silverlight/#Map/Cluster

I am clustering based off of the "Clustering" demo, and would like to show a summation of the total square footage represented by a cluster in the ClusterItem text (eg: "25 museums" would become "15039 sq. feet"). With my knowledge of XAML, the only way I can think of doing this would be to add a "sumOfSquareFeet" field to the ClusterItem, and every time a new item is added to a ClusterItem the sumOfSquareFeet value would be updated to store the new sum. 

In the clustering example, the cluster is bound to the count of items inside of the "ClusterItem"
<TextBlock Text="{Binding Path=Count}" Style="{StaticResource clusterTextBlockStyle}"/>

I'd like to bind to the sum of square footage represented by a ClusterItem.

Any ideas would be appreciated.

1 Answer, 1 is accepted

Sort by
0
Andrey
Telerik team
answered on 20 Dec 2013, 04:13 PM
Hi Derek,

I already replied in the support thread you sent but I will post the information here to make it publicly available in case someone encounters the same issue:

In fact the visualization layer uses the ClusterData class for the cluster. This class contains the Data property. The property can be used to pass extra information to the cluster's data template or by a cluster generator when detecting that the item belongs to the particular cluster. The visualization layer also allows the usage of custom cluster generator. Such a generator can be specified using the VisualizationLayer.ClusterGenerator property.

So, you can use your own cluster generator to specify any additional information via the ClusterData.Data property. And you can use this property for data binding in your cluster template. You  follow these steps to implement the approach:

1. Add new class which represents additional information for the cluster.

public class MyClusterItem : INotifyPropertyChanged
{
    private double sumOfSquareFeet;
  
    public event PropertyChangedEventHandler PropertyChanged;
  
    public double SumOfSquareFeet
    {
        get
        {
            return this.sumOfSquareFeet;
        }
        set
        {
            this.sumOfSquareFeet = value;
            this.OnPropertyChanged("SumOfSquareFeet");
        }
    }
  
    private void OnPropertyChanged(string name)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChangedEventArgs eventArgs = new PropertyChangedEventArgs(name);
            this.PropertyChanged(this, eventArgs);
        }
    }
}

2. Implement a custom cluster generator which specifies additional information in the ClusterData.Data property.

public class CustomGenerator : DefaultClusterGenerator
{
    public override ClusterData CreateCluster(Location center, object item)
    {
        ClusterData clusterData = base.CreateCluster(center, item);
  
        MyMapItem mapItem = item as MyMapItem;
        if (mapItem != null)
        {
            clusterData.Data = new MyClusterItem()
            {
                SumOfSquareFeet = mapItem.SquareFeet
            };
        }
  
        return clusterData;
    }
  
    public override bool IsItemInClusterRegion(ClusterData cluster, MapObjectInfo info, int zoomLevel)
    {
        bool inRegion = base.IsItemInClusterRegion(cluster, info, zoomLevel);
        if (inRegion)
        {
            MyMapItem mapItem = info.Item as MyMapItem;
            MyClusterItem data = cluster.Data as MyClusterItem;
            if (mapItem != null && data != null)
            {
                data.SumOfSquareFeet += mapItem.SquareFeet;
            }
        }
  
        return inRegion;
    }
}

3. Use the custom cluster generator in the visualization layer and apply data bindings.

<UserControl x:Class="CustomClusterGenerator.MainPage"
    xmlns:local="clr-namespace:CustomClusterGenerator"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <DataTemplate x:Key="myToolTipTemplate">
            <Border Background="#7F000000" 
                    HorizontalAlignment="Center"
                    VerticalAlignment="Top" Padding="5">
                <StackPanel>
                    <TextBlock Text="{Binding Title}" Foreground="White"/>
                    <TextBlock Text="{Binding Description}" Foreground="White"/>
                </StackPanel>
            </Border>
        </DataTemplate>
  
        <Style x:Key="CustomPushpin" TargetType="telerik:Pushpin">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="telerik:Pushpin">
                        <Border>
                            <telerik:MapLayer.HotSpot>
                                <telerik:HotSpot X="0.5" Y="1.0" ElementName="Pin" />
                            </telerik:MapLayer.HotSpot>
                            <Canvas x:Name="Pin" Height="32" Width="20">
                                <Path Fill="Yellow"
                              Height="32.005"
                              StrokeStartLineCap="Flat"
                              Stretch="Fill"
                              StrokeEndLineCap="Flat"
                              Stroke="Black"
                              StrokeThickness="1"
                              StrokeMiterLimit="10"
                              StrokeLineJoin="Miter"
                              Width="20.01"
                              Data="M1054.5088,458.105L1065.5188,458.105C1067.7278,458.105,1069.5188,459.896,1069.5188,462.105L1069.5188,473.084C1069.5188,475.293,1067.7278,477.084,1065.5188,477.084C1065.5188,477.084,1062.6868,476.831,1062.2128,479.103C1061.6608,481.751,1060.2208,489.11,1060.2208,489.11L1059.3548,489.11C1059.3548,489.11,1058.0138,482.546,1057.2888,479.106C1056.8538,477.041,1054.5088,477.084,1054.5088,477.084C1052.2998,477.084,1050.5088,475.293,1050.5088,473.084L1050.5088,462.105C1050.5088,459.896,1052.2998,458.105,1054.5088,458.105z" />
                                <Path Canvas.Top="2.989" Canvas.Left="3.188"
                              Data="M1066.6162,472.8125C1066.6212,473.9125,1065.7252,474.8125,1064.6252,474.8125L1055.2502,474.8125C1054.1502,474.8125,1053.2462,473.9125,1053.2412,472.8125L1053.1962,462.5935C1053.1912,461.4935,1054.0872,460.5935,1055.1872,460.5935L1064.5622,460.5935C1065.6622,460.5935,1066.5662,461.4935,1066.5712,462.5935z"
                              Fill="Black"
                              Height="14.219"
                              Stretch="Fill"
                              Width="13.42"/>
                            </Canvas>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
  
        <DataTemplate x:Key="ClusteredItemTemplate">
            <telerik:Pushpin telerik:MapLayer.Location="{Binding Path=Location}" Style="{StaticResource CustomPushpin}"
                             telerik:RadToolTipService.ToolTipContent="{Binding}"
                             telerik:RadToolTipService.Placement="Mouse"
                             telerik:RadToolTipService.ToolTipContentTemplate="{StaticResource myToolTipTemplate}"
                             MouseLeftButtonUp="ClusteredItemMouseClick"/>
        </DataTemplate>
  
        <Style x:Key="clusterTextBlockStyle" TargetType="TextBlock">
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="VerticalAlignment" Value="Top"/>
            <Setter Property="TextAlignment" Value="Center"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Width" Value="Auto"/>
            <Setter Property="TextWrapping" Value="Wrap"/>
        </Style>
  
        <DataTemplate x:Key="ClusterTemplate">
            <Grid x:Name="ParentRoot"
                  Width="Auto" Height="50"
                  telerik:MapLayer.Location="{Binding Path=Center}"
                  telerik:MapLayer.HotSpot="0.5,1"
                  MouseLeftButtonUp="ClusterMouseClick">
                <Path Width="{Binding Width,ElementName=ParentRoot}"
                      Height="{Binding Height,ElementName=ParentRoot}"
                      Data="M978.6509,491.334L958.6109,491.334L954.4549,500.874L949.9999,491.334L930.6259,491.334C928.4169,491.334,926.6259,489.543,926.6259,487.334L926.6259,433.272C926.6259,431.063,928.4169,429.272,930.6259,429.272L978.6509,429.272C980.8599,429.272,982.6509,431.063,982.6509,433.272L982.6509,487.334C982.6509,489.543,980.8599,491.334,978.6509,491.334z"
                      StrokeStartLineCap="Flat"
                      Stretch="Fill"
                      StrokeEndLineCap="Flat"
                      Stroke="White"
                      StrokeThickness="1"
                      StrokeMiterLimit="10"
                      StrokeLineJoin="Miter"
                      Fill="#7F000000"/>
                <StackPanel Margin="5">
                    <TextBlock Text="{Binding Path=Data.SumOfSquareFeet}" Style="{StaticResource clusterTextBlockStyle}"/>
                    <TextBlock Text="square feet" Style="{StaticResource clusterTextBlockStyle}"/>
                </StackPanel>
            </Grid>
        </DataTemplate>
  
        <local:CustomGenerator x:Key="ClusterGenerator" />
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot">
        <telerik:RadMap x:Name="RadMap1"
                        Center="47, 13">
            <telerik:RadMap.Providers>
                <telerik:BingMapProvider/>
            </telerik:RadMap.Providers>
            <telerik:VisualizationLayer x:Name="visualizationLayer"
                                        ClusterGenerator="{StaticResource ClusterGenerator}"
                                        ClusteringEnabled="True"
                                        ClusterItemTemplate="{StaticResource ClusterTemplate}"
                                        ItemTemplate="{StaticResource ClusteredItemTemplate}"
                                        GenerateClustersOnZoom="True"
                                        ItemsSource="{Binding}">
            </telerik:VisualizationLayer>
        </telerik:RadMap>
    </Grid>
</UserControl>


Regards,
Andrey Murzov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.

Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.

Sign up for Free application insights >>
Tags
Map
Asked by
Derek
Top achievements
Rank 1
Answers by
Andrey
Telerik team
Share this question
or