Address Locator task

The Address Locator task allows you to perform geocoding and reverse geocoding operations. With the Address Locator, you can find either the geographic location of an address or the address of a geographic location. To use the Address Locator task, your ArcGIS API for WPF application must contain the following:

NoteNote:

While the input and output interfaces can technically be implemented in .NET code (that is, code-behind), the best practice is to separate an application's presentation layer from its business logic. XAML is intended to house the presentation layer, while the code-behind is for an application's business logic.

The code from a ArcGIS API for WPF application that uses the Address Locator task to enable both geocoding and reverse geocoding follows. To enable geocoding, the code defines text boxes for inputting address information and a button to initiate the operation. Reverse geocoding is triggered by clicking the map. Both geocoding and reverse geocoding results are drawn in GraphicsLayers that have MapTips enabled. The remainder of this topic walks you through the sample, paying particular attention to how the task is used.

NoteNote:

The code sections in this topic require that the project has a refererence to the ESRI.ArcGIS.Client assembly. The Window of the application's main window (for example, MainWindow.xaml) needs to have the following XML namespace declaration:

xmlns:esri="http://schemas.esri.com/arcgis/client/2009"

The code-behind (for example, MainWindow.xaml.cs) must include the following using statements:

using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Tasks;
using ESRI.ArcGIS.Client.Symbols;
using ESRI.ArcGIS.Client.Geometry;

The Grid shown in the following code section replaces the main Grid in the XAML.

<Grid x:Name="LayoutRoot">

  <!-- LOCATOR TASK RESOURCES -->
  <Grid.Resources>
    <esri:PictureMarkerSymbol x:Key="AddressToLocationSymbol" OffsetX="0" OffsetY="31" 
      Source="/Assets/images/flag-yellow-32x32.png" />
    <esri:PictureMarkerSymbol x:Key="LocationToAddressSymbol" OffsetX="12" OffsetY="12" 
      Source="/Assets/images/x-24x24.png" />
  </Grid.Resources>

  <!-- MAP -->
  <esri:Map x:Name="MyMap" Extent="-74.18,40.69,-73.89,40.89" MouseClick="MyMap_MouseClick" >
    <esri:Map.Layers>
      <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer"
        Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
      <esri:GraphicsLayer ID="AddressToLocationGraphicsLayer">
        <esri:GraphicsLayer.MapTip>
          <Grid Background="LightYellow">
            <StackPanel Margin="5" >
              <TextBlock Text="{Binding [Address]}" HorizontalAlignment="Left" />
              <TextBlock Text="{Binding [LatLon]}" HorizontalAlignment="Left" />								
            </StackPanel>
            <Border BorderBrush="Black" BorderThickness="1" />
          </Grid>
        </esri:GraphicsLayer.MapTip>
      </esri:GraphicsLayer>
      <esri:GraphicsLayer ID="LocationToAddressGraphicsLayer">
        <esri:GraphicsLayer.MapTip>
          <Grid Background="LightYellow">
            <StackPanel Orientation="Vertical" Margin="5" >
              <TextBlock Text="{Binding [Address1]}" />
              <TextBlock Text="{Binding [Address2]}" />
              <TextBlock Text="{Binding [LatLon]}" />
            </StackPanel>
            <Border BorderBrush="Black" BorderThickness="1" />
          </Grid>
        </esri:GraphicsLayer.MapTip>
      </esri:GraphicsLayer>
    </esri:Map.Layers>
  </esri:Map>

  <!-- LOCATOR TASK INTERFACE -->
  <StackPanel Margin="10" HorizontalAlignment="Left">
    <Grid>
      <Rectangle Fill="#CC5C90B2" Stroke="Gray"  RadiusX="10" RadiusY="10" />
      <StackPanel Margin="10" HorizontalAlignment="Center" >
        <TextBlock Text="Click Find to locate an address" HorizontalAlignment="Center" 
          Margin="0,0,0,5" Foreground="White" FontStyle="Italic" />
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
          <TextBlock Text="Address: " Foreground="White" />
          <TextBox x:Name="Address" Text="1000 Broadway" Width="125" />
        </StackPanel>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
          <TextBlock Text="City: " Foreground="White" />
          <TextBox x:Name="City" Text="New York" Width="125" />
        </StackPanel>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
          <TextBlock Text="State: " Foreground="White" />
          <TextBox x:Name="State" Text="NY" Width="125"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
          <TextBlock Text="Zip: " Foreground="White" />
          <TextBox x:Name="Zip" Text="" Width="125" />
        </StackPanel>
        <Button x:Name="FindAddressButton" Content="Find" Width="100" HorizontalAlignment="Center"
          Click="FindAddressButton_Click" Margin="0,5,0,0" />
        <Line HorizontalAlignment="Center" X1="0" Y1="10" X2="180" Y2="10" StrokeThickness="1" Stroke="White" />
        <TextBlock Text="Or click map to retrieve address" FontStyle="Italic" HorizontalAlignment="Center" 
          Foreground="White" Margin="0,10,0,0" />
      </StackPanel>
    </Grid>
  </StackPanel>
