User Tools

Site Tools


source_code_wpf_desktopeditionsample_mapsuiteusdemographicmap_cs_141201.zip

Source Code Wpf DesktopEditionSample MapSuiteUSDemographicMap CS 141201.zip

MainWindow.xaml

 <Window x:Class="ThinkGeo.MapSuite.USDemographicMap.MainWindow"  
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
         xmlns:local="clr-namespace:ThinkGeo.MapSuite.USDemographicMap"  
         xmlns:wpf="clr-namespace:ThinkGeo.MapSuite.WpfDesktopEdition;assembly=WpfDesktopEdition"  
         Title="US Demographic Map" Height="675" Width="1155" WindowState="Maximized" Icon="/MapSuiteUSDemographicMap;Component/Image/MapSuite.ico" Loaded="Window_Loaded">  
     <Window.Resources>  
         <ResourceDictionary>  
             <Style x:Key="ColumnItemList" TargetType="ListBox">  
                 <Style.Resources>  
                     <Style TargetType="ListBoxItem" BasedOn="{StaticResource ColumnDataSelectionItem}" />  
                 </Style.Resources>  
                 <Setter Property="SelectionMode" Value="Single"/>  
                 <Setter Property="Margin" Value="20 5 0 0" />  
                 <Setter Property="ItemsSource" Value="{Binding Columns}" />  
                 <Setter Property="Template">  
                     <Setter.Value>  
                         <ControlTemplate>  
                             <StackPanel IsItemsHost="True" />  
                         </ControlTemplate>  
                     </Setter.Value>  
                 </Setter>  
                 <Setter Property="ItemTemplate">  
                     <Setter.Value>  
                         <DataTemplate>  
                             <Grid Width="250" Margin="0 3 0 3">  
                                 <Grid.ColumnDefinitions>  
                                     <ColumnDefinition Width="*" />  
                                     <ColumnDefinition Width="auto" />  
                                     <ColumnDefinition Width="auto" />  
                                 </Grid.ColumnDefinitions>  
                                 <TextBlock Grid.Column="0" Text="{Binding Alias}" Style="{StaticResource bodyText1}" />  
 
                                 <StackPanel Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal">  
                                     <Button Width="20" ToolTip="Present the data in Value Circles."  
                                             Template="{StaticResource ImageButtonTemplate}"  
                                             Margin="{StaticResource TitleImageButtonMargin}" VerticalAlignment="Center" Click="ValueCirclesClick"  
                                             Content="/MapSuiteUSDemographicMap;Component/Image/valueCircle.png"  
                                             Tag="/MapSuiteUSDemographicMap;Component/Image/valueCircle_Disable.png" />  
                                     <Button Width="20" ToolTip="Present the data in Thematic Colors."  
                                             Template="{StaticResource ImageButtonTemplate}"  
                                             Margin="{StaticResource TitleImageButtonMargin}" VerticalAlignment="Center" Click="ThematicColorsClick"  
                                             Content="/MapSuiteUSDemographicMap;Component/Image/thematic.png"  
                                             Tag="/MapSuiteUSDemographicMap;Component/Image/thematic_Disable.png" />  
                                     <Button Width="20" ToolTip="Present the data with Dot Density."  
                                             Template="{StaticResource ImageButtonTemplate}"  
                                             Margin="{StaticResource TitleImageButtonMargin}" VerticalAlignment="Center" Click="DotDensityClick"  
                                             Content="/MapSuiteUSDemographicMap;Component/Image/dotdensity.png"  
                                             Tag="/MapSuiteUSDemographicMap;Component/Image/dotdensity_Disable.png" />  
                                 </StackPanel>  
 
                                 <CheckBox Grid.Column="2" Click="ColumnCheckBox_Click" Style="{StaticResource msCheckBox}"  
                                           IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding CheckBoxVisiblity}"/>  
                             </Grid>  
                         </DataTemplate>  
                     </Setter.Value>  
                 </Setter>  
             </Style>  
         </ResourceDictionary>  
     </Window.Resources>  
     <Grid Style="{StaticResource sampleBody}">  
         <Grid.RowDefinitions>  
             <RowDefinition Height="auto" />  
             <RowDefinition Height="*" />  
             <RowDefinition Height="auto" />  
         </Grid.RowDefinitions>  
         <Border BorderThickness="0,0,0,5" Padding="10" CornerRadius="2" KeyboardNavigation.TabNavigation="Local"  
                             KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2">  
             <Border.Background>  
                 <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">  
                     <LinearGradientBrush.GradientStops>  
                         <GradientStop Offset="0" Color="#ffffff" />  
                         <GradientStop Offset="0.4" Color="#fafafa" />  
                         <GradientStop Offset="0.55" Color="#f2f2f2" />  
                         <GradientStop Offset="0.6" Color="#f0f0f0" />  
                         <GradientStop Offset="0.9" Color="#e2e2e2" />  
                     </LinearGradientBrush.GradientStops>  
                 </LinearGradientBrush>  
             </Border.Background>  
             <Border.BorderBrush>  
                 <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">  
                     <LinearGradientBrush.GradientStops>  
                         <GradientStop Offset="0.85" Color="#5c707d" />  
                         <GradientStop Offset="1" Color="#305c707d" />  
                     </LinearGradientBrush.GradientStops>  
                 </LinearGradientBrush>  
             </Border.BorderBrush>  
             <StackPanel Orientation="Horizontal">  
                 <TextBlock Style="{StaticResource ControlFont}" Margin="{StaticResource TitleMargin}">  
                     <Run FontSize="16">Map Suite</Run>  
                     <Run FontSize="20">US Demographic Map</Run>  
                 </TextBlock>  
             </StackPanel>  
         </Border>  
         <Grid Grid.Row="1">  
             <Grid.ColumnDefinitions>  
                 <ColumnDefinition Width="auto" />  
                 <ColumnDefinition Width="*" />  
             </Grid.ColumnDefinitions>  
             <Grid Grid.Column="0" Grid.Row="0">  
                 <Grid.ColumnDefinitions>  
                     <ColumnDefinition Width="*" />  
                     <ColumnDefinition Width="auto" />  
                     <ColumnDefinition Width="5" />  
                 </Grid.ColumnDefinitions>  
                 <Grid x:Name="gridDockPanel" HorizontalAlignment="Left">  
                     <Grid.Resources>  
                         <Style TargetType="Grid">  
                             <Style.Triggers>  
                                 <DataTrigger Binding="{Binding ElementName=CollapseToggleButton,Path=IsChecked}" Value="true">  
                                     <Setter Property="Visibility" Value="Collapsed" />  
                                 </DataTrigger>  
                             </Style.Triggers>  
                         </Style>  
                     </Grid.Resources>  
                     <Grid>  
                         <Grid.RowDefinitions>  
                             <RowDefinition Height="40" />  
                             <RowDefinition Height="*" />  
                             <RowDefinition Height="*" />  
                         </Grid.RowDefinitions>  
                         <Grid Grid.Row="0">  
                             <TextBlock  
                        Style="{StaticResource h4}"  
                        Text="Select data for display:"  
                        HorizontalAlignment="Left"  
                        VerticalAlignment="Center"  
                        Width="290"  
                        Margin="5 0 0 0"  
                        TextWrapping="Wrap" />  
                         </Grid>  
                         <Border Grid.Row="1" BorderBrush="LightGray" BorderThickness="1" CornerRadius="5" Margin="5 10 0 0">  
                             <ListBox Margin="5 5 5 5"  
                                      BorderBrush="Transparent" SelectionMode="Single"  
                                      ItemsSource="{Binding CategoryList}" SelectedItem="{Binding SelectedCategory,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">  
                                 <ListBox.Resources>  
                                     <Style BasedOn="{StaticResource CategoryDataSelectionItem}" TargetType="{x:Type ListBoxItem}"/>  
                                 </ListBox.Resources>  
                                 <ListBox.ItemTemplateSelector>  
                                     <local:CategoryItemTemplateSelector>  
                                         <local:CategoryItemTemplateSelector.DefaultDataTemplate>  
                                             <DataTemplate>  
                                                 <Grid Width="280">  
                                                     <Grid.RowDefinitions>  
                                                         <RowDefinition Height="45" />  
                                                         <RowDefinition Height="auto" />  
                                                     </Grid.RowDefinitions>  
                                                     <Border BorderBrush="LightGray" Grid.Row="0" BorderThickness="0 0 0 1">  
                                                         <Grid>  
                                                             <Grid.ColumnDefinitions>  
                                                                 <ColumnDefinition Width="auto" />  
                                                                 <ColumnDefinition Width="*" />  
                                                                 <ColumnDefinition Width="auto" />  
                                                             </Grid.ColumnDefinitions>  
                                                             <Image Grid.Column="0" Source="{Binding CategoryImage}" Style="{StaticResource msImage}" />  
                                                             <TextBlock Text="{Binding Title}" Grid.Column="1" Style="{StaticResource CategoryHeaderText}" />  
                                                             <Button Template="{StaticResource ImageButtonTemplate}"  
                                                                     Margin="{StaticResource PieChartImageButtonMargin}"  
                                                                     Visibility="{Binding RelativeSource={RelativeSource FindAncestor,  
                                                                     AncestorType={x:Type ListBoxItem}}, Path=IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,  
                                                                     Converter={StaticResource BoolToVisibility}}"  
                                                                     Height="20" Width="20" Grid.Column="2"  
                                                                     VerticalAlignment="Center" ToolTip="Display pie charts on the map representing the breakdown of all data points selected below."  
                                                                     IsEnabled="{Binding CanUsePieView,Mode=TwoWay}"  
                                                                     Click="PieChartClick"  
                                                                     Content="/MapSuiteUSDemographicMap;Component/Image/pie.png"  
                                                                     Tag="/MapSuiteUSDemographicMap;Component/Image/pie_Disable.png" />  
                                                         </Grid>  
                                                     </Border>  
                                                     <ListBox Grid.Row="1" Visibility="{Binding RelativeSource={RelativeSource FindAncestor,  
                                         AncestorType={x:Type ListBoxItem}}, Path=IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,  
                                         Converter={StaticResource BoolToVisibility}}" Style="{StaticResource ColumnItemList}" />  
                                                 </Grid>  
                                             </DataTemplate>  
                                         </local:CategoryItemTemplateSelector.DefaultDataTemplate>  
                                         <local:CategoryItemTemplateSelector.CustomDataTemplate>  
                                             <DataTemplate>  
                                                 <Grid Width="280">  
                                                     <Grid.RowDefinitions>  
                                                         <RowDefinition Height="45" />  
                                                         <RowDefinition Height="auto" />  
                                                     </Grid.RowDefinitions>  
                                                     <Border BorderBrush="LightGray" Grid.Row="0" BorderThickness="0 0 0 1">  
                                                         <Grid>  
                                                             <Grid.ColumnDefinitions>  
                                                                 <ColumnDefinition Width="auto" />  
                                                                 <ColumnDefinition Width="*" />  
                                                                 <ColumnDefinition Width="auto" />  
                                                             </Grid.ColumnDefinitions>  
                                                             <Image Grid.Column="0" Source="{Binding CategoryImage}"  Style="{StaticResource msImage}" />  
                                                             <TextBlock Text="{Binding Title}" Grid.Column="1" Style="{StaticResource CategoryHeaderText}" />  
                                                             <Button Template="{StaticResource ImageButtonTemplate}"  
                                                                 Margin="{StaticResource PieChartImageButtonMargin}"  
                                                                                 Visibility="{Binding RelativeSource={RelativeSource FindAncestor,  
                                                                                 AncestorType={x:Type ListBoxItem}}, Path=IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,  
                                                                                 Converter={StaticResource BoolToVisibility}}"  
                                                                                 Height="20" Width="20" Grid.Column="2"  
                                                                                 VerticalAlignment="Center" ToolTip="Display pie charts on the map representing the breakdown of all data points selected below."  
                                                                                 IsEnabled="{Binding CanUsePieView,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"  
                                                                                 Click="PieChartClick"  
                                                                                 Content="/MapSuiteUSDemographicMap;Component/Image/pie.png"  
                                                                                 Tag="/MapSuiteUSDemographicMap;Component/Image/pie_Disable.png" />  
                                                         </Grid>  
                                                     </Border>  
                                                     <Grid Grid.Row="1" Margin="0 5 0 0" Visibility="{Binding RelativeSource={RelativeSource FindAncestor,  
                                         AncestorType={x:Type ListBoxItem}}, Path=IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,  
                                         Converter={StaticResource BoolToVisibility}}">  
                                                         <Grid.RowDefinitions>  
                                                             <RowDefinition Height="auto" />  
                                                             <RowDefinition Height="auto" />  
                                                         </Grid.RowDefinitions>  
                                                         <StackPanel Grid.Row="0" HorizontalAlignment="Left" Orientation="Horizontal">  
                                                             <TextBox Width="180" IsEnabled="False" Text="{Binding CustomDataFilePathName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />  
                                                             <Button Margin="10 0 0 0" Content="Browse" Width="80" Click="BrowseCustomDataClick" />  
                                                         </StackPanel>  
                                                         <ListBox Grid.Row="1" Style="{StaticResource ColumnItemList}" />  
                                                     </Grid>  
                                                 </Grid>  
                                             </DataTemplate>  
                                         </local:CategoryItemTemplateSelector.CustomDataTemplate>  
                                     </local:CategoryItemTemplateSelector>  
                                 </ListBox.ItemTemplateSelector>  
                             </ListBox>  
                         </Border>  
                         <Grid Grid.Row="2" Margin="5 10 0 10" VerticalAlignment="Top">  
                             <Grid.RowDefinitions>  
                                 <RowDefinition Height="auto" />  
                                 <RowDefinition Height="auto" />  
                             </Grid.RowDefinitions>  
                             <Grid Grid.Row="0">  
                                 <Grid.RowDefinitions>  
                                     <RowDefinition Height="35"/>  
                                     <RowDefinition Height="auto"/>  
                                 </Grid.RowDefinitions>  
                                 <Grid.ColumnDefinitions>  
                                     <ColumnDefinition Width="140"/>  
                                     <ColumnDefinition Width="150"/>  
                                 </Grid.ColumnDefinitions>  
                                 <TextBlock VerticalAlignment="Center" Grid.Row="0" Grid.Column="0" Style="{StaticResource bodyHeaderText2}" Text="{Binding DisplayColorText}"/>  
                                 <ComboBox x:Name="cmbSelectColor" Grid.Row="0" Grid.Column="1"  Style="{StaticResource ColorSelectBox}" SelectedItem="{Binding SelectedColorItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"  
                                             ItemsSource="{Binding GeoColorList}" />  
                                 <Grid Visibility="{Binding ThematicVisibility}" Grid.Row="1" Grid.ColumnSpan="2">  
                                     <Grid.RowDefinitions>  
                                         <RowDefinition Height="35"/>  
                                         <RowDefinition Height="35"/>  
                                     </Grid.RowDefinitions>  
                                     <Grid.ColumnDefinitions>  
                                         <ColumnDefinition Width="140"/>  
                                         <ColumnDefinition Width="150"/>  
                                     </Grid.ColumnDefinitions>  
                                     <TextBlock VerticalAlignment="Center" Grid.Row="0" Grid.Column="0"  Style="{StaticResource bodyHeaderText2}" Text="Display End Color:" />  
                                     <ComboBox Grid.Row="0" Grid.Column="1"  Style="{StaticResource ColorSelectBox}" SelectedItem="{Binding SelectedEndColorItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"  
                                                 ItemsSource="{Binding GeoColorList}" />  
                                     <TextBlock VerticalAlignment="Center" Grid.Row="1" Grid.Column="0"  Style="{StaticResource bodyHeaderText2}" Text="ColorWheelDirection:" />  
                                     <ComboBox Grid.Row="1" Grid.Column="1" Style="{StaticResource ColorSelectBox}"  
                                                 ItemsSource="{Binding ColorWheelDirections}"  
                                                 SelectedItem="{Binding SelectedColorWheelDirection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >  
                                         <ComboBox.ItemTemplate>  
                                             <DataTemplate>  
                                                 <TextBlock Text="{Binding .}" />  
                                             </DataTemplate>  
                                         </ComboBox.ItemTemplate>  
                                     </ComboBox>  
                                 </Grid>  
                             </Grid>  
                             <Grid Visibility="{Binding DotDensityVisibility}" Grid.Row="2" >  
                                 <Grid.ColumnDefinitions>  
                                     <ColumnDefinition Width="*" />  
                                     <ColumnDefinition Width="auto" />  
                                 </Grid.ColumnDefinitions>  
                                 <TextBlock Grid.Column="0" VerticalAlignment="Top" Margin="0 13 0 0" Style="{StaticResource bodyHeaderText2}" Text="DotDensity Unit:" />  
                                 <Grid Grid.Column="1"  
                                       Width="170"  
                                       Margin="0 10 0 0"  
                                       HorizontalAlignment="Left">  
                                     <Grid.RowDefinitions>  
                                         <RowDefinition Height="auto" />  
                                         <RowDefinition Height="2" />  
                                         <RowDefinition Height="auto" />  
                                     </Grid.RowDefinitions>  
                                     <Grid.ColumnDefinitions>  
                                         <ColumnDefinition Width="auto" />  
                                         <ColumnDefinition Width="*" />  
                                         <ColumnDefinition Width="auto" />  
                                     </Grid.ColumnDefinitions>  
                                     <Slider Grid.Row="0"  
                                             Grid.ColumnSpan="3"  
                                             Maximum="5"  
                                             Minimum="1"  
                                             Value="3"  
                                             Width="160"  
                                             HorizontalAlignment="Right"  
                                             Focusable="False"  
                                             x:Name="sldDotDensityDemographicStyleDotsCount"  
                                             IsSnapToTickEnabled="True"  
                                             TickPlacement="BottomRight"  
                                             Thumb.DragCompleted="DotDensityStyleDotsCountSlider_DragCompleted"  
                                             ButtonBase.Click="DotDensityStyleDotsCountSlider_Click"  
                                             ValueChanged="DotDensityStyleDotsCountSlider_ValueChanged" />  
                                     <TextBlock Grid.Row="2"  
                                                Grid.Column="0"  
                                                Style="{StaticResource bodyText1}"  
                                                FontSize="10"  
                                                Text="Fewer dots" />  
                                     <TextBlock Grid.Row="2"  
                                                Grid.Column="2"  
                                                Style="{StaticResource bodyText1}"  
                                                FontSize="10"  
                                                Text="More dots" />  
                                 </Grid>  
                             </Grid>  
                             <Grid Visibility="{Binding ValueCircleVisibility}" Grid.Row="2" >  
                                 <Grid.ColumnDefinitions>  
                                     <ColumnDefinition Width="*" />  
                                     <ColumnDefinition Width="auto" />  
                                 </Grid.ColumnDefinitions>  
                                 <TextBlock Grid.Column="0"  
                                            Style="{StaticResource bodyHeaderText2}"  
                                            Text="MAGNIFICATION:"  
                                            VerticalAlignment="Bottom"  
                                            Margin="0 0 0 3" />  
                                 <Slider x:Name="sldValueCircleDemographicStyleRadius"  
                                         Grid.Column="1"  
                                         Margin="0 10 0 0"  
                                         Width="160"  
                                         Maximum="5"  
                                         Minimum="1"  
                                         Value="3"  
                                         Focusable="False"  
                                         IsSnapToTickEnabled="True"  
                                         TickPlacement="BottomRight"  
                                         ValueChanged="ValueCircleStyleRadiusSlider_ValueChanged"  
                                         Thumb.DragCompleted="ValueCircleStyleRadiusSlider_DragCompleted"  
                                         ButtonBase.Click="ValueCircleStyleRadiusSlider_Click" />  
                             </Grid>  
                         </Grid>  
                     </Grid>  
                 </Grid>  
                 <ToggleButton x:Name="CollapseToggleButton" Content="/Image/Collapse.gif" Tag="/Image/Expand.gif" Template="{StaticResource ToggleButtonTemplate}" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Cursor="Hand" Background="Transparent"  BorderBrush="Transparent" />  
                 <Rectangle Grid.Row="0" Grid.Column="2">  
                     <Rectangle.Fill>  
                         <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">  
                             <GradientStop Color="#5c707d" Offset="0"></GradientStop>  
                             <GradientStop Color="#305c707d" Offset="1"></GradientStop>  
                         </LinearGradientBrush>  
                     </Rectangle.Fill>  
                 </Rectangle>  
             </Grid>  
             <wpf:WpfMap x:Name="wpfMap" Grid.Column="1" Panel.ZIndex="-1"/>  
         </Grid>  
         <Grid Grid.Row="2">  
             <Border BorderBrush="Gray" BorderThickness="0 1 0 0">  
                 <StatusBar Height="30">  
                     <StatusBarItem  HorizontalContentAlignment="Stretch">  
                         <Grid HorizontalAlignment="Right">  
                             <Grid.ColumnDefinitions>  
                                 <ColumnDefinition Width="auto" />  
                                 <ColumnDefinition Width="5" />  
                                 <ColumnDefinition Width="auto" />  
                             </Grid.ColumnDefinitions>  
                             <TextBlock Text="{Binding CoordinateX,StringFormat=X:{0:N6}}"  HorizontalAlignment="Right" Width="75" VerticalAlignment="Center" Grid.Column="0"/>  
                             <TextBlock Text="{Binding CoordinateY,StringFormat=Y:{0:N6}}" VerticalAlignment="Center" Width="75" Grid.Column="2" />  
                         </Grid>  
                     </StatusBarItem>  
                 </StatusBar>  
             </Border>  
         </Grid>  
     </Grid>  
 </Window>  
 

