User Tools

Site Tools


source_code_wpf_desktopeditionsample_mapsuitevehicletracking_cs.zip

Source Code Wpf DesktopEditionSample MapSuiteVehicleTracking CS.zip

MainWindow.xaml

 <Window x:Class="ThinkGeo.MapSuite.VehicleTracking.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.VehicleTracking"  
         xmlns:wpf="clr-namespace:ThinkGeo.MapSuite.WpfDesktopEdition;assembly=WpfDesktopEdition"  
         Title="Vehicle Tracking" Height="675" Width="1155" WindowState="Maximized" Loaded="Window_Loaded" Icon="/Image/MapSuite.ico">  
     <Window.Resources>  
         <ResourceDictionary>  
             <local:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />  
             <local:EnumToBoolConverter x:Key="EnumToBoolConverter" />  
         </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 Margin="{StaticResource TitleMargin}">  
                     <Run FontSize="16">Map Suite</Run>  
                     <Run FontSize="20">Vehicle Tracking</Run>  
                 </TextBlock>  
             </StackPanel>  
         </Border>  
         <Grid Grid.Row="1">  
             <Grid.ColumnDefinitions>  
                 <ColumnDefinition Width="auto" />  
                 <ColumnDefinition Width="*" />  
             </Grid.ColumnDefinitions>  
             <Grid Margin="5 0 0 10">  
                 <Grid.ColumnDefinitions>  
                     <ColumnDefinition Width="*" />  
                     <ColumnDefinition Width="auto" />  
                     <ColumnDefinition Width="5" />  
                 </Grid.ColumnDefinitions>  
                 <Grid  Grid.Row="0" Grid.Column="0" Style="{StaticResource collapseExpandEffect}" Margin="0 0 5 10">  
                     <Grid.RowDefinitions>  
                         <RowDefinition Height="Auto" />  
                         <RowDefinition Height="Auto" />  
                         <RowDefinition Height="Auto" />  
                         <RowDefinition Height="Auto" />  
                         <RowDefinition Height="Auto" />  
                         <RowDefinition Height="Auto" />  
                         <RowDefinition Height="*" />  
                     </Grid.RowDefinitions>  
 
                     <TextBlock Grid.Row="0" Text="Click to refresh vehicles:" Style="{StaticResource h4}" Margin="0 10 0 10" />  
                     <Border Grid.Row="1" Style="{StaticResource fileset}">  
                         <StackPanel>  
                             <StackPanel Orientation="Horizontal">  
                                 <ToggleButton  IsChecked="{Binding AutoRefresh,Mode=TwoWay}" Content="/Image/AutoRefresh.png" ToolTip="Auto Refresh" Template="{StaticResource newAutoRefreshTemplate}" Margin="{StaticResource normalMargin}" />  
                                 <TextBlock Text="Auto Refresh: " Style="{StaticResource bodyText}" VerticalAlignment="Center" />  
                                 <TextBlock Text="{Binding AutoRefreshMode}" Style="{StaticResource warningBodyText1}" VerticalAlignment="Center" />  
                             </StackPanel>  
                             <StackPanel Orientation="Horizontal" Margin="0 5 0 0">  
                                 <Button Content="/Image/RefreshManually.png" Command="{Binding RefreshCommand}" ToolTip="Refresh" Template="{StaticResource imageButtonTemplate}" Margin="{StaticResource normalMargin}" />  
                                 <TextBlock Text="Refresh Manually" Style="{StaticResource bodyText}" VerticalAlignment="Center" />  
                             </StackPanel>  
                         </StackPanel>  
                     </Border>  
 
                     <TextBlock Grid.Row="2" Text="Interact with the map using these tools:" Style="{StaticResource h4}" Margin="0 10 0 0" />  
                     <Border Grid.Row="3" Style="{StaticResource fileset}">  
                         <StackPanel Orientation="Horizontal">  
                             <RadioButton IsChecked="{Binding MapMode,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=Pan}" GroupName="Map" Content="/Image/pan.png" ToolTip="Pan map" Template="{StaticResource imageButtonTemplate}" Margin="{StaticResource normalMargin}" />  
                             <RadioButton GroupName="Map" Content="/Image/draw.png" ToolTip="Draw fences" IsChecked="{Binding MapMode,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=DrawFence}" Template="{StaticResource imageButtonTemplate}" Margin="{StaticResource normalMargin}" />  
                             <RadioButton GroupName="Map" Content="/Image/measure.png" ToolTip="Measure distance" IsChecked="{Binding MapMode,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=Measure}" Template="{StaticResource imageButtonTemplate}" Margin="{StaticResource normalMargin}" />  
                         </StackPanel>  
                     </Border>  
                     <StackPanel Grid.Row="4" Orientation="Horizontal" x:Name="editPanel" Visibility="{Binding EditPanelVisibility}">  
                         <RadioButton x:Name="rbtnDrawNewFence" IsChecked="{Binding DrawFenceMode,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=NewFence}" Content="/Image/draw_polygon.png" GroupName="draw" ToolTip="Track new fences" Template="{StaticResource imageButtonTemplate}" Margin="{StaticResource editButtonMargin}" />  
                         <RadioButton x:Name="rbtnEditFence" IsChecked="{Binding DrawFenceMode,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=EditFence}" Content="/Image/edit_polygon.png" GroupName="draw" ToolTip="Edit the selected fence" Template="{StaticResource imageButtonTemplate}" Margin="{StaticResource editButtonMargin}" />  
                         <Button Content="/Image/Remove_Polygon.png" Command="{Binding DeleteFenceCommand}" ToolTip="Delete" Template="{StaticResource imageButtonTemplate}" Margin="15 0 5 0" />  
                         <Button Content="/Image/save.png" Command="{Binding SaveFenceCommand}" ToolTip="Save" Template="{StaticResource imageButtonTemplate}" Margin="{StaticResource editButtonMargin}" />  
                         <Button Content="/Image/clear.png" Command="{Binding CancelEditCommand}" ToolTip="Cancel" Template="{StaticResource imageButtonTemplate}" Margin="{StaticResource editButtonMargin}" />  
                     </StackPanel>  
 
                     <StackPanel Grid.Row="4" Orientation="Horizontal" x:Name="measurePanel" Visibility="{Binding MeasurePanelVisibility}">  
                         <RadioButton x:Name="rbtnMeasureLine" GroupName="Measure" IsChecked="{Binding MeasureMode,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=MeasureLine}" Content="/Image/line.png" ToolTip="Measure line" Template="{StaticResource imageButtonTemplate}" Margin="{StaticResource editButtonMargin}" />  
                         <RadioButton GroupName="Measure" Content="/Image/polygon.png" IsChecked="{Binding MeasureMode,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=MeasurePolygon}" ToolTip="Measure polygon" Template="{StaticResource imageButtonTemplate}" Margin="{StaticResource editButtonMargin}" />  
                         <Button Content="/Image/clear.png" Command="{Binding CancelMeasureCommand}" ToolTip="Cancel" Template="{StaticResource imageButtonTemplate}" Margin="{StaticResource editButtonMargin}" />  
                         <TextBlock Text="Measure Unit:" VerticalAlignment="Center" Margin="10 0 5 0" />  
                         <ComboBox ItemsSource="{Binding UnitSystems}" SelectedItem="{Binding SelectedUnitSystem,Mode=TwoWay}" Height="20" Width="72" VerticalAlignment="Center">  
                             <ComboBox.ItemTemplate>  
                                 <DataTemplate>  
                                     <TextBlock Text="{Binding .}" VerticalAlignment="Center" />  
                                 </DataTemplate>  
                             </ComboBox.ItemTemplate>  
                         </ComboBox>  
                     </StackPanel>  
                     <Border Grid.Row="5" Style="{StaticResource headerBanner}">  
                         <TextBlock Style="{StaticResource headerText2}" Text="Tracked Vehicles"></TextBlock>  
                     </Border>  
                     <Border Grid.Row="6" Style="{StaticResource fileset}" Width="300">  
                         <ScrollViewer VerticalScrollBarVisibility="Auto">  
                             <ItemsControl ItemsSource="{Binding Vehicles}">  
                                 <ItemsControl.ItemTemplate>  
                                     <DataTemplate>  
                                         <Grid Margin="0 0 0 10">  
                                             <Grid.ColumnDefinitions>  
                                                 <ColumnDefinition Width="40" />  
                                                 <ColumnDefinition Width="15" />  
                                                 <ColumnDefinition Width="*" />  
                                             </Grid.ColumnDefinitions>  
                                             <Button Content="{Binding IconUri}" Command="{Binding ZoomToVehicleCommand}" Template="{StaticResource imageButtonTemplate}" HorizontalAlignment="Center" VerticalAlignment="Top" />  
                                             <StackPanel Grid.Column="2">  
                                                 <TextBlock Cursor="Hand" FontWeight="Bold" TextDecorations="Underline" Style="{StaticResource bodyText}">  
                                                     <Hyperlink Command="{Binding ZoomToVehicleCommand}" Foreground="Black">  
                                                         <Run Text="{Binding OwnerName}"/>  
                                                     </Hyperlink>  
                                                 </TextBlock>  
                                                 <StackPanel Orientation="Horizontal">  
                                                     <Image Stretch="None" Source="/Image/ball_green.png" />  
                                                     <TextBlock Text="{Binding Status}" Style="{StaticResource bodyText}" Foreground="#339900" Margin="3 0 0 0" />  
                                                 </StackPanel>  
                                                 <Grid>  
                                                     <Grid.ColumnDefinitions>  
                                                         <ColumnDefinition Width="Auto" />  
                                                         <ColumnDefinition Width="5" />  
                                                         <ColumnDefinition Width="*" />  
                                                     </Grid.ColumnDefinitions>  
                                                     <Grid.RowDefinitions>  
                                                         <RowDefinition Height="Auto" />  
                                                         <RowDefinition Height="Auto" />  
                                                         <RowDefinition Height="Auto" />  
                                                     </Grid.RowDefinitions>  
                                                     <TextBlock Style="{StaticResource bodyText}" Text="Area:" />  
                                                     <TextBlock Style="{StaticResource bodyText}" Text="Speed:" Grid.Row="1" />  
                                                     <TextBlock Style="{StaticResource bodyText}" Text="Duration:" Grid.Row="2" />  
                                                     <TextBlock Style="{StaticResource bodyText}" Text="{Binding Area}" Grid.Column="2" />  
                                                     <TextBlock Style="{StaticResource bodyText}" Text="{Binding Speed}" Grid.Row="1" Grid.Column="2" />  
                                                     <TextBlock Style="{StaticResource bodyText}" Text="{Binding Duration}" Grid.Row="2" Grid.Column="2" />  
                                                 </Grid>  
                                             </StackPanel>  
                                         </Grid>  
                                     </DataTemplate>  
                                 </ItemsControl.ItemTemplate>  
                             </ItemsControl>  
                         </ScrollViewer>  
                     </Border>  
                 </Grid>  
                 <ToggleButton x:Name="PanelToggleButton" Template="{DynamicResource collapseExpandTemplate}" Grid.Row="0" Grid.Column="1" 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 Grid.Column="1" x:Name="wpfMap1" Panel.ZIndex="-1" />  
             <Grid Grid.Column="1" x:Name="loadingControl"  Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibilityConverter}}" Background="#30D6D6D6" DockPanel.Dock="Bottom">  
                 <local:LoadingImageUserControl />  
             </Grid>  
         </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:N2}}" HorizontalAlignment="Right" Width="95" VerticalAlignment="Center" Grid.Column="0" />  
                             <TextBlock Text="{Binding CoordinateY,StringFormat=Y: {0:N2}}" VerticalAlignment="Center" Width="100" Grid.Column="2" />  
                         </Grid>  
                     </StatusBarItem>  
                 </StatusBar>  
             </Border>  
         </Grid>  
     </Grid>  
 </Window>  
 

MainWindow.xaml.cs

 using System.Windows;  
 
 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     /// <summary>  
     /// Interaction logic for MainWindow.xaml  
     /// </summary>  
     public partial class MainWindow : Window  
     {  
         public MainWindow()  
         {  
             InitializeComponent();  
         }  
 
         private void Window_Loaded(object sender, RoutedEventArgs e)  
         {  
             DataContext = new MainWindowViewModel(wpfMap1);  
         }  
     }  
 }  
 

MainWindowViewModel.cs

 using System;  
 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Configuration;  
 using System.Data.OleDb;  
 using System.Globalization;  
 using System.IO;  
 using System.Linq;  
 using System.Threading.Tasks;  
 using System.Windows;  
 using System.Windows.Input;  
 using System.Windows.Threading;  
 using ThinkGeo.MapSuite.Core;  
 using ThinkGeo.MapSuite.VehicleTracking.Properties;  
 using ThinkGeo.MapSuite.WpfDesktopEdition;  
 
 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     public class MainWindowViewModel : ViewModelBase  
     {  
         private static readonly DateTime adjustedStartTime = DateTime.Parse("2009/7/10 11:31:0");  
         private static readonly DateTime applicationStartTime = DateTime.Now;  
         private static readonly string databasePathFileName;  
 
         private bool isBusy;  
         private bool autoRefresh;  
         private double coordinateX;  
         private double coordinateY;  
 
         private WpfMap mapControl;  
         private MapModel mapModel;  
         private ControlMapMode mapMode;  
         private MeasureMode measureMode;  
         private DrawFenceMode drawFenceMode;  
         private UnitSystem selectedUnitSystem;  
         private DispatcherTimer dispatcherTimer;  
         private Visibility editPanelVisibility;  
         private Visibility measurePanelVisibility;  
         private AutoRefreshMode autoRefreshMode;  
         private Collection<UnitSystem> unitSystems;  
         private ObservableCollection<VehicleViewModel> vehicles;  
 
         private CommandBase refreshCommand;  
         private CommandBase saveFenceCommand;  
         private CommandBase cancelEditCommand;  
         private CommandBase deleteFenceCommand;  
         private CommandBase cancelMeasureCommand;  
 
         static MainWindowViewModel()  
         {  
             databasePathFileName = ConfigurationManager.AppSettings["databasePathFileName"];  
         }  
 
         public MainWindowViewModel()  
             : this(null)  
         { }  
 
         public MainWindowViewModel(WpfMap map)  
         {  
             dispatcherTimer = new DispatcherTimer();  
             dispatcherTimer.Interval = TimeSpan.FromMilliseconds(5000);  
             dispatcherTimer.Tick += AutoRefreshTimer_Tick;  
 
             vehicles = new ObservableCollection<VehicleViewModel>();  
             unitSystems = new Collection<UnitSystem>();  
             unitSystems.Add(UnitSystem.Imperial);  
             unitSystems.Add(UnitSystem.Metric);  
             selectedUnitSystem = UnitSystem.Metric;  
             autoRefreshMode = AutoRefreshMode.On;  
             autoRefresh = true;  
             drawFenceMode = DrawFenceMode.DrawNewFence;  
             measureMode = MeasureMode.Line;  
             mapMode = ControlMapMode.Pan;  
             measurePanelVisibility = Visibility.Collapsed;  
             editPanelVisibility = Visibility.Collapsed;  
 
             MapControl = map;  
 
             dispatcherTimer.Start();  
         }  
 
         public WpfMap MapControl  
         {  
             get { return mapControl; }  
             set  
             {  
                 mapControl = value;  
                 RaisePropertyChanged(() => MapControl);  
 
                 if (mapControl != null)  
                 {  
                     mapModel = new MapModel(mapControl);  
                     mapModel.MapControl.MapTools.MouseCoordinate.CustomFormatted += MouseCoordinate_CustomFormatted;  
                     mapModel.MapControl.OverlaysDrawing += WpfMap1_OverlaysDrawing;  
                     mapModel.MapControl.OverlaysDrawn += WpfMap1_OverlaysDrawn;  
 
                     UpdateSpatialFencesAndVehicles();  
                 }  
             }  
         }  
 
         public bool IsBusy  
         {  
             get { return isBusy; }  
             set  
             {  
                 isBusy = value;  
                 RaisePropertyChanged(() => IsBusy);  
             }  
         }  
 
         public bool AutoRefresh  
         {  
             get { return autoRefresh; }  
             set  
             {  
                 autoRefresh = value;  
                 RaisePropertyChanged(() => AutoRefresh);  
                 if (value)  
                 {  
                     dispatcherTimer.Start();  
                     AutoRefreshMode = AutoRefreshMode.On;  
                 }  
                 else  
                 {  
                     dispatcherTimer.Stop();  
                     AutoRefreshMode = AutoRefreshMode.Off;  
                 }  
             }  
         }  
 
         public ControlMapMode MapMode  
         {  
             get { return mapMode; }  
             set  
             {  
                 mapMode = value;  
                 RaisePropertyChanged(() => MapMode);  
                 switch (value)  
                 {  
                     case ControlMapMode.Pan:  
                         MeasurePanelVisibility = Visibility.Collapsed;  
                         EditPanelVisibility = Visibility.Collapsed;  
                         mapModel.TrackMode = TrackMode.None;  
                         break;  
 
                     case ControlMapMode.DrawFence:  
                         mapModel.MapControl.TrackOverlay.TrackEnded -= TrackOverlay_TrackEnded;  
                         mapModel.MapControl.TrackOverlay.TrackMode = TrackMode.Polygon;  
                         mapModel.MapControl.Cursor = Cursors.Arrow;  
 
                         MeasurePanelVisibility = Visibility.Collapsed;  
                         EditPanelVisibility = Visibility.Visible;  
                         break;  
 
                     case ControlMapMode.Measure:  
                         mapModel.MapControl.TrackOverlay.MapMouseClick -= TrackOverlay_MapMouseClick;  
                         if (mapModel.MapControl.EditOverlay.EditShapesLayer.InternalFeatures.Count > 0)  
                         {  
                             SaveSpatialFences();  
                         }  
                         else if (mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Count > 0)  
                         {  
                             CancelEditCommand.Execute(null);  
                         }  
                         mapModel.MapControl.Cursor = Cursors.Arrow;  
                         mapModel.TrackMode = measureMode == MeasureMode.Line ? TrackMode.Line : TrackMode.Polygon;  
                         mapModel.MapControl.TrackOverlay.TrackStarting -= TrackOverlay_TrackStarting;  
                         mapModel.MapControl.TrackOverlay.TrackStarting += TrackOverlay_TrackStarting;  
                         mapModel.MapControl.TrackOverlay.TrackEnded -= TrackOverlay_TrackEnded;  
                         mapModel.MapControl.TrackOverlay.TrackEnded += TrackOverlay_TrackEnded;  
 
                         MeasurePanelVisibility = Visibility.Visible;  
                         EditPanelVisibility = Visibility.Collapsed;  
                         break;  
                 }  
             }  
         }  
 
         public MeasureMode MeasureMode  
         {  
             get { return measureMode; }  
             set  
             {  
                 measureMode = value;  
                 RaisePropertyChanged(() => MeasureMode);  
                 switch (value)  
                 {  
                     case MeasureMode.Line:  
                         mapModel.TrackMode = TrackMode.Line;  
                         break;  
 
                     case MeasureMode.Polygon:  
                         mapModel.TrackMode = TrackMode.Polygon;  
                         break;  
                 }  
             }  
         }  
 
         public DrawFenceMode DrawFenceMode  
         {  
             get { return drawFenceMode; }  
             set  
             {  
                 drawFenceMode = value;  
                 RaisePropertyChanged(() => DrawFenceMode);  
 
                 switch (value)  
                 {  
                     case DrawFenceMode.DrawNewFence:  
                         ResetFences();  
                         break;  
 
                     case DrawFenceMode.EditFence:  
                         ClearMeasuresAndPopups();  
                         mapModel.MapControl.TrackOverlay.TrackMode = TrackMode.None;  
 
                         // Move spatial fences from spatial fence layer to edit overlay for editing  
                         foreach (Feature feature in mapModel.SpatialFenceLayer.InternalFeatures)  
                         {  
                             if (!mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Contains(feature.Id))  
                             {  
                                 mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(feature.Id, feature);  
                             }  
                             if (!mapModel.SpatialFenceLayer.FeatureIdsToExclude.Contains(feature.Id))  
                             {  
                                 mapModel.SpatialFenceLayer.FeatureIdsToExclude.Add(feature.Id);  
                             }  
                         }  
 
                         mapModel.MapControl.TrackOverlay.MapMouseClick -= TrackOverlay_MapMouseClick;  
                         mapModel.MapControl.TrackOverlay.MapMouseClick += TrackOverlay_MapMouseClick;  
 
                         UpdateVehicles(mapModel.TraceOverlay, GetAdjustedCurrentDateTime());  
                         mapModel.MapControl.Refresh(mapModel.SpatialFenceOverlay);  
                         mapModel.MapControl.Refresh(mapModel.MapControl.TrackOverlay);  
                         break;  
                 }  
             }  
         }  
 
         public Visibility EditPanelVisibility  
         {  
             get { return editPanelVisibility; }  
             set  
             {  
                 editPanelVisibility = value;  
                 RaisePropertyChanged(() => EditPanelVisibility);  
             }  
         }  
 
         public Visibility MeasurePanelVisibility  
         {  
             get { return measurePanelVisibility; }  
             set  
             {  
                 measurePanelVisibility = value;  
                 RaisePropertyChanged(() => MeasurePanelVisibility);  
             }  
         }  
 
         public CommandBase RefreshCommand  
         {  
             get  
             {  
                 return refreshCommand ?? (refreshCommand = new CommandBase(UpdateSpatialFencesAndVehicles));  
             }  
         }  
 
         public CommandBase CancelMeasureCommand  
         {  
             get  
             {  
                 return cancelMeasureCommand ?? (cancelMeasureCommand = new CommandBase(ClearMeasuresAndPopups));  
             }  
         }  
 
         public CommandBase SaveFenceCommand  
         {  
             get  
             {  
                 return saveFenceCommand ?? (saveFenceCommand = new CommandBase(() =>  
                 {  
                     mapModel.MapControl.TrackOverlay.MapMouseClick -= TrackOverlay_MapMouseClick;  
                     SaveSpatialFences();  
 
                     UpdateSpatialFencesAndVehicles();  
 
                     if (drawFenceMode == DrawFenceMode.EditFence)  
                     {  
                         DrawFenceMode = DrawFenceMode.DrawNewFence;  
                         ResetFences();  
                     }  
                 }));  
             }  
         }  
 
         public CommandBase CancelEditCommand  
         {  
             get  
             {  
                 return cancelEditCommand ?? (cancelEditCommand = new CommandBase(() =>  
                 {  
                     mapModel.MapControl.EditOverlay.EditShapesLayer.InternalFeatures.Clear();  
 
                     foreach (var editFeature in mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Where(f => f.Tag != "Measure").ToList())  
                     {  
                         mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Remove(editFeature);  
                     }  
 
                     mapModel.SpatialFenceLayer.FeatureIdsToExclude.Clear();  
                     mapModel.MapControl.Refresh();  
                     if (drawFenceMode == DrawFenceMode.EditFence)  
                     {  
                         DrawFenceMode = DrawFenceMode.DrawNewFence;  
                         ResetFences();  
                     }  
                 }));  
             }  
         }  
 
         public CommandBase DeleteFenceCommand  
         {  
             get  
             {  
                 return deleteFenceCommand ?? (deleteFenceCommand = new CommandBase(() =>  
                 {  
                     if (mapModel.MapControl.EditOverlay.EditShapesLayer.InternalFeatures.Count > 0)  
                     {  
                         if (MessageBox.Show(Resources.DeleteFenceWarning, "Vehicle Tracking", MessageBoxButton.OKCancel) == MessageBoxResult.OK)  
                         {  
                             mapModel.MapControl.TrackOverlay.MapMouseClick -= TrackOverlay_MapMouseClick;  
                             mapModel.MapControl.EditOverlay.EditShapesLayer.InternalFeatures.Clear();  
                             mapModel.SpatialFenceLayer.InternalFeatures.Clear();  
                             SaveSpatialFences();  
                             UpdateSpatialFencesAndVehicles();  
                         }  
                     }  
                     else  
                     {  
                         MessageBox.Show(Resources.ChooseFenceWarning, "Vehicle Tracking");  
                     }  
                 }));  
             }  
         }  
 
         public AutoRefreshMode AutoRefreshMode  
         {  
             get { return autoRefreshMode; }  
             set  
             {  
                 autoRefreshMode = value;  
                 RaisePropertyChanged(() => AutoRefreshMode);  
             }  
         }  
 
         public double CoordinateX  
         {  
             get { return coordinateX; }  
             set  
             {  
                 coordinateX = value;  
                 RaisePropertyChanged(() => CoordinateX);  
             }  
         }  
 
         public double CoordinateY  
         {  
             get { return coordinateY; }  
             set  
             {  
                 coordinateY = value;  
                 RaisePropertyChanged(() => CoordinateY);  
             }  
         }  
 
         public Collection<UnitSystem> UnitSystems  
         {  
             get { return unitSystems; }  
         }  
 
         public UnitSystem SelectedUnitSystem  
         {  
             get { return selectedUnitSystem; }  
             set  
             {  
                 selectedUnitSystem = value;  
                 mapModel.UpdateUnitSystem(SelectedUnitSystem);  
                 RaisePropertyChanged(() => SelectedUnitSystem);  
             }  
         }  
 
         public ObservableCollection<VehicleViewModel> Vehicles  
         {  
             get { return vehicles; }  
         }  
 
         private void TrackOverlay_MapMouseClick(object sender, MapMouseClickInteractiveOverlayEventArgs e)  
         {  
             PointShape clickedPoint = new PointShape(e.InteractionArguments.WorldX, e.InteractionArguments.WorldY);  
             RectangleShape rect = MapSuiteSampleHelper.GetBufferedRectangle(clickedPoint, mapModel.MapControl.CurrentResolution);  
             Collection<Feature> intersectingFeatures = mapModel.MapControl.TrackOverlay.TrackShapeLayer.QueryTools.GetFeaturesIntersecting(rect, ReturningColumnsType.AllColumns);  
             if (intersectingFeatures.Count > 0)  
             {  
                 if (mapModel.MapControl.EditOverlay.EditShapesLayer.InternalFeatures.Count > 0)  
                 {  
                     foreach (var item in mapModel.MapControl.EditOverlay.EditShapesLayer.InternalFeatures)  
                     {  
                         mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(item.Id, item);  
                     }  
                     mapModel.MapControl.EditOverlay.EditShapesLayer.InternalFeatures.Clear();  
                 }  
                 mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Remove(intersectingFeatures[0].Id);  
                 mapModel.MapControl.EditOverlay.EditShapesLayer.InternalFeatures.Add(intersectingFeatures[0]);  
                 mapModel.MapControl.EditOverlay.CalculateAllControlPoints();  
                 mapModel.MapControl.Refresh(mapModel.MapControl.TrackOverlay);  
                 mapModel.MapControl.Refresh(mapModel.MapControl.EditOverlay);  
             }  
         }  
 
         private void MouseCoordinate_CustomFormatted(object sender, CustomFormattedMouseCoordinateMapToolEventArgs e)  
         {  
             CoordinateX = e.WorldCoordinate.X;  
             CoordinateY = e.WorldCoordinate.Y;  
         }  
 
         private void WpfMap1_OverlaysDrawing(object sender, OverlaysDrawingWpfMapEventArgs e)  
         {  
             IsBusy = true;  
         }  
 
         private void WpfMap1_OverlaysDrawn(object sender, OverlaysDrawnWpfMapEventArgs e)  
         {  
             IsBusy = false;  
         }  
 
         private void AutoRefreshTimer_Tick(object sender, EventArgs e)  
         {  
             UpdateSpatialFencesAndVehicles();  
         }  
 
         private void TrackOverlay_TrackEnded(object sender, TrackEndedTrackInteractiveOverlayEventArgs e)  
         {  
             if (mapModel.MapControl.TrackOverlay.TrackMode == TrackMode.Polygon)  
             {  
                 PolygonShape polygonShape = e.TrackShape as PolygonShape;  
                 if (polygonShape != null)  
                 {  
                     double area = -1;  
                     string areaUnit = "sq.m.";  
                     switch (SelectedUnitSystem)  
                     {  
                         case UnitSystem.Metric:  
                             areaUnit = "sq.m.";  
                             area = polygonShape.GetArea(GeographyUnit.Meter, AreaUnit.SquareMeters);  
                             break;  
 
                         case UnitSystem.Imperial:  
                             areaUnit = "ac.";  
                             area = polygonShape.GetArea(GeographyUnit.Meter, AreaUnit.Acres);  
                             break;  
                     }  
                     if (area > 0)  
                     {  
                         string content = string.Format(CultureInfo.InvariantCulture, "Area: {0} {1}", area.ToString("N1"), areaUnit);  
                         ShowPopup(new PointShape(polygonShape.OuterRing.Vertices[polygonShape.OuterRing.Vertices.Count|- 2]), content);  
                     }  
                     mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.LastOrDefault().Tag = "Measure";  
                 }  
             }  
 
             if (mapModel.MapControl.TrackOverlay.TrackMode == TrackMode.Line)  
             {  
                 string unit = string.Empty;  
                 LineShape lineShape = e.TrackShape as LineShape;  
                 if (lineShape != null)  
                 {  
                     double lenth = 0;  
                     if (SelectedUnitSystem == UnitSystem.Metric)  
                     {  
                         lenth = lineShape.GetLength(GeographyUnit.Meter, DistanceUnit.Meter);  
                         unit = "m";  
                         if (lenth >= 1000)  
                         {  
                             unit = "km";  
                             lenth = Math.Round(lenth / 1000d, 1, MidpointRounding.AwayFromZero);  
                         }  
                     }  
                     else if (SelectedUnitSystem == UnitSystem.Imperial)  
                     {  
                         lenth = lineShape.GetLength(GeographyUnit.Meter, DistanceUnit.Feet);  
                         unit = "ft";  
                         if (lenth >= 5280)  
                         {  
                             unit = "mi";  
                             lenth = Math.Round(lenth / 5280d, 1, MidpointRounding.AwayFromZero);  
                         }  
                     }  
 
                     string lengthString = lenth.ToString("N1");  
                     string content = string.Format(CultureInfo.InvariantCulture, "Total Length: {0} {1}", lengthString, unit);  
                     ShowPopup(new PointShape(lineShape.Vertices[lineShape.Vertices.Count|- 1]), content);  
                     mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.LastOrDefault().Tag = "Measure";  
                 }  
             }  
         }  
 
         private void TrackOverlay_TrackStarting(object sender, TrackStartingTrackInteractiveOverlayEventArgs e)  
         {  
             if (mapModel.TrackMode == TrackMode.Line || mapModel.TrackMode == TrackMode.Polygon)  
             {  
                 ClearMeasuresAndPopups();  
             }  
         }  
 
         private void UpdateSpatialFencesAndVehicles()  
         {  
             DateTime currentTime = GetAdjustedCurrentDateTime();  
             Task.Factory.StartNew(() =>  
             {  
                 lock (mapModel.SpatialFenceOverlay)  
                 {  
                     // Update the fences from database.  
                     UpdateSpatialFences();  
                 }  
                 lock (mapModel.TraceOverlay)  
                 {  
                     // Update the vehicle locations on the map.  
                     UpdateVehicles(mapModel.TraceOverlay, currentTime);  
                 }  
 
                 Application.Current.Dispatcher.BeginInvoke(new Action(mapModel.MapControl.Refresh));  
             });  
         }  
 
         // Here we update the vehicles from the database.  In this sample we create our data provider each time and  
         // when we are finsihed with it we dispose it.  This is very safe however you may get better performance  
         // if you were to cache this.  We wanted to sample to be clean and safe and it is up to your expertise to  
         // enhance it further  
         private void UpdateVehicles(LayerOverlay traceOverlay, DateTime currentTime)  
         {  
             Dictionary<int, Vehicle> currentVehicles;  
             using (TrackingAccessProvider vehicleProvider = new TrackingAccessProvider(databasePathFileName))  
             {  
                 currentVehicles = vehicleProvider.GetCurrentVehicles(currentTime);  
             }  
 
             // Loop through all the vehicle to add the history points  
             if (currentVehicles != null && currentVehicles.All(v => !string.IsNullOrEmpty(v.Value.IconPath)))  
             {  
                 InMemoryFeatureLayer vehicleTrailLayer;  
 
                 // Initialize vehicle overlay if it's not initialized  
                 if (!traceOverlay.Layers.Contains("VehicleTrail"))  
                 {  
                     // Create an InMemoryMarkerOverlay for the vehicle to hold the points and current location  
                     vehicleTrailLayer = new InMemoryFeatureLayer();  
                     vehicleTrailLayer.Open();  
                     vehicleTrailLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = GetVehicleTrailStyle();  
                     vehicleTrailLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
                     // Add all the required columns so we can populate later  
                     vehicleTrailLayer.FeatureSource.Open();  
                     vehicleTrailLayer.Columns.Add(new FeatureSourceColumn("Speed"));  
                     vehicleTrailLayer.Columns.Add(new FeatureSourceColumn("DateTime"));  
                     vehicleTrailLayer.Columns.Add(new FeatureSourceColumn("Longitude"));  
                     vehicleTrailLayer.Columns.Add(new FeatureSourceColumn("Latitude"));  
                     vehicleTrailLayer.Columns.Add(new FeatureSourceColumn("VehicleName"));  
                     vehicleTrailLayer.Columns.Add(new FeatureSourceColumn("Duration"));  
                     Application.Current.Dispatcher.BeginInvoke(new Action(() =>  
                     {  
                         lock (traceOverlay.Layers)  
                         {  
                             traceOverlay.Layers.Add("VehicleTrail", vehicleTrailLayer);  
                         }  
                     }));  
                 }  
                 else  
                 {  
                     // Find the overlay in the map  
                     vehicleTrailLayer = (InMemoryFeatureLayer)traceOverlay.Layers["VehicleTrail"];  
                 }  
                 vehicleTrailLayer.InternalFeatures.Clear();  
                 foreach (int vehicleId in currentVehicles.Keys)  
                 {  
                     Vehicle currentVehicle = currentVehicles[vehicleId];  
                     VehicleViewModel tempVehicleViewModel = Vehicles.FirstOrDefault(v => v.OwnerName == currentVehicle.Name);  
                     if (tempVehicleViewModel == null)  
                     {  
                         tempVehicleViewModel = new VehicleViewModel(currentVehicle, mapModel);  
                         Application.Current.Dispatcher.BeginInvoke(new Action(() => Vehicles.Add(tempVehicleViewModel)));  
                     }  
                     else  
                     {  
                         tempVehicleViewModel.Vehicle = currentVehicle;  
                         tempVehicleViewModel.Load();  
                     }  
 
                     bool isInSpatialFence = IsInSpatialFence(currentVehicle);  
                     tempVehicleViewModel.Area = isInSpatialFence ? "In restricted area" : "Out of restricted area";  
 
                     // Add the vheicle's bread crumbs  
                     foreach (Location historyLocation in currentVehicle.HistoryLocations.Take(6))  
                     {  
                         Feature breadcrumbFeature = new Feature(historyLocation.GetLocation().GetWellKnownBinary(), currentVehicle.Name + historyLocation.DateTime.ToString(CultureInfo.InvariantCulture));  
                         breadcrumbFeature.ColumnValues["DateTime"] = historyLocation.DateTime.ToString(CultureInfo.InvariantCulture);  
                         breadcrumbFeature.ColumnValues["Speed"] = historyLocation.Speed.ToString(CultureInfo.InvariantCulture);  
                         breadcrumbFeature.ColumnValues["Longitude"] = historyLocation.Longitude.ToString(CultureInfo.InvariantCulture);  
                         breadcrumbFeature.ColumnValues["Latitude"] = historyLocation.Latitude.ToString(CultureInfo.InvariantCulture);  
                         breadcrumbFeature.ColumnValues["VehicleName"] = currentVehicle.Name;  
                         breadcrumbFeature.ColumnValues["Duration"] = currentVehicle.GetSpeedDuration().ToString(CultureInfo.InvariantCulture);  
                         vehicleTrailLayer.InternalFeatures.Add(breadcrumbFeature.Id, breadcrumbFeature);  
                     }  
 
                     InMemoryFeatureLayer currentVehicleLayer;  
                     if (!traceOverlay.Layers.Contains(currentVehicle.Name))  
                     {  
                         // Create an InMemoryMarkerOverlay for the vehicle to hold the points and current location  
                         currentVehicleLayer = new InMemoryFeatureLayer();  
                         currentVehicleLayer.Open();  
                         currentVehicleLayer.Name = currentVehicle.Id.ToString(CultureInfo.InvariantCulture);  
                         currentVehicleLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = GetCurrentVehicleStyle(currentVehicle.IconPath);  
                         currentVehicleLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
                         // Add all the required columns so we can populate later  
                         currentVehicleLayer.FeatureSource.Open();  
                         currentVehicleLayer.Columns.Add(new FeatureSourceColumn("Speed"));  
                         currentVehicleLayer.Columns.Add(new FeatureSourceColumn("DateTime"));  
                         currentVehicleLayer.Columns.Add(new FeatureSourceColumn("Longitude"));  
                         currentVehicleLayer.Columns.Add(new FeatureSourceColumn("Latitude"));  
                         currentVehicleLayer.Columns.Add(new FeatureSourceColumn("VehicleName"));  
                         currentVehicleLayer.Columns.Add(new FeatureSourceColumn("Duration"));  
                         Application.Current.Dispatcher.BeginInvoke(new Action(() =>  
                         {  
                             lock (traceOverlay.Layers)  
                             {  
                                 traceOverlay.Layers.Add(currentVehicle.Name, currentVehicleLayer);  
                             }  
                         }));  
                     }  
                     else  
                     {  
                         // Find the overlay in the map  
                         currentVehicleLayer = (InMemoryFeatureLayer)traceOverlay.Layers[currentVehicle.Name];  
                     }  
                     currentVehicleLayer.InternalFeatures.Clear();  
                     // Add the vehicle's latest position  
                     Feature latestPositionFeature = new Feature(currentVehicle.Location.GetLocation().GetWellKnownBinary(), currentVehicle.Name);  
                     latestPositionFeature.ColumnValues["DateTime"] = currentVehicle.Location.DateTime.ToString(CultureInfo.InvariantCulture);  
                     latestPositionFeature.ColumnValues["Speed"] = currentVehicle.Location.Speed.ToString(CultureInfo.InvariantCulture);  
                     latestPositionFeature.ColumnValues["Longitude"] = currentVehicle.Location.Longitude.ToString(CultureInfo.InvariantCulture);  
                     latestPositionFeature.ColumnValues["Latitude"] = currentVehicle.Location.Latitude.ToString(CultureInfo.InvariantCulture);  
                     latestPositionFeature.ColumnValues["VehicleName"] = currentVehicle.Name;  
                     latestPositionFeature.ColumnValues["Duration"] = currentVehicle.GetSpeedDuration().ToString(CultureInfo.InvariantCulture);  
                     currentVehicleLayer.InternalFeatures.Add(latestPositionFeature.Id, latestPositionFeature);  
                 }  
             }  
         }  
 
         private void UpdateSpatialFences()  
         {  
             // Get the spatial fence overlay and layer and then clear them  
             mapModel.SpatialFenceLayer.InternalFeatures.Clear();  
 
             // Get the spatial fences from the database  
             Collection<Feature> spatialFences;  
             using (TrackingAccessProvider vehicleProvider = new TrackingAccessProvider(databasePathFileName))  
             {  
                 spatialFences = vehicleProvider.GetSpatialFences();  
             }  
 
             // Insert fences from database into fence layer  
             if (spatialFences != null)  
             {  
                 foreach (Feature spatialFence in spatialFences)  
                 {  
                     spatialFence.ColumnValues["Restricted"] = "Restricted";  
                     mapModel.SpatialFenceLayer.InternalFeatures.Add(spatialFence.Id, spatialFence);  
                 }  
             }  
         }  
 
         private bool IsInSpatialFence(Vehicle vehicle)  
         {  
             InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)mapModel.SpatialFenceOverlay.Layers["SpatialFenceLayer"];  
 
             // Get the point shape and then check if it is within any of the sptail fences using the QueryTools  
             PointShape pointShape = new PointShape(vehicle.Location.Longitude, vehicle.Location.Latitude);  
             bool isInSpatialFence = false;  
             lock (spatialFenceLayer)  
             {  
                 spatialFenceLayer.Open();  
                 Collection<Feature> spatialFencesWithin = spatialFenceLayer.QueryTools.GetFeaturesContaining(pointShape, ReturningColumnsType.NoColumns);  
                 if (spatialFencesWithin.Count > 0)  
                 {  
                     isInSpatialFence = true;  
                 }  
             }  
             return isInSpatialFence;  
         }  
 
         private void SaveSpatialFences()  
         {  
             TrackingAccessProvider vehicleProvider = null;  
 
             try  
             {  
                 foreach (var item in mapModel.SpatialFenceLayer.FeatureIdsToExclude)  
                 {  
                     if (mapModel.SpatialFenceLayer.InternalFeatures.Contains(item))  
                     {  
                         mapModel.SpatialFenceLayer.InternalFeatures.Remove(item);  
                     }  
                 }  
                 mapModel.SpatialFenceLayer.FeatureIdsToExclude.Clear();  
                 foreach (Feature feature in mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Where(f => f.Tag != "Measure"))  
                 {  
                     if (!mapModel.SpatialFenceLayer.InternalFeatures.Contains(feature.Id))  
                     {  
                         mapModel.SpatialFenceLayer.InternalFeatures.Add(feature.Id, feature);  
                     }  
                 }  
 
                 foreach (Feature feature in mapModel.MapControl.EditOverlay.EditShapesLayer.InternalFeatures)  
                 {  
                     if (!mapModel.SpatialFenceLayer.InternalFeatures.Contains(feature.Id))  
                     {  
                         mapModel.SpatialFenceLayer.InternalFeatures.Add(feature.Id, feature);  
                     }  
                 }  
                 mapModel.SpatialFenceOverlay.Refresh();  
 
                 vehicleProvider = new TrackingAccessProvider(databasePathFileName);  
 
                 // Delete Spatial fences which is not in current spatial fence layer  
                 vehicleProvider.DeleteSpatialFencesExcluding(mapModel.SpatialFenceLayer.InternalFeatures);  
 
                 // Add or update the spatial fences that already exist  
                 foreach (Feature feature in mapModel.SpatialFenceLayer.InternalFeatures)  
                 {  
                     // Update Spatial fence by feature Id  
                     // if the affected data row number is 0, we will add a new row in the database  
                     int updatedCount = vehicleProvider.UpdateSpatialFenceByFeature(feature);  
                     if (updatedCount == 0)  
                     {  
                         vehicleProvider.InsertSpatialFence(feature);  
                     }  
                 }  
             }  
             catch (OleDbException)  
             {  
                 MessageBox.Show(string.Format(CultureInfo.InvariantCulture, "Please make sure {0} is writable", databasePathFileName), "Save Spatial Fences");  
             }  
             catch (Exception e)  
             {  
                 MessageBox.Show(e.Message, "Save Spatial Fences");  
             }  
             finally  
             {  
                 mapModel.MapControl.TrackOverlay.TrackMode = TrackMode.None;  
                 mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Clear();  
                 mapModel.MapControl.EditOverlay.EditShapesLayer.InternalFeatures.Clear();  
                 mapModel.PopupOverlay.Popups.Clear();  
                 mapModel.MapControl.Refresh();  
                 if (vehicleProvider != null) { vehicleProvider.Dispose(); }  
                 if (drawFenceMode == DrawFenceMode.EditFence || drawFenceMode == DrawFenceMode.DrawNewFence)  
                 {  
                     DrawFenceMode = DrawFenceMode.DrawNewFence;  
                     ResetFences();  
                 }  
             }  
         }  
 
         private void ResetFences()  
         {  
             CancelEditCommand.Execute(null);  
             mapModel.MapControl.TrackOverlay.MapMouseClick -= TrackOverlay_MapMouseClick;  
             mapModel.MapControl.TrackOverlay.TrackMode = TrackMode.Polygon;  
         }  
 
         private void ShowPopup(PointShape pointShape, string content)  
         {  
             Popup popup = new Popup(pointShape);  
             PopupUserControl popupUserControl = new PopupUserControl(content);  
             popupUserControl.PopupOverlay = mapModel.PopupOverlay;  
 
             popup.Content = popupUserControl;  
             mapModel.PopupOverlay.Popups.Add(popup);  
             mapModel.PopupOverlay.Refresh();  
         }  
 
         private void ClearMeasuresAndPopups()  
         {  
             foreach (var measureFeature in mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Where(f => f.Tag == "Measure").ToList())  
             {  
                 mapModel.MapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Remove(measureFeature);  
             }  
 
             mapModel.PopupOverlay.Popups.Clear();  
             mapModel.MapControl.Refresh(mapModel.MapControl.TrackOverlay);  
             mapModel.MapControl.Refresh(mapModel.PopupOverlay);  
         }  
 
         private static DateTime GetAdjustedCurrentDateTime()  
         {  
             // This vehicle tracking sample contains some simulated data  
             // This method stores the real time when the application started and reflects to the start sample time  
             // When the actual time increments 1 second, the sample time increments 6 seconds  
             //  
             // To make the application run in real time just have this method return to current date time  
             //  
             double sampleSecondPerActualSecond = 12;  
             double realSpentTime = TimeSpan.FromTicks(DateTime.Now.Ticks - applicationStartTime.Ticks).TotalSeconds;  
             int sampleSpentTime = (int)(realSpentTime * sampleSecondPerActualSecond);  
             DateTime currentSampleTime = adjustedStartTime.AddSeconds(sampleSpentTime);  
 
             return currentSampleTime;  
         }  
 
         private static PointStyle GetVehicleTrailStyle()  
         {  
             Stream historyStream = MapSuiteSampleHelper.GetResourceStream("trail point.png");  
             historyStream.Seek(0, SeekOrigin.Begin);  
 
             return new PointStyle(new GeoImage(historyStream));  
         }  
 
         private static PointStyle GetCurrentVehicleStyle(string iconVirtualPath)  
         {  
             Stream vehicleStream = MapSuiteSampleHelper.GetResourceStream(iconVirtualPath);  
             GeoImage vehicleImage = new GeoImage(vehicleStream);  
 
             return new PointStyle(vehicleImage);  
         }  
     }  
 }  
 