</Grid>

The methods shown in the following code section follow the constructor in the code-behind.

// Find the location of an address when the Find button is clicked.
private void FindAddressButton_Click(object sender, RoutedEventArgs e)
{
  // Initialize the Locator.
  Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/" +
    "Locators/ESRI_Geocode_USA/GeocodeServer");
  locatorTask.AddressToLocationsCompleted += LocatorTask_AddressToLocationsCompleted;
  locatorTask.Failed += LocatorTask_Failed;

  // Initialize the address.
  AddressToLocationsParameters addressParameters = new AddressToLocationsParameters();
  Dictionary<string, string> address = addressParameters.Address;

  address.Add("Address", Address.Text);
  address.Add("City", City.Text);
  address.Add("State", State.Text);
  address.Add("Zip", Zip.Text);

  // Call method to locate the address.
  locatorTask.AddressToLocationsAsync(addressParameters);
}

// When the address has been located, show the best match on the map.
private void LocatorTask_AddressToLocationsCompleted(object sender, ESRI.ArcGIS.Client.Tasks.AddressToLocationsEventArgs args)
{
  // Check whether results were found.
  if (args.Results.Count > 0)
  {
    // Get the best match.
    AddressCandidate bestCandidate = args.Results[0];
    foreach (AddressCandidate candidate in args.Results)
      bestCandidate = (candidate.Score > bestCandidate.Score) ? candidate : bestCandidate;

    // Create a graphic for the match.
    Graphic graphic = new Graphic()
    {
      Symbol = LayoutRoot.Resources["AddressToLocationSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
      Geometry = bestCandidate.Location
    };

    // Add the address and coordinates to the graphic.
    graphic.Attributes.Add("Address", bestCandidate.Address);
    string latLon = String.Format("{0}, {1}", bestCandidate.Location.X, bestCandidate.Location.Y);
    graphic.Attributes.Add("LatLon", latLon);

    // Show the graphic by adding it to a graphics layer.
    GraphicsLayer graphicsLayer = MyMap.Layers["AddressToLocationGraphicsLayer"] as GraphicsLayer;
    graphicsLayer.ClearGraphics();
    graphicsLayer.Graphics.Add(graphic);
  }
  else  
  {
    // Notify user.
    MessageBox.Show("No results found");
  }
}

// Find the address at the clicked location.
private void MyMap_MouseClick(object sender, Map.MouseEventArgs e)
{
  // Initialize the Locator.
  Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Locators/" +
    "ESRI_Geocode_USA/GeocodeServer");
  locatorTask.LocationToAddressCompleted += LocatorTask_LocationToAddressCompleted;
  locatorTask.Failed += LocatorTask_Failed;

  // Find the address within 20 meters of the clicked point.
  locatorTask.LocationToAddressAsync(e.MapPoint, 20);
}