MainWindow.xaml.cs

 using Microsoft.Win32;  
 using System.Linq;  
 using System.Windows;  
 using System.Windows.Controls.Primitives;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     /// <summary>  
     /// Interaction logic for MainWindow.xaml  
     /// </summary>  
     public partial class MainWindow : Window  
     {  
         private bool isSliderClicked;  
         private MapModel mapModel;  
         private MainWindowViewModel mainWindowViewModel;  
 
         public MainWindow()  
         {  
             InitializeComponent();  
         }  
 
         private void Window_Loaded(object sender, RoutedEventArgs e)  
         {  
             mapModel = new MapModel(wpfMap);  
             mainWindowViewModel = new MainWindowViewModel(mapModel);  
             DataContext = mainWindowViewModel;  
 
             mainWindowViewModel.UpdateMap();  
             mapModel.MapControl.Refresh();  
         }  
 
         private void ColumnCheckBox_Click(object sender, RoutedEventArgs e)  
         {  
             if (mainWindowViewModel.SelectedCategory.Columns.Count(d => d.IsSelected) >= 2)  
             {  
                 mainWindowViewModel.SelectedCategory.CanUsePieView = true;  
                 mainWindowViewModel.CreatePieDemographicStyle();  
                 mainWindowViewModel.UpdateMap();  
             }  
             else  
             {  
                 mainWindowViewModel.SelectedCategory.CanUsePieView = false;  
             }  
         }  
 
         private void DotDensityStyleDotsCountSlider_Click(object sender, RoutedEventArgs e)  
         {  
             isSliderClicked = true;  
         }  
 
         private void DotDensityStyleDotsCountSlider_DragCompleted(object sender, DragCompletedEventArgs e)  
         {  
             mainWindowViewModel.DotDensityDemographicStyle.DotDensityValue = 50 * (sldDotDensityDemographicStyleDotsCount.Value / 3);  
             mainWindowViewModel.UpdateMap();  
         }  
 
         private void DotDensityStyleDotsCountSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)  
         {  
             if (isSliderClicked)  
             {  
                 mainWindowViewModel.DotDensityDemographicStyle.DotDensityValue = 50 * (sldDotDensityDemographicStyleDotsCount.Value / 3);  
                 mainWindowViewModel.UpdateMap();  
                 isSliderClicked = false;  
             }  
         }  
 
         private void ValueCircleStyleRadiusSlider_Click(object sender, RoutedEventArgs e)  
         {  
             isSliderClicked = true;  
         }  
 
         private void ValueCircleStyleRadiusSlider_DragCompleted(object sender, DragCompletedEventArgs e)  
         {  
             mainWindowViewModel.ValueCircleDemographicStyle.RadiusRatio = sldValueCircleDemographicStyleRadius.Value / 3;  
             mainWindowViewModel.UpdateMap();  
         }  
 
         private void ValueCircleStyleRadiusSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)  
         {  
             if (isSliderClicked)  
             {  
                 mainWindowViewModel.ValueCircleDemographicStyle.RadiusRatio = sldValueCircleDemographicStyleRadius.Value / 3;  
                 mainWindowViewModel.UpdateMap();  
                 isSliderClicked = false;  
             }  
         }  
 
         private void ValueCirclesClick(object sender, RoutedEventArgs e)  
         {  
             CollapseControls();  
             mainWindowViewModel.ValueCircleVisibility = Visibility.Visible;  
             ColumnViewModel columnViewModel = sender.GetDataContext<ColumnViewModel>();  
             if (columnViewModel != null && !(columnViewModel.Parent is CustomDataCategoryViewModel))  
             {  
                 mapModel.DefaultFeatureLayer = mapModel.CensusStateFeatureLayer;  
             }  
             else  
             {  
                 mapModel.DefaultFeatureLayer = mapModel.CustomDataFeatureLayer;  
             }  
             RenderDemographicStyle(sender, mainWindowViewModel.ValueCircleDemographicStyle);  
         }  
 
         private void ThematicColorsClick(object sender, RoutedEventArgs e)  
         {  
             CollapseControls();  
             mainWindowViewModel.ThematicVisibility = Visibility.Visible;  
             mainWindowViewModel.DisplayColorText = "Display Start Color:";  
             ColumnViewModel columnViewModel = sender.GetDataContext<ColumnViewModel>();  
             if (columnViewModel != null && !(columnViewModel.Parent is CustomDataCategoryViewModel))  
             {  
                 mapModel.DefaultFeatureLayer = mapModel.CensusStateFeatureLayer;  
             }  
             else  
             {  
                 mapModel.DefaultFeatureLayer = mapModel.CustomDataFeatureLayer;  
             }  
             RenderDemographicStyle(sender, mainWindowViewModel.ThematicDemographicStyle);  
         }  
 
         private void DotDensityClick(object sender, RoutedEventArgs e)  
         {  
             CollapseControls();  
             mainWindowViewModel.DotDensityVisibility = Visibility.Visible;  
             ColumnViewModel columnViewModel = sender.GetDataContext<ColumnViewModel>();  
             if (columnViewModel != null && !(columnViewModel.Parent is CustomDataCategoryViewModel))  
             {  
                 mapModel.DefaultFeatureLayer = mapModel.CensusStateFeatureLayer;  
             }  
             else  
             {  
                 mapModel.DefaultFeatureLayer = mapModel.CustomDataFeatureLayer;  
             }  
             RenderDemographicStyle(sender, mainWindowViewModel.DotDensityDemographicStyle);  
         }  
 
         private void PieChartClick(object sender, RoutedEventArgs e)  
         {  
             CollapseControls();  
             if (sender.GetDataContext<CustomDataCategoryViewModel>() == null)  
             {  
                 mapModel.DefaultFeatureLayer = mapModel.CensusStateFeatureLayer;  
             }  
             else  
             {  
                 mapModel.DefaultFeatureLayer = mapModel.CustomDataFeatureLayer;  
             }  
             mainWindowViewModel.CreatePieDemographicStyle();  
             mainWindowViewModel.UpdateMap();  
         }  
 
         private void CollapseControls()  
         {  
             mainWindowViewModel.DotDensityVisibility = Visibility.Collapsed;  
             mainWindowViewModel.ValueCircleVisibility = Visibility.Collapsed;  
             mainWindowViewModel.ThematicVisibility = Visibility.Collapsed;  
             mainWindowViewModel.DisplayColorText = "Display Color:";  
         }  
 
         private void RenderDemographicStyle(object sender, DemographicStyleBuilder demographicStyleBuilder)  
         {  
             FrameworkElement frameworkElement = (FrameworkElement)sender;  
             ColumnViewModel columnViewModel = (ColumnViewModel)frameworkElement.DataContext;  
             columnViewModel.IsSelected = true;  
             foreach (var item in mainWindowViewModel.SelectedCategory.Columns)  
             {  
                 item.CheckBoxVisiblity = Visibility.Hidden;  
             }  
 
             mainWindowViewModel.UpdateUIControls(demographicStyleBuilder);  
 
             mainWindowViewModel.CurrentStyleBuilder.SelectedColumns.Clear();  
             mainWindowViewModel.CurrentStyleBuilder.SelectedColumns.Add(columnViewModel.ColumnName);  
             mapModel.LegendTitle = columnViewModel.LegendTitle;  
 
             mainWindowViewModel.UpdateMap();  
         }  
 
         private void BrowseCustomDataClick(object sender, RoutedEventArgs e)  
         {  
             CustomDataCategoryViewModel customDataCategoryViewModel = ((FrameworkElement)sender).DataContext as CustomDataCategoryViewModel;  
             OpenFileDialog openFileDialog = new OpenFileDialog();  
             openFileDialog.Filter = "Shape File(*.shp)|*.shp";  
             if (openFileDialog.ShowDialog().GetValueOrDefault())  
             {  
                 ShapeFileFeatureLayer shapeFileFeatureLayer = new ShapeFileFeatureLayer(openFileDialog.FileName);  
                 shapeFileFeatureLayer.Open();  
 
                 if (shapeFileFeatureLayer.GetShapeFileType() == ShapeFileType.Polygon)  
                 {  
                     customDataCategoryViewModel.CustomDataFilePathName = openFileDialog.FileName;  
                     customDataCategoryViewModel.Columns.Clear();  
 
                     foreach (DbfColumn dbfColumn in shapeFileFeatureLayer.FeatureSource.GetColumns().OfType<DbfColumn>())  
                     {  
                         if (dbfColumn.ColumnType == DbfColumnType.Float  
                             || dbfColumn.ColumnType == DbfColumnType.Numeric  
                             || dbfColumn.ColumnType == DbfColumnType.Double  
                             || dbfColumn.ColumnType == DbfColumnType.DoubleInBinary  
                             || dbfColumn.ColumnType == DbfColumnType.Integer  
                             || dbfColumn.ColumnType == DbfColumnType.IntegerInBinary)  
                         {  
                             customDataCategoryViewModel.Columns.Add(new ColumnViewModel(dbfColumn.ColumnName, dbfColumn.ColumnName) { LegendTitle = dbfColumn.ColumnName, Parent = customDataCategoryViewModel });  
                         }  
                     }  
                     customDataCategoryViewModel.CanUsePieView = customDataCategoryViewModel.Columns.Count >= 2;  
                     mapModel.CustomDataFeatureLayer = shapeFileFeatureLayer;  
                 }  
                 else  
                 {  
                     MessageBox.Show("The shapefile must be polygon type, please try another one.", "Warning");  
                 }  
             }  
         }  
     }  
 }  
 

