dot
Address locator task

The Address Locator task allows you to perform geocoding and reverse geocoding operations. With the Address Locator, you can either find the geographic location of an address or the address of a geographic location. When you use the Address Locator task, your Silverlight application must contain four parts:

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

The code for a sample Silverlight application that uses the Address Locator task to enable both geocoding and reverse geocoding is shown below. To enable geocoding, the code defines TextBoxes 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 will walk you through the sample, paying particular attention to how the task is used.

[XAML]

<UserControl x:Class="SilverlightApp.Page"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
	xmlns:esri="clr-namespace:ESRI.ArcGIS.Client;assembly=ESRI.ArcGIS.Client"
	xmlns:esriConverters="clr-namespace:ESRI.ArcGIS.Client.ValueConverters;assembly=ESRI.ArcGIS.Client"
	xmlns:esriSymbols="clr-namespace:ESRI.ArcGIS.Client.Symbols;assembly=ESRI.ArcGIS.Client">

	<Grid x:Name="LayoutRoot" Background="White" >

		<!-- LOCATOR TASK RESOURCES -->
		<Grid.Resources>
			<esriConverters:DictionaryConverter x:Name="MyDictionaryConverter" />
			<esriSymbols:PictureMarkerSymbol x:Name="AddressToLocationSymbol" OffsetX="0" OffsetY="31" 
											 Source="/Assets/images/flag-yellow-32x32.png" />
			<esriSymbols:PictureMarkerSymbol x:Name="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 Converter={StaticResource MyDictionaryConverter}, 
                                        ConverterParameter=Address, Mode=OneWay}" HorizontalAlignment="Left" />
								<TextBlock Text="{Binding Converter={StaticResource MyDictionaryConverter}, 
                                        ConverterParameter=LatLon, Mode=OneWay}" 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 Converter={StaticResource MyDictionaryConverter}, 
									ConverterParameter=Address1, Mode=OneWay}" />
								<TextBlock Text="{Binding Converter={StaticResource MyDictionaryConverter}, 
									ConverterParameter=Address2, Mode=OneWay}" />
								<TextBlock Text="{Binding Converter={StaticResource MyDictionaryConverter}, 
									ConverterParameter=LatLon, Mode=OneWay}" />
							</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>
</UserControl>

[C#]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Tasks;
using ESRI.ArcGIS.Client.Symbols;
using ESRI.ArcGIS.Client.Geometry;

namespace SilverlightApp
{
	public partial class Page : UserControl
	{
		public Page() { InitializeComponent(); }

		// Find location of address when Find button is clicked
		private void FindAddressButton_Click(object sender, RoutedEventArgs e)
		{
			// Initialize 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 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 address
			locatorTask.AddressToLocationsAsync(addressParameters);
		}

		// When address has been located, show 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 = AddressToLocationSymbol,
					Geometry = bestCandidate.Location
				};

				// Add address and coordinates to 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 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 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 address within 20 meters of clicked point
			locatorTask.LocationToAddressAsync(e.MapPoint, tolerance);
		}

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

			// Create graphic at click point
			Graphic graphic = new Graphic()
			{
				Symbol = LocationToAddressSymbol,
				Geometry = address.Location,
			};

			// Add address and coordinates at click point to 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 graphic by adding it to a graphics layer
			GraphicsLayer graphicsLayer = MyMap.Layers["LocationToAddressGraphicsLayer"] as GraphicsLayer;
			graphicsLayer.Graphics.Add(graphic);
		}

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

Using an Address Locator task

The following steps assume you have created a Silverlight application with a map and a base layer as described in Creating a Map and that you are already familiar with creating simple Silverlight 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 page (e.g. Page.xaml) should look similar to the following:

<UserControl x:Class="SilverlightApp.Page"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
	xmlns:esri="clr-namespace:ESRI.ArcGIS.Client;assembly=ESRI.ArcGIS.Client">

	<Grid x:Name="LayoutRoot" Background="White">

		<!-- 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>
</UserControl>

The code in the main page's code-behind (e.g. Page.xaml.cs) should be unchanged from when you created your Silverlight application project in Visual Studio.

