This sample demonstrates using the ArcGIS Runtime SDK for WPF to reverse-geocoding points using a LocalGeocodeService and a Locator. To use the sample, simply click on or near a street in the map. When a result is found, it will be drawn on the map with the returned address in the graphic's MapTip.
In the code-behind, a LocalGeocodeService is started and the Url is used to create a Locator to perform an address lookup operation for the clicked point. When a result is returned, a graphic is added to the map, and the address is added to the graphic's attributes such that it shows up in the graphic's MapTip.
The
supported source for a LocalGeocodeService is an ArcGIS Locator Package (. gcpk
), which can be authored in ArcGIS for Desktop.
<UserControlx:Class="ArcGISWPFSDK.LocalReverseGeocode"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:esri="http://schemas.esri.com/arcgis/client/2009"mc:Ignorable="d"d:DesignHeight="300"d:DesignWidth="300"><GridName="LayoutRoot"><Grid.Resources><BooleanToVisibilityConverterx:Key="BooleanToVisibilityConverter"/><esri:MarkerSymbolx:Key="StrobeMarkerSymbol"><esri:MarkerSymbol.ControlTemplate><ControlTemplate><Canvas><VisualStateManager.VisualStateGroups><VisualStateGroupx:Name="CommonStates"><VisualStatex:Name="Normal"><StoryboardRepeatBehavior="Forever"><DoubleAnimationBeginTime="0"Storyboard.TargetName="ellipse"Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"From="1"To="10"Duration="00:00:02"/><DoubleAnimationBeginTime="0"Storyboard.TargetName="ellipse"Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"From="1"To="10"Duration="00:00:02"/><DoubleAnimationBeginTime="0"Storyboard.TargetName="ellipse"Storyboard.TargetProperty="(UIElement.Opacity)"From="1"To="0"Duration="00:00:01"/></Storyboard></VisualState></VisualStateGroup></VisualStateManager.VisualStateGroups><EllipseHeight="10"Width="10"Canvas.Left="-5"Canvas.Top="-5"RenderTransformOrigin="0.5,0.5"x:Name="ellipse"IsHitTestVisible="False"><Ellipse.RenderTransform><ScaleTransform/></Ellipse.RenderTransform><Ellipse.Fill><RadialGradientBrush><GradientStopColor="#00FF0000"/><GradientStopColor="#FFFF0000"Offset="0.25"/><GradientStopColor="#00FF0000"Offset="0.5"/><GradientStopColor="#FFFF0000"Offset="0.75"/><GradientStopColor="#00FF0000"Offset="1"/></RadialGradientBrush></Ellipse.Fill></Ellipse><EllipseHeight="10"Width="10"Canvas.Left="-5"Canvas.Top="-5"Fill="#FFFF0000"x:Name="ellipse1"/></Canvas></ControlTemplate></esri:MarkerSymbol.ControlTemplate></esri:MarkerSymbol><LinearGradientBrushx:Key="PanelGradient"EndPoint="0.5,1"StartPoint="0.5,0"><LinearGradientBrush.RelativeTransform><TransformGroup><ScaleTransformCenterY="0.5"CenterX="0.5"/><SkewTransformCenterY="0.5"CenterX="0.5"/><RotateTransformAngle="176"CenterY="0.5"CenterX="0.5"/><TranslateTransform/></TransformGroup></LinearGradientBrush.RelativeTransform><GradientStopColor="#FF145787"Offset="0.16"/><GradientStopColor="#FF3D7FAC"Offset="0.502"/><GradientStopColor="#FF88C5EF"Offset="0.984"/></LinearGradientBrush></Grid.Resources><esri:Mapx:Name="MyMap"Background="#FFE3E3E3"IsEnabled="False"MouseClick="MyMap_MouseClick"Extent="-122.519985221, 37.836494682 ,-122.302264539 , 37.698485944"><esri:ArcGISLocalTiledLayerPath="..\Data\TPKS\SanFrancisco.tpk"/><esri:GraphicsLayerID="MyGraphicsLayer"><esri:GraphicsLayer.MapTip><GridBackground="LightYellow"><StackPanelOrientation="Vertical"Margin="5"><TextBlockText="{Binding [Address1]}"HorizontalAlignment="Left"Foreground="Black"/><TextBlockText="{Binding [LatLon]}"HorizontalAlignment="Left"Foreground="Black"/></StackPanel><BorderBorderBrush="Black"BorderThickness="1"/></Grid></esri:GraphicsLayer.MapTip></esri:GraphicsLayer></esri:Map><GridHorizontalAlignment="Right"VerticalAlignment="Top"Margin="0,15,15,0"Width="350"><RectangleFill="{StaticResource PanelGradient}"Stroke="Gray"RadiusX="10"RadiusY="10"Margin="0,0,0,5"><Rectangle.Effect><DropShadowEffect/></Rectangle.Effect></Rectangle><RectangleFill="#FFFFFFFF"Stroke="DarkGray"RadiusX="5"RadiusY="5"Margin="10,10,10,15"/><TextBlockx:Name="InformationText"Text="Click on or near a street in the map to define a location. The address of the location will be displayed in a MapTip when the cursor hovers over the marker."HorizontalAlignment="Center"VerticalAlignment="Top"TextAlignment="Left"Margin="30,20,20,30"TextWrapping="Wrap"Foreground="Black"/></Grid><ProgressBarx:Name="MyProgressBar"IsIndeterminate="True"VerticalAlignment="Bottom"Width="200"Height="20"Margin="10"Visibility="{Binding Path=IsBusy, Converter={StaticResource BooleanToVisibilityConverter}}"></ProgressBar></Grid></UserControl>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Tasks;
using ESRI.ArcGIS.Client.Local;
using ESRI.ArcGIS.Client.Geometry;
using System.ComponentModel;
namespace ArcGISWPFSDK
{
publicpartialclass LocalReverseGeocode : UserControl , INotifyPropertyChanged
{
publicevent PropertyChangedEventHandler PropertyChanged;
privatebool _isBusy = true;
publicbool IsBusy
{
get
{
return _isBusy;
}
set
{
_isBusy = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsBusy"));
}
}
}
LocalGeocodeService _localGeocodeService;
Locator _locatorTask;
GraphicsLayer _locationGraphicsLayer;
public LocalReverseGeocode()
{
InitializeComponent();
_locationGraphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
LocalGeocodeService.GetServiceAsync("..\\Data\\Locators\\SanFrancisco\\SanFranciscoLocator.gcpk", "SanFranciscoLocator", (gs) =>
{
if (gs.Error != null)
{
MessageBox.Show(gs.Error.Message);
}
if (gs.Status == LocalServiceStatus.Running)
{
_localGeocodeService = gs;
MyMap.IsEnabled = true;
DataContext = this;
IsBusy = false;
}
});
}
privatevoid MyMap_MouseClick(object sender, ESRI.ArcGIS.Client.Map.MouseEventArgs e)
{
IsBusy = true;
_locatorTask = new Locator(_localGeocodeService.UrlGeocodeService);
_locatorTask.LocationToAddressCompleted += LocatorTask_LocationToAddressCompleted;
_locatorTask.Failed += LocatorTask_Failed;
double tolerance = 50;
MapPoint geographicPoint = new MapPoint(e.MapPoint.X, e.MapPoint.Y, new SpatialReference(4326));
_locatorTask.LocationToAddressAsync(geographicPoint, tolerance);
}
privatevoid LocatorTask_LocationToAddressCompleted(object sender, AddressEventArgs args)
{
Address address = args.Address;
Dictionary<string, object> attributes = address.Attributes;
Graphic graphic = new Graphic()
{
Geometry = address.Location,
Symbol = LayoutRoot.Resources["StrobeMarkerSymbol"] as ESRI.ArcGIS.Client.Symbols.MarkerSymbol
};
string latlon = String.Format("{0}, {1}", address.Location.X, address.Location.Y);
string address1 = String.Format("{0}, {1} {2}", attributes["Street"], attributes["State"], attributes["ZIP"]);
graphic.Attributes.Add("LatLon", latlon);
graphic.Attributes.Add("Address1", address1);
_locationGraphicsLayer.Graphics.Clear();
_locationGraphicsLayer.Graphics.Add(graphic);
IsBusy = false;
}
privatevoid LocatorTask_Failed(object sender, TaskFailedEventArgs e)
{
MessageBox.Show("Unable to determine an address. Try selecting a location closer to a street.");
IsBusy = false;
}
}
}
Imports System.Collections.Generic
Imports System.Windows
Imports System.Windows.Controls
Imports ESRI.ArcGIS.Client
Imports ESRI.ArcGIS.Client.Tasks
Imports ESRI.ArcGIS.Client.Local
Imports ESRI.ArcGIS.Client.Geometry
Imports System.ComponentModel
Namespace ArcGISWPFSDK
PartialPublicClass LocalReverseGeocode
Inherits UserControl
Implements INotifyPropertyChanged
PublicEvent PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private _isBusy AsBoolean = TruePublicProperty IsBusy() AsBooleanGetReturn _isBusy
EndGetSet(value AsBoolean)
_isBusy = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("IsBusy"))
EndSetEndPropertyPrivate _localGeocodeService As LocalGeocodeService
Private _locatorTask As Locator
Private _locationGraphicsLayer As GraphicsLayer
PublicSubNew()
InitializeComponent()
_locationGraphicsLayer = TryCast(MyMap.Layers("MyGraphicsLayer"), GraphicsLayer)
LocalGeocodeService.GetServiceAsync("..\Data\Locators\SanFrancisco\SanFranciscoLocator.gcpk", "SanFranciscoLocator", Function(gs)
If gs.[Error] IsNotNothingThen
MessageBox.Show(gs.[Error].Message)
EndIfIf gs.Status = LocalServiceStatus.Running Then
_localGeocodeService = gs
MyMap.IsEnabled = True
DataContext = Me
IsBusy = FalseEndIfEndFunction)
EndSubPrivateSub MyMap_MouseClick(sender AsObject, e As ESRI.ArcGIS.Client.Map.MouseEventArgs)
IsBusy = True
_locatorTask = New Locator(_localGeocodeService.UrlGeocodeService)
AddHandler _locatorTask.LocationToAddressCompleted, AddressOf LocatorTask_LocationToAddressCompleted
AddHandler _locatorTask.Failed, AddressOf LocatorTask_Failed
Dim tolerance AsDouble = 50
Dim geographicPoint AsNew MapPoint(e.MapPoint.X, e.MapPoint.Y, New SpatialReference(4326))
_locatorTask.LocationToAddressAsync(geographicPoint, tolerance)
EndSubPrivateSub LocatorTask_LocationToAddressCompleted(sender AsObject, args As AddressEventArgs)
Dim address As Address = args.Address
Dim attributes As Dictionary(Of String, Object) = address.Attributes
Dim graphic AsNew Graphic() With { _
.Geometry = address.Location, _
.Symbol = TryCast(LayoutRoot.Resources("StrobeMarkerSymbol"), ESRI.ArcGIS.Client.Symbols.MarkerSymbol) _
}
Dim latlon AsString = [String].Format("{0}, {1}", address.Location.X, address.Location.Y)
Dim address1 AsString = [String].Format("{0}, {1} {2}", attributes("Street"), attributes("State"), attributes("ZIP"))
graphic.Attributes.Add("LatLon", latlon)
graphic.Attributes.Add("Address1", address1)
_locationGraphicsLayer.Graphics.Clear()
_locationGraphicsLayer.Graphics.Add(graphic)
IsBusy = FalseEndSubPrivateSub LocatorTask_Failed(sender AsObject, e As TaskFailedEventArgs)
MessageBox.Show("Unable to determine an address. Try selecting a location closer to a street.")
IsBusy = FalseEndSubEndClassEndNamespace