Geocode an Address

Download Samples Repository

Description

Demonstrates how to geocode an address using the OnlineLocatorTask.

"Desktop" "Store" "Phone" Available for Desktop, Store, Phone

Sample Code

<UserControl x:Class="ArcGISRuntime.Samples.Desktop.GeocodeAddress"
             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/runtime/2013">
    <Grid x:Name="LayoutRoot">
        <Grid.Resources>
            <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
        </Grid.Resources>
        
        <esri:MapView x:Name="MyMapView" WrapAround="True">
			<esri:Map InitialViewpoint="-122.554,37.615,-122.245,37.884,4326">
				<esri:ArcGISTiledMapServiceLayer 
                    ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />
			</esri:Map>
			<esri:MapView.GraphicsOverlays>
				<esri:GraphicsOverlay ID="AddressOverlay" />
			</esri:MapView.GraphicsOverlays>
		</esri:MapView>

		<Border Background="White" BorderBrush="Black" BorderThickness="1"
				 HorizontalAlignment="Right" VerticalAlignment="Top"
				 Margin="30" Padding="20">
			<Border.Effect>
				<DropShadowEffect />
			</Border.Effect>
			<Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>

                <StackPanel Grid.Row="0">
                    <TextBlock Text="Enter Address Information" FontWeight="Bold" HorizontalAlignment="Center"/>
                    
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,10">
                        <RadioButton x:Name="btnSingleLine" Content="Single Line Input" Margin="0,0,20,0" IsChecked="True" Checked="btnMultipleLine_Checked" />
                        <RadioButton x:Name="btnMultipleLine" Content="Multiple Line Input" Checked="btnMultipleLine_Checked" />
                    </StackPanel>

                    <Grid Visibility="{Binding ElementName=btnSingleLine, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        
                        <TextBlock Grid.Column="0" Text="Address:" Margin="0,0,10,0" />
                        <TextBox x:Name="txtSingleLine" Grid.Column="1" Text="400 Market Street, San Francisco, CA 94111" />
                    </Grid>

                    <Grid Visibility="{Binding ElementName=btnMultipleLine, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}">
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>

                        <TextBlock Grid.Row="0" Grid.Column="0" Text="Address: " TextAlignment="Right" Margin="3" />
                        <TextBox x:Name="InputAddress" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch" Text="2920 Zoo Dr" Margin="3" />
                        <TextBlock Grid.Row="1" Grid.Column="0" Text="City: " TextAlignment="Right" Margin="3" />
                        <TextBox x:Name="City" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch" Text="San Diego" Margin="3" />
                        <TextBlock Grid.Row="2" Grid.Column="0" Text="State: " Margin="3" TextAlignment="Right" />
                        <TextBox x:Name="State" Grid.Row="2" Grid.Column="1" Text="CA" Margin="3" />
                        <TextBlock Grid.Row="3" Grid.Column="0" Text="Zip: " TextAlignment="Right" Margin="3" />
                        <TextBox x:Name="Zip" Grid.Row="3" Grid.Column="1" Text="92101" Margin="3" />
                    </Grid>

                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,12,0,0">
                        <TextBlock Text="Match Score:" VerticalAlignment="Center" Margin="0,-5,10,0" />
                        <Slider x:Name="MatchScoreSlider" Width="125" Minimum="0" Maximum="100" Value="100" 
                                IsSnapToTickEnabled="True" AutoToolTipPlacement="BottomRight" AutoToolTipPrecision="0" 
                                TickPlacement="BottomRight" Ticks="0, 50, 75, 90, 100"
                                ValueChanged="MatchScoreSlider_ValueChanged" />
                    </StackPanel>

                    <Button Content="Geocode Address" IsDefault="True" Click="GeocodeButton_Click" Margin="0,10,0,0" Padding="5"/>
                </StackPanel>

                <ProgressBar x:Name="progress" Grid.Row="1" IsIndeterminate="True" Visibility="Collapsed" Margin="12" />

                <ListView x:Name="listResults" Grid.Row="2" Margin="0,12,0,0" Visibility="Collapsed">
                    <ListView.ItemContainerStyle>
                        <Style TargetType="ListViewItem">
                            <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
                            <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
                            <Setter Property="Visibility" Value="{Binding Path=IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}" />
                        </Style>
                    </ListView.ItemContainerStyle>

                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="250" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>

                                <StackPanel Grid.Column="0">
                                    <StackPanel Margin="4">
                                        <TextBlock Text="{Binding Attributes[Address]}" FontWeight="Bold" TextWrapping="Wrap" />

                                        <TextBlock>
                                            <Run Text="Location: " />
                                            <Run Text="{Binding Attributes[LocationDisplay]}" />
                                        </TextBlock>

                                        <TextBlock>
                                            <Run Text="Match Type: " />
                                            <Run Text="{Binding Attributes[MatchType]}" />
                                        </TextBlock>
                                    </StackPanel>
                                </StackPanel>

                                <StackPanel Grid.Column="1" VerticalAlignment="Center">
                                    <TextBlock Text="Score" />
                                    <TextBlock Text="{Binding Attributes[Score]}" FontSize="18" TextAlignment="Center" />
                                </StackPanel>
                            </Grid>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </Grid>
        </Border>
    </Grid>
</UserControl>
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Layers;
using Esri.ArcGISRuntime.Symbology;
using Esri.ArcGISRuntime.Tasks.Geocoding;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;