VehicleViewModel.cs

 using System.Globalization;  
 using System.Linq;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     public class VehicleViewModel : ViewModelBase  
     {  
         private static string vehicleImageFormat = "/Image/{0}";  
 
         private string area;  
         private string speed;  
         private string status;  
         private string iconUri;  
         private string duration;  
         private string ownerName;  
         private MapModel mapModel;  
         private Vehicle vehicle;  
         private CommandBase zoomToVehicleCommand;  
 
         public VehicleViewModel()  
             : this(null, null)  
         { }  
 
         public VehicleViewModel(Vehicle vehicle, MapModel mapModel)  
             : base()  
         {  
             this.vehicle = vehicle;  
             this.ownerName = vehicle.Name;  
             this.mapModel = mapModel;  
             this.iconUri = string.Format(CultureInfo.InvariantCulture, vehicleImageFormat, vehicle.IconPath);  
 
             this.Load();  
         }  
 
         public Vehicle Vehicle  
         {  
             get { return vehicle; }  
             set { vehicle = value; }  
         }  
 
         public string Status  
         {  
             get { return status; }  
             set  
             {  
                 status = value;  
                 RaisePropertyChanged(() => Status);  
             }  
         }  
 
         public string IconUri  
         {  
             get { return iconUri; }  
             set  
             {  
                 iconUri = value;  
                 RaisePropertyChanged(() => IconUri);  
             }  
         }  
 
         public string Area  
         {  
             get { return area; }  
             set  
             {  
                 area = value;  
                 RaisePropertyChanged(() => Area);  
             }  
         }  
 
         public string OwnerName  
         {  
             get { return ownerName; }  
             set  
             {  
                 ownerName = value;  
                 RaisePropertyChanged(() => OwnerName);  
             }  
         }  
 
         public string Speed  
         {  
             get { return speed; }  
             set  
             {  
                 speed = value;  
                 RaisePropertyChanged(() => Speed);  
             }  
         }  
 
         public string Duration  
         {  
             get { return duration; }  
             set  
             {  
                 duration = value;  
                 RaisePropertyChanged(() => Duration);  
             }  
         }  
 
         public CommandBase ZoomToVehicleCommand  
         {  
             get  
             {  
                 return zoomToVehicleCommand ?? (zoomToVehicleCommand = new CommandBase(() =>  
                 {  
                     InMemoryFeatureLayer vehicleFeatureLayer = mapModel.TraceOverlay.Layers[OwnerName] as InMemoryFeatureLayer;  
                     if (vehicleFeatureLayer != null)  
                     {  
                         mapModel.MapControl.ZoomIntoCenter(60, vehicleFeatureLayer.InternalFeatures.LastOrDefault());  
                     }  
                 }));  
             }  
         }  
 
         public void Load()  
         {  
             Status = vehicle.GetCurrentState() == VehicleMotionState.Idle ? "Idle" : "In Motion";  
             Speed = vehicle.Location.Speed.ToString(CultureInfo.InvariantCulture) + " mph";  
             Duration = vehicle.GetSpeedDuration().ToString(CultureInfo.InvariantCulture) + " min";  
         }  
     }  
 }  
 