// Draw the graphic at the click point with attributes containing the location's address.
private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
{
  // Get the address of the click point.
  Address address = args.Address;
  Dictionary<string, object> attributes = args.Address.Attributes;

  // Create the graphic at the click point.
  Graphic graphic = new Graphic()
  {
    Symbol = LayoutRoot.Resources["LocationToAddressSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
    Geometry = address.Location,
  };

  // Add the address and coordinates at the click point to the graphic's attributes.
  string latLon = String.Format("{0}, {1}", address.Location.X, address.Location.Y);
  string address1 = attributes["Address"].ToString();
  string address2 = String.Format("{0}, {1} {2}", attributes["City"], attributes["State"], attributes["Zip"]);

  graphic.Attributes.Add("LatLon", latLon);
  graphic.Attributes.Add("Address1", address1);
  graphic.Attributes.Add("Address2", address2);

  // Show the graphic by adding it to a graphics layer.
  GraphicsLayer graphicsLayer = MyMap.Layers["LocationToAddressGraphicsLayer"] as GraphicsLayer;
  graphicsLayer.Graphics.Add(graphic);
}

// Notify the user if the task fails to execute.
private void LocatorTask_Failed(object sender, TaskFailedEventArgs e)
{
  MessageBox.Show("Locator service failed: " + e.Error);
}

NoteNote:

Additional examples of the Address Locator task functionality can be found in the Interactive SDK.

Using an Address Locator task

The following steps assume you have created an ArcGIS API for WPF application with a map and a base layer as described in Creating a map and that you are already familiar with creating simple WPF user interface (UI) elements and specifying MapTips on GraphicsLayers as shown in the Query task, Find task, and Identify task topics. The XAML view of your application's main window (for example, MainWindow.xaml) should look similar to the following:

<Window x:Class="WPFApp.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:esri="http://schemas.esri.com/arcgis/client/2009"
  Title="MainWindow" Height="350" Width="525">
  <Grid x:Name="LayoutRoot" >

    <!-- MAP -->
    <esri:Map x:Name="MyMap" Extent="-74.18,40.69,-73.89,40.89" >
      <esri:Map.Layers>
        <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" 
          Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
      </esri:Map.Layers>
    </esri:Map>
  </Grid>
</Window>

The code in the main window's code-behind (for example, MainWindow.xaml.cs) should be unchanged from when you created your application project in Visual Studio.

Creating the input interface

Tasks do not define UIs, so it's up to you as a developer to implement an interface for the Address Locator's input. For geocoding input, you'll define a TextBlock for instructions, TextBoxes for the address information, and a Button to start the operation. For reverse geocoding, you'll specify a TextBlock for instructions and a handler for the map's MouseClick event.

  1. In XAML, define the background for the task's input interface. In the structure shown below, the Rectangle will define the background color and will automatically fit to elements within the inner StackPanel.
    <StackPanel Margin="10" HorizontalAlignment="Left">
      <Grid>
        <Rectangle Fill="#CC5C90B2" Stroke="Gray"  RadiusX="10" RadiusY="10" />
        <StackPanel Margin="10" HorizontalAlignment="Center" >
        </StackPanel>
      </Grid>
    </StackPanel>
    
  2. Specify the geocoding interface. Use a TextBlock for the operation instructions, TextBoxes for the address information, and a Button to initiate the operation. Be sure to specify a handler for the Button's click event. Later in the walkthrough, you'll implement this handler so that it processes the user input and starts the geocoding operation.
    <StackPanel Margin="10" HorizontalAlignment="Left">
      <Grid>
        <Rectangle Fill="#CC5C90B2" Stroke="Gray"  RadiusX="10" RadiusY="10" />
        <StackPanel Margin="10" HorizontalAlignment="Center" >
          <TextBlock Text="Click Find to locate an address" HorizontalAlignment="Center" 
            Margin="0,0,0,5" Foreground="White" FontStyle="Italic" />
          <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
            <TextBlock Text="Address: " Foreground="White" />
            <TextBox x:Name="Address" Text="1000 Broadway" Width="125" />
          </StackPanel> 
          <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
            <TextBlock Text="City: " Foreground="White" />
            <TextBox x:Name="City" Text="New York" Width="125" />
          </StackPanel>
          <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
            <TextBlock Text="State: " Foreground="White" />
            <TextBox x:Name="State" Text="NY" Width="125"/>
          </StackPanel>
          <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
            <TextBlock Text="Zip: " Foreground="White" />
            <TextBox x:Name="Zip" Text="" Width="125" />
          </StackPanel>
          <Button x:Name="FindAddressButton" Content="Find" Width="100" HorizontalAlignment="Center"
            Click="FindAddressButton_Click" Margin="0,5,0,0" />
        </StackPanel>
      </Grid>
    </StackPanel>
    
  3. Specify instructions for reverse geocoding. Add a separator line below the geocoding interface and a TextBlock containing the instructions.
    <StackPanel Margin="10" HorizontalAlignment="Left">
      <Grid>
        <Rectangle Fill="#CC5C90B2" Stroke="Gray"  RadiusX="10" RadiusY="10" />
        <StackPanel Margin="10" HorizontalAlignment="Center" >
          <TextBlock Text="Click Find to locate an address" HorizontalAlignment="Center" 
            Margin="0,0,0,5" Foreground="White" FontStyle="Italic" />
          <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
            <TextBlock Text="Address: " Foreground="White" />
            <TextBox x:Name="Address" Text="1000 Broadway" Width="125" />
          </StackPanel>
          <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
            <TextBlock Text="City: " Foreground="White" />
            <TextBox x:Name="City" Text="New York" Width="125" />
          </StackPanel>
          <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
            <TextBlock Text="State: " Foreground="White" />
            <TextBox x:Name="State" Text="NY" Width="125"/>
          </StackPanel>
          <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
            <TextBlock Text="Zip: " Foreground="White" />
            <TextBox x:Name="Zip" Text="" Width="125" />
          </StackPanel>
          <Button x:Name="FindAddressButton" Content="Find" Width="100" HorizontalAlignment="Center"
            Click="FindAddressButton_Click" Margin="0,5,0,0" />
          <Line HorizontalAlignment="Center" X1="0" Y1="10" X2="180" Y2="10" StrokeThickness="1" Stroke="White" />
          <TextBlock Text="Or click map to retrieve address" FontStyle="Italic" HorizontalAlignment="Center" 
            Foreground="White" Margin="0,10,0,0" />
        </StackPanel>
      </Grid>
    </StackPanel>
    
  4. On the Map control, specify a handler for the MouseClick event. You'll implement this handler later so that it uses the click point to initiate a reverse geocoding operation.
    <esri:Map x:Name="MyMap" Extent="-74.18,40.69,-73.89,40.89" MouseClick="MyMap_MouseClick" >
      <esri:Map.Layers>
        <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" 
          Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
      </esri:Map.Layers>
    </esri:Map>
    

Creating the output interface

To display a task's results, you need to specify an output interface. For displaying the geometry of result features, you'll use two GraphicsLayers and two PictureMarkerSymbols—one layer/symbol pair for geocoding output and one for reverse geocoding output. Then you'll specify MapTips on each GraphicsLayer for displaying non-geographic results data. The MapTips will bind to attributes on the task's results.

  1. Declare two PictureMarkerSymbols as resources of the root Grid element.
    <Grid.Resources>
      <esri:PictureMarkerSymbol x:Key="AddressToLocationSymbol" OffsetX="0" OffsetY="31" 
        Source="/Assets/images/flag-yellow-32x32.png" />
      <esri:PictureMarkerSymbol x:Key="LocationToAddressSymbol" OffsetX="12" OffsetY="12" 
        Source="/Assets/images/x-24x24.png" />
    </Grid.Resources>
    
  2. Add two GraphicsLayers to the Map control XAML element—one each for geocoding and reverse geocoding results.
    NoteNote:

    The GraphicsLayers are specified below the map service layer in the XAML so that they are drawn above the map service layer at run time. For further information, see the Adding layers topic.

    <esri:Map x:Name="MyMap" Extent="-74.18,40.69,-73.89,40.89" MouseClick="MyMap_MouseClick" >
      <esri:Map.Layers>
        <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" 
          Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
        <esri:GraphicsLayer ID="AddressToLocationGraphicsLayer">
        </esri:GraphicsLayer>
        <esri:GraphicsLayer ID="LocationToAddressGraphicsLayer">
        </esri:GraphicsLayer>
      </esri:Map.Layers>
    </esri:Map>
    
  3. Within the element for the geocoding (address to location) results GraphicsLayer, specify a MapTip to display the non-geographic data of the results. Bind the MapTip to attributes called Address and LatLon. You'll explicitly add these attributes to the geocoding results in the window's code-behind. For further information on binding attributes to MapTips, see the Query task, Find task, and Identify task topics.
    <esri:Map x:Name="MyMap" Extent="-74.18,40.69,-73.89,40.89" MouseClick="MyMap_MouseClick" >
      <esri:Map.Layers>
        <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" 
          Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
        <esri:GraphicsLayer ID="AddressToLocationGraphicsLayer">
          <esri:GraphicsLayer.MapTip>
            <Grid Background="LightYellow">
              <StackPanel Margin="5" >
                <TextBlock Text="{Binding [Address]}" HorizontalAlignment="Left" />
                <TextBlock Text="{Binding [LatLon]}" HorizontalAlignment="Left" />								
              </StackPanel>
              <Border BorderBrush="Black" BorderThickness="1" />
            </Grid>
          </esri:GraphicsLayer.MapTip>
        </esri:GraphicsLayer>
        <esri:GraphicsLayer ID="LocationToAddressGraphicsLayer">
        </esri:GraphicsLayer>
      </esri:Map.Layers>
    </esri:Map>
    
  4. On the reverse geocoding (location to address) results GraphicsLayer, specify a MapTip that will bind to attributes called Address1, Address2, and LatLon.
    <esri:Map x:Name="MyMap" Extent="-74.18,40.69,-73.89,40.89" MouseClick="MyMap_MouseClick" >
      <esri:Map.Layers>
        <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" 
          Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
        <esri:GraphicsLayer ID="AddressToLocationGraphicsLayer">
          <esri:GraphicsLayer.MapTip>
            <Grid Background="LightYellow">
              <StackPanel Margin="5" >
                <TextBlock Text="{Binding [Address]}" HorizontalAlignment="Left" />
                <TextBlock Text="{Binding [LatLon]}" HorizontalAlignment="Left" />	
              </StackPanel>
              <Border BorderBrush="Black" BorderThickness="1" />
            </Grid>
          </esri:GraphicsLayer.MapTip>
        </esri:GraphicsLayer>
        <esri:GraphicsLayer ID="LocationToAddressGraphicsLayer">
          <esri:GraphicsLayer.MapTip>
            <Grid Background="LightYellow">
              <StackPanel Orientation="Vertical" Margin="5" >
                <TextBlock Text="{Binding [Address1]}" />
                <TextBlock Text="{Binding [Address2]}" />
                <TextBlock Text="{Binding [LatLon]}" />
              </StackPanel>
              <Border BorderBrush="Black" BorderThickness="1" />
            </Grid>
          </esri:GraphicsLayer.MapTip>
        </esri:GraphicsLayer>
      </esri:Map.Layers>
    </esri:Map>
    

Implementing the task's execution logic

Now that you've specified the Address Locator task's UI, you need to define its execution logic. As previously mentioned, this task can perform both geocoding and reverse geocoding. In this section, you'll implement the Find button's click event handler to initiate a geocoding operation by calling the task's AddressToLocationsAsync method. Then you'll define a handler for the map's MouseClick event to perform reverse geocoding by calling the task's LocationToAddressAsync method. The code for these handlers will be implemented in .NET code contained in the main window's code-behind. This code is linked to the XAML presentation layer by manipulating elements that you declared in XAML with "x:Name" or "ID" attributes and implementing methods that you declared in XAML as event handlers.

To use the Address Locator's execution methods, you need to instantiate the task, specify the geocoding service that will be used to lookup address information, wire the task's event handlers, initialize the operation's parameters, and call the execution method. The steps below show you how to do this in the code-behind of your application's main window (for example, MainWindow.xaml.cs) . The task is declared and initialized in the code-behind because tasks alone do not define any UI, but rather encapsulate pieces of execution logic. XAML is reserved for an application's presentation layer, while the code-behind is where business logic is implemented.

Initiating a geocoding operation

  1. In the code-behind class of your application's main window, implement a handler for the FindAddressButton's click event. You declared this handler when you defined the FindAddressButton control in the window's XAML.
    private void FindAddressButton_Click(object sender, RoutedEventArgs e)
    {
    }
    
  2. In the click handler, declare and instantiate an Address Locator task. Set the geocode service that the task will use to lookup addresses by passing the service's URL to the task's constructor. To find the URL, you can use the ArcGIS Services Directory. See the Discovering Services topic for more information. This example uses the ESRI_Geocode_USA service.
    private void FindAddressButton_Click(object sender, RoutedEventArgs e)
    {
      Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/" +
        "Locators/ESRI_Geocode_USA/GeocodeServer");
    }
    
  3. Specify a handler for the task's AddressToLocationsCompleted event. The method specified will be called when the Address Locator task has completed a geocode operation. You'll implement this handler in the Handling geocoding results section.
    private void FindAddressButton_Click(object sender, RoutedEventArgs e)
    {
      Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/" +
        "Locators/ESRI_Geocode_USA/GeocodeServer");
      locatorTask.AddressToLocationsCompleted += LocatorTask_AddressToLocationsCompleted;
    }
    
  4. Specify a handler for the task's Failed event, which fires when there is a problem performing a geocoding or reverse geocoding operation. You will define this handler in the Handling execution errors section.
    private void FindAddressButton_Click(object sender, RoutedEventArgs e)
    {
      Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/" +
        "Locators/ESRI_Geocode_USA/GeocodeServer");
      locatorTask.AddressToLocationsCompleted += LocatorTask_AddressToLocationsCompleted;
      locatorTask.Failed += LocatorTask_Failed;
    }
    
  5. Declare and instantiate an AddressToLocationsParameters object. This object is used to define the execution parameters for geocoding operations.
    private void FindAddressButton_Click(object sender, RoutedEventArgs e)
    {
      Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/" +
        "Locators/ESRI_Geocode_USA/GeocodeServer");
      locatorTask.AddressToLocationsCompleted += LocatorTask_AddressToLocationsCompleted;
      locatorTask.Failed += LocatorTask_Failed;
    
      AddressToLocationsParameters addressParameters = new AddressToLocationsParameters();
    }
    
  6. Retrieve the address information from the input TextBoxes you specified in the window's XAML and use it to initialize the parameter object's Address property.
    private void FindAddressButton_Click(object sender, RoutedEventArgs e)
    {
      Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/" +
        "Locators/ESRI_Geocode_USA/GeocodeServer");
      locatorTask.AddressToLocationsCompleted += LocatorTask_AddressToLocationsCompleted;
      locatorTask.Failed += LocatorTask_Failed;
    
      AddressToLocationsParameters addressParameters = new AddressToLocationsParameters();
      Dictionary<string, string> address = addressParameters.Address;
    
      address.Add("Address", Address.Text);
      address.Add("City", City.Text);
      address.Add("State", State.Text);
      address.Add("Zip", Zip.Text);
    }
    
  7. Execute the geocoding operation with the specified address.
    private void FindAddressButton_Click(object sender, RoutedEventArgs e)
    {
      Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/" +
        "Locators/ESRI_Geocode_USA/GeocodeServer");
      locatorTask.AddressToLocationsCompleted += LocatorTask_AddressToLocationsCompleted;
      locatorTask.Failed += LocatorTask_Failed;
    
      AddressToLocationsParameters addressParameters = new AddressToLocationsParameters();
      Dictionary<string, string> address = addressParameters.Address;
    
      address.Add("Address", Address.Text);
      address.Add("City", City.Text);
      address.Add("State", State.Text);
      address.Add("Zip", Zip.Text);
    
      locatorTask.AddressToLocationsAsync(addressParameters);
    }
    