Create the input interface

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 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.
  2. <StackPanel Margin="10" HorizontalAlignment="Left">
    	<Grid>
    		<Rectangle Fill="#CC5C90B2" Stroke="Gray"  RadiusX="10" RadiusY="10" />
    		<StackPanel Margin="10" HorizontalAlignment="Center" >
    		</StackPanel>
    	</Grid>
    </StackPanel>

  3. 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.
  4. <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>

  5. Specify instructions for reverse geocoding. Add a separator line below the geocoding interface and a TextBlock containing the instructions.
  6. <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>

  7. On the Map control, specify a handler for the MouseClick event. You will implement this handler later so that it uses the click point to initiate a reverse geocoding operation.
  8. <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 will use two GraphicsLayers and two a PictureMarkerSymbols - one layer/symbol pair for geocoding output and one for reverse geocoding output. Then you will specify MapTips on each GraphicsLayer for displaying non-geographic results data. The MapTips will use the DictionaryConverter class to enable binding to attributes on the Find task's results.

  1. Add two XML namespaces - one each to map to the ESRI.ArcGIS.Client.ValueConverters and ESRI.ArcGIS.Client.Symbols namespaces in the ESRI.ArcGIS.Client assembly.
  2. <UserControl x:Class="SilverlightApp.Page"
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    	xmlns:esri="clr-namespace:ESRI.ArcGIS.Client;assembly=ESRI.ArcGIS.Client"
    	xmlns:esriConverters="clr-namespace:ESRI.ArcGIS.Client.ValueConverters;assembly=ESRI.ArcGIS.Client"
    	xmlns:esriSymbols="clr-namespace:ESRI.ArcGIS.Client.Symbols;assembly=ESRI.ArcGIS.Client">

  3. Specify a DictionaryConverter and two PictureMarkerSymbols as resources in your Silverlight application. The DictionaryConverter allows you specify binding to a particular Dictionary key.
  4. The PictureMarkerSymbols will be used to show Address Locator output on the Map.

    <Grid.Resources>
    	<esriConverters:DictionaryConverter x:Name="MyDictionaryConverter" />
    	<esriSymbols:PictureMarkerSymbol x:Name="AddressToLocationSymbol" OffsetX="0" OffsetY="31" 
    									 Source="/Assets/images/flag-yellow-32x32.png" />
    	<esriSymbols:PictureMarkerSymbol x:Name="LocationToAddressSymbol" OffsetX="12" OffsetY="12" 
    									 Source="/Assets/images/x-24x24.png" />
    </Grid.Resources>

  5. Add two GraphicsLayers to the Map control XAML element - one each for geocoding and reverse geocoding results. Note that 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, refer to the Adding layers topic.
  6. <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>

  7. Within the element for the geocoding results (i.e. address to location) GraphicsLayer, specify a MapTip to display the non-geographic data of the results. Using the DictionaryConverter you declared above, bind the MapTip to attributes called Address and LatLon. You will explicitly add these attributes to the geocoding results in the page's code-behind. For further information on binding attributes to MapTips, refer to the Query task, Find task, and Identify task topics.
  8. <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 Converter={StaticResource MyDictionaryConverter}, 
                                    ConverterParameter=Address, Mode=OneWay}" HorizontalAlignment="Left" />
    						<TextBlock Text="{Binding Converter={StaticResource MyDictionaryConverter}, 
                                    ConverterParameter=LatLon, Mode=OneWay}" 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>

  9. On the reverse geocoding (i.e. location to address) results GraphicsLayer, specify a MapTip that will bind to attributes called Address1, Address2, and LatLon.
  10. <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 Converter={StaticResource MyDictionaryConverter}, 
                                    ConverterParameter=Address, Mode=OneWay}" HorizontalAlignment="Left" />
    						<TextBlock Text="{Binding Converter={StaticResource MyDictionaryConverter}, 
                                    ConverterParameter=LatLon, Mode=OneWay}" 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 Converter={StaticResource MyDictionaryConverter}, 
    							ConverterParameter=Address1, Mode=OneWay}" />
    						<TextBlock Text="{Binding Converter={StaticResource MyDictionaryConverter}, 
    							ConverterParameter=Address2, Mode=OneWay}" />
    						<TextBlock Text="{Binding Converter={StaticResource MyDictionaryConverter}, 
    							ConverterParameter=LatLon, Mode=OneWay}" />
    					</StackPanel>
    					<Border BorderBrush="Black" BorderThickness="1" />
    				</Grid>
    			</esri:GraphicsLayer.MapTip>
    		</esri:GraphicsLayer>
    	</esri:Map.Layers>
    </esri:Map>

Implement the task's execution logic

Now that you've specified the Address Locator task's user interface, you need to define its execution logic. 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 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 page'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 will show you how to do this in the code-behind of your application's main page (e.g. Page.xaml.cs). The task is declared and initialized in the code-behind because tasks alone do not define any user interface, but rather encapsulate pieces of execution logic. In Silverlight, XAML is reserved for an application's presentation layer, while the code-behind is where business logic is implemented.