namespace ArcGISRuntime.Samples.Desktop
{
	/// <summary>
	/// Demonstrates how to geocode an address using the OnlineLocatorTask.
	/// </summary>
	/// <title>Geocode an Address</title>
	/// <category>Tasks</category>
	/// <subcategory>Geocoding</subcategory>
	public partial class GeocodeAddress : UserControl
	{
		private const string OnlineLocatorUrl = "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer";

		private GraphicsOverlay _addressOverlay;
		private LocatorServiceInfo _locatorServiceInfo;
		private OnlineLocatorTask _locatorTask;

		public GeocodeAddress()
		{
			InitializeComponent();

			_addressOverlay = MyMapView.GraphicsOverlays["AddressOverlay"];
			_locatorTask = new OnlineLocatorTask(new Uri(OnlineLocatorUrl));
			_locatorTask.AutoNormalize = true;

			SetSimpleRendererSymbols();
		}

		// Setup the pin graphic and graphics overlay renderer
		private async void SetSimpleRendererSymbols()
		{
			try
			{
				var markerSymbol = new PictureMarkerSymbol() { Width = 48, Height = 48, YOffset = 24 };
				await markerSymbol.SetSourceAsync(new Uri("pack://application:,,,/ArcGISRuntimeSamplesDesktop;component/Assets/RedStickpin.png"));
				var renderer = new SimpleRenderer() { Symbol = markerSymbol };

				_addressOverlay.Renderer = renderer;
			}
			catch (Exception ex)
			{
				MessageBox.Show("Error occurred : " + ex.Message, "Find Place Sample");
			}
		}

		private async void GeocodeButton_Click(object sender, RoutedEventArgs e)
		{
			try
			{
				progress.Visibility = Visibility.Visible;
				listResults.Visibility = Visibility.Collapsed;
				_addressOverlay.Graphics.Clear();

				if (_locatorServiceInfo == null)
					_locatorServiceInfo = await _locatorTask.GetInfoAsync();

				var candidateResults = await _locatorTask.GeocodeAsync(
					GetInputAddressFromUI(), new List<string> { "Addr_type","Score","X","Y" }, MyMapView.SpatialReference, CancellationToken.None);

				if (candidateResults == null || candidateResults.Count == 0)
					throw new Exception("No candidates found.");

				foreach (var candidate in candidateResults)
					AddGraphicFromLocatorCandidate(candidate);

				var visibleGraphics = _addressOverlay.Graphics.Where(g => g.IsVisible);
				listResults.ItemsSource = visibleGraphics;
				listResults.Visibility = Visibility.Visible;

				var extent = GeometryEngine.Union(visibleGraphics.Select(g => g.Geometry)).Extent.Expand(1.2);
				await MyMapView.SetViewAsync(extent);
			}
			catch (AggregateException ex)
			{
				var innermostExceptions = ex.Flatten().InnerExceptions;
				if (innermostExceptions != null && innermostExceptions.Count > 0)
					MessageBox.Show(string.Join(" > ", innermostExceptions.Select(i => i.Message).ToArray()));
				else
					MessageBox.Show(ex.Message);
			}
			catch (System.Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
			finally
			{
				progress.Visibility = Visibility.Collapsed;
			}
		}

		private Dictionary<string, string> GetInputAddressFromUI()
		{
			Dictionary<string, string> address = new Dictionary<string, string>();

			if (btnSingleLine.IsChecked == true)
			{
				address[_locatorServiceInfo.SingleLineAddressField.FieldName] = txtSingleLine.Text;
			}
			else
			{
				if (!string.IsNullOrEmpty(InputAddress.Text))
				{
					string fieldName = "Address";
					address.Add(fieldName, InputAddress.Text);
				}
				if (!string.IsNullOrEmpty(City.Text))
				{
					string fieldName = "City";
					address.Add(fieldName, City.Text);
				}
				if (!string.IsNullOrEmpty(State.Text))
				{
					string fieldName = "Region";
					address.Add(fieldName, State.Text);
				}
				if (!string.IsNullOrEmpty(Zip.Text))
				{
					string fieldName = "Postal";
					address.Add(fieldName, Zip.Text);
				}
			}

			return address;
		}

		private void AddGraphicFromLocatorCandidate(LocatorGeocodeResult candidate)
		{
			var graphic = new Graphic(new MapPoint(candidate.Location.X, candidate.Location.Y, MyMapView.SpatialReference));
			graphic.Attributes["Address"] = candidate.Address;
			graphic.Attributes["Score"] = candidate.Score;
			graphic.Attributes["MatchType"] = candidate.Attributes["Addr_type"];

			double x = 0.0, y = 0.0;
			double.TryParse(candidate.Attributes["X"], out x);
			double.TryParse(candidate.Attributes["Y"], out y);
			graphic.Attributes["LocationDisplay"] = string.Format("{0:0.000}, {1:0.000}", x, y);

			graphic.IsVisible = (candidate.Score >= MatchScoreSlider.Value);
			_addressOverlay.Graphics.Add(graphic);
		}

		private void btnMultipleLine_Checked(object sender, RoutedEventArgs e)
		{
			if (listResults != null)
				listResults.Visibility = Visibility.Collapsed;
		}

		private void MatchScoreSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			if (_addressOverlay == null)
				return;

			foreach (var graphic in _addressOverlay.Graphics)
			{
				graphic.IsVisible = (Convert.ToInt32(graphic.Attributes["Score"]) >= e.NewValue);
			}

			listResults.ItemsSource = _addressOverlay.Graphics.Where(g => g.IsVisible);
		}
	}
}
Feedback on this topic?