Initiating a reverse geocoding operation

  1. In the code-behind class of the application's main window, implement a handler for the map's MouseClick event. You declared this handler when you specified its name on the Map element in the window's XAML.
    private void MyMap_MouseClick(object sender, Map.MouseEventArgs e)
    {
    }
    
  2. In the handler, declare and instantiate an Address Locator task. Set the geocode service that the task will use to lookup addresses by passing the service's URL to the task's constructor. To find the URL, you can use the ArcGIS Services Directory. See the Discovering Services topic for more information. This example uses the ESRI_Geocode_USA service.
    private void MyMap_MouseClick(object sender, Map.MouseEventArgs e)
    {
      Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Locators/" +
        "ESRI_Geocode_USA/GeocodeServer");
    }
    
  3. Specify a handler for the task's LocationToAddressCompleted event. The method specified will be called when the Address Locator task is has completed a reverse geocode operation. You will implement this handler in the Handling reverse geocoding results section.
    private void MyMap_MouseClick(object sender, Map.MouseEventArgs e)
    {
      Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Locators/" +
        "ESRI_Geocode_USA/GeocodeServer");
      locatorTask.LocationToAddressCompleted += LocatorTask_LocationToAddressCompleted;
    }
    
  4. Specify a handler for the task's Failed event, which fires when there is a problem performing a geocoding or reverse geocoding operation. You will define this handler in the Handling execution errors section.
    private void MyMap_MouseClick(object sender, Map.MouseEventArgs e)
    {
      Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Locators/" +
        "ESRI_Geocode_USA/GeocodeServer");
      locatorTask.LocationToAddressCompleted += LocatorTask_LocationToAddressCompleted;
      locatorTask.Failed += LocatorTask_Failed;
    }
    
  5. Execute the reverse geocoding operation to find the address at the point clicked on the map. Specify a tolerance of 20 for the operation. This means that the task will search within 20 meters of the click point to find the nearest address.
    private void MyMap_MouseClick(object sender, Map.MouseEventArgs e)
    {
      Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Locators/" +
        "ESRI_Geocode_USA/GeocodeServer");
      locatorTask.LocationToAddressCompleted += LocatorTask_LocationToAddressCompleted;
      locatorTask.Failed += LocatorTask_Failed;
    
      locatorTask.LocationToAddressAsync(e.MapPoint, 20);
    }
    