PopupUserControl.xaml

 <UserControl x:Class="ThinkGeo.MapSuite.VehicleTracking.PopupUserControl"  
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
              mc:Ignorable="d"  
              d:DesignHeight="300" d:DesignWidth="300">  
     <Grid Margin="5">  
         <Grid.RowDefinitions>  
             <RowDefinition Height="Auto" />  
             <RowDefinition Height="*" />  
         </Grid.RowDefinitions>  
         <Grid>  
             <Grid.ColumnDefinitions>  
                 <ColumnDefinition Width="*" />  
                 <ColumnDefinition Width="Auto" />  
             </Grid.ColumnDefinitions>  
             <TextBlock x:Name="txtContent" Visibility="Collapsed" />  
             <TextBlock x:Name="txtName" Style="{StaticResource h4}" FontWeight="Bold" HorizontalAlignment="Left" />  
             <Button Content="/Image/popup_close.png" Template="{StaticResource imageButtonTemplate}" Click="ClosePopupClick" HorizontalAlignment="Right" VerticalAlignment="Top" Grid.Column="1" Margin="5 0 0 0" />  
         </Grid>  
         <Grid Grid.Row="1" x:Name="vehiclePanel">  
             <Grid.RowDefinitions>  
                 <RowDefinition Height="Auto" />  
                 <RowDefinition Height="2" />  
                 <RowDefinition Height="Auto" />  
                 <RowDefinition Height="2" />  
                 <RowDefinition Height="Auto" />  
                 <RowDefinition Height="2" />  
                 <RowDefinition Height="Auto" />  
             </Grid.RowDefinitions>  
             <Grid.ColumnDefinitions>  
                 <ColumnDefinition Width="70" />  
                 <ColumnDefinition Width="*" />  
             </Grid.ColumnDefinitions>  
             <TextBlock Text="Longitude:" Grid.Row="0" Grid.Column="0" />  
             <TextBlock x:Name="txtLongitude" Grid.Row="0" Grid.Column="1"/>  
             <TextBlock Text="Latitude:" Grid.Row="2" Grid.Column="0"/>  
             <TextBlock x:Name="txtLatitude" Grid.Row="2" Grid.Column="1"/>  
             <TextBlock Text="Speed:" Grid.Row="4" Grid.Column="0"/>  
             <TextBlock x:Name="txtSpeed" Grid.Row="4" Grid.Column="1"/>  
             <TextBlock Text="Time:" Grid.Row="6" Grid.Column="0"/>  
             <TextBlock x:Name="txtTime" Grid.Row="6" Grid.Column="1"/>  
         </Grid>  
     </Grid>  
 </UserControl>  
 

