Table of Contents

Source Code GeocoderSample AddressLocator CS.zip

MainWindow.xaml.cs

 using System.Windows;  
 
 namespace ThinkGeo.MapSuite.GeoCoderExamples  
 {  
     /// <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);  
         }  
     }  
 }  
 

App.xaml.cs

 using System;  
 using System.Collections.Generic;  
 using System.Configuration;  
 using System.Data;  
 using System.Linq;  
 using System.Windows;  
 
 namespace ThinkGeo  
 {  
     /// <summary>  
     /// Interaction logic for App.xaml  
     /// </summary>  
     public partial class App : Application  
     {  
     }  
 }  
 

MainWindowViewModel.cs

 using System;  
 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Data;  
 using System.Globalization;  
 using System.Linq;  
 using System.Text;  
 using System.Windows;  
 using System.Windows.Controls;  
 using System.Windows.Media.Imaging;  
 using ThinkGeo.MapSuite.Core;  
 using ThinkGeo.MapSuite.MapSuiteGeocoder;  
 using ThinkGeo.MapSuite.WpfDesktopEdition;  
 
 namespace ThinkGeo.MapSuite.GeoCoderExamples  
 {  
     public class MainWindowViewModel : ViewModelBase  
     {  
         private static readonly RectangleShape defaultExtent = new RectangleShape(-88.3330001640625, 42.5966329101563, -86.9157638359375, 41.1629170898438);  
         private static readonly BitmapImage markerImageSource = new BitmapImage(new Uri("pack://application:,,,/AddressLocator;Component/Image/marker.png", UriKind.RelativeOrAbsolute));  
 
         private WpfMap mapControl;  
         private double coordinateX;  
         private double coordinateY;  
         private string searchText;  
         private string exampleText;  
         private string selectedAddress;  
         private DataView resultListView;  
         private CommandBase cleanCommand;  
         private CommandBase searchCommand;  
         private CommandBase zoomToResultCommand;  
         private Visibility zoomToColumnVisibility;  
         private SimpleMarkerOverlay simpleMarkerOverlay;  
         private DataGridHeadersVisibility headerVisibility;  
         private GeocoderSearchType selectedGeocoderSearchType;  
         private ObservableCollection<string> defaultAddresses;  
         private ObservableCollection<GeocoderSearchType> searchTypeCandidates;  
 
         public MainWindowViewModel(WpfMap mapControl)  
             : base()  
         {  
             MapControl = mapControl;  
             InitializeMap();  
             searchText = "Enter an Address:";  
             SelectedGeocoderSearchType = GeocoderSearchType.Street;  
             SearchAddress(SelectedAddress);  
         }  
 
         public DataGridHeadersVisibility HeaderVisibility  
         {  
             get { return headerVisibility; }  
             set  
             {  
                 headerVisibility = value;  
                 RaisePropertyChanged(() => HeaderVisibility);  
             }  
         }  
 
         public Visibility ZoomToColumnVisibility  
         {  
             get { return zoomToColumnVisibility; }  
             set  
             {  
                 zoomToColumnVisibility = value;  
                 RaisePropertyChanged(() => ZoomToColumnVisibility);  
             }  
         }  
 
         public string ExampleText  
         {  
             get { return exampleText; }  
             set  
             {  
                 exampleText = value;  
                 RaisePropertyChanged(() => ExampleText);  
             }  
         }  
 
         public string SearchText  
         {  
             get { return searchText; }  
             set  
             {  
                 searchText = value;  
                 RaisePropertyChanged(() => SearchText);  
             }  
         }  
 
         public CommandBase SearchCommand  
         {  
             get { return searchCommand ?? (searchCommand = new CommandBase(obj => SearchAddress(SelectedAddress))); }  
         }  
 
         public CommandBase CleanCommand  
         {  
             get  
             {  
                 return cleanCommand ?? (cleanCommand = new CommandBase(obj =>  
                 {  
                     ResultListView = new DataTable().AsDataView();  
                     simpleMarkerOverlay.Markers.Clear();  
                     simpleMarkerOverlay.Refresh();  
                 }));  
             }  
         }  
 
         public CommandBase ZoomToResultCommand  
         {  
             get  
             {  
                 return zoomToResultCommand ?? (zoomToResultCommand = new CommandBase(obj =>  
                 {  
                     Button ibtn = obj as Button;  
                     if (ibtn != null && ibtn.Tag != null)  
                     {  
                         PointShape location = (PointShape)BaseShape.CreateShapeFromWellKnownData(ibtn.Tag.ToString());  
                         mapControl.ZoomTo(location, 2252.9288864135742);  
                     }  
                 }));  
             }  
         }  
 
         public WpfMap MapControl  
         {  
             get { return mapControl; }  
             set { mapControl = value; }  
         }  
 
         public double CoordinateY  
         {  
             get  
             {  
                 if (coordinateY == double.NaN) coordinateY = defaultExtent.GetCenterPoint().Y;  
                 return coordinateY;  
             }  
             set  
             {  
                 coordinateY = value;  
                 RaisePropertyChanged(() => CoordinateY);  
             }  
         }  
 
         public double CoordinateX  
         {  
             get  
             {  
                 if (coordinateX == double.NaN) coordinateX = defaultExtent.GetCenterPoint().X;  
                 return coordinateX;  
             }  
             set  
             {  
                 coordinateX = value;  
                 RaisePropertyChanged(() => CoordinateX);  
             }  
         }  
 
         public ObservableCollection<string> AddressCandidates  
         {  
             get { return defaultAddresses ?? (defaultAddresses = new ObservableCollection<string>()); }  
         }  
 
         public string SelectedAddress  
         {  
             get { return selectedAddress; }  
             set  
             {  
                 selectedAddress = value;  
                 RaisePropertyChanged(() => SelectedAddress);  
             }  
         }  
 
         public ObservableCollection<GeocoderSearchType> SearchTypeCandidates  
         {  
             get  
             {  
                 if (searchTypeCandidates == null)  
                 {  
                     searchTypeCandidates = new ObservableCollection<GeocoderSearchType>();  
                     searchTypeCandidates.Add(GeocoderSearchType.Street);  
                     searchTypeCandidates.Add(GeocoderSearchType.Reverse);  
                 }  
                 return searchTypeCandidates;  
             }  
         }  
 
         public DataView ResultListView  
         {  
             get { return resultListView ?? (resultListView = new DataView()); }  
             set  
             {  
                 resultListView = value;  
                 RaisePropertyChanged(() => ResultListView);  
             }  
         }  
 
         public GeocoderSearchType SelectedGeocoderSearchType  
         {  
             get { return selectedGeocoderSearchType; }  
             set  
             {  
                 selectedGeocoderSearchType = value;  
                 RaisePropertyChanged(() => SelectedGeocoderSearchType);  
 
                 AddressCandidates.Clear();  
                 MapSuiteSampleHelper.GetGeocoderAddressCandidates(value).ForEach(item => AddressCandidates.Add(item));  
                 SelectedAddress = AddressCandidates.First();  
                 switch (value)  
                 {  
                     case GeocoderSearchType.Reverse:  
                         SearchText = "Enter Coordinates:";  
                         ExampleText = "(ex: '42.011431 -87.678457' etc.)";  
                         break;  
                     case GeocoderSearchType.Street:  
                         SearchText = "Enter an Address:";  
                         ExampleText = "(ex: '5300 N Winthrop Ave' etc.)";  
                         break;  
                 }  
             }  
         }  
 
         private void InitializeMap()  
         {  
             mapControl.MapUnit = GeographyUnit.DecimalDegree;  
             mapControl.CurrentExtent = defaultExtent;  
 
             mapControl.Overlays.Add("WMK", new WorldMapKitWmsWpfOverlay());  
 
             simpleMarkerOverlay = new SimpleMarkerOverlay();  
             mapControl.Overlays.Add("SimpleMarker", simpleMarkerOverlay);  
 
             mapControl.MapTools.MouseCoordinate.IsEnabled = true;  
             mapControl.MapTools.MouseCoordinate.MouseCoordinateType = MouseCoordinateType.Custom;  
             mapControl.MapTools.MouseCoordinate.CustomFormatted += (s, e) =>  
             {  
                 CoordinateX = e.WorldCoordinate.X;  
                 CoordinateY = e.WorldCoordinate.Y;  
             };  
 
             mapControl.MapTools.PanZoomBar.GlobeButtonClick += (s, e) =>  
             {  
                 e.NewExtent = defaultExtent;  
             };  
         }  
 
         private void UpdateResultListView(IList<GeocoderMatch> searchResultItems)  
         {  
             DataTable resultTable = new DataTable();  
             if (searchResultItems.Count > 0)  
             {  
                 foreach (var nameValuePair in searchResultItems[0].NameValuePairs)  
                 {  
                     resultTable.Columns.Add(new DataColumn(nameValuePair.Key));  
                 }  
 
                 foreach (var searchResultItem in searchResultItems)  
                 {  
                     DataRow row = resultTable.NewRow();  
                     foreach (var nameValuePair in searchResultItem.NameValuePairs)  
                     {  
                         row[nameValuePair.Key] = nameValuePair.Value;  
                     }  
 
                     resultTable.Rows.Add(row);  
                 }  
                 HeaderVisibility = DataGridHeadersVisibility.All;  
                 ZoomToColumnVisibility = Visibility.Visible;  
             }  
             else  
             {  
                 DataColumn column = new DataColumn("Warning", typeof(string));  
                 resultTable.Columns.Add(column);  
 
                 DataRow row = resultTable.NewRow();  
                 row[column] = "No match found";  
                 resultTable.Rows.Add(row);  
                 HeaderVisibility = DataGridHeadersVisibility.None;  
                 ZoomToColumnVisibility = Visibility.Collapsed;  
             }  
 
             ResultListView = resultTable.AsDataView();  
         }  
 
         private void SearchAddress(string address)  
         {  
             UsaGeocoder usaGeocoder = new UsaGeocoder(@"App_Data\", MatchMode.ExactMatch, StreetNumberMatchingMode.Default);  
             Collection<GeocoderMatch> results;  
 
             try  
             {  
                 usaGeocoder.Open();  
                 results = usaGeocoder.Match(address);  
             }  
             finally  
             {  
                 usaGeocoder.Close();  
             }  
 
             simpleMarkerOverlay.Markers.Clear();  
 
             string matchString = SelectedGeocoderSearchType == GeocoderSearchType.Street ? "Street" : String.Empty;  
             MultipointShape multiPointShape = new MultipointShape();  
             Collection<GeocoderMatch> searchResultItems = new Collection<GeocoderMatch>();  
             foreach (GeocoderMatch item in results)  
             {  
                 if (string.IsNullOrEmpty(matchString) || item.NameValuePairs.ContainsKey(matchString))  
                 {  
                     AddSearchResultMarkerWithToolTip(item, multiPointShape);  
                     searchResultItems.Add(item);  
                 }  
             }  
 
             UpdateResultListView(searchResultItems);  
             if (multiPointShape.Points.Count > 0) mapControl.CurrentExtent = multiPointShape.GetBoundingBox();  
 
             mapControl.Refresh();  
         }  
 
         private void AddSearchResultMarkerWithToolTip(GeocoderMatch matchItem, MultipointShape multiPointShape)  
         {  
             PointShape point = new PointShape(matchItem.NameValuePairs["CentroidPoint"]);  
             Marker marker = new Marker(point);  
             marker.ImageSource = markerImageSource;  
             marker.ToolTip = GetToolTip(matchItem);  
 
             multiPointShape.Points.Add(point);  
             simpleMarkerOverlay.Markers.Add(marker);  
         }  
 
         private static ToolTip GetToolTip(GeocoderMatch matchItem)  
         {  
             StackPanel panel = new StackPanel();  
             panel.Margin = new Thickness(5);  
 
             TextBlock header = GetTextBlock(13, () => GetHearTextFromMatch(matchItem));  
             TextBlock information = GetTextBlock(10, () => GetMatchItemDescription(matchItem));  
 
             panel.Children.Add(header);  
             panel.Children.Add(new Separator());  
             panel.Children.Add(information);  
 
             ToolTip newToolTip = new ToolTip();  
             newToolTip.Content = panel;  
             return newToolTip;  
         }  
 
         private static TextBlock GetTextBlock(int fontSize, Func<string> getText)  
         {  
             string text = string.Empty;  
             if (getText != null) text = getText();  
 
             return new TextBlock  
             {  
                 FontSize = fontSize,  
                 FontStyle = FontStyles.Normal,  
                 FontWeight = FontWeights.DemiBold,  
                 Text = text  
             };  
         }  
 
         private static string GetHearTextFromMatch(GeocoderMatch matchItem)  
         {  
             IEnumerable<string> streetkeyList = new[] { "Street", "Zip", "State" };  
 
             StringBuilder keyValuesBuilder = new StringBuilder();  
             foreach (string item in streetkeyList)  
             {  
                 keyValuesBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0} ", matchItem.NameValuePairs[item]);  
             }  
 
             return keyValuesBuilder.ToString();  
         }  
 
         private static string GetMatchItemDescription(GeocoderMatch matchItem)  
         {  
             StringBuilder description = new StringBuilder();  
             foreach (var item in matchItem.NameValuePairs.Take(5))  
             {  
                 description.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0} : {1}", item.Key, item.Value));  
             }  
 
             return description.ToString();  
         }  
     }  
 }  
 

