Overview

You will learn: how to build apps that can search for places and find addresses and display them on a map using the ArcGIS Runtime SDK for .NET.

With the ArcGIS Runtime SDK for .NET you can easily find places and addresses all around the world. The process of matching locations or place names on the map to an address is referred to as geocoding. Your user can specify a location of interest or street address and see it on the map. You can use the ArcGIS World Geocoding Service as a locator which has the ability to search for places, business names and addresses, and supports many different input formats. You can also perform reverse geocoding where you pass in a point location or latitude and longitude and the locator will return the address it finds. With this functionality you can build powerful apps that allow users to easily find what they are looking for.

Locating addresses is a complex topic. Refer to Search for places (geocoding) if you would like to learn more about the geocoding process and the options you can control.

In this lab, you will build a simple search app that can find places in and around the Los Angeles area.

Steps

Create a new ArcGIS Runtime App Visual Studio Project

  1. Start Visual Studio.

  2. Choose File > New > Project and select the ArcGIS Runtime Application (WPF) template. Although the instructions for this lab are for a WPF app, the code can be easily modified if you're comfortable creating a simple UI for another supported platform.

Create a UI to enter an address and see suggestions

  1. Open the MainWindow.xaml file in your project. Make sure you are viewing the file in XAML view and find the <Grid> element. Delete the entire element and all of its contents.

  2. Place the following XAML at the same location as the previous Grid. This defines a map view and a simple UI for locating an address.

    <Grid>
        <esri:MapView x:Name="MyMapView"
                      Map="{Binding Map, Source={StaticResource MapViewModel}}">
            <esri:MapView.GraphicsOverlays>
                <esri:GraphicsOverlay/>
            </esri:MapView.GraphicsOverlays>
        </esri:MapView>
        <Border Background="White" BorderBrush="Black" BorderThickness="1"
                HorizontalAlignment="Right" VerticalAlignment="Top"
                Margin="15" Padding="10"
                Width="325">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <TextBox x:Name="AddressTextBox"
                         Grid.Row="0"
                         Margin="0,5"
                         TextChanged="AddressTextChanged" />
                <ListBox x:Name="SuggestionList"
                         Grid.Row="1"
                         Height="150"
                         ItemsSource="{Binding AddressSuggestions, Source={StaticResource MapViewModel}}"
                         DisplayMemberPath="Label"
                         SelectionChanged="SuggestionChosen" />
            </Grid>
       </Border>
    </Grid>
    

Create an address locator

  1. Open the MapViewModel.cs code file in your project.

  2. Add the following using statement at the top of the MapViewModel.cs file (with the other using statements):

    using Esri.ArcGISRuntime.Tasks.Geocoding;
    
  3. Add the following code inside the definition of the MapViewModel class:

    public Esri.ArcGISRuntime.UI.Controls.MapView MapView;
    private LocatorTask _geocoder;
    
  4. Add the following code in the MapViewModel class constructor to create a locator task that uses the Esri World Geocoding Service and set the initial view and scale of the map:

    public MapViewModel()
    {
       _geocoder = new LocatorTask(new Uri("https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer"));
       _geocoder.LoadAsync();
       _map.InitialViewpoint = new Viewpoint(34.05293, -118.24368, 600000);
    }
    

Find address suggestions

  1. Add the following property to the MapViewModel class to expose a list of suggestions for an address.

    private IReadOnlyList<SuggestResult> _suggestions;
    public IReadOnlyList<SuggestResult> AddressSuggestions
    {
       get { return _suggestions; }
       set
       {
           _suggestions = value;
           OnPropertyChanged();
       }
    }
    
  2. Add the following function to the MapViewModel class to create the list of suggestions for a specified address string.

    public async void GetAddressSuggestions(string searchText)
    {
       if (_geocoder.LocatorInfo.SupportsSuggestions)
       {
           Geometry currentExtent = MapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry;
           SuggestParameters suggestParams = new SuggestParameters { MaxResults = 10, SearchArea = currentExtent };
           IReadOnlyList<SuggestResult> suggestions = await _geocoder.SuggestAsync(searchText, suggestParams);
           AddressSuggestions = suggestions;
       }
    }
    

Match an address and show it on the map

  1. Add the following function to the MapViewModel class to show a selected address.

    public async void ShowAddressLocation(SuggestResult suggestion)
    {
       IReadOnlyList<GeocodeResult> matches = await _geocoder.GeocodeAsync(suggestion);
       GeocodeResult bestMatch = (from match in matches orderby match.Score select match).FirstOrDefault();
       if(bestMatch == null) { return; }
    
       GraphicsOverlay matchOverlay = MapView.GraphicsOverlays.FirstOrDefault();
       matchOverlay.Graphics.Clear();
    
       Graphic matchGraphic = new Graphic(bestMatch.DisplayLocation);
       matchGraphic.Symbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Circle, System.Windows.Media.Colors.Cyan, 16);
       matchOverlay.Graphics.Add(matchGraphic);
    
       MapView.SetViewpointAsync(new Viewpoint(bestMatch.DisplayLocation, 24000));
    }
    

Add geocoding functionality

  1. Open the MainWindow.xaml.cs code file in your project.

  2. Add the following using statement at the top of the MainWindow.xaml.cs file (with the other using statements):

    using Esri.ArcGISRuntime.Tasks.Geocoding;
    
  3. Add the following code inside the definition of the MainWindow class:

    private MapViewModel _viewModel;
    
  4. Add the following code in the MainWindow class constructor:

    public MainWindow()
    {
        InitializeComponent();
        _viewModel = this.FindResource("MapViewModel") as MapViewModel;
        _viewModel.MapView = MyMapView;
    }
    
  5. Add the following code in the MainWindow class to handle text change events in the address text box:

    private void AddressTextChanged(object sender, TextChangedEventArgs e)
    {
       string address = AddressTextBox.Text.Trim();
    
       if (string.IsNullOrEmpty(address) || address.Length < 3)
       {
           return;
       }
    
       SuggestResult suggestion = SuggestionList.SelectedItem as SuggestResult;
       if (suggestion != null && suggestion.Label == address) { return; }
    
       _viewModel.GetAddressSuggestions(address);
    }
    
  6. Add the following code in the MainWindow class to handle selection change events for the suggestion list box:

    private void SuggestionChosen(object sender, SelectionChangedEventArgs e)
    {
       SuggestResult suggestion = SuggestionList.SelectedItem as SuggestResult;
       if (suggestion == null) { return; }
    
       AddressTextBox.Text = suggestion.Label;
    
       _viewModel.ShowAddressLocation(suggestion);
    }
    

Congratulations, you're done!

Your app displays a map of world streets. Enter at least three characters of text in the text box and a list of suggested addresses appear. Click a suggestion from the list to show and zoom to its location on the map.

Challenge

Explore graphics

Try different symbols for the graphic result shown in the ShowAddressLocation function in MapViewModel - change the symbol style, size, and color.

Geocoding parameters

Can you discover other geocoding parameters available to the locator task? For example, change the search area.

Reverse geocode

The LocatorTask class has a ReverseGeocodeAsync method that returns an interpolated address (string) for a location (map point). Experiment with code that uses a click on the map to perform a reverse geocode.