PopupUserControl.xaml.cs

 using System;  
 using System.Globalization;  
 using System.Windows;  
 using System.Windows.Controls;  
 using ThinkGeo.MapSuite.Core;  
 using ThinkGeo.MapSuite.WpfDesktopEdition;  
 
 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     /// <summary>  
     /// Interaction logic for PopupUserControl.xaml  
     /// </summary>  
     public partial class PopupUserControl : UserControl  
     {  
         private PopupOverlay popupOverlay;  
 
         public PopupUserControl()  
             : this(string.Empty)  
         { }  
 
         public PopupUserControl(Feature feature)  
         {  
             InitializeComponent();  
 
             string speed = feature.ColumnValues["Speed"];  
             string name = feature.ColumnValues["VehicleName"];  
             string latitude = feature.ColumnValues["Latitude"];  
             string dateTime = feature.ColumnValues["DateTime"];  
             string longitude = feature.ColumnValues["Longitude"];  
 
             txtName.Text = name;  
             double x, y;  
             if (double.TryParse(longitude, out x) && double.TryParse(latitude, out y))  
             {  
                 ManagedProj4Projection proj4 = new ManagedProj4Projection();  
                 proj4.InternalProjectionParametersString = Proj4Projection.GetDecimalDegreesParametersString();  
                 proj4.ExternalProjectionParametersString = Proj4Projection.GetGoogleMapParametersString();  
                 proj4.Open();  
 
                 Vertex vertex = proj4.ConvertToInternalProjection(x, y);  
                 txtLongitude.Text = vertex.X.ToString("N6", CultureInfo.InvariantCulture);  
                 txtLatitude.Text = vertex.Y.ToString("N6", CultureInfo.InvariantCulture);  
 
                 proj4.Close();  
             }  
             else  
             {  
                 txtLongitude.Text = longitude;  
                 txtLatitude.Text = latitude;  
             }  
 
             txtSpeed.Text = speed + " mph";  
             txtTime.Text = dateTime;  
         }  
 
         public PopupUserControl(string content)  
         {  
             InitializeComponent();  
 
             txtContent.Text = content;  
             txtContent.Visibility = Visibility.Visible;  
             vehiclePanel.Visibility = Visibility.Collapsed;  
             txtName.Visibility = Visibility.Collapsed;  
         }  
 
         public PopupOverlay PopupOverlay  
         {  
             get { return popupOverlay; }  
             set { popupOverlay = value; }  
         }  
 
         private void ClosePopupClick(object sender, RoutedEventArgs e)  
         {  
             if (PopupOverlay != null)  
             {  
                 PopupOverlay.Popups.Remove((Popup) Parent);  
                 PopupOverlay.Refresh();  
             }  
         }  
     }  
 }  
 
 