BooleanToReverseVisibilityConverter.cs

 using System;  
 using System.Windows;  
 using System.Windows.Data;  
 
 namespace ThinkGeo.MapSuite.GeoCoderExamples  
 {  
     public class BooleanToReverseVisibilityConverter : IValueConverter  
     {  
         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
         {  
             if (value is bool)  
             {  
                 bool isVisible = (bool)value;  
                 return isVisible ? Visibility.Collapsed : Visibility.Visible;  
             }  
 
             return Binding.DoNothing;  
         }  
 
         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
         {  
             return Binding.DoNothing;  
         }  
     }  
 }  
 

SearchTypeToTextConverter.cs

 using System;  
 using System.Windows.Data;  
 
 namespace ThinkGeo.MapSuite.GeoCoderExamples  
 {  
     public class SearchTypeToTextConverter : IValueConverter  
     {  
         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
         {  
             GeocoderSearchType type = (GeocoderSearchType)value;  
             string displayText = type == GeocoderSearchType.Street ? "Geocoder" : "Reverse Geocoder";  
             return displayText;  
         }  
 
         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
         {  
             return Binding.DoNothing;  
         }  
     }  
 }  
 

CommandBase.cs

 using System;  
 using System.Diagnostics;  
 using System.Windows.Input;  
 
 namespace ThinkGeo.MapSuite.GeoCoderExamples  
 {  
     public class CommandBase : ICommand  
     {  
         private readonly Predicate<object> canExecute;  
         private readonly Action<object> execute;  
 
         public CommandBase(Action<object> execute)  
 
             : this(execute, null)  
         {  
         }  
 
         public CommandBase(Action<object> execute, Predicate<object> canExecute)  
         {  
             if (execute == null)  
             {  
                 throw new ArgumentNullException("execute");  
             }  
 
             this.execute = execute;  
             this.canExecute = canExecute;  
         }  
 
         public event EventHandler CanExecuteChanged  
         {  
             add { CommandManager.RequerySuggested += value; }  
             remove { CommandManager.RequerySuggested -= value; }  
         }  
 
         [DebuggerStepThrough]  
         public bool CanExecute(object parameter)  
         {  
             return canExecute == null || canExecute(parameter);  
         }  
 
         public void Execute(object parameter)  
         {  
             execute(parameter);  
         }  
     }  
 }  
 

