Learn how to find an address or place with a search bar and the geocoding service.
Geocoding is the process of converting address or place text into a location. The geocoding service can search for an address or a place and perform reverse geocoding.
In this tutorial, you use a search bar in the user interface to access the Geocoding service and search for addresses and places.
Prerequisites
Before starting this tutorial:
-
You need an ArcGIS Location Platform or ArcGIS Online account.
-
Confirm that your system meets the minimum system requirements.
-
An IDE for Java.
Steps
Get an access token
You need an access token to use the location services used in this tutorial.
-
Go to the Create an API key tutorial to obtain an access token using your ArcGIS Location Platform or ArcGIS Online account.
-
Ensure that the following privileges are enabled: Location services > Basemaps > Basemap styles service and Location services > Geocoding.
-
Copy the access token as it will be used in the next step.
To learn more about other ways to get an access token, go to Types of authentication.
Open a Java project with Gradle
-
To start this tutorial, complete the Display a map tutorial, or download and unzip the Display a map solution into a new folder.
-
Open the build.gradle file as a project in IntelliJ IDEA.
-
In IntelliJ IDEA's Project tool window, open src/main/java/com.example.app and double-click App.
-
In the
start()
method, set the API key property on theArcGISRuntimeEnvironment
with your access token. Replace YOUR_ACCESS_TOKEN with your copied access token. Be sure to surround your access token with double quotes as it is a string.App.javaUse dark colors for code blocks ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
Add import statements and variable declarations
Add import statements and variable declarations to reference the packages and classes required for this tutorial.
-
In IntelliJ IDEA's Project tool window, open src/main/java/com.example.app and double-click App.
-
Add the following imports above the existing imports:
App.javaUse dark colors for code blocks 34 35 36 37 38 39 40 41 42 43 44Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. import java.util.List; import java.util.concurrent.ExecutionException; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.paint.Color; import javafx.scene.control.Alert; import javafx.scene.control.TextField; import com.esri.arcgisruntime.concurrent.ListenableFuture; import com.esri.arcgisruntime.mapping.view.Graphic; import com.esri.arcgisruntime.mapping.view.GraphicsOverlay; import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol; import com.esri.arcgisruntime.symbology.TextSymbol; import com.esri.arcgisruntime.tasks.geocode.GeocodeParameters; import com.esri.arcgisruntime.tasks.geocode.GeocodeResult; import com.esri.arcgisruntime.tasks.geocode.LocatorTask; import com.esri.arcgisruntime.ArcGISRuntimeEnvironment; import com.esri.arcgisruntime.mapping.ArcGISMap; import com.esri.arcgisruntime.mapping.BasemapStyle; import com.esri.arcgisruntime.mapping.Viewpoint; import com.esri.arcgisruntime.mapping.view.MapView; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layout.StackPane; import javafx.stage.Stage;
-
Within the
App
class, add the following member variables to easily reference them from other parts of the application:App.javaUse dark colors for code blocks 46 47 48 49Add line. Add line. Add line. Add line. Add line. public class App extends Application { private MapView mapView; private GeocodeParameters geocodeParameters; private GraphicsOverlay graphicsOverlay; private LocatorTask locatorTask; private TextField searchBox;
Add a graphics overlay
A graphics overlay is a container for graphics. A graphic will be added later in this tutorial as a visual means to display the search result on the map.
-
In the
start()
method, create a newGraphicsOverlay
and add it to themap
.View App.javaUse dark colors for code blocks 82 83 84 85 86Add line. Add line. Add line. Add line. ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map on the map view mapView.setMap(map); mapView.setViewpoint(new Viewpoint(34.02700, -118.80543, 144447.638572)); // create a graphics overlay and add it to the map view graphicsOverlay = new GraphicsOverlay(); mapView.getGraphicsOverlays().add(graphicsOverlay);
Add a UI for user input
To search an address using the application, add a UI element to prompt the user for text input. The text input will be used as the geocode search text in a later step.
-
Create a new private method named
setup
.Text Field() -
Within the method body, create a JavaFX
Text
, assign it to theField search
member variable, and set its width and prompt text.Box App.javaUse dark colors for code blocks 90 91 92 93Add line. Add line. Add line. Add line. Add line. mapView.getGraphicsOverlays().add(graphicsOverlay); } private void setupTextField() { searchBox = new TextField(); searchBox.setMaxWidth(400); searchBox.setPromptText("Search for an address"); }
-
Call the
setup
method in theText Field() start()
method.App.javaUse dark colors for code blocks 90 91Add line. mapView.getGraphicsOverlays().add(graphicsOverlay); setupTextField();
-
Add the
search
to the top left of the map, setting its alignment and margins as shown:Box App.javaUse dark colors for code blocks 92 93 97 98Add line. Add line. Add line. setupTextField(); stackPane.getChildren().add(searchBox); StackPane.setAlignment(searchBox, Pos.TOP_LEFT); StackPane.setMargin(searchBox, new Insets(10, 0, 0, 10)); }
Create a locator task with geocode parameters
Geocoding is implemented with a locator, typically created by referencing a service such as the Geocoding service or, for offline geocoding, by referencing locator data contained in a mobile package. Geocoding parameters can be used to fine-tune the results, such as setting the maximum number of results or requesting additional attributes in the results.
-
Create a new private method named
create
.Locator Task And Default Parameters() -
Within the method body, create a new
LocatorTask
based on the Geocoding service, and assign it to thelocator
member variable.Task A locator task is used to convert an address to a point (geocode) or vice-versa (reverse geocode). An address includes any type of information that distinguishes a place. A locator involves finding matching locations for a given address. Reverse-geocoding is the opposite and finds the closest address for a given location.
-
Create new
GeocodeParameters
, and assign it to thegeocode
member variable. Specify the geocode's attributes as follows:Parameters - Specify which attributes to return by calling the
.add()
method on theGeocodeParameters.getResultAttributeNames()
.*
is used to return all attributes. - Set the maximum number of results to be returned with
GeocodeParameters.setMaxResults()
. In this tutorial, only return the best match by passing in1
. Results are ordered byscore
, so returning only the first result will return the highest scoring result. - Set the spatial reference with
GeocodeParameters.setOutputSpatialReference()
. By default the output spatial reference is determined by the geocode service. For optimal performance when displaying the geocode result, ensure the returned coordinates match those of the map view by providingmap
as a parameter.View.get Spatial Reference()
When geocoding an address, you can optionally provide
GeocodeParameters
to control certain aspects of the geocoding operation, and specify the kinds of results to return from the locator task.App.javaUse dark colors for code blocks 100 101 102 103 104 105Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. private void setupTextField() { searchBox = new TextField(); searchBox.setMaxWidth(400); searchBox.setPromptText("Search for an address"); } private void createLocatorTaskAndDefaultParameters() { locatorTask = new LocatorTask("https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer"); geocodeParameters = new GeocodeParameters(); geocodeParameters.getResultAttributeNames().add("*"); geocodeParameters.setMaxResults(1); geocodeParameters.setOutputSpatialReference(mapView.getSpatialReference()); }
- Specify which attributes to return by calling the
-
Call the
create
method in theLocator Task And Default Parameters() start()
method.App.javaUse dark colors for code blocks 92 93Add line. setupTextField(); createLocatorTaskAndDefaultParameters();
Get the geocode results with a geocode operation
An asynchronous geocode operation is required to find and return the location candidates for a given address and geocode parameters.
-
Create a new private method named
perform
that takes aGeocode() String
parameter for the address. -
To find the location for a given address, call the
LocatorTask.geocodeAsync()
method on thelocator
, providing theTask address
string andgeocode
as parameters, and store the result in a local variable namedParameters geocode
. The result is an immutable list ofResults GeocodeResult
objects. In this tutorial, only one result will be returned, as the maximum results parameter was set to 1. Get the location result by calling anListenableFuture.addDoneListener()
on thegeocode
. The result will be displayed visually in the next step.Results App.javaUse dark colors for code blocks 108 109 110 111 112 113 114 115 116Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. private void createLocatorTaskAndDefaultParameters() { locatorTask = new LocatorTask("https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer"); geocodeParameters = new GeocodeParameters(); geocodeParameters.getResultAttributeNames().add("*"); geocodeParameters.setMaxResults(1); geocodeParameters.setOutputSpatialReference(mapView.getSpatialReference()); } private void performGeocode(String address) { ListenableFuture<List<GeocodeResult>> geocodeResults = locatorTask.geocodeAsync(address, geocodeParameters); geocodeResults.addDoneListener(() -> { try { List<GeocodeResult> geocodes = geocodeResults.get(); if (geocodes.size() > 0) { GeocodeResult result = geocodes.get(0); } else { new Alert(Alert.AlertType.INFORMATION, "No results found.").show(); } } catch (InterruptedException | ExecutionException e) { new Alert(Alert.AlertType.ERROR, "Error getting result.").show(); e.printStackTrace(); } }); }
Display the result
The result obtained from the geocode operation can be displayed by adding a graphic to the map view's graphics overlay.
-
Create a new private method taking a
GeocodeResult
(the result to be displayed on the map) as a parameter, and name itdisplay
.Result() -
Within the method body, create and style two
Graphic
objects and add them to thegraphics
. Use theOverlay geocode
's label and display location to add one graphic showing the geocode result's label text (the address), and another showing the geocode result's location.Result App.javaUse dark colors for code blocks 126 127 128 129 130 131 132 133 134 135Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. } else { new Alert(Alert.AlertType.INFORMATION, "No results found.").show(); } } catch (InterruptedException | ExecutionException e) { new Alert(Alert.AlertType.ERROR, "Error getting result.").show(); e.printStackTrace(); } }); } private void displayResult(GeocodeResult geocodeResult) { graphicsOverlay.getGraphics().clear(); // clears the overlay of any previous result // create a graphic to display the address text String label = geocodeResult.getLabel(); TextSymbol textSymbol = new TextSymbol(18, label, Color.BLACK, TextSymbol.HorizontalAlignment.CENTER, TextSymbol.VerticalAlignment.BOTTOM); Graphic textGraphic = new Graphic(geocodeResult.getDisplayLocation(), textSymbol); graphicsOverlay.getGraphics().add(textGraphic); // create a graphic to display the location as a red square SimpleMarkerSymbol markerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.SQUARE, Color.RED, 12.0f); Graphic markerGraphic = new Graphic(geocodeResult.getDisplayLocation(), geocodeResult.getAttributes(), markerSymbol); graphicsOverlay.getGraphics().add(markerGraphic); mapView.setViewpointCenterAsync(geocodeResult.getDisplayLocation()); }
-
In the
perform
method, in the lambda expression body, call theGeocode() display
method, passing inResult() result
as the parameter. This will display the result of the geocode operation on the map.App.javaUse dark colors for code blocks 120 121 122 123 124 125Add line. geocodeResults.addDoneListener(() -> { try { List<GeocodeResult> geocodes = geocodeResults.get(); if (geocodes.size() > 0) { GeocodeResult result = geocodes.get(0); displayResult(result);
-
In the
start()
method, set an action on thesearch
to get the input text. Get the text from the search box and callBox perform
, passing in the text as the parameter.Geocode() App.javaUse dark colors for code blocks 94 95Add line. Add line. Add line. Add line. Add line. Add line. createLocatorTaskAndDefaultParameters(); searchBox.setOnAction(event -> { String address = searchBox.getText(); if (!address.isBlank()) { performGeocode(address); } });
-
Run the app. Ensure to run the app as a Gradle task and not as an application in your IDE. In the Gradle tool window, under Tasks > application, double-click run.
You should see a search box on the top left of the map. Search for an address by entering an address and press Return on the keyboard. The result of the search should display on the map as a red square.
What's next?
Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials: