Spatial Analytics

How to Geocode Addresses for Free?

Nikhil Hubballi

Nikhil Hubballi

21 minutes

How to Geocode Addresses for Free?

Spatial Analytics

The use of location data has been on the rise in recent years. Everything we do is geo-tagged. It might be the restaurant we had a meal at, the jogging circuit we frequent. Companies and industries selling goods & services want to understand where the revenue is high, where their customers are based and many such location-related queries. But the data for places is usually in the form of addresses or a description relating to the location. And when we want to map and visualise, it's generally not possible. Therefore, we need to assign the geographical coordinates to each of these places of interest. It helps us to be able to show data on a map. And we use the process of geocoding to do precisely this. Here in this blog, we look at the process of geocoding and how we can geocode addresses for free.

If you would like to read more about how location(geospatial) data is rising in importance and is the way forward in data analytics, check out my article on the topic here.

What's Geocoding?

Geocoding is the process of transforming a description of a location - usually, the name of a place or its address into geographical coordinates that represent the place's location on the earth's surface. This is given as a pair of coordinates called, latitude and longitude. Latitude is the coordinate that represents the position of a subject in the north-south direction on the earth's surface (-90° to 90°). While longitude is the coordinate in the east-west direction (-180° to 180°).

In some cases, the description of the location can be of different types as well, such as IP address, pair of coordinates in a different coordinate system etc.

Process of Geocoding

Individual Address vs Bulk Addresses

There are several map platforms existing today that enable searching any given address on the globe. Google Maps is one of the most used tools for this purpose. If it's just a few handfuls of places you are looking to geocode, you can use this platform and get the geographic coordinates for the location. You can also use other platforms like Bing, Mapbox, OpenStreetMap etc. It helps in geocoding for quick use cases of locating the address on a map and visualising it.

How to Geocode addresses for free
Searching for an address of Papa John's Pizza in Mountain View, California - "571 W. El Camino Real, Mountain View, California 94040" on Google Maps gives us a result of the location view on the map with additional information like images on the left sidebar. Photo by Author

But in many cases, you have large counts of addresses to geocode and identify the geographic coordinates. Following the above method, visualising the location one by one for several hundred places is not feasible. It would be a terrible waste of time, even if you did. So we look for options to geocode multiple addresses in bulk by automating the process.

For geocoding in bulk, we use some tools offered as UI or an API on the web. These services are usually charged money on each geocoding request of an address into coordinates. If you have a few thousand addresses, it can cost you anywhere between $2-$10 based on the provider you choose. We'll look at a few service providers and tools that help geocode addresses for free for most of our use cases.

Bonus: If you are interested and have some time to spare, you can even set up your geocoding server using which you can geocode as many addresses as you want.

Preparing the address column

Before you send in your addresses for geocoding, you need to make sure your address is in the correct and standard format used for geocoding. Instead of having each of the street address, area, city and postal codes in different columns, preferably, you need to have one single line of text in order as you generally see on a postcard.

It's ideal to have the data of each component of an address standardised. If it doesn't match the format of the addresses on the official postal database, you might end up with a wrong or no match at all. Fundamentally, geocoding is checking an address against a standardised locations database of addresses for the best match. Therefore this is a necessary step to avoid errors.

Standard order of the address used - name, house number, street name, city name, state name, ZIP Code

GUI-based Geocoding Tools

There are a few options online that offer bulk geocoding of addresses for free. Of course, these services have limits on how many geocoding requests you can make. But these tools should be sufficient for someone who is working on some one-off projects or handles a limited amount of data.

Local Focus

Known as the Batch Geocoder for Journalists, this tool can geocode for addresses in bulk. Once you open the link, choose the country from the drop-down. It helps optimise the process of geocoding. Next, you need to paste all the addresses you want to geocode, with each location address in a single line. By clicking on "Add to Geocoder", you start the process and get an output to copy at the end with three columns - latitude, longitude and status appended to the address.

How to Geocode addresses for free
Indicate the country and paste all the addresses in the box to start the geocoding process. Photo by Author.
How to Geocode addresses for free
Once the process is started you see the status on successful geocoding and the results box starts getting populated with outputs. Photo by Author

Google Spreadsheets - Using Add-ons

Google Spreadsheets offers a simple solution for geocoding. All you need is an add-on & you can start geocoding a few thousand location addresses. There are several add-ons, and here we demo Geocode by Awesome Table. This add-on uses the 'address' column you specify on the sheet to geocode and add two more columns for the latitude and longitude when done.

To use this tool, choose Add-ons > Geocode by Awesome Table > Start Geocoding. Be sure to check the 'Try wider results' box before you start geocoding. Another cool feature of this tool is if you have the address in multiple columns, such as street address and city name, it lets you concatenate the columns to create a full location address on the go.

There's a limit of 10,000 rows per day per account on this tool, but it should be enough for most use cases.

google spreadsheets plugin geocode
Starting the geocode process adds two columns for latitude and longitude and runs sequentially. Photo by Author.

You can check out another add-on for GSheets: Geocoding by SmartMonkey

QGIS Plugins

QGIS is one of the software packages you'll come across when learning to handle geospatial data. Being an open-source package, it has so many features and algorithms to run on spatial data. Plugins help increase its already existing capabilities. One such plugin is 'MMQGIS'. This plugin can do several of the analysis tasks on spatial data. But for geocoding, we are using the 'Geocode CSV with Web Service' from the drop-down.

Supply a CSV file with all the necessary columns for address and optional city, state and country columns to run the geocoding. You can geocode using four different services offered in the plugin - Google, OSM Nominatim, US Census Bureau and ESRI Server. You would need the API keys for both Google and ESRI. Whereas, for the others, you can straight away head to geocoding.

qgis plugin geocode
Run the geocoding on the MMQGIS plugin by choosing the CSV file with addresses and defining outputs. Photo by Author.

Script-based Geocoding using APIs

Even though the tools mentioned above can handle geocoding in many cases, it would make the entire process much faster and easier if you could run bulk requests for geocoding using scripts. Many services offer API with endpoint URLs. You need to make a web request by supplying the query parameters for an address, and you'll receive a response that would generally be a JSON object. This object has the details of the location address along with the geographic coordinates.

These API services are typically on a subscription model. They charge money for each of the geocoding requests you make. But, almost all of them offer a free tier of the plan, and that's sufficient for a typical user's use cases in a given month. Following are some of the services and their free quota limits.

  • Position Stack's Accurate Forward & Reverse Batch Geocoding REST API: This service offers geocoding for more than 2 billion addresses around the world. It has multiple service tiers based on usage requirements, and the free tier plan allows a total of 25,000 requests per month for an account. You can perform both forward and reverse geocoding on this API using any of the following languages PHP, Python, Go, Ruby, Nodejs, or jQuery. The responses are JSON, XML or GeoJSON objects. See pricing.
    Sign up and get your free API key here and Read the documentation on API usage here.
  • ESRI's Geocoding and Search API: Signing up for an ArcGIS developer account gives you access to a wide variety of services related to mapping. And geocoding is one of the default services activated for your API key. You need to choose the type of API you wish to use, whether on python, javascript or other methods.
    This service offers a total of 20,000 free requests per month, then on $0.5 per 1,000 Geocodes if you cross the limit. One thing to be noted is that geocode results from the web requests you make are temporary JSON response objects and are not stored. See pricing.
    Sign up and get your API key here and Read the documentation on the API usage here.
  • Mapbox: Mapbox has been a go-to service when dealing with building custom maps with JavaScript. And its services with maps, navigation, search and tilesets API are among the cheapest solutions available. It generously offers a total of 100,000 free requests per month when you use its geocoding API and slab-wise charging per 1000 requests later on. Each address constitutes one geocoding request made & the results are not stored on the account. The response received is a JSON object similar to other services. See pricing.
    Sign up and get your API key here and Read the documentation on the API usage here.
  • LocationIQ: It's another provider that provides multiple services for mapping along with geocoding. It offers one of the cheapest pricing and a whopping 5,000 requests per day which translates to almost 150,000 requests per month on average. Though the limit looks good on paper, the limit per day option has its drawbacks. Even if you have a slightly larger number than 5K places, you'll have to wait for a whole day for counters to reset after you exhaust your daily quota. Also, the requests can't be more than 2 per second. However, when dealing with a limited number of addresses without a time constraint, this service offers the maximum limit for a free quota for geocoding. See pricing.
    Sign up and get your API key here and Read the documentation on the API usage here.
  • MapQuest: Mapquest offers several services for mapping ranging from geocoding, directions, and elevation to a static map, traffic etc. You can get a free quota of 15,000 transactions per month. This quota is across all the services offered rather than just geocoding. See pricing.
    Sign up and get your API key here and Read the documentation on the API usage here.
  • OpenRouteService: An open source-based service that provides geocoding API along with directions, isochrones, elevation, time-distance matrix etc., offers a per day quota of 1,000 requests @100 requests per minute. You can donate to the development of the service, but there's no paid tier for this.
    Sign up and get your API key here and Read the documentation on the API usage here.
  • What3Words: We generally use geographic coordinates or postal addresses to identify a place on the earth's surface. But this mapping service completely changes how we identify a location. This service uses a unique algorithm to convert the entire globe into grids of 3m x 3m size and assign a 3-word address to each. This 3-word address can be in multiple languages offered by the provider. If you want to geocode these 3-word addresses, you can use their API that offers up to 1,000 free requests per month. And you can have unlimited reverse geocoding of locations (geographical coordinates to 3-word address). See pricing.
    Sign up and get your API key here and Read the documentation on the API usage here.
  • FreeGeoIP.net: Another unique type of address used for geocoding is the IP address of a network. Each IP address is associated with location information. Each IP address has a piece of associated location information. We can get this information in any format required (country/state/city/lat-long) by geocoding. It helps to geolocate the origin of network pings on the web to identify systems or people like hackers. The service FreeGeoIP.net offers an API, using which you can geocode IP addresses with a free quota of 10,000 requests per month. See pricing. Sign up and get your API key here and Read the documentation on the API usage here.

Requesting from API endpoints

Usually, you can use an API by using the endpoints set by the service providers. When you make a web request with all the required query parameters, you receive the response, generally, as a JSON object. Here we demonstrate the use of cURL and the python method to fetch the output from the services.

1. Positionstack - Python

The following code shows how to make a geocoding request for the address 'Copacabana' in the Rio de Janeiro region using the positionstack API. Look into the usage docs to know more about the parameters and response objects.


# Python 3
import http.client, urllib.parse

# End point of the Positionstack API.
conn = http.client.HTTPConnection('api.positionstack.com') 

# Add query and other parameters to be sent with the request
params = urllib.parse.urlencode({
		# set up the API key as an environment variable instead of using 
		# in the scripts for security.
    'access_key': YOUR_ACCESS_KEY, 
    'query': 'Copacabana',
    'region': 'Rio de Janeiro',
    'limit': 1,
    })

# append the path for forward geocoding to the API endpoint.
conn.request('GET', '/v1/forward?{}'.format(params)) 

res = conn.getresponse()
data = res.read()

# decodes the response object and prints to the console.
print(data.decode('utf-8'))

The printed output of this request would look as below.


{
    "data": [
        {
            "latitude": -22.976478,
            "longitude": -43.187679,
            "type": "neighbourhood",
            "name": "Copacabana",
            "number": null,
            "postal_code": null,
            "street": null,
            "confidence": 1,
            "region": "Rio De Janeiro",
            "region_code": "RJ",
            "county": "Rio de Janeiro",
            "locality": "Rio de Janeiro",
            "administrative_area": null,
            "neighbourhood": "Copacabana",
            "country": "Brazil",
            "country_code": "BRA",
            "continent": "South America",
            "label": "Copacabana, Rio de Janeiro, Brazil",
            "map_url": "https://map.positionstack.com/export/embed.html?bbox=-43.2037353516,-22.9996381682,-43.1647100542,-22.9583933135&layer=mapnik&marker=-22.976478,-43.187679"
        }
    ]
}

2. Open Route Service - Python

When you make a web request using this open-source service, you get multiple matches for the address. You need to mention the max number of results you wish to receive with each request.


import requests

headers = {
    'Accept': 'application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8',
}

# Add query and other parameters to be sent with the request
params = {
    'api_key': YOUR_ACCESS_KEY,
    'text': 'Namibian Brewery'
    }

# make a request at the endpoint by supplementing with headers and params
call = requests.get(
    'https://api.openrouteservice.org/geocode/search',
    headers=headers,
    params=params
)

# prints the response object
print(call.status_code, call.reason)
print(call.text)

The printed output of this request would look as below.


{
    "geocoding": {
        "version": "0.2",
        "attribution": "https://openrouteservice.org/terms-of-service/#attribution-geocode",
        "query": {
            "text": "Namibian Brewery",
            "size": 10,
            "layers": [
                "venue",
                "street",
                "country",
                "macroregion",
                "region",
                "county",
                "localadmin",
                "locality",
                "borough",
                "neighbourhood",
                "continent",
                "empire",
                "dependency",
                "macrocounty",
                "macrohood",
                "microhood",
                "disputed",
                "postalcode",
                "ocean",
                "marinearea"
            ],
            "private": false,
            "lang": {
                "name": "English",
                "iso6391": "en",
                "iso6393": "eng",
                "defaulted": true
            },
            "querySize": 20,
            "parser": "pelias",
            "parsed_text": {
                "subject": "Namibian Brewery",
                "place": "Namibian Brewery"
            }
        },
        "warnings": [
            "performance optimization: excluding 'address' layer"
        ],
        "engine": {
            "name": "Pelias",
            "author": "Mapzen",
            "version": "1.0"
        },
        "timestamp": 1615975984871
    },
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    16.646344,
                    -20.459019
                ]
            },
            "properties": {
                "id": "node/4684870705",
                "gid": "openstreetmap:venue:node/4684870705",
                "layer": "venue",
                "source": "openstreetmap",
                "source_id": "node/4684870705",
                "name": "Namibian Brewery",
                "confidence": 1,
                "match_type": "exact",
                "accuracy": "point",
                "country": "Namibia",
                "country_gid": "whosonfirst:country:85632535",
                "country_a": "NAM",
                "region": "Otjozondjupa",
                "region_gid": "whosonfirst:region:85675217",
                "region_a": "OD",
                "county": "Otjiwarongo",
                "county_gid": "whosonfirst:county:421186163",
                "county_a": "OW",
                "continent": "Africa",
                "continent_gid": "whosonfirst:continent:102191573",
                "label": "Namibian Brewery, Namibia"
            }
        }
    ]
}

3. Mapbox - Curl

In this case, we are using the curl method that's run on the terminal to geocode 'Mountain View, California' using the Mapbox API.


curl "https://api.mapbox.com/geocoding/v5/mapbox.places/mountain view, california.json?&access_token=YOUR_ACCESS_KEY"

The printed output of this request would look as below.


{
    "type": "FeatureCollection",
    "query": [
        "mountainview",
        "california"
    ],
    "features": [
        {
            "id": "address.4153806601286382",
            "type": "Feature",
            "place_type": [
                "address"
            ],
            "relevance": 0.5,
            "properties": {
                "accuracy": "street"
            },
            "text": "Mountain View Road",
            "place_name": "Mountain View Road, Mohave Valley, Arizona 86440, United States",
            "matching_text": "Mountainview",
            "matching_place_name": "Mountainview, Mohave Valley, Arizona 86440, United States",
            "center": [
                -114.5842096,
                34.8734472
            ],
            "geometry": {
                "type": "Point",
                "coordinates": [
                    -114.5842096,
                    34.8734472
                ]
            },
            "context": [
                {
                    "id": "postcode.5393511149700320",
                    "text": "86440"
                },
                {
                    "id": "place.9906976918604840",
                    "wikidata": "Q615832",
                    "text": "Mohave Valley"
                },
                {
                    "id": "district.8390610447114160",
                    "wikidata": "Q58696",
                    "text": "Mohave County"
                },
                {
                    "id": "region.9522999891724140",
                    "wikidata": "Q816",
                    "short_code": "US-AZ",
                    "text": "Arizona"
                },
                {
                    "id": "country.19678805456372290",
                    "wikidata": "Q30",
                    "short_code": "us",
                    "text": "United States"
                }
            ]
        }
    ],
    "attribution": "NOTICE: © 2021 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained. POI(s) provided by Foursquare."
}

4. FreeGeoIP.net - Python

We use a random US IP address for geocoding using the service here.


import requests

# Add query and other parameters to be sent with the request
params = {
	# set up the API key as an environment variable instead of using
    # in the scripts for security.
    'access_key': YOUR_ACCESS_KEY, 
    }

# append the path for forward geocoding to the API endpoint.
ip_address = '89.187.182.6'
call = requests.get(
    f'http://api.ipstack.com/{ip_address}',
    params=params
)

print(call.status_code, call.reason)
print(call.text)

The printed output of this request would look as below.


{
    "ip": "89.187.182.6",
    "type": "ipv4",
    "continent_code": "NA",
    "continent_name": "North America",
    "country_code": "US",
    "country_name": "United States",
    "region_code": "IL",
    "region_name": "Illinois",
    "city": "Chicago",
    "zip": "60608",
    "latitude": 41.84885025024414,
    "longitude": -87.67124938964844,
    "location": {
        "geoname_id": 4887398,
        "capital": "Washington D.C.",
        "languages": [
            {
                "code": "en",
                "name": "English",
                "native": "English"
            }
        ],
        "country_flag": "http://assets.ipstack.com/flags/us.svg",
        "country_flag_emoji": "🇺🇸",
        "country_flag_emoji_unicode": "U+1F1FA U+1F1F8",
        "calling_code": "1",
        "is_eu": false
    }
}

5. What3Words - Python

For this, the API offers a python module, 'what3words', which can be installed using pip as pip install what3words. Then it's imported and requested for geocoding on a 3-word address as given in the code below.


import what3words

geocoder = what3words.Geocoder(YOUR_ACCESS_KEY)

result = geocoder.convert_to_coordinates('prom.cape.pump')
print(result)

The printed output of this request would look as below.


{
    'country': 'GB',
    'square': {
        'southwest': {
            'lng': -0.195426,
            'lat': 51.484449
        },
        'northeast': {
            'lng': -0.195383,
            'lat': 51.484476
        }
    }, 
    'nearestPlace': 'Kensington, London', 
    'coordinates': {
        'lng': -0.195405, 
        'lat': 51.484463
    }, 
    'words': 'prom.cape.pump', 
    'language': 'en', 
    'map': 'https://w3w.co/prom.cape.pump'
}

Using Modules on Python

The use of different APIs with endpoints means you have to remember the URLs and query parameters for each of them. You have to create a request for each address with its query, headers and parameters. To simplify this process and automate most of the task involved, we use python modules that have functions to run geocoding. These modules (two particularly) help in geocoding by collating various APIs and their endpoints. You only have to provide the address (and an API key in some cases) to run geocoding.

Geocoder and GeoPy are powerful modules and offer a lot of features. In this blog, we cover the Geocoder module in detail. You can check out the documentation on using these both here – Geocoder, Geopy.

1. OSM Nominatim

The Nominatim Server is based on the OpenStreetMap and offers free geocoding without an API key. You can run as many requests as possible with the limitation of one request per second. Nominatim restricts the bulk geocoding with these rules. (from the Nominatim usage policy)

  • limit your requests to a single thread
  • limited to 1 machine only, no distributed scripts (including multiple Amazon EC2 instances or similar)
  • Results must be cached on your side. Clients sending, repeatedly, the same query may be classified as faulty and blocked.

This means you can make up to 86,400 geocoding requests per day.

However, if you have an Ubuntu machine and want to set up your own Nominatim server locally, you can do so by installing the Nominatim. Doing so will help you make as many geocoding requests as you want. Once you have set up the server, you can even update it regularly.


import geocoder as gc

# it doesn't require an API key
g = gc.osm('11 Wall Street, New York')
print(g.json)

"""
{'address': 'Redlands, California',
 'bbox': {'northeast': [34.12838000000007, -117.10958999999995],
  'southwest': [33.98238000000007, -117.25558999999994]},
 'confidence': 2,
 'lat': 34.05538000000007,
 'lng': -117.18258999999995,
 'ok': True,
 'quality': 'Locality',
 'raw': {'name': 'Redlands, California',
  'extent': {'xmin': -117.25558999999994,
   'ymin': 33.98238000000007,
   'xmax': -117.10958999999995,
   'ymax': 34.12838000000007},
  'feature': {'geometry': {'x': -117.18258999999995, 'y': 34.05538000000007},
   'attributes': {'Score': 100, 'Addr_Type': 'Locality'}}},
 'score': 100,
 'status': 'OK'}
"""

2. ArcGIS

For this service, you can do a similar query like OSM to get the resulting JSON object. You can also supply maxRows as a parameter to limit the number of responses received with geocoding.


import geocoder as gc

g = gc.arcgis('1433 S SAM HOUSTON BLVD, HOUSTON')
print(g.json)

"""
{
    "address":"1433 S Sam Houston Blvd, Houston, Missouri, 65483",
    "bbox":{
        "northeast":[
            37.31414338240304,
            -91.95921759521254
        ],
        "southwest":[
            37.31214338240304,
            -91.96121759521255
        ]
    },
    "confidence":9,
    "lat":37.31314338240304,
    "lng":-91.96021759521254,
    "ok":true,
    "quality":"StreetAddress",
    "raw":{
        "name":"1433 S Sam Houston Blvd, Houston, Missouri, 65483",
        "extent":{
            "xmin":-91.96121759521255,
            "ymin":37.31214338240304,
            "xmax":-91.95921759521254,
            "ymax":37.31414338240304
        },
        "feature":{
            "geometry":{
                "x":-91.96021759521254,
                "y":37.31314338240304
            },
            "attributes":{
                "Score":100,
                "Addr_Type":"StreetAddress"
            }
        }
    },
    "score":100,
    "status":"OK"
}
"""

3. Mapbox

This function uses all the parameters used by the Mapbox API. You can even set up an environment variable for your API key instead of using it directly in your script. You can define the API key by doing the following from your system's terminal.


$ export MAPBOX_ACCESS_TOKEN=|Secret Access Token|;

Parameters that can be used:

proximity: Search nearby [lat, lng]

bbox: Search within a bounding box [minX, minY, maxX, maxY]. Pass as an array.

country: Filtering by country code

method: (default=geocode) geocode, reverse


import geocoder as gc

g = gc.mapbox('1433 S SAM HOUSTON BLVD, HOUSTON', key=os.environ['MAPBOX_ACCESS_TOKEN'])
print(g.json)

""" 
{'address': '1433 South Sam Houston Boulevard, Houston, Missouri 65483, United States',
 'city': 'Houston',
 'country': 'United States',
 'housenumber': '1433',
 'lat': 37.313745,
 'lng': -91.962086,
 'ok': True,
 'postal': '65483',
 'quality': 1,
 'raw': {'id': 'address.5433137056342074',
  'type': 'Feature',
  'place_type': ['address'],
  'relevance': 1,
  'properties': {'accuracy': 'point'},
  'text': 'South Sam Houston Boulevard',
  'place_name': '1433 South Sam Houston Boulevard, Houston, Missouri 65483, United States',
  'center': [-91.962086, 37.313745],
  'geometry': {'type': 'Point', 'coordinates': [-91.962086, 37.313745]},
  'address': '1433',
  'context': [{'id': 'postcode.13130712598922390', 'text': '65483'},
   {'id': 'place.3932763880172470', 'wikidata': 'Q962428', 'text': 'Houston'},
   {'id': 'district.7195775730342410',
    'wikidata': 'Q477870',
    'text': 'Texas County'},
   {'id': 'region.8055790072597390',
    'wikidata': 'Q1581',
    'short_code': 'US-MO',
    'text': 'Missouri'},
   {'id': 'country.19678805456372290',
    'wikidata': 'Q30',
    'short_code': 'us',
    'text': 'United States'}],
  'postcode': '65483',
  'place': 'Houston',
  'district': 'Texas County',
  'region': 'Missouri',
  'country': 'United States'},
 'state': 'Missouri',
 'status': 'OK'}
"""

4. LocationIQ

This function uses all the parameters used by LocationIQ API. You can set up an environment variable for your API key just as for Mapbox instead of using it directly in your script. You can define the API key by doing the following from your system's terminal.


$ export LOCATIONIQ_API_KEY=|Secret API Key|;

Parameters that can be used:

url: custom osm server

maxRows: (default=1) Max number of results to fetch

method: (default=geocode) geocode


import geocoder as gc

g = gc.locationiq('1433 S SAM HOUSTON BLVD, HOUSTON', key=os.environ['LOCATIONIQ_API_KEY'])
print(g.json)

"""
{'accuracy': 0.511,
 'address': 'Walmart Supercenter, 1433, South Sam Houston Boulevard, Mineral Springs City, Houston, Texas County, Missouri, 65483, USA',
 'allotments': 'Mineral Springs City',
 'bbox': {'northeast': [37.3142924, -91.9621119],
  'southwest': [37.313216, -91.9630708]},
 'city': 'Houston',
 'confidence': 10,
 'country': 'United States of America',
 'country_code': 'us',
 'county': 'Texas County',
 'farm': 'Mineral Springs City',
 'hamlet': 'Mineral Springs City',
 'housenumber': '1433',
 'icon': '<https://locationiq.org/static/images/mapicons/shopping_supermarket.p.20.png>',
 'importance': 0.511,
 'isolated_dwelling': 'Mineral Springs City',
 'lat': 37.31353095,
 'lng': -91.9625989642648,
 'ok': True,
 'osm_id': '194856740',
 'osm_type': 'way',
 'place_id': '132580538',
 'postal': '65483',
 'quality': 'supermarket',
 'raw': {'place_id': '132580538',
  'licence': '<https://locationiq.com/attribution>',
  'osm_type': 'way',
  'osm_id': '194856740',
  'boundingbox': ['37.313216', '37.3142924', '-91.9630708', '-91.9621119'],
  'lat': '37.31353095',
  'lon': '-91.9625989642648',
  'display_name': 'Walmart Supercenter, 1433, South Sam Houston Boulevard, Mineral Springs City, Houston, Texas County, Missouri, 65483, USA',
  'class': 'shop',
  'type': 'supermarket',
  'importance': 0.511,
  'icon': '<https://locationiq.org/static/images/mapicons/shopping_supermarket.p.20.png>',
  'address': {'supermarket': 'Walmart Supercenter',
   'house_number': '1433',
   'road': 'South Sam Houston Boulevard',
   'hamlet': 'Mineral Springs City',
   'city': 'Houston',
   'county': 'Texas County',
   'state': 'Missouri',
   'postcode': '65483',
   'country': 'United States of America',
   'country_code': 'us'}},
 'region': 'Missouri',
 'state': 'Missouri',
 'status': 'OK',
 'street': 'South Sam Houston Boulevard',
 'type': 'supermarket'}
"""

5. MapQuest

This function uses all the parameters used by MapQuest API. You can set up an environment variable for your API key instead of using it directly in your script. You can define the API key by doing the following from your system's terminal.


$ export MAPQUEST_API_KEY=|Secret API Key|;

Parameters that can be used:

maxRows: (default=1) Max number of results to fetch

bbox: Search within a bounding box [minX, minY, maxX, maxY]. Pass as an array.

method: (default=geocode) geocode, batch


import geocoder as gc

g = gc.mapquest('1433 S SAM HOUSTON BLVD, HOUSTON', key=os.environ['MAPQUEST_API_KEY'])
print(g.json)

"""
{'address': '1433 S Sam Houston Blvd',
 'city': 'Houston',
 'country': 'US',
 'county': 'Texas',
 'lat': 37.313526,
 'lng': -91.960059,
 'ok': True,
 'postal': '65483-2131',
 'quality': 'POINT',
 'raw': {'street': '1433 S Sam Houston Blvd',
  'adminArea6': '',
  'adminArea6Type': 'Neighborhood',
  'adminArea5': 'Houston',
  'adminArea5Type': 'City',
  'adminArea4': 'Texas',
  'adminArea4Type': 'County',
  'adminArea3': 'MO',
  'adminArea3Type': 'State',
  'adminArea1': 'US',
  'adminArea1Type': 'Country',
  'postalCode': '65483-2131',
  'geocodeQualityCode': 'P1ABA',
  'geocodeQuality': 'POINT',
  'dragPoint': False,
  'sideOfStreet': 'L',
  'linkId': 'r25234418|p141805161|n33711116',
  'unknownInput': '',
  'type': 's',
  'latLng': {'lat': 37.313526, 'lng': -91.960059},
  'displayLatLng': {'lat': 37.313931, 'lng': -91.962339},
  'mapUrl': '<http://www.mapquestapi.com/staticmap/v5/map?key=qFUuYaYi7UVGhvUAniIvLG12ayLFk3ss&type=map&size=225,160&locations=37.313526,-91.960059|marker-sm-50318A-1&scalebar=true&zoom=15&rand=1291703922>'},
 'state': 'MO',
 'status': 'OK',
 'street': '1433 S Sam Houston Blvd'}
"""

Similarly, we can run the geocoding for other services like What3Words, FreeGeoIP.net etc.

Conclusion

Geocoding is an integral part of spatial data science. It helps convert every address of the data into usable and geographically mappable coordinates on the surface of the earth. But the costs of geocoding with these services are usually high in large scale projects. Therefore, we look for some free resources available to fulfil our needs. These services cover the most basic types of geocoding addresses for free. Thus, helping users with many of the use cases.

Subscribe to the blog now and get notified about future blog posts. You can find me on LinkedIn, Twitter for any queries or discussions. Check out my previous blog on How Alternative Data is Helping the Companies Invest Big here, and why you need to use Geopackage instead of Shapefile or Geojson here.

Nikhil Hubballi

Nikhil Hubballi

Hi there. My name is Nikhil Hubballi, and I’m a Data Scientist with a background in Space Sciences. Currently, as a Senior Data Scientist @PwC AC Kolkata‘s Spatial Analytics team, I work with geospatial data to derive actionable insights.

Do you like our stuff? Subscribe now.