MapModel.cs

 using System.Windows;  
 using ThinkGeo.MapSuite.Core;  
 using ThinkGeo.MapSuite.USDemographicMap.Properties;  
 using ThinkGeo.MapSuite.WpfDesktopEdition;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     public class MapModel  
     {  
         private static RectangleShape globeExtent = new RectangleShape(-128.090753125, 58.27777578125, -68.149346875, 19.10492421875);  
 
         private WpfMap mapControl;  
         private LayerOverlay demographicLayerOverlay;  
         private LegendAdornmentLayer legendAdornmentLayer;  
         private HighlightOverlay highlightOverlay;  
         private ShapeFileFeatureLayer censusStateFeatureLayer;  
         private ShapeFileFeatureLayer customDataFeatureLayer;  
 
         public MapModel()  
             : this(null)  
         { }  
 
         public MapModel(WpfMap wpfMap)  
         {  
             mapControl = wpfMap;  
 
             InitializeMap();  
             InitializeEvents();  
         }  
 
         public WpfMap MapControl  
         {  
             get { return mapControl; }  
             set { mapControl = value; }  
         }  
 
         public HighlightOverlay HighlightOverlay  
         {  
             get { return highlightOverlay; }  
         }  
 
         public LegendAdornmentLayer LegendAdornmentLayer  
         {  
             get { return legendAdornmentLayer; }  
         }  
 
         public LayerOverlay DemographicLayerOverlay  
         {  
             get { return demographicLayerOverlay; }  
         }  
 
         public ShapeFileFeatureLayer DefaultFeatureLayer  
         {  
             get { return (ShapeFileFeatureLayer)demographicLayerOverlay.Layers["DefaultFeatureLayer"]; }  
             set { demographicLayerOverlay.Layers["DefaultFeatureLayer"] = value; }  
         }  
 
         public ShapeFileFeatureLayer CustomDataFeatureLayer  
         {  
             get { return customDataFeatureLayer; }  
             set { customDataFeatureLayer = value; }  
         }  
 
         public ShapeFileFeatureLayer CensusStateFeatureLayer  
         {  
             get { return censusStateFeatureLayer; }  
         }  
 
         public string LegendTitle  
         {  
             get { return legendAdornmentLayer.Title.TextStyle.TextColumnName; }  
             set { legendAdornmentLayer.Title.TextStyle.TextColumnName = value; }  
         }  
 
         private void InitializeMap()  
         {  
             mapControl.MapTools.Logo.IsEnabled = true;  
             mapControl.MapTools.Logo.Margin = new Thickness(0, 0, 10, 5);  
             mapControl.MapTools.MouseCoordinate.IsEnabled = true;  
             mapControl.MapTools.MouseCoordinate.Visibility = Visibility.Hidden;  
             mapControl.MapTools.MouseCoordinate.Margin = new Thickness(0, 0, 100, 5);  
             mapControl.MapTools.MouseCoordinate.MouseCoordinateType = MouseCoordinateType.Custom;  
 
             mapControl.Overlays.Add(new WorldMapKitWmsWpfOverlay());  
 
             censusStateFeatureLayer = new ShapeFileFeatureLayer(MapSuiteSampleHelper.GetValueFromConfiguration("UsShapefilePath"));  
             censusStateFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
             censusStateFeatureLayer.DrawingMarginPercentage = 100;  
 
             demographicLayerOverlay = new LayerOverlay();  
             demographicLayerOverlay.TileType = TileType.SingleTile;  
             mapControl.Overlays.Add(demographicLayerOverlay);  
 
             highlightOverlay = new HighlightOverlay();  
             mapControl.Overlays.Add(highlightOverlay);  
 
             legendAdornmentLayer = new LegendAdornmentLayer();  
             legendAdornmentLayer.Location = AdornmentLocation.LowerLeft;  
             legendAdornmentLayer.Title = new LegendItem();  
             legendAdornmentLayer.Title.ImageJustificationMode = LegendImageJustificationMode.JustifyImageRight;  
             legendAdornmentLayer.Title.TopPadding = 10;  
             legendAdornmentLayer.Title.BottomPadding = 10;  
             legendAdornmentLayer.Title.TextStyle = new TextStyle("Population", new GeoFont("Segoe UI", 12), new GeoSolidBrush(GeoColor.SimpleColors.Black));  
             mapControl.AdornmentOverlay.Layers.Add(legendAdornmentLayer);  
 
             DefaultFeatureLayer = censusStateFeatureLayer;  
 
             MapControl.CurrentExtent = globeExtent;  
         }  
 
         private void InitializeEvents()  
         {  
             MapControl.MapTools.PanZoomBar.GlobeButtonClick += PanZoomBar_GlobeButtonClick;  
         }  
 
         private void PanZoomBar_GlobeButtonClick(object sender, GlobeButtonClickPanZoomBarMapToolEventArgs e)  
         {  
             e.NewExtent = globeExtent;  
         }  
     }  
 }  
 
 

HighlightOverlay.cs

 using System.Drawing;  
 using System.Drawing.Drawing2D;  
 using System.Linq;  
 using System.Windows.Controls;  
 using System.Windows.Media;  
 using ThinkGeo.MapSuite.Core;  
 using ThinkGeo.MapSuite.WpfDesktopEdition;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     // This overlay is to highlight a feature when mouse over.  
     public class HighlightOverlay : Overlay  
     {  
         private bool isPanningMap;  
         private double currentScale;  
         private Feature highlightFeature;  
         private InMemoryFeatureLayer highlightFeatureLayer;  
         private TranslateTransform translateTransform;  
 
         public HighlightOverlay()  
             : base()  
         {  
             isPanningMap = false;  
 
             highlightFeatureLayer = new InMemoryFeatureLayer();  
             highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.FromArgb(150, GeoColor.FromHtml("#449FBC")), GeoColor.FromHtml("#014576"), 1);  
             highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
             translateTransform = new TranslateTransform();  
             OverlayCanvas.RenderTransform = translateTransform;  
         }  
 
         public bool IsPanningMap  
         {  
             get { return isPanningMap; }  
         }  
 
         public Feature HighlightFeature  
         {  
             get { return highlightFeature; }  
             set { highlightFeature = value; }  
         }  
 
         protected override void DrawCore(RectangleShape targetExtent, OverlayRefreshType overlayRefreshType)  
         {  
             LayerTile tile = GetTile(targetExtent, MapArguments.ActualWidth, MapArguments.ActualHeight, 0, 0, MapArguments.GetSnappedZoomLevelIndex(targetExtent));  
             if (overlayRefreshType == OverlayRefreshType.Pan)  
             {  
                 isPanningMap = true;  
                 PanOverlay(targetExtent);  
             }  
             else  
             {  
                 isPanningMap = false;  
                 RefreshHighlightLayerTileAndPopup(targetExtent, tile);  
             }  
         }  
 
         private void RefreshHighlightLayerTileAndPopup(RectangleShape targetExtent, LayerTile tile)  
         {  
             bool isRefreshTile = false;  
             if (translateTransform.X != 0 || translateTransform.Y != 0 || MapArguments.CurrentScale != currentScale)  
             {  
                 translateTransform.X = 0;  
                 translateTransform.Y = 0;  
                 tile = DrawHighlightTile(targetExtent, tile);  
                 isRefreshTile = true;  
             }  
 
             if (highlightFeature != null)  
             {  
                 string key = highlightFeature.ColumnValues.Select(k => k.Key).ToArray()[0];  
                 if (highlightFeatureLayer.InternalFeatures.Count == 0 || !highlightFeatureLayer.InternalFeatures[0].ColumnValues.ContainsKey(key) ||  
                     (highlightFeatureLayer.InternalFeatures.Count > 0 && (highlightFeature.ColumnValues[key] != highlightFeatureLayer.InternalFeatures[0].ColumnValues[key])))  
                 {  
                     highlightFeatureLayer.InternalFeatures.Clear();  
                     highlightFeatureLayer.InternalFeatures.Add(highlightFeature);  
                     tile = DrawHighlightTile(targetExtent, tile);  
                     isRefreshTile = true;  
                 }  
             }  
             else if (highlightFeatureLayer.InternalFeatures.Count > 0)  
             {  
                 highlightFeatureLayer.InternalFeatures.Clear();  
                 tile = DrawHighlightTile(targetExtent, tile);  
                 isRefreshTile = true;  
             }  
 
             RefreshOverlayCanvas(targetExtent, tile, isRefreshTile);  
             currentScale = MapArguments.CurrentScale;  
         }  
 
         private void RefreshOverlayCanvas(RectangleShape targetExtent, LayerTile tile, bool isRefreshTile)  
         {  
             if (isRefreshTile)  
             {  
                 OverlayCanvas.Children.Clear();  
 
                 Canvas.SetTop(tile, 0);  
                 Canvas.SetLeft(tile, 0);  
 
                 OverlayCanvas.Children.Add(tile);  
             }  
         }  
 
         private LayerTile DrawHighlightTile(RectangleShape targetExtent, LayerTile tile)  
         {  
             tile.DrawingLayers.Clear();  
             if (highlightFeatureLayer.InternalFeatures.Count > 0)  
             {  
                 tile.DrawingLayers.Add(highlightFeatureLayer);  
             }  
 
             GeoCanvas geoCanvas = new GdiPlusGeoCanvas()  
             {  
                 CompositingQuality = CompositingQuality.HighSpeed,  
                 DrawingQuality = DrawingQuality.HighSpeed,  
                 SmoothingMode = SmoothingMode.HighSpeed  
             };  
             Bitmap bitmap = new Bitmap((int)tile.Width, (int)tile.Height);  
             geoCanvas.BeginDrawing(bitmap, targetExtent, MapArguments.MapUnit);  
             tile.Draw(geoCanvas);  
             geoCanvas.EndDrawing();  
             tile.CommitDrawing(geoCanvas, MapSuiteSampleHelper.GetImageSourceFromNativeImage(bitmap));  
 
             return tile;  
         }  
 
         private LayerTile GetTile(RectangleShape targetExtent, double tileScreenWidth, double tileScreenHeight, long tileColumnIndex, long tileRowIndex, int zoomLevelIndex)  
         {  
             LayerTile layerTile = new LayerTile();  
             layerTile.Width = tileScreenWidth;  
             layerTile.Height = tileScreenHeight;  
             layerTile.IsAsync = false;  
             layerTile.RowIndex = tileRowIndex;  
             layerTile.ColumnIndex = tileColumnIndex;  
             layerTile.TargetExtent = targetExtent;  
             layerTile.ZoomLevelIndex = zoomLevelIndex;  
             layerTile.DrawingExceptionMode = DrawingExceptionMode;  
             layerTile.Background = new SolidColorBrush(Colors.Transparent);  
 
             return layerTile;  
         }  
 
         private void PanOverlay(RectangleShape targetExtent)  
         {  
             if (PreviousExtent != null)  
             {  
                 double resolution = MapArguments.CurrentResolution;  
                 double worldOffsetX = targetExtent.UpperLeftPoint.X - PreviousExtent.UpperLeftPoint.X;  
                 double worldOffsetY = targetExtent.UpperLeftPoint.Y - PreviousExtent.UpperLeftPoint.Y;  
                 double screenOffsetX = worldOffsetX / resolution;  
                 double screenOffsetY = worldOffsetY / resolution;  
 
                 translateTransform.X -= screenOffsetX;  
                 translateTransform.Y += screenOffsetY;  
             }  
         }  
     }  
 }  
 

ColumnViewModel.cs

 using System.Windows;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     public class ColumnViewModel : ViewModelBase  
     {  
         private bool isSelected;  
         private string alias;  
         private string columnName;  
         private string legendTitle;  
         private Visibility checkBoxVisiblity;  
         private DataCategoryViewModel parent;  
 
         public ColumnViewModel()  
             : this(string.Empty, string.Empty)  
         { }  
 
         public ColumnViewModel(string columnName, string displayName)  
         {  
             this.columnName = columnName;  
             alias = displayName;  
             IsSelected = true;  
             CheckBoxVisiblity = Visibility.Hidden;  
         }  
 
         public string Alias  
         {  
             get { return alias; }  
             set  
             {  
                 alias = value;  
                 RaisePropertyChanged(() => Alias);  
             }  
         }  
 
         public string ColumnName  
         {  
             get { return columnName; }  
             set { columnName = value; }  
         }  
 
         public string LegendTitle  
         {  
             get { return legendTitle; }  
             set { legendTitle = value; }  
         }  
 
         public bool IsSelected  
         {  
             get { return isSelected; }  
             set  
             {  
                 isSelected = value;  
                 RaisePropertyChanged(() => IsSelected);  
             }  
         }  
 
         public Visibility CheckBoxVisiblity  
         {  
             get { return checkBoxVisiblity; }  
             set  
             {  
                 checkBoxVisiblity = value;  
                 RaisePropertyChanged(() => CheckBoxVisiblity);  
             }  
         }  
 
         public DataCategoryViewModel Parent  
         {  
             get { return parent; }  
             set { parent = value; }  
         }  
     }  
 }  
 

CustomDataCategoryViewModel.cs

 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     public class CustomDataCategoryViewModel : DataCategoryViewModel  
     {  
         private string customDataFilePathName;  
 
         public CustomDataCategoryViewModel()  
             : base()  
         {  
             CanUsePieView = false;  
         }  
 
         public string CustomDataFilePathName  
         {  
             get { return customDataFilePathName; }  
             set  
             {  
                 customDataFilePathName = value;  
                 RaisePropertyChanged(() => CustomDataFilePathName);  
             }  
         }  
     }  
 }  
 

DataCategoryViewModel.cs

 using System.Collections.ObjectModel;  
 using System.Windows.Media.Imaging;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     public class DataCategoryViewModel : ViewModelBase  
     {  
         private bool canUsePieView;  
         private string title;  
         private BitmapImage categoryImage;  
         private ObservableCollection<ColumnViewModel> columns;  
 
         public DataCategoryViewModel()  
         {  
             columns = new ObservableCollection<ColumnViewModel>();  
         }  
 
         public bool CanUsePieView  
         {  
             get { return canUsePieView; }  
             set  
             {  
                 canUsePieView = value;  
                 RaisePropertyChanged(() => CanUsePieView);  
             }  
         }  
 
         public BitmapImage CategoryImage  
         {  
             get { return categoryImage; }  
             set  
             {  
                 categoryImage = value;  
                 RaisePropertyChanged(() => CategoryImage);  
             }  
         }  
 
         public ObservableCollection<ColumnViewModel> Columns  
         {  
             get { return columns; }  
         }  
 
         public string Title  
         {  
             get { return title; }  
             set  
             {  
                 title = value;  
                 RaisePropertyChanged(() => Title);  
             }  
         }  
     }  
 }  
 

GeoColorViewModel.cs

 using System.Windows.Media;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     public class GeoColorViewModel  
     {  
         private string colorName;  
         private SolidColorBrush colorBrush;  
         private GeoColor geoColor;  
 
         public GeoColorViewModel()  
             : this(GeoColor.StandardColors.Transparent, "Transparent")  
         { }  
 
         public GeoColorViewModel(GeoColor color, string colorName)  
         {  
             ColorBrush = new SolidColorBrush(Color.FromArgb(color.AlphaComponent, color.RedComponent, color.GreenComponent, color.BlueComponent));  
             ColorName = colorName;  
             GeoColor = color;  
         }  
 
         public string ColorName  
         {  
             get { return colorName; }  
             set { colorName = value; }  
         }  
 
         public SolidColorBrush ColorBrush  
         {  
             get { return colorBrush; }  
             set { colorBrush = value; }  
         }  
 
         public GeoColor GeoColor  
         {  
             get { return geoColor; }  
             set { geoColor = value; }  
         }  
     }  
 }  
 