AutoRefreshMode.cs

 
 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     public enum AutoRefreshMode  
     {  
         On = 0,  
         Off = 1  
     }  
 }  
 

ControlMapMode.cs

 
 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     public enum ControlMapMode  
     {  
         Pan = 0,  
         DrawFence = 1,  
         Measure = 2  
     }  
 }  
 
 

DrawFenceMode.cs

 
 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     public enum DrawFenceMode  
     {  
         DrawNewFence = 0,  
         EditFence = 1  
     }  
 }  
 
 

Location.cs

 using System;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     /// <summary>  
     /// This class specify the basic information for a location.  
     /// </summary>  
     public class Location  
     {  
         private double speed;  
         private double latitude;  
         private double longitude;  
         private DateTime dateTime;  
 
         public Location()  
             : this(0, 0, 0, DateTime.Now)  
         { }  
 
         public Location(double longitude, double latitude, double speed, DateTime dateTime)  
         {  
             Longitude = longitude;  
             Latitude = latitude;  
             Speed = speed;  
             DateTime = dateTime;  
         }  
 
         public double Speed  
         {  
             get { return speed; }  
             set { speed = value; }  
         }  
 
         public double Longitude  
         {  
             get { return longitude; }  
             set { longitude = value; }  
         }  
 
         public double Latitude  
         {  
             get { return latitude; }  
             set { latitude = value; }  
         }  
 
         public DateTime DateTime  
         {  
             get { return dateTime; }  
             set { dateTime = value; }  
         }  
 
         public PointShape GetLocation()  
         {  
             return new PointShape(Longitude, Latitude);  
         }  
     }  
 }  
 
 