Handling geocoding results

  1. Declare a handler for the Address Locator task's AddressToLocationsCompleted event. This handler will be invoked when a geocoding operation is complete. A list of AddressCandidates containing information about the possible matches for the input address is passed to the handler's args parameter. Each AddressCandidate contains the score, address, and location for the match.
    private void LocatorTask_AddressToLocationsCompleted(object sender, ESRI.ArcGIS.Client.Tasks.AddressToLocationsEventArgs args)
    {
    }
    
  2. Check whether any results were found.
    private void LocatorTask_AddressToLocationsCompleted(object sender, ESRI.ArcGIS.Client.Tasks.AddressToLocationsEventArgs args)
    {
      if (args.Results.Count > 0)
      {
      }
      else
      {
      }
    }
    
  3. If results were found, loop through them and store a reference to the one with the highest match score.
    private void LocatorTask_AddressToLocationsCompleted(object sender, ESRI.ArcGIS.Client.Tasks.AddressToLocationsEventArgs args)
    {
      if (args.Results.Count > 0)
      {
        AddressCandidate bestCandidate = args.Results[0];
        foreach (AddressCandidate candidate in args.Results)
          bestCandidate = (candidate.Score > bestCandidate.Score) ? candidate : bestCandidate;
      }
      else
      {
      }
    }
    
  4. Create a Graphic to display the best match on the map. Initialize it with the result's location and the geocoding result symbol you defined in the window's XAML.
    private void LocatorTask_AddressToLocationsCompleted(object sender, ESRI.ArcGIS.Client.Tasks.AddressToLocationsEventArgs args)
    {
      if (args.Results.Count > 0)
      {
        AddressCandidate bestCandidate = args.Results[0];
        foreach (AddressCandidate candidate in args.Results)
          bestCandidate = (candidate.Score > bestCandidate.Score) ? candidate : bestCandidate;
    
        Graphic graphic = new Graphic()
        {
          Symbol = LayoutRoot.Resources["AddressToLocationSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
          Geometry = bestCandidate.Location
        };
      }
      else
      {
      }
    }
    
  5. Add the Address of the result to the graphic. Specify an attribute name of Address, which will allow the value to be bound to a MapTip through XAML you specified earlier.
    private void LocatorTask_AddressToLocationsCompleted(object sender, ESRI.ArcGIS.Client.Tasks.AddressToLocationsEventArgs args)
    {
      if (args.Results.Count > 0)
      {
        AddressCandidate bestCandidate = args.Results[0];
        foreach (AddressCandidate candidate in args.Results)
          bestCandidate = (candidate.Score > bestCandidate.Score) ? candidate : bestCandidate;
    
        Graphic graphic = new Graphic()
        {
          Symbol = LayoutRoot.Resources["AddressToLocationSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
          Geometry = bestCandidate.Location
        };
    
        graphic.Attributes.Add("Address", bestCandidate.Address);
      }
      else
      {
        MessageBox.Show("No results found");
      }
    }
    
  6. Add the coordinates of the result to the Graphic in an attribute named LatLon. This attribute will also be bound to the Graphic's MapTip through XAML you specified earlier.
    private void LocatorTask_AddressToLocationsCompleted(object sender, ESRI.ArcGIS.Client.Tasks.AddressToLocationsEventArgs args)
    {
      if (args.Results.Count > 0)
      {
        AddressCandidate bestCandidate = args.Results[0];
        foreach (AddressCandidate candidate in args.Results)
          bestCandidate = (candidate.Score > bestCandidate.Score) ? candidate : bestCandidate;
    
        Graphic graphic = new Graphic()
        {
          Symbol = LayoutRoot.Resources["AddressToLocationSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
          Geometry = bestCandidate.Location
        };
    
        graphic.Attributes.Add("Address", bestCandidate.Address);
        string latLon = String.Format("{0}, {1}", bestCandidate.Location.X, bestCandidate.Location.Y);
        graphic.Attributes.Add("LatLon", latLon);
      }
      else
      {
      }
    }
    
  7. Retrieve the geocoding results GraphicsLayer, and clear it of any previous results.
    private void LocatorTask_AddressToLocationsCompleted(object sender, ESRI.ArcGIS.Client.Tasks.AddressToLocationsEventArgs args)
    {
      if (args.Results.Count > 0)
      {
        AddressCandidate bestCandidate = args.Results[0];
        foreach (AddressCandidate candidate in args.Results)
          bestCandidate = (candidate.Score > bestCandidate.Score) ? candidate : bestCandidate;
    
        Graphic graphic = new Graphic()
        {
          Symbol = LayoutRoot.Resources["AddressToLocationSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
          Geometry = bestCandidate.Location
        };
    
        graphic.Attributes.Add("Address", bestCandidate.Address);
        string latLon = String.Format("{0}, {1}", bestCandidate.Location.X, bestCandidate.Location.Y);
        graphic.Attributes.Add("LatLon", latLon);
    
        GraphicsLayer graphicsLayer = MyMap.Layers["AddressToLocationGraphicsLayer"] as GraphicsLayer;
        graphicsLayer.ClearGraphics();
      }
      else
      {
      }
    }
    
  8. Add the new geocoding result to the GraphicsLayer so that it is shown on the map.
    private void LocatorTask_AddressToLocationsCompleted(object sender, ESRI.ArcGIS.Client.Tasks.AddressToLocationsEventArgs args)
    {
      if (args.Results.Count > 0)
      {
        AddressCandidate bestCandidate = args.Results[0];
        foreach (AddressCandidate candidate in args.Results)
          bestCandidate = (candidate.Score > bestCandidate.Score) ? candidate : bestCandidate;
    
        Graphic graphic = new Graphic()
        {
          Symbol = LayoutRoot.Resources["AddressToLocationSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
          Geometry = bestCandidate.Location
        };
    
        graphic.Attributes.Add("Address", bestCandidate.Address);
        string latLon = String.Format("{0}, {1}", bestCandidate.Location.X, bestCandidate.Location.Y);
        graphic.Attributes.Add("LatLon", latLon);
    
        GraphicsLayer graphicsLayer = MyMap.Layers["AddressToLocationGraphicsLayer"] as GraphicsLayer;
        graphicsLayer.ClearGraphics();
        graphicsLayer.Graphics.Add(graphic);
      }
      else
      {
      }
    }
    
  9. If no features were found, notify the user with a MessageBox.
    private void LocatorTask_AddressToLocationsCompleted(object sender, ESRI.ArcGIS.Client.Tasks.AddressToLocationsEventArgs args)
    {
      if (args.Results.Count > 0)
      {
        AddressCandidate bestCandidate = args.Results[0];
        foreach (AddressCandidate candidate in args.Results)
          bestCandidate = (candidate.Score > bestCandidate.Score) ? candidate : bestCandidate;
    
        Graphic graphic = new Graphic()
        {
          Symbol = LayoutRoot.Resources["AddressToLocationSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
          Geometry = bestCandidate.Location
        };
    
        graphic.Attributes.Add("Address", bestCandidate.Address);
        string latLon = String.Format("{0}, {1}", bestCandidate.Location.X, bestCandidate.Location.Y);
        graphic.Attributes.Add("LatLon", latLon);
    
        GraphicsLayer graphicsLayer = MyMap.Layers["AddressToLocationGraphicsLayer"] as GraphicsLayer;
        graphicsLayer.ClearGraphics();
        graphicsLayer.Graphics.Add(graphic);
      }
      else
      {
        MessageBox.Show("No results found");
      }
    }
    

Handling reverse geocoding results

  1. Declare a handler for the Address Locator task's LocationToAddressCompleted event. This handler will be invoked when a reverse geocoding operation is complete. The address information for the address closest to the input point is passed to the handler's args parameter.
    private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
    {
    }
    
  2. Get references to the found address and its attributes.
    private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
    {
      Address address = args.Address;
      Dictionary<string, object> attributes = args.Address.Attributes;
    }
    
  3. Create a Graphic to display the address. Initialize it with the result's location and the reverse geocoding result symbol you defined in the window's XAML.
    private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
    {
      Address address = args.Address;
      Dictionary<string, object> attributes = args.Address.Attributes;
    
      Graphic graphic = new Graphic()
      {
        Symbol = LayoutRoot.Resources["LocationToAddressSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
        Geometry = address.Location,
      };
    }
    
  4. Get the coordinates and address of the result and format them for display on the Graphic's MapTip.
    private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
    {
      Address address = args.Address;
      Dictionary<string, object> attributes = args.Address.Attributes;
    
      Graphic graphic = new Graphic()
      {
        Symbol = LayoutRoot.Resources["LocationToAddressSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
        Geometry = address.Location,
      };
    
      string latLon = String.Format("{0}, {1}", address.Location.X, address.Location.Y);
      string address1 = attributes["Address"].ToString();
      string address2 = String.Format("{0}, {1} {2}", attributes["City"], attributes["State"], attributes["Zip"]);
    }
    
  5. Add the coordinates and address of the result to the Graphic in attributes named LatLon, Address1, and Address2. In the window's XAML, you specified attributes with these names to be bound to the MapTips of the reverse geocoding GraphicsLayer. Adding the address information to the Graphic with these attributes names will result in this information being displayed on the Graphic's MapTip.
    private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
    {
      Address address = args.Address;
      Dictionary<string, object> attributes = args.Address.Attributes;
    
      Graphic graphic = new Graphic()
      {
        Symbol = LayoutRoot.Resources["LocationToAddressSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
        Geometry = address.Location,
      };
    
      string latLon = String.Format("{0}, {1}", address.Location.X, address.Location.Y);
      string address1 = attributes["Address"].ToString();
      string address2 = String.Format("{0}, {1} {2}", attributes["City"], attributes["State"], attributes["Zip"]);
    
      graphic.Attributes.Add("LatLon", latLon);
      graphic.Attributes.Add("Address1", address1);
      graphic.Attributes.Add("Address2", address2);
    }
    
  6. Retrieve the reverse geocoding results GraphicsLayer, and add the Graphic to it.
    private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
    {
      Address address = args.Address;
      Dictionary<string, object> attributes = args.Address.Attributes;
    
      Graphic graphic = new Graphic()
      {
        Symbol = LayoutRoot.Resources["LocationToAddressSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
        Geometry = address.Location,
      };
    
      string latLon = String.Format("{0}, {1}", address.Location.X, address.Location.Y);
      string address1 = attributes["Address"].ToString();
      string address2 = String.Format("{0}, {1} {2}", attributes["City"], attributes["State"], attributes["Zip"]);
    
      graphic.Attributes.Add("LatLon", latLon);
      graphic.Attributes.Add("Address1", address1);
      graphic.Attributes.Add("Address2", address2);
    
      GraphicsLayer graphicsLayer = MyMap.Layers["LocationToAddressGraphicsLayer"] as GraphicsLayer;
      graphicsLayer.Graphics.Add(graphic);
    }
    

Handling execution errors

  1. Declare a handler for the Address Locator task's Failed event. This handler will be invoked if there is a problem with executing a geocoding or reverse geocoding operation.
    private void LocatorTask_Failed(object sender, TaskFailedEventArgs e)
    {
    }
    
  2. Notify the user of the problem with a MessageBox.
    private void LocatorTask_Failed(object sender, TaskFailedEventArgs e)
    {
      MessageBox.Show("Locator service failed: " + e.Error);
    }
    
1/23/2012