Search for places and addresses

The process of transforming an address or place name to a geographical location on a map is known as geocoding. The opposite task, searching for the nearest address to a particular point on a map using geographic coordinates, is referred to as reverse geocoding. This topic describes how to perform geocoding and reverse geocoding from both local data and online services using the Locator class of the Java API.

Before getting started, you need access to one of the following data sources:

  • Online: a geocode service hosted by Esri, such as the World Geocoding Service, or a geocode service that you've created and shared.
  • Local: locator files for offline geocoding.

Geocode services are based on address locators. An address locator is the major component in the geocoding process and contains all the data necessary to match addresses and place names to locations (such as a latitude longitude pair) and vice-versa. Address locators can reside in an ArcGIS geodatabase or as files on disk. They rely on GIS datasets and other reference data to find addresses and locations. Each address locator uses an address style for parsing addresses and standardizing them into well-structured address components.

In general to perform geocoding or reverse-geocoding, complete the following steps:

  1. Create a Locator instance using either an online geocode service or local locator files that reside in storage on your device.
  2. Decide whether you want to perform geocoding (start from an address to get a coordinate) or reverse-geocoding (start from a map coordinate to get an address).
    • If you want to perform geocoding, find out if your locator expects a formatted address as input, or a single line of text.
  3. Decide whether you want to use a synchronous or asynchronous method for the task.
  4. Based on your choices above, call the appropriate method on the Locator instance.
  5. Process the results and display them to the user.

These steps are explained below.

Create a locator

To instantiate an online locator, you need to provide the URL to a geocode service REST endpoint, such as the World Geocoding Service. This URL is usually of the form http://<server:port>/<instance>/services/<service>/GeocodeServer. If the web service is secured, you also need to provide the credentials that can be used to access the service. The following code snippet creates an online locator using the World Geocoding Service REST endpoint:

Locator onlinelLocator = Locator.createOnlineLocator(
    "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer");

To instantiate a local locator, you need to provide the path of the *.loc file on disk. The following code creates a local locator from the path to the 'myLocator.loc' file (all locator files (*.lox, *.loc, *.plbs) must be present in the same directory as the .loc file):

Locator localLocator = Locator.createLocalLocator("c:/path/to/myLocator.loc");

Geocode an address or place name

You can geocode using two types of inputs, depending on what is supported by your local locator or by the online geocode service:

  • a single line of text (using the locator's find method);
  • address fields, in a map of field name to field value (using the locator's geocode method).

Geocode with a single line text input

If you're using a service that supports single line geocoding, you can provide a single line of text as the search string for a Locator's find method. For example, the single line search string could be an address such as “380 New York St, Redlands, CA 92373”, the name of a place such as “Seattle, Washington”, a point of interest such as “Disneyland Paris”. This text input does not get passed directly to the Locator instance, but rather to a LocatorFindParameters instance. The following code sample shows how to create such an instance using the search string and how to set some additional parameters:

LocatorFindParameters parameters = new LocatorFindParameters(
  "380 New York St, Redlands, CA"); // search string
// max results to return
parameters.setMaxLocations(15);
// set point location to search from
parameters.setLocation(myLocation, map.getSpatialReference());
// 2km search radius from location set above
parameters.setDistance(2000);
// output spatial reference should match the map's spatial reference
parameters.setOutSR(map.getSpatialReference());

Geocode with address fields

If you're using a service that requires input as a set of address fields and their values, you need to prepare a map of key-value pairs for input to the locator's geocode method. For example, the TA_Streets_US geocode service has the address fields: 'Street', 'City', 'State', and 'ZIP'. The following shows how to create a key-value map of address elements if your locator contains the address fields just mentioned:

Map<String, String> addressElements = new HashMap<String, String>(); 
addressElements.put("Street", "400 Market Street"); 
addressElements.put("City", "San Francisco"); 
addressElements.put("State", "CA"); 
addressElements.put("Zip", "94111");

Reverse-geocode a point coordinate

Reverse geocoding takes a location and provides the addresses within a given distance of that location. To perform reverse geocoding, use the locator's reverseGeocode method. At the minimum, you'll need to provide the geographic location as a point in map coordinates, and a search distance from that location. Here is a code sample preparing those parameters, where screen coordinates (from a mouse click) are converted to map coordinates using the JMap's toMapPoint method:

public void onMouseClicked(MouseEvent event) {
  // get clicked point, convert to map point
  Point location = jMap.toMapPoint(event.getX(), event.getY());
  double searchDistance = 50; // in metres
  // ... call the reverseGeocode method
}

Obtain results

Whether you want to perform geocoding using a single-line text input, geocoding using address fields, or reverse-geocoding, you have the choice of performing the task synchronously or asynchronously.

Synchronous execution

Here is an example of obtaining results of a geocode operation using LocatorFindParameters and Locator's find method:

// create parameters as above
LocatorFindParameters parameters = new LocatorFindParameters(
  "380 New York St, Redlands, CA");
...
// obtain the list of results using synchronous 'find' version
List<LocatorGeocodeResult> results = locator.find(parameters);

Asynchronous execution

Here is the corresponding example using the asynchronous overload of Locator's find method, and obtaining results through the callback:

// create parameters as above
LocatorFindParameters parameters = new LocatorFindParameters(
  "380 New York St, Redlands, CA");
...
// obtain results using 'find' asynchronous call to not freeze the UI
locator.find(parameters, new CallbackListener<List<LocatorGeocodeResult>>() {
  @Override
  public void onError(Throwable e) {
    // show / deal with error
    JOptionPane.showMessageDialog(contentPane.getParent(), e.getMessage());
  }
  @Override
  public void onCallback(List<LocatorGeocodeResult> results) {
    if (results != null) {
      // display the results, should be on UI thread via e.g. SwingUtilities.invokeLater
      displayResults(results);
    }
  }
});

Process and display the results

All that remains to do is to process the return value and display it to the user. If you performed a geocoding operation using find or geocode, a list of LocatorGeocodeResult objects is returned, and the result with the highest score (best match) will be the first item in the list. You will most likely want to display the resulting location on the map for the user to see. The following code sample shows how to retrieve the highest scored result from the result list and use it to create a graphic and display it in a graphics layer:

GraphicsLayer myGraphicsLayer = new GraphicsLayer(); 
jMap.getLayers().add(myGraphicsLayer);
...
LocatorGeocodeResult highestScoreResult = results.get(0);

// create a graphic at this location 
Graphic addressGraphic = new Graphic(highestScoreResult.getLocation(), pointSymbol, attributes, null); 
// show graphic in graphics layer
myGraphicsLayer.addGraphic(addressGraphic);

For a reverse geocoding operation, the reverseGeocode method returns a single LocatorReverseGeocodeResult. From this result object, you can obtain the details of the found address from the getAddressFields method and display the address to the user, either as an attribute of the graphic which you can display using a map tip or a pop-up window, or simply as a text label. The code sample below shows synchronous reverse geocoding, getting the address from the result object, and showing the address to the user in a JLabel that was previously created:

// get result, synchronously here
LocatorReverseGeocodeResult result = locator.reverseGeocode(location, distance);
Map<String, String> addressFields = result.getAddressFields();
String address = addressFields.values().toString();
addressLabel.setText("Address: " + address);

Sample code

To view sample applications related to geocoding, launch the ArcGIS Runtime SDK for Java sample viewer application that was installed with the SDK, and explore the interactive samples and their source code in the Search section.

Related topics