MapModel.cs

 using System;  
 using System.Collections.ObjectModel;  
 using System.IO;  
 using System.Linq;  
 using System.Windows;  
 using System.Windows.Input;  
 using ThinkGeo.MapSuite.Core;  
 using ThinkGeo.MapSuite.VehicleTracking.Properties;  
 using ThinkGeo.MapSuite.WpfDesktopEdition;  
 
 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     public class MapModel  
     {  
         private static RectangleShape defaultExtent = new RectangleShape(-10785241.6495495, 3916508.33762434, -10778744.5183967, 3912187.74540771);  
         private static Cursor handCursor = new Cursor(Application.GetResourceStream(new Uri("/MapSuiteVehicleTracking;component/Image/cursor_hand.cur", UriKind.RelativeOrAbsolute)).Stream);  
 
         private WpfMap mapControl;  
 
         public MapModel()  
             : this(null)  
         { }  
 
         public MapModel(WpfMap map)  
         {  
             mapControl = map;  
             InitializeMap();  
         }  
 
         public WpfMap MapControl  
         {  
             get { return mapControl; }  
         }  
 
         public PopupOverlay PopupOverlay  
         {  
             get { return (PopupOverlay)mapControl.Overlays["PopupOverlay"]; }  
         }  
 
         public LayerOverlay TraceOverlay  
         {  
             get { return (LayerOverlay)mapControl.Overlays["TraceOverlay"]; }  
         }  
 
         public LayerOverlay SpatialFenceOverlay  
         {  
             get { return (LayerOverlay)mapControl.Overlays["SpatialFenceOverlay"]; }  
         }  
 
         public InMemoryFeatureLayer SpatialFenceLayer  
         {  
             get { return (InMemoryFeatureLayer)SpatialFenceOverlay.Layers["SpatialFenceLayer"]; }  
         }  
 
         public TrackMode TrackMode  
         {  
             get { return mapControl.TrackOverlay.TrackMode; }  
             set  
             {  
                 mapControl.TrackOverlay.TrackMode = value;  
                 mapControl.Cursor = mapControl.TrackOverlay.TrackMode == TrackMode.None ? handCursor : Cursors.Arrow;  
             }  
         }  
 
         private void InitializeMap()  
         {  
             TrackMode = TrackMode.None;  
             mapControl.MapClick += WpfMap1_MapClick;  
             mapControl.MapUnit = GeographyUnit.Meter;  
             mapControl.CurrentExtent = defaultExtent;  
 
             InitializeMapTools();  
             InitializeOverlays();  
         }  
 
         public void UpdateUnitSystem(UnitSystem selectedUnitSystem)  
         {  
             if (mapControl.AdornmentOverlay.Layers.Contains("ScaleBar"))  
             {  
                 ScaleBarAdornmentLayer scaleBarLayer = (ScaleBarAdornmentLayer)mapControl.AdornmentOverlay.Layers["ScaleBar"];  
                 scaleBarLayer.UnitFamily = selectedUnitSystem;  
                 mapControl.AdornmentOverlay.Refresh();  
             }  
         }  
 
         private void WpfMap1_MapClick(object sender, MapClickWpfMapEventArgs e)  
         {  
             if (e.MouseButton == MapMouseButton.Left)  
             {  
                 RectangleShape clickedArea = MapSuiteSampleHelper.GetBufferedRectangle(e.WorldLocation, mapControl.CurrentResolution);  
                 PopupOverlay.Popups.Clear();  
                 foreach (InMemoryFeatureLayer vehicleLayer in TraceOverlay.Layers.OfType<InMemoryFeatureLayer>())  
                 {  
                     vehicleLayer.Open();  
                     Collection<Feature> resultFeatures = vehicleLayer.QueryTools.GetFeaturesIntersecting(clickedArea, ReturningColumnsType.AllColumns);  
                     if (resultFeatures.Count > 0)  
                     {  
                         Popup popup = new Popup(e.WorldLocation);  
                         PopupUserControl popupUserControl = new PopupUserControl(resultFeatures[0]);  
                         popupUserControl.PopupOverlay = PopupOverlay;  
 
                         popup.Content = popupUserControl;  
                         PopupOverlay.Popups.Add(popup);  
                         PopupOverlay.Refresh();  
                         break;  
                     }  
                 }  
             }  
         }  
 
         private void OverlaySwitcher_BaseOverlayChanged(object sender, OverlayChangedOverlaySwitcherEventArgs e)  
         {  
             BingMapsOverlay bingMapsOverlay = e.Overlay as BingMapsOverlay;  
             if (bingMapsOverlay != null)  
             {  
                 bool cancel = ApplyBingMapsKey();  
                 e.Cancel = cancel;  
             }  
         }  
 
         private bool ApplyBingMapsKey()  
         {  
             bool cancel = false;  
             string bingMapsKey = MapSuiteSampleHelper.GetBingMapsKey();  
             if (!string.IsNullOrEmpty(bingMapsKey))  
             {  
                 foreach (var bingOverlay in MapControl.Overlays.OfType<BingMapsOverlay>())  
                 {  
                     bingOverlay.ApplicationId = bingMapsKey;  
                 }  
             }  
             else  
             {  
                 cancel = true;  
             }  
 
             return cancel;  
         }  
 
         private void InitializeOverlays()  
         {  
             string cacheFolder = Path.Combine(Path.GetTempPath(), "TileCache");  
 
             WorldMapKitWmsWpfOverlay worldMapKitOverlay = new WorldMapKitWmsWpfOverlay();  
             worldMapKitOverlay.Name = Resources.WorldMapKitName;  
             worldMapKitOverlay.TileHeight = 512;  
             worldMapKitOverlay.TileWidth = 512;  
             worldMapKitOverlay.IsVisible = true;  
             worldMapKitOverlay.Projection = WorldMapKitProjection.SphericalMercator;  
             worldMapKitOverlay.TileCache = new FileBitmapTileCache(cacheFolder, "WorldMapKit");  
             mapControl.Overlays.Add(Resources.WorldMapKitKey, worldMapKitOverlay);  
 
             OpenStreetMapOverlay openStreetMapOverlay = new OpenStreetMapOverlay();  
             openStreetMapOverlay.Name = Resources.OpenStreetMapName;  
             openStreetMapOverlay.TileHeight = 512;  
             openStreetMapOverlay.TileWidth = 512;  
             openStreetMapOverlay.IsVisible = false;  
             openStreetMapOverlay.TileCache = new FileBitmapTileCache(cacheFolder, "OpenStreetMap");  
             mapControl.Overlays.Add(Resources.OpenStreetMapKey, openStreetMapOverlay);  
 
             BingMapsOverlay bingMapsAerialOverlay = new BingMapsOverlay();  
             bingMapsAerialOverlay.Name = Resources.BingMapsAerialMapName;  
             bingMapsAerialOverlay.TileHeight = 512;  
             bingMapsAerialOverlay.TileWidth = 512;  
             bingMapsAerialOverlay.MapType = BingMapsMapType.Aerial;  
             bingMapsAerialOverlay.IsVisible = false;  
             bingMapsAerialOverlay.TileCache = new FileBitmapTileCache(cacheFolder, "BingMapsAerial");  
             mapControl.Overlays.Add(Resources.BingAerialKey, bingMapsAerialOverlay);  
 
             BingMapsOverlay bingMapsRoadOverlay = new BingMapsOverlay();  
             bingMapsRoadOverlay.Name = Resources.BingMapsRoadMapName;  
             bingMapsRoadOverlay.TileHeight = 512;  
             bingMapsRoadOverlay.TileWidth = 512;  
             bingMapsRoadOverlay.MapType = BingMapsMapType.Road;  
             bingMapsRoadOverlay.IsVisible = false;  
             bingMapsRoadOverlay.TileCache = new FileBitmapTileCache(cacheFolder, "BingMapsRoad");  
             mapControl.Overlays.Add(Resources.BingRoadKey, bingMapsRoadOverlay);  
 
             InMemoryFeatureLayer spatialFenceLayer = new InMemoryFeatureLayer();  
             spatialFenceLayer.Open();  
             spatialFenceLayer.Columns.Add(new FeatureSourceColumn(Resources.RestrictedName, "Charater", 10));  
             spatialFenceLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = new AreaStyle(new GeoPen(GeoColor.FromArgb(255, 204, 204, 204), 2), new GeoSolidBrush(GeoColor.FromArgb(112, 255, 0, 0)));  
             spatialFenceLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle(Resources.RestrictedName, "Arial", 12, DrawingFontStyles.Regular, GeoColor.StandardColors.Black, GeoColor.SimpleColors.White, 2);  
             spatialFenceLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
             LayerOverlay spatialFenceOverlay = new LayerOverlay();  
             spatialFenceOverlay.TileType = TileType.SingleTile;  
             spatialFenceOverlay.Name = Resources.SpatialFenceOverlayName;  
             spatialFenceOverlay.Layers.Add(Resources.SpatialFenceLayerName, spatialFenceLayer);  
             mapControl.Overlays.Add(Resources.SpatialFenceOverlayName, spatialFenceOverlay);  
 
             LayerOverlay traceOverlay = new LayerOverlay();  
             traceOverlay.Name = Resources.TraceOverlayName;  
             traceOverlay.TileType = TileType.SingleTile;  
             mapControl.Overlays.Add(Resources.TraceOverlayName, traceOverlay);  
 
             mapControl.Overlays.Add(Resources.PopupOverlayName, new PopupOverlay { Name = Resources.PopupOverlayName });  
 
             ScaleBarAdornmentLayer scaleBarAdormentLayer = new ScaleBarAdornmentLayer();  
             scaleBarAdormentLayer.UnitFamily = UnitSystem.Metric;  
             mapControl.AdornmentOverlay.Layers.Add(Resources.ScaleBarName, scaleBarAdormentLayer);  
         }  
 
         private void InitializeMapTools()  
         {  
             mapControl.MapTools.MouseCoordinate.IsEnabled = true;  
             mapControl.MapTools.MouseCoordinate.Visibility = Visibility.Hidden;  
             mapControl.MapTools.MouseCoordinate.MouseCoordinateType = MouseCoordinateType.Custom;  
             mapControl.MapTools.PanZoomBar.GlobeButtonClick += PanZoomBar_GlobeButtonClick;  
 
             OverlaySwitcher overlaySwitcher = new OverlaySwitcher();  
             overlaySwitcher.Initialize(mapControl);  
             overlaySwitcher.OverlayChanged += OverlaySwitcher_BaseOverlayChanged;  
             mapControl.MapTools.Add(overlaySwitcher);  
         }  
 
         private static void PanZoomBar_GlobeButtonClick(object sender, GlobeButtonClickPanZoomBarMapToolEventArgs e)  
         {  
             e.NewExtent = defaultExtent;  
         }  
     }  
 }  
 
 

