Address Locator task

The Address Locator task allows you to perform geocoding and reverse geocoding operations. Geocoding takes an address and returns the geographic location of that address. In reverse geocoding, a geographic location is provide and an address that matches it is returned. Once the location or address is returned, you can use .NET code to display the information in your application. To use an Address Locator task, you will need to include code to define its user interface and specify its execution logic.

Samples of Address Locator task applications, including both geocoding and reverse geocoding, are available in the Address Matching section of the Interactive SDK.

Creating an Address Locator task

The following sections of this topic walk you through building an example of XAML and .NET code (in this case C#) for a simple Windows Phone application that includes an Address Locator task. It includes the following steps:

  1. Creating an input interface for the Address Locator task
  2. Creating an output interface for the Address Locator task
  3. Implementing the Address Locator task's execution logic, including:

This application defines an Address Locator task that uses a set of TextBox controls to specify input and a button for geocoding, or a click on the map for reverse geocoding. The resulting geocoding feature is displayed in a GraphicsLayer, while the address determined by reverse geocoding is displayed in the TextBoxes.

The following sections assume you have created a Windows Phone application with a map as a base layer as described in Creating a map. The XAML view of your application's ContentGrid in MainPage.xaml should look like the following code:

<Grid x:Name="ContentGrid" Grid.Row="1">
    <esri:Map x:Name="MyMap" Extent="-120, 20, -100, 40">
        <esri:Map.Layers>
            <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer"
                Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer">
            </esri:ArcGISTiledMapServiceLayer>
        </esri:Map.Layers>
    </esri:Map>
</Grid>

NoteNote:

In the example code below, the extent of the Map was changed to "-117.20, 34.04, -117.18, 34.06" in order to display Redlands, CA at the street level.

The code in your code-behind file, MainPage.xaml.cs, should be unchanged from when you created your Windows Phone project in Visual Studio.

Creating an input interface for the Address Locator task

Tasks do not define user interfaces, so it's up to you as a developer to implement an interface for the Address Locator's input. For geocoding input, you will define a TextBlock for instructions, TextBoxes for the address information, and a Button to start the operation. For reverse geocoding, you will specify a TextBlock for instructions and a handler for the Map's MapGesture 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 x:Name="InfoPanel" 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 will implement this handler so that it processes the user input and starts the geocoding operation.
    <StackPanel x:Name="InfoPanel" 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="380 New York St." Width="325"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
                    <TextBlock Text="City: " Foreground="White" />
                    <TextBox x:Name="City" Text="Redlands" Width="325" />
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
                    <TextBlock Text="State: " Foreground="White" />
                    <TextBox x:Name="State" Text="CA" Width="325"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
                    <TextBlock Text="Zip: " Foreground="White" />    
                    <TextBox x:Name="Zip" Text="92373" Width="325" />
                </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 x:Name="InfoPanel" 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="380 New York St." Width="325"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
                    <TextBlock Text="City: " Foreground="White" />
                    <TextBox x:Name="City" Text="Redlands" Width="325" />
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
                    <TextBlock Text="State: " Foreground="White" />
                    <TextBox x:Name="State" Text="CA" Width="325"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
                    <TextBlock Text="Zip: " Foreground="White" />    
                    <TextBox x:Name="Zip" Text="92373" Width="325" />
                </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="280" 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. Since the input interface takes up a larger amount of the screen, add an application bar icon that shows and hides the input interface. Replace the sample ApplicationBar XAML with the following code:
    <phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
            <shell:ApplicationBarIconButton IconUri="list.png" Text="Info view"/>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>
    
    NoteNote:

    You will need to add the icon's image file to your project. You will also need to set the icon image's Build Action property to Content.

  5. Add a click event handler for the ApplicationBar icon.
    <shell:ApplicationBarIconButton IconUri="list.png" Text="Info view"
        Click="ApplicationBarIconButton_Click"/>
    
  6. Implement the click event for the ApplicationBar's icon button in the code-behind, showing and hiding the address information panel, InfoPanel.
    private void ApplicationBarIconButton_Click(object sender, EventArgs e)
    {
        if (InfoPanel.Visibility == System.Windows.Visibility.Collapsed)
            InfoPanel.Visibility = System.Windows.Visibility.Visible;
        else
            InfoPanel.Visibility = System.Windows.Visibility.Collapsed;
    }
    
  7. Specify instructions for showing and hiding the InfoPanel. Add a separator line below the reverse geocoding instructions, along with a TextBlock containing the instructions for the InfoPanel.
    <StackPanel x:Name="InfoPanel" 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="380 New York St." Width="325"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
                    <TextBlock Text="City: " Foreground="White" />
                    <TextBox x:Name="City" Text="Redlands" Width="325" />
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
                    <TextBlock Text="State: " Foreground="White" />
                    <TextBox x:Name="State" Text="CA" Width="325"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
                    <TextBlock Text="Zip: " Foreground="White" />    
                    <TextBox x:Name="Zip" Text="92373" Width="325" />
                </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="280" 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" />
                <Line HorizontalAlignment="Center" X1="0" Y1="10" X2="280" Y2="10" 
                      StrokeThickness="1" Stroke="White" />
                <TextBlock Text="Use the app bar to show or hide this panel." 
                           FontStyle="Italic" HorizontalAlignment="Center" 
                           Foreground="White" Margin="0,10,0,0" />
            </StackPanel>
        </Grid>
    </StackPanel>
    
  8. On the Map control, specify a handler for the MapGesture event. You will implement this handler later so that it uses the tap and hold point to initiate a reverse geocoding operation.
    <esri:Map x:Name="MyMap" Extent="-117.20, 34.04, -117.18, 34.06" 
              MapGesture="MyMap_MapGesture"
    

Creating an output interface for the Address Locator task

To display a task's results, you need to specify an output interface. For geocoding, the location of the address will be displayed on the map as a blue circle using a GraphicsLayer and a SimpleMarkerSymbol. For reverse geocoding, the matching address will be displayed in the TextBoxes that were used for input.

Often you will want to also display information about the result. For simplicity in this code, that is not shown here.

  1. Add a reference to the System.Runtime.Serialization assembly to your project.
  2. Add an XML namespaces to the phone:PhoneApplicationPage element to map to the ESRI.ArcGIS.Client.Symbols namespaces in the ESRI.ArcGIS.Client assembly.
    xmlns:esriSymbols="clr-namespace:ESRI.ArcGIS.Client.Symbols;assembly=ESRI.ArcGIS.Client"
    
  3. Add a SimpleMarkerSymbol as a resource by adding it to the LayoutRoot grid of your application. The symbol specified here is semi-transparent with a red fill and outline. Later, you will apply this symbol to the task's results in the page's code-behind.
    <Grid.Resources>
        <esriSymbols:SimpleMarkerSymbol x:Key="ResultsSymbol" Size="15" Color="Blue" />
    </Grid.Resources>
    
  4. Add a GraphicsLayer to the Map control XAML element. Make sure it is placed below the map service layer in the XAML so that it is drawn above the map service layer at run time. For further information, see Adding layers.
    <esri:Map x:Name="MyMap" Extent="-117.20, 34.04, -117.18, 34.06" 
              MapGesture="MyMap_MapGesture">
        <esri:Map.Layers>
            <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer"
                Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer">
            </esri:ArcGISTiledMapServiceLayer>
        <esri:GraphicsLayer ID="MyGraphicsLayer" >
        </esri:GraphicsLayer>
        </esri:Map.Layers>
    </esri:Map>
    

Implementing the Address Locator task's execution logic

Now that you've specified the Address Locator task's user interface, you need to define its execution logic. The execution logic required for this Address Locator example can be divided into the following parts:

As previously mentioned, this task can perform both geocoding and reverse geocoding. In this section, you will implement the Find button's click event handler to initiate a geocoding operation by calling the task's AddressToLocationsAsync method. Then you will define a handler for the Map's MapGesture 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 code-behind file for your Windows Phone application's main page (ex. MainPage.xaml.cs). 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.

Initiate a geocoding operation

  1. In the code-behind class of your application's main page, implement a handler for the FindAddressButton's click event. Recall that you declared this handler when you defined the FindAddressButton control in the page's XAML.
    private void FindAddressButton_Click(object sender, RoutedEventArgs e)
    {
    }
    
  2. Add a using statement for the ESRI.ArcGIS.Client.Tasks namespace.
  3. 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");
    }
    
  4. Specify a handler for the task's AddressToLocationsCompleted event. The method specified will be called when the Address Locator task is has completed a geocode operation. You will implement this handler in the Handle 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;
    }
    
  5. 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 Handle 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;
    }
    
  6. 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();
    }
    
  7. Retrieve the address information from the input TextBoxes you specified in the page'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);
    }
    
  8. 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);
    }
    

