Geocoding
This guide provides an overview of how to do geocoding using the Mapbox Java SDK.
The Mapbox Geocoding API does two things: forward geocoding and reverse geocoding. Forward geocoding lets you convert location text into geographic coordinates, and reverse geocoding turns geographic coordinates into place names.
You'll find the wrapper for the Mapbox Geocoding API in the mapbox-java-services module. MapboxGeocoding
is used to request both forward and reverse geocoding information. Forward geocoding will take a String
, such as a street address or point of interest, and transform it into a Point
object. Reverse geocoding does the opposite, taking in a Point
object and transforming it into an address. The amount of detail provided in the response varies. For example, one response might contain a full address while another response will only contain the city and country.
For more information about this API, including its pricing structure, see the Mapbox Geocoding API documentation. The API documentation contains all available parameters including some that are not listed in this guide.
Before using this wrapper, make sure you have included the correct permissions inside of your AndroidManifest.xml
file if you plan to use this API inside of an Android application.
Import packages
Import the necessary packages for the type of geocoding you want to do.
// for forward geocoding
import com.mapbox.api.geocoding.v6.MapboxV6Geocoding
import com.mapbox.api.geocoding.v6.V6ForwardGeocodingRequestOptions
import com.mapbox.api.geocoding.v6.models.V6Response;
// for reverse geocoding
import com.mapbox.api.geocoding.v6.MapboxV6Geocoding
import com.mapbox.api.geocoding.v6.V6ReverseGeocodingRequestOptions
import com.mapbox.api.geocoding.v6.models.V6Response;
import com.mapbox.geojson.Point
// for batch geocoding (V6BatchResponse consists of multiple V6Response)
import com.mapbox.api.geocoding.v6.MapboxV6BatchGeocoding
import com.mapbox.api.geocoding.v6.models.V6BatchResponse
import com.mapbox.api.geocoding.v6.models.V6Response;
Forward geocoding
Before making a forward geocoding request, you must build the MapboxGeocoding
object by passing in two required parameters: a valid Mapbox access token and a forward geocoding request options object. V6ForwardGeocodingRequestOptions
includes a location query (typically an address or description). Several other parameters are available to help bias and manipulate the response that you receive.
If you are using the Mapbox geocoder to find locations around the user's location, you can use proximity()
and pass in their location as a Point
object to bias results to around their location.
V6ForwardGeocodingRequestOptions requestOptions = V6ForwardGeocodingRequestOptions.builder("1600 Pennsylvania Ave NW")
.autocomplete(false)
.build();
MapboxV6Geocoding mapboxGeocoding = MapboxV6Geocoding.builder(
YOUR_MAPBOX_ACCESS_TOKEN,
requestOptions
).build();
var requestOptions = V6ForwardGeocodingRequestOptions.builder("1600 Pennsylvania Ave NW")
.autocomplete(false)
.build();
var mapboxGeocoding = MapboxV6Geocoding.builder(
YOUR_MAPBOX_ACCESS_TOKEN,
requestOptions
).build()
Geocoding response
Once you have built your MapboxV6Geocoding
object with all the parameters that you want to use in the request, you need to asynchronously send the request using enqueueCall()
. Once the request receives a response, it will tell the callback where you can handle the response appropriately.
Use mapboxGeocoding.cancelCall()
within your onDestroy()
lifecycle method in case your user leaves the activity or application before the callback is notified.
mapboxGeocoding.enqueueCall(new Callback<V6Response>() {
@Override
public void onResponse(Call<V6Response> call, Response<V6Response> response) {
List<Feature> results = response.body().features();
if (results != null && results.size() > 0) {
// Log the geometry of the first result.
Point firstResultPoint = results.get(0).geometry();
Log.d("Geocoder", "onResponse: " + firstResultPoint.toString());
// Example log output: "onResponse: Point{type=Point, bbox=null, coordinates=[-77.036538, 38.897685]}"
} else {
// No result for your request were found.
Log.d("Geocoder", "onResponse: No result found");
}
}
@Override
public void onFailure(Call<V6Response> call, Throwable throwable) {
throwable.printStackTrace();
}
});
mapboxGeocoding.enqueueCall(object : Callback<V6Response> {
override fun onResponse(call: Call<V6Response>, response: Response<V6Response>) {
val results = response.body()!!.features()
if (results.size > 0) {
// Log the geometry of the first result.
val firstResultPoint = results[0].geometry()
Log.d("Geocoder", "onResponse: " + firstResultPoint!!.toString())
// "onResponse: Point{type=Point, bbox=null, coordinates=[-77.036538, 38.897685]}"
} else {
// No result for your request were found.
Log.d("Geocoder", "onResponse: No result found")
}
}
override fun onFailure(call: Call<V6Response>, throwable: Throwable) {
throwable.printStackTrace()
}
})
Reverse geocoding
The process of turning coordinates into a String
address is called reverse geocoding. Instead of supplying the builder with a String
address you'd pass in coordinates instead. Handling the response is like forward geocoding. While the geocoder gives one coordinate, the response will often give you multiple valid ways to describe the specific location. For example, one might be the street name while another result will be the country. The ordering of the list usually goes from most relevant to least.
You can narrow the response like forward geocoding by biasing the result using the available parameters provided in the builder.
import com.mapbox.geojson.Point
...
V6ReverseGeocodingRequestOptions requestOptions = V6ReverseGeocodingRequestOptions.builder(Point.fromLngLat(-77.03655, 38.89770))
.build();
MapboxV6Geocoding mapboxGeocoding = MapboxV6Geocoding.builder(
MAPBOX_ACCESS_TOKEN,
requestOptions
).build();
mapboxGeocoding.enqueueCall(new Callback<V6Response>() {
@Override
public void onResponse(Call<V6Response> call, Response<V6Response> response) {
List<Feature> results = response.body().features();
if (results != null && results.size() > 0) {
// Log the properties of the first result
Map<String, Object> firstResultProperties = results.get(0).properties();
Log.d("Geocoder", "onResponse: " + firstResultProperties.toString());
// Example log output: "onResponse: V6Properties{unrecognized=null, mapboxId=dXJuOm1ieGFkcjoxYWIxM2EwYy00NGI4LTQyMGMtOGE0MS0wZmYyNDE3NjBlNDY, featureType=address, name=1600 Pennsylvania Avenue Northwest, ..."
} else {
// No result for your request was found.
Log.d("Geocoder", "onResponse: No result found");
}
}
@Override
public void onFailure(Call<V6Response> call, Throwable throwable) {
throwable.printStackTrace();
}
});
import com.mapbox.geojson.Point
...
var requestOptions = V6ReverseGeocodingRequestOptions.builder(Point.fromLngLat(-77.03655, 38.89770))
.build()
var mapboxGeocoding = MapboxV6Geocoding.builder(
MAPBOX_ACCESS_TOKEN,
requestOptions
).build()
mapboxGeocoding.enqueueCall(object : Callback<V6Response> {
override fun onResponse(call: Call<V6Response>, response: Response<V6Response>) {
val results = response.body()!!.features()
if (results.size > 0) {
// Log the properties of the first result
val firstResultProperties = results[0].properties()
Log.d("Geocoder", "onResponse: " + firstResultProperties!!.toString())
// onResponse: V6Properties{unrecognized=null, mapboxId=dXJuOm1ieGFkcjoxYWIxM2EwYy00NGI4LTQyMGMtOGE0MS0wZmYyNDE3NjBlNDY, featureType=address, name=1600 Pennsylvania Avenue Northwest, ...
} else {
// No result for your request were found.
Log.d("Geocoder", "onResponse: No result found")
}
}
override fun onFailure(call: Call<V6Response>, throwable: Throwable) {
throwable.printStackTrace()
}
})
Batch geocoding
Batch requests have the same parameters as normal requests, but can include more than one query by setting multiple V6ForwardGeocodingRequestOptions
. You can do up to 50 forward or reverse geocoding queries in a single request. The response is an array of V6Response
formatted in the same way as individual results. Each query in a batch request counts individually against your account's rate limits.
MapboxV6BatchGeocoding mapboxGeocoding = MapboxV6BatchGeocoding
.builder(
MAPBOX_ACCESS_TOKEN,
Arrays.asList(
V6ForwardGeocodingRequestOptions
.builder("1600 Pennsylvania Avenue NW, Washington, DC 20500, United States")
.limit(1)
.build(),
V6ForwardGeocodingRequestOptions
.builder("2 15th Street NW, Washington, DC 20004, United States")
.limit(1)
.build(),
V6ForwardGeocodingRequestOptions
.builder("600 14th Street NW, Washington, DC 20005, United States")
.limit(1)
.build()
)
)
.build();
mapboxGeocoding.enqueueCall(new Callback<V6BatchResponse>() {
@Override
public void onResponse(Call<V6BatchResponse> call, Response<V6BatchResponse> response) {
V6BatchResponse body = response.body();
if (body == null) {
Log.d("Geocoder", "Response body is null");
return;
}
Log.d("Geocoder", "Number of responses: " + body.responses().size());
for (V6Response v6Response : body.responses()) {
String results = v6Response.features()
.stream()
.map(Object::toString)
.collect(Collectors.joining(",
"));
Log.d("Geocoder", "Features: " + results);
}
}
@Override
public void onFailure(Call<V6BatchResponse> call, Throwable throwable) {
throwable.printStackTrace();
}
});
var mapboxGeocoding = MapboxV6BatchGeocoding
.builder(
MAPBOX_ACCESS_TOKEN,
listOf(
V6ForwardGeocodingRequestOptions
.builder("1600 Pennsylvania Avenue NW, Washington, DC 20500, United States")
.types(V6FeatureType.ADDRESS)
.limit(1)
.build(),
V6ForwardGeocodingRequestOptions
.builder("2 15th Street NW, Washington, DC 20004, United States")
.types(V6FeatureType.ADDRESS)
.limit(1)
.build(),
V6ForwardGeocodingRequestOptions
.builder("600 14th Street NW, Washington, DC 20005, United States")
.types(V6FeatureType.ADDRESS)
.limit(1)
.build()
)
)
.build();
mapboxGeocoding.enqueueCall(object : Callback<V6BatchResponse> {
override fun onResponse(call: Call<V6BatchResponse>, response: Response<V6BatchResponse>) {
val body = response.body()
if (body == null) {
Log.d("Geocoder", "Response body is null")
return
}
Log.d("Geocoder", "Number of responses: ${body.responses().size}")
for (v6Response in body.responses()) {
val results = v6Response.features()
.joinToString(", \n") { it.toString() }
Log.d("Geocoder", "Features: $results")
}
}
override fun onFailure(call: Call<V6BatchResponse>, throwable: Throwable) {
throwable.printStackTrace()
}
});