> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/android/ja/java/llms.txt)

# Geocoding

This guide provides an overview of how to do **geocoding** using the Mapbox Java SDK.

> **Note: Looking for the Search SDK for Android?**
> 
> The Mapbox [Search SDK for Android](https://docs.mapbox.com/android/ja/search/) is the recommended way to access the Mapbox Geocoding API on the Android platform.

The [Mapbox Geocoding API](https://docs.mapbox.com/api/search/geocoding/) 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](https://docs.mapbox.com/api/search/geocoding/). 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.

```java
// 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`](https://docs.mapbox.com/android/java/api/libjava-services/7.10.1/com/mapbox/api/geocoding/v6/MapboxV6Geocoding.html) object by passing in two required parameters: a valid Mapbox [access token](https://docs.mapbox.com/help/glossary/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()`](https://docs.mapbox.com/android/java/api/libjava-services/7.10.1/com/mapbox/api/geocoding/v5/MapboxGeocoding.Builder.html#proximity-com.mapbox.geojson.Point-) and pass in their location as a `Point` object to bias results to around their location.

**Java**

```java
V6ForwardGeocodingRequestOptions requestOptions = V6ForwardGeocodingRequestOptions.builder("1600 Pennsylvania Ave NW")
    .autocomplete(false)
    .build();

MapboxV6Geocoding mapboxGeocoding = MapboxV6Geocoding.builder(
    YOUR_MAPBOX_ACCESS_TOKEN,
    requestOptions
).build();
```

**Kotlin**

```kt
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()`](https://docs.mapbox.com/android/java/api/libjava-core/7.10.1/com/mapbox/core/MapboxService.html#enqueueCall-retrofit2.Callback-). Once the request receives a response, it will tell the callback where you can handle the response appropriately.

Use [`mapboxGeocoding.cancelCall()`](https://docs.mapbox.com/android/java/api/libjava-core/7.10.1/com/mapbox/core/MapboxService.html#cancelCall--) within your `onDestroy()` lifecycle method in case your user leaves the activity or application before the callback is notified.

**Java**

```java
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();
    }
});
```

**Kotlin**

```kt
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.

**Java**

```java
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();
    }
});
```

**Kotlin**

```kt
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.

**Java**

```java
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();
    }
});
```

**Kotlin**

```kt
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()
	}
});
```

## Permanent versus temporary geocoding

The Mapbox Geocoding API supports both **permanent** and **temporary** geocoding. Permanent geocoding allows you to store and use geocoding results indefinitely, while temporary geocoding results must be used at once and not stored for future use.

The builders for `MapboxV6Geocoding` and `MapboxV6BatchGeocoding` include a `.permanent(true|false)` method to specify whether the geocoding request is permanent or temporary. By default, requests are temporary (`.permanent(false)`).

**Java**

```java
V6ForwardGeocodingRequestOptions requestOptions = V6ForwardGeocodingRequestOptions.builder("1600 Pennsylvania Ave NW")
    .autocomplete(false)
    .build();

MapboxV6Geocoding mapboxGeocoding = MapboxV6Geocoding.builder(
    accessToken,
    requestOptions
)
// highlight-start
.permanent(true)
// highlight-end
.build();
```

**Kotlin**

```kt
var requestOptions = V6ForwardGeocodingRequestOptions.builder("1600 Pennsylvania Ave NW")
    .autocomplete(false)
    .build();
    
var mapboxGeocoding = MapboxV6Geocoding.builder(
    accessToken,
    requestOptions
)
// highlight-start
    .permanent(true)
// highlight-end
    .build()    
```

For more details on permanent versus temporary geocoding, refer to the [Understand Temporary versus Permanent Geocoding](https://docs.mapbox.com/help/dive-deeper/understand-temporary-vs-permanent-geocoding/) guide.