MapSuiteSampleHelper.cs

 using System;  
 using System.Collections.Generic;  
 
 namespace ThinkGeo.MapSuite.GeoCoderExamples  
 {  
     public static class MapSuiteSampleHelper  
     {  
         public static IEnumerable<string> GetGeocoderAddressCandidates(GeocoderSearchType searchType)  
         {  
             switch (searchType)  
             {  
                 case GeocoderSearchType.Reverse:  
                     yield return "42.020431 -87.666757";  
                     yield return "42.017069 -87.672102";  
                     yield return "42.016106 -87.668558";  
                     yield return "42.005451 -87.664937";  
                     yield return "42.011431 -87.678457";  
                     yield return "42.013912 -87.699847";  
                     break;  
 
                 default:  
                     yield return "5300 N Winthrop Ave";  
                     yield return "1401 W Ainslie St";  
                     yield return "1401 W Estes Ave";  
                     yield return "7430 N Seeley Ave";  
                     yield return "7400 N Greenview Ave";  
                     yield return "1101 W Farwell Ave";  
                     break;  
             }  
         }  
 
         public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)  
         {  
             if (items != null && action != null)  
             {  
                 foreach (var item in items)  
                 {  
                     action(item);  
                 }  
             }  
         }  
     }  
 }  
 

ViewModelBase.cs

 using System;  
 using System.ComponentModel;  
 using System.Linq.Expressions;  
 
 namespace ThinkGeo.MapSuite.GeoCoderExamples  
 {  
     public class ViewModelBase : INotifyPropertyChanged  
     {  
         public event PropertyChangedEventHandler PropertyChanged;  
 
         public ViewModelBase()  
         { }  
 
         protected virtual void RaisePropertyChanged(string propertyName)  
         {  
             PropertyChangedEventHandler handler = PropertyChanged;  
             if (handler != null)  
             {  
                 handler(this, new PropertyChangedEventArgs(propertyName));  
             }  
         }  
 
         protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> expreesion)  
         {  
             RaisePropertyChanged(((MemberExpression)expreesion.Body).Member.Name);  
         }  
     }  
 }  
 

GeocoderSearchType.cs

 namespace ThinkGeo.MapSuite.GeoCoderExamples  
 {  
     public enum GeocoderSearchType  
     {  
         Street = 0,  
         Reverse = 1  
     }  
 }