MainWindowViewModel.cs

 using System;  
 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Globalization;  
 using System.Linq;  
 using System.Reflection;  
 using System.Windows;  
 using System.Windows.Controls;  
 using System.Windows.Input;  
 using System.Windows.Media;  
 using System.Windows.Media.Imaging;  
 using System.Xml.Linq;  
 using ThinkGeo.MapSuite.Core;  
 using ThinkGeo.MapSuite.WpfDesktopEdition;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     public class MainWindowViewModel : ViewModelBase  
     {  
         private string displayColorText;  
         private double coordinateX;  
         private double coordinateY;  
         private ToolTip toolTip;  
         private Visibility dotDensityVisibility;  
         private Visibility valueCircleVisibility;  
         private Visibility thematicVisibility;  
         private ObservableCollection<DataCategoryViewModel> categoryList;  
         private ObservableCollection<GeoColorViewModel> geoColorList;  
         private ObservableCollection<ColorWheelDirection> colorWheelDirections;  
         private GeoColorViewModel selectedColorItem;  
         private GeoColorViewModel selectedEndColorItem;  
         private DataCategoryViewModel selectedCategory;  
         private ValueCircleDemographicStyleBuilder valueCircleStyleBuilder;  
         private DotDensityDemographicStyleBuilder dotDensityStyleBuilder;  
         private ThematicDemographicStyleBuilder thematicStyleBuilder;  
         private PieChartDemographicStyleBuilder pieStyleBuilder;  
         private DemographicStyleBuilder currentStyleBuilder;  
         private MapModel mapModel;  
 
         public MainWindowViewModel(MapModel mapModel)  
         {  
             this.mapModel = mapModel;  
 
             InitializeProperties();  
             InitializetionDataCategories();  
             InitializeGeoSimpleColorsList();  
             InitializeEvents(mapModel);  
 
             UpdateUIControls(ThematicDemographicStyle);  
             SelectedCategory = CategoryList[0];  
             CurrentStyleBuilder.SelectedColumns.Add(SelectedCategory.Columns[0].ColumnName);  
             mapModel.LegendTitle = SelectedCategory.Columns[0].LegendTitle;  
         }  
 
         public Visibility DotDensityVisibility  
         {  
             get { return dotDensityVisibility; }  
             set  
             {  
                 dotDensityVisibility = value;  
                 RaisePropertyChanged(() => DotDensityVisibility);  
             }  
         }  
 
         public Visibility ValueCircleVisibility  
         {  
             get { return valueCircleVisibility; }  
             set  
             {  
                 valueCircleVisibility = value;  
                 RaisePropertyChanged(() => ValueCircleVisibility);  
             }  
         }  
 
         public Visibility ThematicVisibility  
         {  
             get { return thematicVisibility; }  
             set  
             {  
                 thematicVisibility = value;  
                 RaisePropertyChanged(() => ThematicVisibility);  
             }  
         }  
 
         public string DisplayColorText  
         {  
             get { return displayColorText; }  
             set  
             {  
                 displayColorText = value;  
                 RaisePropertyChanged(() => DisplayColorText);  
             }  
         }  
 
         public ObservableCollection<DataCategoryViewModel> CategoryList  
         {  
             get { return categoryList; }  
         }  
 
         public ObservableCollection<ColorWheelDirection> ColorWheelDirections  
         {  
             get { return colorWheelDirections; }  
         }  
 
         public DotDensityDemographicStyleBuilder DotDensityDemographicStyle  
         {  
             get { return dotDensityStyleBuilder; }  
         }  
 
         public ObservableCollection<GeoColorViewModel> GeoColorList  
         {  
             get { return geoColorList; }  
         }  
 
         public PieChartDemographicStyleBuilder PieDemographicStyle  
         {  
             get { return pieStyleBuilder; }  
         }  
 
         public GeoColorViewModel SelectedColorItem  
         {  
             get { return selectedColorItem; }  
             set  
             {  
                 selectedColorItem = value;  
                 RaisePropertyChanged(() => SelectedColorItem);  
                 if (CurrentStyleBuilder != null && CurrentStyleBuilder.Color != selectedColorItem.GeoColor)  
                 {  
                     CurrentStyleBuilder.Color = selectedColorItem.GeoColor;  
                     UpdateMap();  
                 }  
             }  
         }  
 
         public DataCategoryViewModel SelectedCategory  
         {  
             get { return selectedCategory; }  
             set  
             {  
                 selectedCategory = value;  
                 RaisePropertyChanged(() => SelectedCategory);  
             }  
         }  
 
         public ColorWheelDirection SelectedColorWheelDirection  
         {  
             get { return thematicStyleBuilder.ColorWheelDirection; }  
             set  
             {  
                 thematicStyleBuilder.ColorWheelDirection = value;  
                 RaisePropertyChanged(() => SelectedColorWheelDirection);  
                 if (CurrentStyleBuilder != null)  
                 {  
                     UpdateMap();  
                 }  
             }  
         }  
 
         public GeoColorViewModel SelectedEndColorItem  
         {  
             get { return selectedEndColorItem; }  
             set  
             {  
                 selectedEndColorItem = value;  
                 RaisePropertyChanged(() => SelectedEndColorItem);  
                 if (ThematicDemographicStyle != null && ThematicDemographicStyle.EndColor != selectedEndColorItem.GeoColor)  
                 {  
                     ThematicDemographicStyle.EndColor = selectedEndColorItem.GeoColor;  
                     UpdateMap();  
                 }  
             }  
         }  
 
         public ThematicDemographicStyleBuilder ThematicDemographicStyle  
         {  
             get { return thematicStyleBuilder; }  
         }  
 
         public ValueCircleDemographicStyleBuilder ValueCircleDemographicStyle  
         {  
             get { return valueCircleStyleBuilder; }  
         }  
 
         public DemographicStyleBuilder CurrentStyleBuilder  
         {  
             get { return currentStyleBuilder; }  
         }  
 
         public double CoordinateX  
         {  
             get { return coordinateX; }  
             set  
             {  
                 coordinateX = value;  
                 RaisePropertyChanged(() => CoordinateX);  
             }  
         }  
 
         public double CoordinateY  
         {  
             get { return coordinateY; }  
             set  
             {  
                 coordinateY = value;  
                 RaisePropertyChanged(() => CoordinateY);  
             }  
         }  
 
         public void CreatePieDemographicStyle()  
         {  
             PieDemographicStyle.SelectedColumnAliases.Clear();  
             PieDemographicStyle.SelectedColumns.Clear();  
 
             foreach (var item in SelectedCategory.Columns)  
             {  
                 item.CheckBoxVisiblity = Visibility.Visible;  
             }  
 
             foreach (var item in SelectedCategory.Columns.Where(d => d.IsSelected))  
             {  
                 PieDemographicStyle.SelectedColumns.Add(item.ColumnName);  
                 PieDemographicStyle.SelectedColumnAliases.Add(item.Alias);  
             }  
 
             UpdateUIControls(PieDemographicStyle);  
             mapModel.LegendTitle = SelectedCategory.Title;  
         }  
 
         public void UpdateMap()  
         {  
             Collection<ThinkGeo.MapSuite.Core.Style> activeStyles = CurrentStyleBuilder.GetStyles(mapModel.DefaultFeatureLayer.FeatureSource);  
             mapModel.DefaultFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();  
             foreach (var activeStyle in activeStyles)  
             {  
                 mapModel.DefaultFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(activeStyle);  
             }  
             mapModel.DefaultFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
             UpdateLegend(CurrentStyleBuilder, mapModel.LegendAdornmentLayer);  
             mapModel.MapControl.Refresh(new Overlay[] { mapModel.DemographicLayerOverlay, mapModel.MapControl.AdornmentOverlay });  
         }  
 
         public void UpdateUIControls(DemographicStyleBuilder activeSettingViewModel)  
         {  
             GeoColor[] colors = GeoColorList.Select(c => c.GeoColor).ToArray();  
             for (int i = 0; i < colors.Length; i++)  
             {  
                 if (colors[i].Equals(activeSettingViewModel.Color))  
                 {  
                     currentStyleBuilder = activeSettingViewModel;  
                     SelectedColorItem = GeoColorList[i];  
                     break;  
                 }  
             }  
             ThematicDemographicStyleBuilder thematicDemographicStyleBuilder = activeSettingViewModel as ThematicDemographicStyleBuilder;  
             if (thematicDemographicStyleBuilder != null)  
             {  
                 GeoColor styleColor = thematicDemographicStyleBuilder.EndColor;  
                 for (int i = 0; i < colors.Length; i++)  
                 {  
                     if (colors[i].Equals(styleColor))  
                     {  
                         currentStyleBuilder = activeSettingViewModel;  
                         SelectedEndColorItem = GeoColorList[i];  
                         break;  
                     }  
                 }  
             }  
         }  
 
         private void InitializeProperties()  
         {  
             toolTip = new ToolTip();  
             DotDensityVisibility = Visibility.Collapsed;  
             ValueCircleVisibility = Visibility.Collapsed;  
             DisplayColorText = "Display Color:";  
             colorWheelDirections = new ObservableCollection<ColorWheelDirection>();  
             colorWheelDirections.Add(ColorWheelDirection.Clockwise);  
             colorWheelDirections.Add(ColorWheelDirection.CounterClockwise);  
             categoryList = new ObservableCollection<DataCategoryViewModel>();  
             valueCircleStyleBuilder = new ValueCircleDemographicStyleBuilder();  
             dotDensityStyleBuilder = new DotDensityDemographicStyleBuilder();  
             pieStyleBuilder = new PieChartDemographicStyleBuilder();  
             thematicStyleBuilder = new ThematicDemographicStyleBuilder();  
         }  
 
         private void InitializeEvents(MapModel mapModel)  
         {  
             mapModel.MapControl.MapTools.MouseCoordinate.CustomFormatted += MouseCoordinate_CustomFormatted;  
             mapModel.MapControl.MouseMove += WpfMap_MouseMove;  
         }  
 
         private void WpfMap_MouseMove(object sender, MouseEventArgs e)  
         {  
             toolTip.IsOpen = false;  
             mapModel.HighlightOverlay.HighlightFeature = null;  
             if (!mapModel.HighlightOverlay.IsPanningMap)  
             {  
                 Point screenLocation = e.GetPosition(mapModel.MapControl);  
                 PointShape worldLoction = ExtentHelper.ToWorldCoordinate(mapModel.MapControl.CurrentExtent, new ScreenPointF((float)screenLocation.X, (float)screenLocation.Y), (float)mapModel.MapControl.ActualWidth, (float)mapModel.MapControl.ActualHeight);  
 
                 // Here we get tootip for the highlighted feature.  
                 if (worldLoction.X > -180 && worldLoction.X < 180 && worldLoction.Y > -90 && worldLoction.Y < 90)  
                 {  
                     mapModel.DefaultFeatureLayer.Open();  
                     List<string> columnNames = mapModel.DefaultFeatureLayer.FeatureSource.GetColumns().Select(x => x.ColumnName).ToList();  
                     Collection<Feature> nearestFeatures = mapModel.DefaultFeatureLayer.QueryTools.GetFeaturesNearestTo(worldLoction, mapModel.MapControl.MapUnit, 1, columnNames, 1, DistanceUnit.Meter);  
                     if (nearestFeatures.Count > 0)  
                     {  
                         var highlightedFeature = nearestFeatures[0];  
                         mapModel.HighlightOverlay.HighlightFeature = highlightedFeature;  
                         mapModel.HighlightOverlay.Refresh();  
                         var content = GetToolTip(highlightedFeature);  
                         toolTip.Content = content;  
                         toolTip.IsOpen = true;  
                     }  
                 }  
             }  
             mapModel.HighlightOverlay.Refresh();  
         }  
 
         private void MouseCoordinate_CustomFormatted(object sender, CustomFormattedMouseCoordinateMapToolEventArgs e)  
         {  
             CoordinateX = e.WorldCoordinate.X;  
             CoordinateY = e.WorldCoordinate.Y;  
         }  
 
         private void InitializeGeoSimpleColorsList()  
         {  
             geoColorList = new ObservableCollection<GeoColorViewModel>();  
             PropertyInfo[] propertyInfos = GeoColor.SimpleColors.GetType().GetProperties();  
             foreach (PropertyInfo propertyInfo in propertyInfos)  
             {  
                 object value = propertyInfo.GetValue(GeoColor.SimpleColors, null);  
                 string name = propertyInfo.Name;  
 
                 if (name.ToUpperInvariant() == "TRANSPARENT")  
                 {  
                     continue;  
                 }  
 
                 if (value.GetType() == typeof(GeoColor))  
                 {  
                     GeoColorViewModel colorItem = new GeoColorViewModel((GeoColor)value, name);  
                     geoColorList.Add(colorItem);  
                 }  
             }  
         }  
 
         // Here we load all the nodes on the left from xml file.  
         private void InitializetionDataCategories()  
         {  
             var xDoc = XDocument.Load(MapSuiteSampleHelper.GetValueFromConfiguration("CategoryFilePath"));  
             var elements = from category in xDoc.Element("DemographicMap").Elements("Category")  
                            select category;  
 
             foreach (var element in elements)  
             {  
                 DataCategoryViewModel category = null;  
                 string title = element.Attribute("name").Value;  
                 category = title != "Custom Data" ? new DataCategoryViewModel() : new CustomDataCategoryViewModel();  
                 category.Title = title;  
                 category.CategoryImage = new BitmapImage(new Uri(string.Format(CultureInfo.InvariantCulture, "{0}{1}", "pack://application:,,,/MapSuiteUSDemographicMap;component/", element.Attribute("icon").Value), UriKind.RelativeOrAbsolute));  
 
                 foreach (var item in element.Elements("item"))  
                 {  
                     ColumnViewModel categoryItem = new ColumnViewModel();  
                     categoryItem.Parent = category;  
                     categoryItem.ColumnName = item.Element("columnName").Value;  
                     categoryItem.Alias = item.Element("alias").Value;  
                     categoryItem.LegendTitle = item.Element("legendTitle").Value;  
                     category.Columns.Add(categoryItem);  
                 }  
                 category.CanUsePieView = category.Columns.Count >= 2;  
                 CategoryList.Add(category);  
             }  
         }  
 
         public StackPanel GetToolTip(Feature feature)  
         {  
             StackPanel popupPanel = new StackPanel();  
             popupPanel.Margin = new Thickness(5);  
 
             if (mapModel.DefaultFeatureLayer == mapModel.CensusStateFeatureLayer)  
             {  
                 TextBlock stateName = new TextBlock();  
                 stateName.FontWeight = FontWeights.Bold;  
                 stateName.FontFamily = new FontFamily("Segoe UI");  
                 stateName.Text = feature.ColumnValues["NAME"];  
                 stateName.FontSize = 14;  
                 stateName.Margin = new Thickness(0, 0, 0, 10);  
 
                 popupPanel.Children.Add(stateName);  
                 popupPanel.Children.Add(new Separator() { Margin = new Thickness(0, 0, 0, 10) });  
             }  
 
             foreach (var column in CurrentStyleBuilder.SelectedColumns)  
             {  
                 if (feature.ColumnValues.ContainsKey(column))  
                 {  
                     TextBlock columnText = new TextBlock();  
                     columnText.FontFamily = new FontFamily("Segoe UI");  
                     columnText.Text = TextFormatter.GetFormatedString(column, double.Parse(feature.ColumnValues[column]));  
                     columnText.FontSize = 12;  
                     columnText.Margin = new Thickness(0, 0, 0, 3);  
 
                     popupPanel.Children.Add(columnText);  
                 }  
             }  
             return popupPanel;  
         }  
 
         private void UpdateLegend(DemographicStyleBuilder styleBuilder, LegendAdornmentLayer legendAdornmentLayer)  
         {  
             legendAdornmentLayer.LegendItems.Clear();  
 
             if (styleBuilder is ThematicDemographicStyleBuilder)  
             {  
                 AddThematicLegendItems(legendAdornmentLayer);  
             }  
             else if (styleBuilder is DotDensityDemographicStyleBuilder)  
             {  
                 AddDotDensityLegendItems(legendAdornmentLayer);  
             }  
             else if (styleBuilder is ValueCircleDemographicStyleBuilder)  
             {  
                 AddValueCircleLegendItems(legendAdornmentLayer);  
             }  
             else if (styleBuilder is PieChartDemographicStyleBuilder)  
             {  
                 AddPieGraphLegendItems(legendAdornmentLayer);  
             }  
 
             legendAdornmentLayer.ContentResizeMode = LegendContentResizeMode.Fixed;  
             legendAdornmentLayer.Height = GetLegendHeight(legendAdornmentLayer);  
             legendAdornmentLayer.Width = GetLegendWidth(legendAdornmentLayer);  
         }  
 
         private float GetLegendWidth(LegendAdornmentLayer legendAdornmentLayer)  
         {  
             GdiPlusGeoCanvas gdiPlusGeoCanvas = new GdiPlusGeoCanvas();  
             LegendItem title = legendAdornmentLayer.Title;  
             float width = gdiPlusGeoCanvas.MeasureText(title.TextStyle.TextColumnName, new GeoFont("Segoe UI", 12)).Width  
                + title.ImageWidth + title.ImageRightPadding + title.ImageLeftPadding + title.TextRightPadding + title.TextLeftPadding + title.LeftPadding + title.RightPadding;  
 
             foreach (LegendItem legendItem in legendAdornmentLayer.LegendItems)  
             {  
                 float legendItemWidth = gdiPlusGeoCanvas.MeasureText(legendItem.TextStyle.TextColumnName, new GeoFont("Segoe UI", 10)).Width  
                     + legendItem.ImageWidth + legendItem.ImageRightPadding + legendItem.ImageLeftPadding + legendItem.TextRightPadding + legendItem.TextLeftPadding + legendItem.LeftPadding + legendItem.RightPadding;  
                 if (width < legendItemWidth)  
                 {  
                     width = legendItemWidth;  
                 }  
             }  
             return width;  
         }  
 
         private float GetLegendHeight(LegendAdornmentLayer legendAdornmentLayer)  
         {  
             GdiPlusGeoCanvas gdiPlusGeoCanvas = new GdiPlusGeoCanvas();  
             LegendItem title = legendAdornmentLayer.Title;  
             float titleMeasuredHeight = gdiPlusGeoCanvas.MeasureText(title.TextStyle.TextColumnName, new GeoFont("Segoe UI", 12)).Height;  
             float legendHeight = new[] { titleMeasuredHeight, title.ImageHeight, title.Height }.Max();  
             float height = legendHeight + Math.Max(title.ImageTopPadding, title.TextTopPadding) + title.TopPadding + Math.Max(title.ImageBottomPadding, title.TextBottomPadding) + title.BottomPadding;  
 
             foreach (LegendItem legendItem in legendAdornmentLayer.LegendItems)  
             {  
                 float itemLegendHeight = Math.Max(gdiPlusGeoCanvas.MeasureText(legendItem.TextStyle.TextColumnName, new GeoFont("Segoe UI", 10)).Height, legendItem.ImageHeight);  
                 float itemHeight = itemLegendHeight + Math.Max(legendItem.ImageTopPadding, legendItem.TextTopPadding) + legendItem.TopPadding + Math.Max(legendItem.ImageBottomPadding, legendItem.TextBottomPadding) + legendItem.BottomPadding;  
 
                 height += itemHeight;  
             }  
             return height;  
         }  
 
         private void AddPieGraphLegendItems(LegendAdornmentLayer legendAdornmentLayer)  
         {  
             PieZedGraphStyle zedGraphStyle = (PieZedGraphStyle)CurrentStyleBuilder.GetStyles(mapModel.DefaultFeatureLayer.FeatureSource)[0];  
 
             foreach (KeyValuePair<string, GeoColor> item in zedGraphStyle.PieSlices)  
             {  
                 LegendItem legendItem = new LegendItem();  
                 legendItem.ImageWidth = 20;  
                 legendItem.TextRightPadding = 5;  
                 legendItem.RightPadding = 5;  
                 legendItem.ImageStyle = new AreaStyle(new GeoSolidBrush(item.Value));  
                 legendItem.TextStyle = new TextStyle(item.Key, new GeoFont("Segoe UI", 10), new GeoSolidBrush(GeoColor.SimpleColors.Black));  
                 legendAdornmentLayer.LegendItems.Add(legendItem);  
             }  
         }  
 
         private void AddValueCircleLegendItems(LegendAdornmentLayer legendAdornmentLayer)  
         {  
             ValueCircleStyle valueCircleStyle = (ValueCircleStyle)CurrentStyleBuilder.GetStyles(mapModel.DefaultFeatureLayer.FeatureSource)[0];  
 
             // Here we generate 4 legend items, with the area of 160, 320, 640 and 1280 square pixels seperately.  
             int[] circleAreas = new int[] { 160, 320, 640, 1280 };  
             foreach (int circleArea in circleAreas)  
             {  
                 LegendItem legendItem = new LegendItem();  
                 double radius = Math.Sqrt(circleArea / Math.PI);  
                 legendItem.ImageStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(valueCircleStyle.InnerColor), new GeoPen(new GeoSolidBrush(valueCircleStyle.OuterColor)), (int)(radius * 2));  
                 AreaStyle maskStyle = new AreaStyle(new GeoPen(GeoColor.StandardColors.LightGray, 1), new GeoSolidBrush(GeoColor.SimpleColors.Transparent));  
                 legendItem.ImageMask = maskStyle;  
                 legendItem.ImageWidth = 48;  
                 legendItem.TextTopPadding = 16;  
                 legendItem.TextRightPadding = 5;  
                 legendItem.BottomPadding = 16;  
                 legendItem.TopPadding = 16;  
                 legendItem.RightPadding = 5;  
 
                 double drawingRadius = circleArea / valueCircleStyle.DrawingRadiusRatio * valueCircleStyle.BasedScale / valueCircleStyle.DefaultZoomLevel.Scale;  
                 double ratio = (valueCircleStyle.MaxValidValue - valueCircleStyle.MinValidValue) / (valueCircleStyle.MaxCircleAreaInDefaultZoomLevel - valueCircleStyle.MinCircleAreaInDefaultZoomLevel);  
                 double resultValue = (drawingRadius - valueCircleStyle.MinCircleAreaInDefaultZoomLevel) * ratio + valueCircleStyle.MinValidValue;  
 
                 string text = TextFormatter.GetFormatedStringForLegendItem(valueCircleStyle.ColumnName, resultValue);  
                 legendItem.TextStyle = new TextStyle(text, new GeoFont("Segoe UI", 10), new GeoSolidBrush(GeoColor.SimpleColors.Black));  
 
                 legendAdornmentLayer.LegendItems.Add(legendItem);  
             }  
         }  
 
         private void AddDotDensityLegendItems(LegendAdornmentLayer legendAdornmentLayer)  
         {  
             CustomDotDensityStyle dotDensityStyle = (CustomDotDensityStyle)CurrentStyleBuilder.GetStyles(mapModel.DefaultFeatureLayer.FeatureSource)[0];  
 
             // Here we generate 4 legend items, for 5, 10, 20 and 50 points seperately.  
             int[] pointCounts = new int[] { 5, 10, 20, 50 };  
             foreach (int pointCount in pointCounts)  
             {  
                 LegendItem legendItem = new LegendItem();  
                 legendItem.ImageMask = new AreaStyle(new GeoPen(GeoColor.StandardColors.LightGray, 1), new GeoSolidBrush(GeoColor.SimpleColors.Transparent));  
                 legendItem.ImageWidth = 48;  
                 legendItem.TextTopPadding = 16;  
                 legendItem.TextRightPadding = 5;  
                 legendItem.BottomPadding = 16;  
                 legendItem.TopPadding = 16;  
                 legendItem.RightPadding = 5;  
                 CustomDotDensityStyle legendDotDensityStyle = (CustomDotDensityStyle)dotDensityStyle.CloneDeep();  
                 legendDotDensityStyle.DrawingPointsNumber = pointCount;  
                 legendItem.ImageStyle = legendDotDensityStyle;  
 
                 string text = string.Format(CultureInfo.InvariantCulture, "{0:0.####}", TextFormatter.GetFormatedStringForLegendItem(dotDensityStyle.ColumnName, (pointCount / dotDensityStyle.PointToValueRatio)));  
                 legendItem.TextStyle = new TextStyle(text, new GeoFont("Segoe UI", 10), new GeoSolidBrush(GeoColor.SimpleColors.Black));  
 
                 legendAdornmentLayer.LegendItems.Add(legendItem);  
             }  
         }  
 
         private void AddThematicLegendItems(LegendAdornmentLayer legendAdornmentLayer)  
         {  
             ClassBreakStyle thematicStyle = (ClassBreakStyle)CurrentStyleBuilder.GetStyles(mapModel.DefaultFeatureLayer.FeatureSource)[0];  
 
             for (int i = 0; i < thematicStyle.ClassBreaks.Count; i++)  
             {  
                 LegendItem legendItem = new LegendItem();  
 
                 if (i < thematicStyle.ClassBreaks.Count)  
                 {  
                     legendItem.ImageStyle = thematicStyle.ClassBreaks[i].DefaultAreaStyle;  
                     legendItem.ImageWidth = 20;  
                     legendItem.TextRightPadding = 5;  
                     legendItem.RightPadding = 5;  
 
                     string text = string.Empty;  
                     if (i != thematicStyle.ClassBreaks.Count - 1)  
                     {  
                         text = string.Format("{0:#,0.####} ~ {1:#,0.####}",  
                             TextFormatter.GetFormatedStringForLegendItem(thematicStyle.ColumnName, thematicStyle.ClassBreaks[i].Value),  
                             TextFormatter.GetFormatedStringForLegendItem(thematicStyle.ColumnName, thematicStyle.ClassBreaks[i|+ 1].Value));  
                     }  
                     else  
                     {  
                         text = string.Format("> {0:#,0.####}",  
                             TextFormatter.GetFormatedStringForLegendItem(thematicStyle.ColumnName, thematicStyle.ClassBreaks[i].Value));  
                     }  
                     legendItem.TextStyle = new TextStyle(text, new GeoFont("Segoe UI", 10), new GeoSolidBrush(GeoColor.SimpleColors.Black));  
                 }  
                 legendAdornmentLayer.LegendItems.Add(legendItem);  
             }  
         }  
     }  
 }  
 

