This sample demonstrates how to search for places using the World Geocoding Service.
The World Geocoding Service (http://geocode.arcgis.com) supports single field input, multiple field inputs, batch, and reverse geocoding. The service provides access to a comprehensive worldwide database of places, including landmarks, points of interest, and businesses. This sample illustrates how to search for places from a specific location and rank results based on distance from that location. Use the search textbox to enter any valid place and navigate the map to change the location from which the service will prioritize and rank results. Results are displayed on the Map and in a FeatureDataGrid.
using System.Windows;
using System.Windows.Controls;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Tasks;
using System.Collections.Generic;
using ESRI.ArcGIS.Client.Projection;
using ESRI.ArcGIS.Client.Geometry;
using System.ComponentModel;
namespace ArcGISWPFSDK
{
publicpartialclass WorldGeocoding : UserControl, INotifyPropertyChanged
{
publicevent PropertyChangedEventHandler PropertyChanged;
privatebool _isBusy = true;
publicbool IsBusy
{
get
{
return _isBusy;
}
set
{
_isBusy = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsBusy"));
}
}
}
Locator _locatorTask;
GraphicsLayer SearchOriginGraphicsLayer;
GraphicsLayer FindResultLocationsGraphicsLayer;
WebMercator webmercator;
public WorldGeocoding()
{
InitializeComponent();
DataContext = this;
webmercator = new WebMercator();
// Initialize Locator with ArcGIS Online World Geocoding Service. See http://geocode.arcgis.com for details and doc.
_locatorTask = new Locator("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer");
_locatorTask.FindCompleted += (s, a) =>
{
// When a Find operation is initiated, get the find results and add to a graphics layer for display in the map
LocatorFindResult locatorFindResult = a.Result;
if (locatorFindResult.Locations.Count == 0)
{
MessageBox.Show("No locations found, please try again");
}
foreach (Location location in locatorFindResult.Locations)
{
FindResultLocationsGraphicsLayer.Graphics.Add(location.Graphic);
}
IsBusy = false;
SearchButton.IsEnabled = true;
};
_locatorTask.Failed += (s, e) =>
{
IsBusy = false;
SearchButton.IsEnabled = true;
MessageBox.Show("Locator service failed: " + e.Error);
};
FindResultLocationsGraphicsLayer = MyMap.Layers["FindResultLocationsGraphicsLayer"] as GraphicsLayer;
SearchOriginGraphicsLayer = MyMap.Layers["SearchOriginGraphicsLayer"] as GraphicsLayer;
IsBusy = false;
}
privatevoid FindButton_Click(object sender, RoutedEventArgs e)
{
IsBusy = true;
SearchButton.IsEnabled = false;
FindResultLocationsGraphicsLayer.Graphics.Clear();
SearchOriginGraphicsLayer.Graphics.Clear();
// If locator already processing a request, cancel it. Note, the request is not cancelled on the server. if (_locatorTask.IsBusy)
_locatorTask.CancelAsync();
// If search text is empty, returnif (string.IsNullOrEmpty(SearchTextBox.Text))
return;
MapPoint mapCenter = MyMap.Extent.GetCenter();
Envelope mapExtent = MyMap.Extent;
// Search will return results based on a start location. In this sample, the location is the center of the map. // Add a graphic when a search is initiated to determine what location was used to search from and rank results.
SearchOriginGraphicsLayer.Graphics.Add(new Graphic()
{
Geometry = mapCenter,
});
MapPoint wgs84MapCenter = webmercator.ToGeographic(mapCenter) as MapPoint;
Envelope wgs84MapExtent = webmercator.ToGeographic(mapExtent) as Envelope;
// In this sample, the center of the map is used as the location from which results will be ranked and distance calculated. // The distance from the location is optional. Specifies the radius of an area around a point location which is used to boost// the rank of geocoding candidates so that candidates closest to the location are returned first. The distance value is in meters.
LocatorFindParameters locatorFindParams = new LocatorFindParameters()
{
Text = SearchTextBox.Text,
Location = wgs84MapCenter,
Distance = mapExtent.Width / 2,
SearchExtent = wgs84MapExtent,
MaxLocations = 5,
OutSpatialReference = MyMap.SpatialReference
};
locatorFindParams.OutFields.AddRange(newstring[] { "PlaceName", "City", "Region", "Country", "Score", "Distance", "Type" });
_locatorTask.FindAsync(locatorFindParams);
}
privatevoid GraphicsLayer_MouseLeftButtonDown(object sender, GraphicMouseButtonEventArgs e)
{
e.Graphic.Selected = !e.Graphic.Selected;
}
privatevoid Cancel_Click(object sender, RoutedEventArgs e)
{
if (_locatorTask.IsBusy)
_locatorTask.CancelAsync();
SearchButton.IsEnabled = true;
IsBusy = false;
}
}
}
Imports System.Windows.Controls
Imports ESRI.ArcGIS.Client
Imports ESRI.ArcGIS.Client.Tasks
Imports System.Windows
Imports System.ComponentModel
Namespace ArcGISWPFSDK
PartialPublicClass WorldGeocoding
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 _locatorTask As Locator
Private SearchOriginGraphicsLayer As GraphicsLayer
Private FindResultLocationsGraphicsLayer As GraphicsLayer
PublicSubNew()
InitializeComponent()
' Initialize Locator with ArcGIS Online World Geocoding Service. See http://geocode.arcgis.com for details and doc.
_locatorTask = New Locator("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer")
AddHandler _locatorTask.FindCompleted, Sub(s, a)
' When a Find operation is initiated, get the find results and add to a graphics layer for display in the mapDim locatorFindResult As LocatorFindResult = a.Result
ForEach location As Location In locatorFindResult.Locations
FindResultLocationsGraphicsLayer.Graphics.Add(location.Graphic)
Next location
EndSubAddHandler _locatorTask.Failed, Sub(s, e) MessageBox.Show("Locator service failed: " & e.Error.ToString())
FindResultLocationsGraphicsLayer = TryCast(MyMap.Layers("FindResultLocationsGraphicsLayer"), GraphicsLayer)
SearchOriginGraphicsLayer = TryCast(MyMap.Layers("SearchOriginGraphicsLayer"), GraphicsLayer)
EndSubPrivateSub FindButton_Click(ByVal sender AsObject, ByVal e As RoutedEventArgs)
FindResultLocationsGraphicsLayer.Graphics.Clear()
SearchOriginGraphicsLayer.Graphics.Clear()
' If locator already processing a request, cancel it. Note, the request is not cancelled on the server. If _locatorTask.IsBusy Then
_locatorTask.CancelAsync()
EndIf' If search text is empty, returnIfString.IsNullOrEmpty(SearchTextBox.Text) ThenReturnEndIf' Search will return results based on a start location. In this sample, the location is the center of the map. ' Add a graphic when a search is initiated to determine what location was used to search from and rank results.
SearchOriginGraphicsLayer.Graphics.Add(New Graphic() With {.Geometry = MyMap.Extent.GetCenter()})
' In this sample, the center of the map is used as the location from which results will be ranked and distance calculated. ' The distance from the location is optional. Specifies the radius of an area around a point location which is used to boost' the rank of geocoding candidates so that candidates closest to the location are returned first. The distance value is in meters. Dim locatorFindParams AsNew LocatorFindParameters() With {.Text = SearchTextBox.Text, .Location = MyMap.Extent.GetCenter(), .Distance = MyMap.Extent.Width \ 2, .MaxLocations = 5, .OutSpatialReference = MyMap.SpatialReference}
locatorFindParams.OutFields.AddRange(NewString() {"PlaceName", "City", "Region", "Country", "Score", "Distance", "Type"})
_locatorTask.FindAsync(locatorFindParams)
EndSubPrivateSub GraphicsLayer_MouseLeftButtonDown(ByVal sender AsObject, ByVal e As GraphicMouseButtonEventArgs)
e.Graphic.Selected = Not e.Graphic.Selected
EndSubPrivateSub Cancel_Click(ByVal sender AsObject, ByVal e As RoutedEventArgs)
If (_locatorTask.IsBusy) Then
_locatorTask.CancelAsync()
SearchButton.IsEnabled = True
IsBusy = FalseEndIfEndSubEndClassEndNamespace