Geocoding in Python

Find the latitude and longitude coordinates for addresses using the Geocoding API. Geocode single or a batch of addresses, using HTTP requests.

Search addresses to store them in your database or display them on a map
Search addresses to store them in your database or display them on a map

Python is a flexible and powerful programming language that can be used for a wide range of tasks, including data processing and analysis. Therefore, Python is often used to geocode addresses and provide results in the format required.

Geocoding is the process of converting a street address or other description of a location into a set of geographical coordinates (such as latitude and longitude). These coordinates can then be used to place the location on a map, perform spatial analysis, or support location-based services and navigation.

In this article, we'll explore how to geocode addresses using the Geoapify Geocoding API in Python. The Geoapify Geocoding API provides a fast, reliable, and easy-to-use solution for converting addresses into geographical coordinates. We'll go over how to set up the API, perform geocoding requests for a single address and a batch, and handle the response data in Python.

Geocoding One Address vs. Batch Geocoding

Geoapify has two dedicated endpoints for single and batch geocode requests.

Single geocode API will geocode one address at a time and return results immediately. If it finds more than one address matching those values, it will return address suggestions.

Batch geocoding is the process of geocoding multiple addresses at once. This can be a more efficient and cost-effective way of geocoding addresses compared to geocoding each address individually, especially when working with large datasets.

Geocoding a single address and a batch of addresses are similar processes, but there are some key differences between the two:

  1. Speed: Geocoding a batch of addresses is generally faster than geocoding each address individually. This is because many geocoding services, including the Geoapify Geocoding API, provide bulk geocoding services that can process multiple addresses in a single request. This can save time and reduce the overall processing time, especially when working with large datasets.
  2. Cost: The cost of geocoding a batch of addresses is often lower than the cost of geocoding each address individually, especially when using a paid geocoding service like the Geoapify Geocoding API. This is because bulk geocoding services often provide discounts for larger volumes of data.
  3. Result Format: When geocoding a batch of addresses, the results are often returned as a single file or data structure rather than as individual results. This makes it easier to process and analyze the results but may require additional processing to extract information for individual addresses.

Let's look at how to implement both of these concepts in Python.

Geocode a Single Address

Here's an example of how to geocode a single address using the Python requests library to make a GET request to the Geoapify Geocoding API:

import requests

# Replace YOUR_API_KEY with your actual API key. Sign up and get an API key on https://www.geoapify.com/ 
API_KEY = "YOUR_API_KEY"

# Define the address to geocode
address = "1600 Amphitheatre Parkway, Mountain View, CA"

# Build the API URL
url = f"https://api.geoapify.com/v1/geocode/search?text={address}&limit=1&apiKey={API_KEY}"

# Send the API request and get the response
response = requests.get(url)

# Check the response status code
if response.status_code == 200:
    # Parse the JSON data from the response
    data = response.json()

    # Extract the first result from the data
    result = data["features"][0]

    # Extract the latitude and longitude of the result
    latitude = result["geometry"]["coordinates"][1]
    longitude = result["geometry"]["coordinates"][0]

    print(f"Latitude: {latitude}, Longitude: {longitude}")
else:
    print(f"Request failed with status code {response.status_code}")

In this example, we use the requests.get method to send a GET request to the Geoapify Geocoding API.

We pass the API key and the address to geocode as query parameters in the URL. The API returns a JSON response with the results of the geocoding request. We then parse the JSON data, extract the latitude and longitude of the first result, and print the results to the console.

Note that you'll need to replace YOUR_API_KEY with your actual Geoapify Geocoding API key, which you can obtain by signing up for a free account on the Geoapify website.

If you don't have a Python environment set up on your local machine, you can try running the code sample I provided in an online compiler, such as Trinket.io.

Geocode A Batch Of Addresses

Batch Geocoding API enables you to geocode multiple addresses in a single API request, making it a convenient and time-saving solution for processing large amounts of data. Unlike single-address geocoding, Geoapify's batch geocoding operates as an asynchronous process, allowing you to submit up to 1000 addresses at once and receive the results at a later time.

To geocode a batch of addresses in Python, you create a geocoding job, get its ID, and then call the API using that ID to get results. Let's look at how this can be done:

import requests
import time

# You need a Geoapify API key to call the Batch Geocoding API (https://www.geoapify.com/solutions/batch-geocoding-requests)
# Sign up on https://www.geoapify.com/ and generate an API key
# The Free Plan (https://www.geoapify.com/pricing/) lets you geocode up to 6000 addresses/day
# Replace "YOUR_API_KEY" with API key
apiKey = "YOUR_API_KEY"

# With Batch Geocoding, you create a geocoding job by sending addresses and then, after some time, get geocoding results by job id
# You may require a few attempts to get results. Here is a timeout between the attempts - 1 sec. Increase the timeout for larger jobs.
timeout = 1

# Limit the number of attempts
maxAttempt = 10

def getLocations(locations):
    url = "https://api.geoapify.com/v1/batch/geocode/search?apiKey=" + apiKey
    response = requests.post(url, json = locations)
    result = response.json()

    # The API returns the status code 202 to indicate that the job was accepted and pending
    status = response.status_code
    if (status != 202):
        print('Failed to create a job. Check if the input data is correct.')
        return
    jobId = result['id']
    getResultsUrl = url + '&id=' + jobId

    time.sleep(timeout)
    result = getLocationJobs(getResultsUrl, 0)
    if (result):
        print(result)
        print('You can also get results by the URL - ' + getResultsUrl)
    else:
        print('You exceeded the maximal number of attempts. Try to get results later. You can do this in a browser by the URL - ' + getResultsUrl)

def getLocationJobs(url, attemptCount):
    response = requests.get(url)
    result = response.json()
    status = response.status_code
    if (status == 200):
        print('The job is succeeded. Here are the results:')
        return result
    elif (attemptCount >= maxAttempt):
        return
    elif (status == 202):
        print('The job is pending...')
        time.sleep(timeout)
        return getLocationJobs(url, attemptCount + 1)

# Addresses to geocode
data = [
    "668 Cedar St, San Carlos, CA 94070, United States of America",
    "545 Southwest Taylor Street, Portland, OR 97204, United States of America",
    "1415 Southwest Park Avenue, Portland, OR 97201, United States of America",
    "1019 Southwest Morrison Street, Portland, OR 97205, United States of America",
    "400 Southwest 6th Avenue, Portland, OR 97204, United States of America",
    "1972 Northwest Flanders Street, Portland, OR 97209, United States of America",
    "1150 Northwest Quimby Street, Portland, OR 97209, United States of America",
    "2116 Northwest 20th Avenue, Portland, OR 97209, United States of America",
    "200 East 13th Street, Vancouver, WA 98660, United States of America",
    "1108 Main St, Vancouver, WA 98660, United States of America",
    "410 West Mill Plain Boulevard, Vancouver, WA 98660, United States of America",
    "900 W Evergreen Blvd, Vancouver, WA 98660, United States of America",
    "2008 Simpson Ave, Vancouver, WA 98660, United States of America"
]
getLocations(data)

This code demonstrates how to perform batch geocoding of addresses using the Geoapify Geocoding API and the Python requests library: Similar to single address geocoding, you need to obtain an API key by signing up on the Geoapify website before you can use the API. The free plan allows you to geocode up to 6000 addresses per day.

Here are some details to help you understand the implementation:

  • The code makes a POST request to the Geoapify Batch Geocoding API endpoint with the addresses to be geocoded as the input data.
  • The API returns a job ID and a status code of 202 to indicate that the job was accepted and is pending.
  • The code then uses the job ID to make a GET request to the same API endpoint to retrieve the results of the geocoding.
  • The code waits for 1 second between attempts to retrieve the geocoding results, and will make a maximum of 10 attempts. You can adjust the timeout and maximum attempt limit to suit the size of your batch.
  • If the API returns a status code of 200, it means that the geocoding job was successful, and the results are returned.
  • If the API returns a status code of 202, it means that the job is still pending, and the code will wait and make another attempt to retrieve the results.
  • If the code exceeds the maximum number of attempts, it will print a message indicating that you can try to retrieve the results later using the API URL.

More Geocoding options

Since the Geocoding API searches addresses worldwide by default, you can improve your search significantly by setting the filter to the country, region, state, city, or town you are searching for. The bias parameter can be used to search within a bounding box, nearby location, or any other specified location. Input parameters include:

  • Bias: Location preference based on proximity.
  • Type: Types of location, such as a city, street, or county.
  • Filter: Filtering by geographical area.
  • Lang: Results language written in ISO 639-1 codes.

On the other hand, Geoapify has many request parameters to optimize your queries, especially if you provide free-form addresses. Check the full list of parameters. Besides, the Geoapify Geocoding API also has endpoints for reverse search to get addresses by geographical coordinates, searching places through categories and getting place details, and routing.

Conclusion

In conclusion, geocoding is a process of converting addresses or location names into geographic coordinates, and Geoapify's Geocoding API provides a simple and efficient way to geocode single addresses or a batch of addresses.

You can easily make API calls and retrieve the results with a few lines of code using the requests library in Python or any other library for HTTP requests. Whether you are working with a small or large data set, the batch geocoding feature enables you to process a large number of addresses at once, saving time and increasing productivity.

With the free plan offering up to 6000 addresses per day, Geoapify's Geocoding API is a cost-effective solution for all your geocoding needs.