CustomDotDensityStyle.cs

 using System;  
 using System.Collections.ObjectModel;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     // We custom this DotDensity Style to enhance its drawing on the legend.  
     [Serializable]  
     class CustomDotDensityStyle : DotDensityStyle  
     {  
         private int drawingPointsNumber;  
 
         public CustomDotDensityStyle()  
             : base()  
         { }  
 
         public int DrawingPointsNumber  
         {  
             get { return drawingPointsNumber; }  
             set { drawingPointsNumber = value; }  
         }  
 
         protected override void DrawSampleCore(GeoCanvas canvas, DrawingRectangleF drawingExtent)  
         {  
             base.DrawSampleCore(canvas, drawingExtent);  
             PointShape upperLeftPoint = ExtentHelper.ToWorldCoordinate(canvas.CurrentWorldExtent, drawingExtent.CenterX - drawingExtent.Width / 2, drawingExtent.CenterY - drawingExtent.Height / 2, canvas.Width, canvas.Height);  
             PointShape lowerRightPoint = ExtentHelper.ToWorldCoordinate(canvas.CurrentWorldExtent, drawingExtent.CenterX + drawingExtent.Width / 2, drawingExtent.CenterY + drawingExtent.Height / 2, canvas.Width, canvas.Height);  
             RectangleShape rectangle = new RectangleShape(upperLeftPoint, lowerRightPoint);  
             rectangle.ScaleDown(10);  
 
             // Here draw the points on Legend Image  
             Random random = new Random(DateTime.Now.Millisecond);  
             Collection<BaseShape> drawingPoints = new Collection<BaseShape>();  
             for (int i = 0; i < DrawingPointsNumber; i++)  
             {  
                 double x = rectangle.LowerLeftPoint.X + random.NextDouble() * (rectangle.Width);  
                 double y = rectangle.LowerLeftPoint.Y + random.NextDouble() * (rectangle.Height);  
                 drawingPoints.Add(new PointShape(x, y));  
             }  
             TextStyle textStyle = new TextStyle(DrawingPointsNumber.ToString(), new GeoFont("Arial", 20, DrawingFontStyles.Bold), new GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.FromHtml("#d3d3d3"))));  
             textStyle.DrawSample(canvas, drawingExtent);  
             CustomPointStyle.Draw(drawingPoints, canvas, new Collection<SimpleCandidate>(), new Collection<SimpleCandidate>());  
         }  
     }  
 }  
 
 