Initiate a reverse geocoding operation

  1. In the code-behind class of your application's main page, implement a handler for the Map's MapGesture event, responding if the map is touched and held. Recall that you declared this handler when you specified the name of this handler on the Map element in the page's XAML.
    private void MyMap_MapGesture(object sender, ESRI.ArcGIS.Client.Map.MapGestureEventArgs e)
    {
        if (e.Gesture == ESRI.ArcGIS.Client.GestureType.Hold)
        {
        }
    }
    
  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_MapGesture(object sender, ESRI.ArcGIS.Client.Map.MapGestureEventArgs e)
    {
        if (e.Gesture == ESRI.ArcGIS.Client.GestureType.Hold)
        {
            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 Handle reverse geocoding results section.
    private void MyMap_MapGesture(object sender, ESRI.ArcGIS.Client.Map.MapGestureEventArgs e)
    {
        if (e.Gesture == ESRI.ArcGIS.Client.GestureType.Hold)
        {
            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 Handle execution errors section.
    private void MyMap_MapGesture(object sender, ESRI.ArcGIS.Client.Map.MapGestureEventArgs e)
    {
        if (e.Gesture == ESRI.ArcGIS.Client.GestureType.Hold)
        {
            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 held on the map. Specify a tolerance of twenty for the operation. This means that the task will search within twenty meters of the click point to find the nearest address.
    private void MyMap_MapGesture(object sender, ESRI.ArcGIS.Client.Map.MapGestureEventArgs e)
    {
        if (e.Gesture == ESRI.ArcGIS.Client.GestureType.Hold)
        {
            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);
        }
    }
    

Handle 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. Add using statements for the ESRI.ArcGIS.Client and ESRI.ArcGIS.Client.Symbols namespaces.
  5. Create a Graphic to display the best match on the Map. Initialize it with the result's location and the results symbol you defined in the page'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["ResultsSymbol"] as Symbol,
                Geometry = bestCandidate.Location
            };
        }
        else
        {
        }
    }
    
  6. 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["ResultsSymbol"] as Symbol,
                Geometry = bestCandidate.Location
            };
    
            GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
            graphicsLayer.ClearGraphics();
        }
        else
        {
        }
    }
    
  7. 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["ResultsSymbol"] as Symbol,
                Geometry = bestCandidate.Location
            };
    
            GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
            graphicsLayer.ClearGraphics();
            graphicsLayer.Graphics.Add(graphic);
        }
        else
        {
        }
    }
    
  8. Collapse the InfoPanel so the result is not covered on the screen, and pan to the result.
    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["ResultsSymbol"] as Symbol,
                Geometry = bestCandidate.Location
            };
    
            GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
            graphicsLayer.ClearGraphics();
            graphicsLayer.Graphics.Add(graphic);
    
            InfoPanel.Visibility = System.Windows.Visibility.Collapsed;
            MyMap.PanTo(bestCandidate.Location);
        }
        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["ResultsSymbol"] as Symbol,
                Geometry = bestCandidate.Location
            };
    
            GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
            graphicsLayer.ClearGraphics();
            graphicsLayer.Graphics.Add(graphic);
    
            InfoPanel.Visibility = System.Windows.Visibility.Collapsed;
            MyMap.PanTo(bestCandidate.Location);
        }
        else
        {
            MessageBox.Show("No results found");
        }
    }
    

Although not shown in the above code, it can be useful to provide to the user the address of the best match, as well as information about its latitude and longitude. The following code gives an example of setting the address and coordinates to attributes on the graphic, which could then be bound to an element for display:

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

Handle 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 result symbol you defined in the page'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["ResultsSymbol"] as Symbol,
            Geometry = address.Location,
        };
    }
    
  4. Add the address information of the result to the InfoPanel and make sure it is visible.
    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["ResultsSymbol"] as Symbol,
            Geometry = address.Location,
        };
    
        Address.Text = attributes["Address"].ToString();
        City.Text = attributes["City"].ToString();
        State.Text = attributes["State"].ToString();
        Zip.Text = attributes["Zip"].ToString();
        InfoPanel.Visibility = System.Windows.Visibility.Visible;
    }
    
  5. Retrieve the reverse geocoding results GraphicsLayer, clear it, 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["ResultsSymbol"] as Symbol,
            Geometry = address.Location,
        };
    
        Address.Text = attributes["Address"].ToString();
        City.Text = attributes["City"].ToString();
        State.Text = attributes["State"].ToString();
        Zip.Text = attributes["Zip"].ToString();
        InfoPanel.Visibility = System.Windows.Visibility.Visible;
    
        GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
        graphicsLayer.ClearGraphics();
        graphicsLayer.Graphics.Add(graphic);
    }
    

Handle 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);
    }
    

12/1/2010