MeasureMode.cs

 
 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     public enum MeasureMode  
     {  
         Line = 0,  
         Polygon = 1  
     }  
 }  
 
 

Vehicle.cs

 using System.Collections.ObjectModel;  
 
 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     /// <summary>  
     /// This class stands for a vehicle.  
     /// </summary>  
     public class Vehicle  
     {  
         private int id;  
         private string name;  
         private string iconPath;  
         private Location location;  
         private Collection<Location> historyLocations;  
 
         public Vehicle()  
             : this(0)  
         { }  
 
         public Vehicle(int id)  
         {  
             Id = id;  
             Name = string.Empty;  
             Location = new Location();  
             historyLocations = new Collection<Location>();  
         }  
 
         public int Id  
         {  
             get { return id; }  
             set { id = value; }  
         }  
 
         public Location Location  
         {  
             get { return location; }  
             set { location = value; }  
         }  
 
         public Collection<Location> HistoryLocations  
         {  
             get { return historyLocations; }  
         }  
 
         public string Name  
         {  
             get { return name; }  
             set { name = value; }  
         }  
 
         public string IconPath  
         {  
             get { return iconPath; }  
             set { iconPath = value; }  
         }  
 
         public int GetSpeedDuration()  
         {  
             int speedDuration = 0;  
             double lastSpeed = Location.Speed;  
             foreach (Location tempLocation in HistoryLocations)  
             {  
                 if (tempLocation.Speed == lastSpeed) speedDuration++;  
                 else break;  
             }  
 
             return speedDuration;  
         }  
 
         /// <summary>  
         /// If the Vehicle's speed is not 0 in the passed 4 minutes, we say it is in Motion.  
         /// </summary>  
         /// <returns>State of current vehicle.</returns>  
         public VehicleMotionState GetCurrentState()  
         {  
             VehicleMotionState vehicleState = VehicleMotionState.Idle;  
 
             if (Location.Speed != 0)  
             {  
                 vehicleState = VehicleMotionState.Motion;  
             }  
             else  
             {  
                 int locationIndex = 0;  
                 foreach (Location historyLocation in HistoryLocations)  
                 {  
                     if (locationIndex > 3)  
                     {  
                         break;  
                     }  
                     if (historyLocation.Speed != 0)  
                     {  
                         vehicleState = VehicleMotionState.Motion;  
                         break;  
                     }  
                     locationIndex++;  
                 }  
             }  
 
             return vehicleState;  
         }  
     }  
 }  
 
 

VehicleMotionState.cs

 namespace ThinkGeo.MapSuite.VehicleTracking  
 {  
     /// <summary>  
     /// This enumeration specifies the Possible states for Vehicles.  
     /// </summary>  
     public enum VehicleMotionState  
     {  
         Motion = 0,  
         Idle = 1,  
     }  
 }  
 
source_code_wpf_desktopeditionsample_mapsuitevehicletracking_cs.zip.txt · Last modified: 2015/09/17 02:49 by admin