DemographicStyleBuilder.cs

 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Linq;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     // We have the StyleBuilder to generate different styles  
     public abstract class DemographicStyleBuilder  
     {  
         private int opacity;  
         private GeoColor color;  
         private Collection<string> selectedColumns;  
 
         protected DemographicStyleBuilder()  
             : this(new Collection<string>())  
         { }  
 
         protected DemographicStyleBuilder(IEnumerable<string> selectedColumns)  
         {  
             this.Opacity = 100;  
             this.color = GeoColor.FromHtml("#F1F369");  
             this.selectedColumns = new Collection<string>(selectedColumns.ToList());  
         }  
 
         // The generated style would based on the columns we selected here.  
         // Multiple columns are required For PieChart style, only one column is needed for other styles in this sample.  
         public Collection<string> SelectedColumns  
         {  
             get { return selectedColumns; }  
         }  
 
         public GeoColor Color  
         {  
             get { return color; }  
             set { color = value; }  
         }  
 
         public int Opacity  
         {  
             get { return opacity; }  
             protected set { opacity = value; }  
         }  
 
         public Collection<Style> GetStyles(FeatureSource featureSource)  
         {  
             return GetStylesCore(featureSource);  
         }  
 
         protected abstract Collection<Style> GetStylesCore(FeatureSource featureSource);  
     }  
 }  
 

DotDensityDemographicStyleBuilder.cs

 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Globalization;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     public class DotDensityDemographicStyleBuilder : DemographicStyleBuilder  
     {  
         private double dotDensityValue;  
 
         public DotDensityDemographicStyleBuilder()  
             : this(new string[] { })  
         { }  
 
         public DotDensityDemographicStyleBuilder(IEnumerable<string> selectedColumns)  
             : base(selectedColumns)  
         {  
             Opacity = 255;  
             DotDensityValue = 50;  
             Color = GeoColor.SimpleColors.DarkRed;  
         }  
 
         public double DotDensityValue  
         {  
             get { return dotDensityValue; }  
             set { dotDensityValue = value; }  
         }  
 
         protected override Collection<Style> GetStylesCore(FeatureSource featureSource)  
         {  
             // here we generate CustomDotDensityStyle.  
             double totalValue = 0;  
             featureSource.Open();  
             int featureCount = featureSource.GetCount();  
             for (int i = 0; i < featureCount; i++)  
             {  
                 Feature feature = featureSource.GetFeatureById((i + 1).ToString(CultureInfo.InvariantCulture), SelectedColumns);  
                 double columnValue;  
 
                 if (double.TryParse(feature.ColumnValues[SelectedColumns[0], out columnValue))  
                 {  
                     totalValue += columnValue;  
                 }  
             }  
             featureSource.Close();  
 
             CustomDotDensityStyle dotDensityStyle = new CustomDotDensityStyle();  
             dotDensityStyle.ColumnName = SelectedColumns[0];  
             dotDensityStyle.PointToValueRatio = DotDensityValue / (totalValue / featureCount);  
             dotDensityStyle.CustomPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.FromArgb(Opacity, Color), 4);  
 
             return new Collection<Style>() { dotDensityStyle };  
         }  
     }  
 }  
 

PieChartDemographicStyleBuilder.cs

 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Drawing;  
 using ThinkGeo.MapSuite.Core;  
 using ZedGraph;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     public class PieChartDemographicStyleBuilder : DemographicStyleBuilder  
     {  
         private Collection<string> selectedColumnAliases;  
         private Collection<GeoColor> pieColors;  
 
         public PieChartDemographicStyleBuilder()  
             : this(new string[] { })  
         { }  
 
         public PieChartDemographicStyleBuilder(IEnumerable<string> selectedColumns)  
             : base(selectedColumns)  
         {  
             Opacity = 200;  
             Color = GeoColor.SimpleColors.LightBlue;  
             selectedColumnAliases = new Collection<string>();  
         }  
 
         public Collection<string> SelectedColumnAliases  
         {  
             get { return selectedColumnAliases; }  
         }  
 
         protected override Collection<Style> GetStylesCore(FeatureSource featureSource)  
         {  
             // here we generated the PieZedGraphStyle.  
             PieZedGraphStyle zedGraphStyle = new PieZedGraphStyle();  
             zedGraphStyle.ZedGraphDrawing += ZedGraphStyle_ZedGraphDrawing;  
             pieColors = GeoColor.GetColorsInQualityFamily(GeoColor.FromArgb(Opacity, Color), SelectedColumns.Count);  
 
             for (int i = 0; i < SelectedColumns.Count; i++)  
             {  
                 zedGraphStyle.RequiredColumnNames.Add(SelectedColumns[i]);  
                 zedGraphStyle.PieSlices.Add(SelectedColumnAliases[i], pieColors[i]);  
             }  
 
              return new Collection<Style>(){zedGraphStyle};  
         }  
 
         private void ZedGraphStyle_ZedGraphDrawing(object sender, ZedGraphDrawingEventArgs e)  
         {  
             ZedGraphControl zedGraph = new ZedGraphControl();  
             zedGraph.Size = new Size(100, 100);  
 
             zedGraph.GraphPane.Fill.Type = FillType.None;  
             zedGraph.GraphPane.Chart.Fill.Type = FillType.None;  
 
             zedGraph.GraphPane.Border.IsVisible = false;  
             zedGraph.GraphPane.Chart.Border.IsVisible = false;  
             zedGraph.GraphPane.XAxis.IsVisible = false;  
             zedGraph.GraphPane.YAxis.IsVisible = false;  
             zedGraph.GraphPane.Legend.IsVisible = false;  
             zedGraph.GraphPane.Title.IsVisible = false;  
 
             for (int i = 0; i < SelectedColumns.Count; i++)  
             {  
                 double value = 0;  
                 if (!double.TryParse(e.Feature.ColumnValues[SelectedColumns[i], out value))  
                 {  
                     zedGraph.Dispose();  
                     return;  
                 }  
                 Color color = System.Drawing.Color.FromArgb(pieColors[i].AlphaComponent, pieColors[i].RedComponent, pieColors[i].GreenComponent, pieColors[i].BlueComponent);  
                 PieItem pieItem = zedGraph.GraphPane.AddPieSlice(value, color, 0.08, "");  
                 pieItem.LabelDetail.IsVisible = false;  
             }  
             zedGraph.AxisChange();  
 
             e.Bitmap = zedGraph.GraphPane.GetImage();  
             zedGraph.Dispose();  
         }  
     }  
 }  
 

