
# Java Geocoding Tutorial

## OpenCage Geocoding API Java Tutorial

Tutorial for using the OpenCage Geocoding API in Java - An API for reverse and forward geocoding using open geo data

This is a tutorial for using the [OpenCage geocoding API](https://opencagedata.com/api) in Java.

### Topics covered in this tutorial

- General Background
- Agent Skill
- Installing JOpenCage
- Reverse geocoding
- Forward geocoding
- Geocoding a list of places
- Error Handling
- Further reading

### Background

The code examples below will use your geocoding API key once you [log in](https://opencagedata.com/users/sign_in).

#### Before we dive in to the tutorial

1. [Sign up](https://opencagedata.com/users/sign_up) for an OpenCage geocoding API key.
2. Play with the [demo page](https://opencagedata.com/demo), so that you see the actual response the API returns.
3. Browse the [API reference](https://opencagedata.com/api), so you understand the [optional parameters](https://opencagedata.com/api#optional-params), [best practices](https://opencagedata.com/api#bestpractices), [possible response codes](https://opencagedata.com/api#codes), and the [rate limiting](https://opencagedata.com/api#rate-limiting) on free trial accounts.

Working with AI?

We offer an [Agent Skill](https://github.com/OpenCageData/opencage-skills) to make it easy for AI to quickly learn about our geocoding API.

### Agent Skill / Working with AI

Are you developing with AI?

We offer [an Agent Skill](https://github.com/OpenCageData/opencage-skills/) that includes [a reference file specifically about developing code to access our API via Java](https://github.com/OpenCageData/opencage-skills/blob/master/skills/opencage-geocoding-api/references/java.md).

### Add JOpenCage as a dependency to your maven or gradle project

Following the library's [usage instructions](https://github.com/OpenCageData/jopencage#usage)

### Reverse (coordinates to address) Example

Send a coordinate pair (latitude, longitude) and receive an address

    JOpenCageGeocoder jOpenCageGeocoder = new JOpenCageGeocoder("YOUR-API-KEY");
    
    JOpenCageReverseRequest request = new JOpenCageReverseRequest(41.40015, 2.15765);
    request.setLanguage("es"); // show results in a specific language using an IETF format language code
    request.setLimit(5); // only return the first 5 results (default is 10)
    request.setNoAnnotations(true); // exclude additional info such as calling code, timezone, and currency
    request.setMinConfidence(3); // restrict to results with a confidence rating of at least 3 (out of 10)
    
    JOpenCageResponse response = jOpenCageGeocoder.reverse(request);
    
    // get the formatted address of the first result:
    String formattedAddress = response.getResults().get(0).getFormatted();
    // formattedAddress is now 'Travessera de Gràcia, 142, 08012 Barcelona, España'

### Forward (address to coordinates) Example

Send an address and receive a coordinate pair. Format your address according to the steps laid out in our [guide to query formatting](https://opencagedata.com/guides/how-to-format-your-geocoding-query).

    JOpenCageGeocoder jOpenCageGeocoder = new JOpenCageGeocoder("YOUR-API-KEY");
    JOpenCageForwardRequest request = new JOpenCageForwardRequest("375 Albert Rd, Woodstock, Cape Town, 7915, South Africa");
    request.setRestrictToCountryCode("za"); // restrict results to a specific country
    request.setBounds(18.367, -34.109, 18.770, -33.704); // restrict results to a geographic bounding box (southWestLng, southWestLat, northEastLng, northEastLat)
    
    JOpenCageResponse response = jOpenCageGeocoder.forward(request);
    JOpenCageLatLng firstResultLatLng = response.getFirstPosition(); // get the coordinate pair of the first result
    System.out.println(firstResultLatLng.getLat().toString() + "," + firstResultLatLng.getLng().toString());
    // prints -33.9275623,18.4571101

### Batch Geocode a List of Addresses from a File

This example is for forward geocoding a list of addresses; the process to reverse geocode a list of coordinate pairs would be similar. Start with a text file of addresses formatted according to the steps laid out in our [guide to query formatting](https://opencagedata.com/guides/how-to-format-your-geocoding-query).

    // myAddresses.txt
    25 Queen Victoria St, Gardens, Cape Town, 8001, South Africa
    Via Giuseppe Garibaldi, 183, 16032 Camogli GE, Italy
    1 Hacker Way, Menlo Park, CA 94025, USA
    Iguazu National Park, Brazil
    Stanford, 7210, South Africa
    
    // Read the file and geocode the addresses:
    JOpenCageGeocoder jOpenCageGeocoder = new JOpenCageGeocoder("YOUR-API-KEY");
    
    InputStream inputFile = getClass().getClassLoader().getResourceAsStream("myAddresses.txt");
    
    List<String> listOfAddresses = new ArrayList<>();
    try (BufferedReader br = new BufferedReader(new InputStreamReader(inputFile, StandardCharsets.UTF_8))) {
      listOfAddresses = br.lines().collect(Collectors.toList());
    } catch (IOException e) {
      System.out.println("Unable to read file");
      e.printStackTrace();
    }
    
    System.out.println("Latitude, Longitude:");
    for (String address : listOfAddresses) {
      JOpenCageForwardRequest request = new JOpenCageForwardRequest(address);
      request.setLimit(1);
      request.setNoAnnotations(true);
      JOpenCageResponse response = this.jOpenCageGeocoder.forward(request);
    
      if (response != null && response.getResults() != null && !response.getResults().isEmpty()) {
        JOpenCageLatLng coordinates = response.getResults().get(0).getGeometry();
        System.out.println(coordinates.getLat().toString() + "," + coordinates.getLng().toString());
      } else {
        System.out.println("Unable to geocode input address: " + address);
      }
    
      try {
        Thread.sleep(1000); // free trial accounts limited to 1 request/sec
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    };

### Error handling

In the case of an error, an appropriate error message will be logged, such as:
- `400: "Invalid request (bad request; a required parameter is missing)!"`
- `401: "Invalid or missing API key!"`
- `402: "Valid request but quota exceeded (payment required)!"`
- `403: "Forbidden. API key blocked"`

### Further Reading

- [OpenCage geocoding API Reference](https://opencagedata.com/api)
- [Comparing geocoding services](https://opencagedata.com/guides/how-to-compare-and-test-geocoding-services)
- [Cleaning / formatting your forward geocoding query](https://opencagedata.com/guides/how-to-format-your-geocoding-query)
- [Geocoding more quickly](https://opencagedata.com/guides/how-to-geocode-more-quickly)
- [Geocoding large datasets](https://opencagedata.com/guides/how-to-geocode-large-datasets)
- [Geocoding and preserving privacy](https://opencagedata.com/guides/how-to-preserve-privacy-by-showing-only-an-imprecise-location)
- [Sample address and coordinate lists for testing](https://opencagedata.com/tools/address-lists)