The code shown in these steps is written in C#.

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.
  2. private void FindAddressButton_Click(object sender, RoutedEventArgs e)
    {
    }

  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.
  4. private void FindAddressButton_Click(object sender, RoutedEventArgs e)
    {
    	Locator locatorTask = new Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/" +
    		"Locators/ESRI_Geocode_USA/GeocodeServer");
    }

  5. 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.
  6. 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;
    }

  7. 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 execute errors" section.
  8. 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;
    }

  9. Declare and instantiate an AddressToLocationsParameters object. This object is used to define the execution parameters for geocoding operations.
  10. 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();
    }

  11. 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.
  12. 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);
    }

  13. Execute the geocoding operation with the specified address.
  14. 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 MouseClick event. Recall that you declared this handler when you specified the name of this handler on the Map element in the page's XAML.
  2. private void MyMap_MouseClick(object sender, Map.MouseEventArgs e)
    {
    }

  3. 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.
  4. 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");
    }

  5. 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.
  6. 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;
    }

  7. 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.
  8. 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;
    }

  9. Execute the reverse geocoding operation to find the address at the point clicked 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.
  10. 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);
    }

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.
  3. private void LocatorTask_AddressToLocationsCompleted(object sender, ESRI.ArcGIS.Client.Tasks.AddressToLocationsEventArgs args)
    {
    	if (args.Results.Count > 0)
    	{
    	}
    	else
    	{
    	}
    }
    

  4. If results were found, loop through them and store a reference to the one with the highest match score.
  5. 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
    	{
    	}
    }
    

  6. 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 page's XAML.
  7. 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 = AddressToLocationSymbol,
    			Geometry = bestCandidate.Location
    		};
    	}
    	else
    	{
    	}
    }
    

  8. 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.
  9. 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 = AddressToLocationSymbol,
    			Geometry = bestCandidate.Location
    		};
    
    		graphic.Attributes.Add("Address", bestCandidate.Address);
    	}
    	else
    	{
    		MessageBox.Show("No results found");
    	}
    }
    

  10. 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.
  11. 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 = AddressToLocationSymbol,
    			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
    	{
    	}
    }
    

  12. Retrieve the geocoding results GraphicsLayer and clear it of any previous results.
  13. 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 = AddressToLocationSymbol,
    			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
    	{
    	}
    }
    

  14. Add the new geocoding result to the GraphicsLayer so that it is shown on the Map.
  15. 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 = AddressToLocationSymbol,
    			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
    	{
    	}
    }
    

  16. If no features were found, notify the user with a MessageBox.
  17. 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 = AddressToLocationSymbol,
    			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");
    	}
    }
    

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.
  3. private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
    {
    	Address address = args.Address;
    	Dictionary<string, object> attributes = args.Address.Attributes;
    }

  4. Create a Graphic to display the address. Initialize it with the result's location and the reverse geocoding result symbol you defined in the page's XAML.
  5. private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
    {
    	Address address = args.Address;
    	Dictionary<string, object> attributes = args.Address.Attributes;
    
    	Graphic graphic = new Graphic()
    	{
    		Symbol = LocationToAddressSymbol,
    		Geometry = address.Location,
    	};
    }

  6. Get the coordinates and address of the result and format them for display on the Graphic's MapTip.
  7. private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
    {
    	Address address = args.Address;
    	Dictionary<string, object> attributes = args.Address.Attributes;
    
    	Graphic graphic = new Graphic()
    	{
    		Symbol = LocationToAddressSymbol,
    		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"]);
    }

  8. Add the coordinates and address of the result to the Graphic in attributes named LatLon, Address1, and Address2. Recall that, in the page's XAML, you specified attributes with these names to be bound to the MapTips of the reverse geocoding GraphicsLayer. So adding the address information to the Graphic with these attributes names will result in this information being displayed on the Graphic's MapTip.
  9. private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
    {
    	Address address = args.Address;
    	Dictionary<string, object> attributes = args.Address.Attributes;
    
    	Graphic graphic = new Graphic()
    	{
    		Symbol = LocationToAddressSymbol,
    		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);
    }

  10. Retrieve the reverse geocoding results GraphicsLayer and add the Graphic to it.
  11. private void LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
    {
    	Address address = args.Address;
    	Dictionary<string, object> attributes = args.Address.Attributes;
    
    	Graphic graphic = new Graphic()
    	{
    		Symbol = LocationToAddressSymbol,
    		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);
    }

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.
  2. private void LocatorTask_Failed(object sender, TaskFailedEventArgs e)
    {
    }

  3. Notify the user of the problem with a MessageBox
  4. private void LocatorTask_Failed(object sender, TaskFailedEventArgs e)
    {
    	MessageBox.Show("Locator service failed: " + e.Error);
    }