PieZedGraphStyle.cs

 using System.Collections.Generic;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     // We custom this class just make it a bit easier to use.  
     public class PieZedGraphStyle : ZedGraphStyle  
     {  
         private Dictionary<string, GeoColor> pieSlices;  
 
         public PieZedGraphStyle()  
         {  
             pieSlices = new Dictionary<string, GeoColor>();  
         }  
 
         public Dictionary<string, GeoColor> PieSlices  
         {  
             get { return pieSlices; }  
         }  
     }  
 }  
 

ThematicDemographicStyleBuilder.cs

 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Globalization;  
 using System.Linq;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     public class ThematicDemographicStyleBuilder : DemographicStyleBuilder  
     {  
         private int classBreakCount;  
         private GeoColor endColor;  
         private ColorWheelDirection colorWheelDirection;  
 
         public ThematicDemographicStyleBuilder()  
             : this(new string[] { })  
         { }  
 
         public ThematicDemographicStyleBuilder(IEnumerable<string> selectedColumns)  
             : base(selectedColumns)  
         {  
             Opacity = 200;  
             ClassBreakCount = 10;  
             Color = GeoColor.SimpleColors.LightBlue;  
             EndColor = GeoColor.SimpleColors.LightRed;  
             ColorWheelDirection = ColorWheelDirection.CounterClockwise;  
         }  
 
         public int ClassBreakCount  
         {  
             get { return classBreakCount; }  
             set { classBreakCount = value; }  
         }  
 
         public ColorWheelDirection ColorWheelDirection  
         {  
             get { return colorWheelDirection; }  
             set { colorWheelDirection = value; }  
         }  
 
         public GeoColor StartColor  
         {  
             get { return Color; }  
             set { Color = value; }  
         }  
 
         public GeoColor EndColor  
         {  
             get { return endColor; }  
             set { endColor = value; }  
         }  
 
         protected override Collection<Style> GetStylesCore(FeatureSource featureSource)  
         {  
             // here we generated a class break style and a text style.  
             Collection<GeoColor> familyColors = GeoColor.GetColorsInQualityFamily(Color, EndColor, classBreakCount, ColorWheelDirection);  
 
             featureSource.Open();  
             int featureCount = featureSource.GetCount();  
             double[] values = new double[featureCount];  
             for (int i = 0; i < featureCount; i++)  
             {  
                 Feature feature = featureSource.GetFeatureById((i + 1).ToString(CultureInfo.InvariantCulture), SelectedColumns);  
                 double columnValue;  
                 if (double.TryParse(feature.ColumnValues[SelectedColumns[0], out columnValue))  
                 {  
                     values[i] = columnValue;  
                 }  
             }  
             featureSource.Close();  
 
             ClassBreakStyle classBreakStyle = new ClassBreakStyle(SelectedColumns[0]) { BreakValueInclusion = BreakValueInclusion.IncludeValue };  
             double[] classBreakValues = GetClusterClassBreaks(values, ClassBreakCount - 1);  
             for (int i = 0; i < classBreakValues.Length; i++)  
             {  
                 ClassBreak classBreak = new ClassBreak(classBreakValues[i], AreaStyles.CreateSimpleAreaStyle(new GeoColor(this.Opacity, familyColors[i]), GeoColor.FromHtml("#f05133"), 1));  
                 classBreakStyle.ClassBreaks.Add(classBreak);  
             }  
 
             return new Collection<Style>() { classBreakStyle, TextStyles.Country1("NAME") };  
         }  
 
         private double[] GetClusterClassBreaks(double[] values, int count)  
         {  
             var result = new List<double>();  
 
             var orderedValues = values.OrderBy(v => v).ToArray();  
             var min = orderedValues[0];  
             var max = orderedValues[orderedValues.Length|- 1];  
 
             var classesCount = (int)(orderedValues.Length / count);  
             var breakValue = min;  
 
             for (var i = 1; i < count; i++)  
             {  
                 breakValue = orderedValues[i|* classesCount];  
                 if (!result.Contains(breakValue))  
                 {  
                     result.Add(breakValue);  
                 }  
             }  
             result.Insert(0, 0);  
 
             return result.ToArray();  
         }  
     }  
 }  
 

ValueCircleDemographicStyleBuilder.cs

 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Globalization;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     public class ValueCircleDemographicStyleBuilder : DemographicStyleBuilder  
     {  
         private double radiusRatio;  
 
         public ValueCircleDemographicStyleBuilder()  
             : this(new string[] { })  
         { }  
 
         public ValueCircleDemographicStyleBuilder(IEnumerable<string> selectedColumns)  
             : base(selectedColumns)  
         {  
             radiusRatio = 1;  
             Color = GeoColor.SimpleColors.BrightOrange;  
             Opacity = 160;  
         }  
 
         public double RadiusRatio  
         {  
             get { return radiusRatio; }  
             set { radiusRatio = value; }  
         }  
 
         protected override Collection<Style> GetStylesCore(FeatureSource featureSource)  
         {  
             // here we generate a ValueCircle Style.  
             double minValue = double.MaxValue;  
             double maxValue = double.MinValue;  
 
             featureSource.Open();  
             for (int i = 0; i < featureSource.GetCount(); i++)  
             {  
                 Feature feature = featureSource.GetFeatureById((i + 1).ToString(CultureInfo.InvariantCulture), SelectedColumns);  
                 double columnValue;  
                 if (double.TryParse(feature.ColumnValues[SelectedColumns[0], out columnValue))  
                 {  
                     if (columnValue < minValue)  
                     {  
                         minValue = columnValue;  
                     }  
                     else if (columnValue > maxValue)  
                     {  
                         maxValue = columnValue;  
                     }  
                 }  
             }  
             featureSource.Close();  
 
             ValueCircleStyle valueCircleStyle = new ValueCircleStyle();  
             valueCircleStyle.ColumnName = SelectedColumns[0];  
             valueCircleStyle.DrawingRadiusRatio = radiusRatio;  
             valueCircleStyle.MinValidValue = minValue;  
             valueCircleStyle.MaxValidValue = maxValue;  
             valueCircleStyle.MinCircleAreaInDefaultZoomLevel = 80;  
             valueCircleStyle.MaxCircleAreaInDefaultZoomLevel = 10000;  
             valueCircleStyle.InnerColor = GeoColor.FromArgb(this.Opacity, Color);  
             valueCircleStyle.OuterColor = GeoColor.SimpleColors.White;  
 
             return new Collection<Style>(){valueCircleStyle};  
         }  
     }  
 }  
 

ValueCircleStyle.cs

 using System;  
 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace ThinkGeo.MapSuite.USDemographicMap  
 {  
     // This custom style is for displaying circles with different sizes based on the value.  
     public class ValueCircleStyle : Style  
     {  
         private string columnName;  
         private double baseScale;  
         private double minValidValue;  
         private double maxValidValue;  
         private double drawingRadiusRatio;  
         private double maxCircleRadiusInDefaultZoomLevel;  
         private double minCircleRadiusInDefaultZoomLevel;  
         private GeoColor innerColor;  
         private GeoColor outerColor;  
         private ZoomLevel defaultZoomLevel;  
 
         public ValueCircleStyle()  
             : base()  
         {  
             ZoomLevelSet zoomLevelSet = new ZoomLevelSet();  
             defaultZoomLevel = zoomLevelSet.ZoomLevel04;  
             baseScale = zoomLevelSet.ZoomLevel05.Scale;  
 
             drawingRadiusRatio = 1;  
             outerColor = GeoColor.FromArgb(255, 10, 20, 255);  
             innerColor = GeoColor.FromArgb(100, 10, 20, 255);  
             minCircleRadiusInDefaultZoomLevel = 10;  
             maxCircleRadiusInDefaultZoomLevel = 100;  
         }  
 
         public string ColumnName  
         {  
             get { return columnName; }  
             set { columnName = value; }  
         }  
 
         public ZoomLevel DefaultZoomLevel  
         {  
             get { return defaultZoomLevel; }  
             set { defaultZoomLevel = value; }  
         }  
 
         public double DrawingRadiusRatio  
         {  
             get { return drawingRadiusRatio; }  
             set { drawingRadiusRatio = value; }  
         }  
 
         public GeoColor InnerColor  
         {  
             get { return innerColor; }  
             set { innerColor = value; }  
         }  
 
         // The data might be dramatically different but we don't want any circle be super large  
         // on the map, so here we have this property to identify the max circle we can have on map.  
         public double MaxCircleAreaInDefaultZoomLevel  
         {  
             get { return maxCircleRadiusInDefaultZoomLevel; }  
             set { maxCircleRadiusInDefaultZoomLevel = value; }  
         }  
 
         public double MaxValidValue  
         {  
             get { return maxValidValue; }  
             set { maxValidValue = value; }  
         }  
 
         // The data might be dramatically different but we don't want any circle be super tiny  
         // on the map, so here we have this property to identify the min circle we can have on map.  
         public double MinCircleAreaInDefaultZoomLevel  
         {  
             get { return minCircleRadiusInDefaultZoomLevel; }  
             set { minCircleRadiusInDefaultZoomLevel = value; }  
         }  
 
         public double MinValidValue  
         {  
             get { return minValidValue; }  
             set { minValidValue = value; }  
         }  
 
         public GeoColor OuterColor  
         {  
             get { return outerColor; }  
             set { outerColor = value; }  
         }  
 
         public double BasedScale  
         {  
             get { return baseScale; }  
         }  
 
         protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)  
         {  
             double ratio = (maxValidValue - minValidValue) / (maxCircleRadiusInDefaultZoomLevel - minCircleRadiusInDefaultZoomLevel);  
 
             // here we calculate the size of each circle based on every feature's value.  
             foreach (Feature feature in features)  
             {  
                 double value = 0;  
                 if (!double.TryParse(feature.ColumnValues[columnName], out value))  
                 {  
                     continue;  
                 }  
 
                 if (value > maxValidValue || value < minValidValue)  
                 {  
                     continue;  
                 }  
 
                 double drawingDefaultCircleArea = (value - minValidValue) / ratio + minCircleRadiusInDefaultZoomLevel;  
 
                 double graphArea = drawingDefaultCircleArea * defaultZoomLevel.Scale / baseScale * drawingRadiusRatio;  
                 double graphHeght = Math.Sqrt(graphArea / Math.PI);  
 
                 PointShape center = feature.GetShape().GetCenterPoint();  
                 canvas.DrawEllipse(center, (float)(graphHeght * 2), (float)(graphHeght * 2), new GeoPen(outerColor, 1), new GeoSolidBrush(innerColor), DrawingLevel.LevelOne);  
             }  
         }  
 
         protected override Collection<string> GetRequiredColumnNamesCore()  
         {  
             Collection<string> requiredFieldNames = new Collection<string>();  
             requiredFieldNames.Add(columnName);  
 
             return requiredFieldNames;  
         }  
     }  
 }  
 
source_code_wpf_desktopeditionsample_mapsuiteusdemographicmap_cs_141201.zip.txt · Last modified: 2015/09/09 03:39 by admin