Geocoding in Python Tutorial

Geocoding is a very important task this days to locate your customers as well as find addresses and which are properly formatted.
For this tutorial we have used Geokeo Geocoder Api. You can sign up for free and get 2500 api limit daily.



First we will learn how to forward geocode then reverse geocode then do the same with mysql.

Forward Geocoding in Python


Forward geocoding is nothing but converting addresses to latitude and longitude

for eg- empire state building -> LAT-40.74843124430164 , LNG- -73.9856567114413
Formatted address- Empire State Building,Manhattan Island,Midtown South,5th Avenue,New York County,New York City,10018,United States Of America.

This can be used geolocate your customers to a known location and provide service as required. Find postal address and various many activities
import requests

url = 'https://geokeo.com/geocode/v1/search.php?q=empire+state+building&api=YOUR_API_KEY'


resp = requests.get(url=url)
data = resp.json()
if 'status' in data:
    if data['status']=='ok':
        address=data['results'][0]['formatted_address']
        latitude=data['results'][0]['geometry']['location']['lat']
        longitude=data['results'][0]['geometry']['location']['lng']
        #do something with the data

In the line url = "https://geokeo.com/geocode/v1/search.php?q=empire+state+building&api=YOUR_API_KEY"
two parameters are used one is the string which is to be searched (empire state building) another is YOUR_API_KEY which can be available by login to geokeo.com and in the dashboard api section.
Responses are available in json and xml format. default is json format. for more information follow the documentation.



The result of the last query is

{
  "results": [
     {
      "class": "tourism",
      "type": "attraction",
      "address_components": {
        "name": "Empire State Building",
        "island": "Manhattan Island",
        "neighbourhood": "Midtown South",
        "street": "5th Avenue",
        "subdistrict": "Manhattan",
        "district": "New York County",
        "city": "New York City",
        "state": "New York",
        "postcode": "10018",
        "country": "United States Of America"
      },
      "formatted_address": "Empire State Building,Manhattan Island,Midtown South,5th Avenue,New York County,New York City,10018,United States Of America",
      "geometry": {
        "location": {
          "lat": "40.74843124430164",
          "lng": "-73.9856567114413"
        },
        "viewport": {
          "northeast": {
            "lat": "40.747922600363026",
            "lng": "-73.9864855"
          },
          "southwest": {
            "lat": "40.74894220036315",
            "lng": "-73.98482589999999"
          }
        }
      },
      "osmurl": "https://www.openstreetmap.org/search?query=40.74843124430164%2C-73.9856567114413#map=17/40.74843124430164/-73.9856567114413",
      
    }
  ],
  "credits": "https://geokeo.com/credits.php",
  "status": "ok"
}

In pyhton json data is directly available for which we invoke data=resp.json(). Then the data is available as associative dict as well as indexed array.

Reverse Geocode in Pyhton


Reverse geocoding is just the opposite of forward geocoding- for eg- 40.74843124430164,-73.9856567114413 -> Formatted address- Empire State Building,Manhattan Island,Midtown South,5th Avenue,New York County,New York City,10018,United States Of America. This can be utilized to format addresses from data received from browser location or android devices etc.
import requests

url = 'https://geokeo.com/geocode/v1/reverse.php?lat=40.74842&lng=-73.9856&api=YOUR_API_KEY'


resp = requests.get(url=url)
data = resp.json()
if 'status' in data:
    if data['status']=='ok':
        address=data['results'][0]['formatted_address']
        latitude=data['results'][0]['geometry']['location']['lat']
        longitude=data['results'][0]['geometry']['location']['lng']
        #do something with the data
In the line url = "https://geokeo.com/geocode/v1/reverse.php?lat=40.74842&lng=-73.9856&api=YOUR_API_KEY" three parameters are used one is the latitude which is to be searched (40.74842) another is longitude (-73.9856) and another is YOUR_API_KEY which can be available by login to geokeo.com and in the dashboard api section.

Responses are available in json and xml format. default is json format. for more information follow the

The result of the last query is

{
  "results": [
     {
      "class": "tourism",
      "type": "attraction",
      "address_components": {
        "name": "Empire State Building",
        "island": "Manhattan Island",
        "neighbourhood": "Midtown South",
        "street": "5th Avenue",
        "subdistrict": "Manhattan",
        "district": "New York County",
        "city": "New York City",
        "state": "New York",
        "postcode": "10018",
        "country": "United States Of America"
      },
      "formatted_address": "Empire State Building,Manhattan Island,Midtown South,5th Avenue,New York County,New York City,10018,United States Of America",
      "geometry": {
        "location": {
          "lat": "40.74843124430164",
          "lng": "-73.9856567114413"
        },
        "viewport": {
          "northeast": {
            "lat": "40.747922600363026",
            "lng": "-73.9864855"
          },
          "southwest": {
            "lat": "40.74894220036315",
            "lng": "-73.98482589999999"
          }
        }
      },
      "osmurl": "https://www.openstreetmap.org/search?query=40.74843124430164%2C-73.9856567114413#map=17/40.74843124430164/-73.9856567114413",
      "distance": "0.0010302984507433km"

      
    }
  ],
  "credits": "https://geokeo.com/credits.php",
  "status": "ok"
}

The extra result here is the distance which shows how far the actual co ordinates are from the available address in the database.

Forward geocoding in Python with Mysql



Mysql is a very popular database which can be used to fetch data from database and feed to the above function to update your database.
import mysql.connector
import requests

mydb = mysql.connector.connect(
  host="localhost",
  user="user",
  password="password",
  database="db"
)  


mycursor = mydb.cursor()
savecursor = mydb.cursor()
mycursor.execute("SELECT id, address FROM addresses")

myresult = mycursor.fetchall()

for x in myresult:
    id=x[0]
    address=x[1]
    url = 'https://geokeo.com/geocode/v1/search.php?q='+address+'&api=YOUR_API_KEY'


    resp = requests.get(url=url)
    data = resp.json()
    if 'status' in data:
        if data['status']=='ok':
            formattedaddress=data['results'][0]['formatted_address']
            latitude=data['results'][0]['geometry']['location']['lat']
            longitude=data['results'][0]['geometry']['location']['lng']
            query="UPDATE addresses SET formattedaddress='"+formattedaddress+"',latitude='"+latitude+"',longitude='"+longitude+"' WHERE id="+id
            savecursor.execute(query)
            mydb.commit()
This snippets of code can be utilized to convert your unformatted addresses into formatted addresses with proper latitude and longitude data.This method can be used to do bulk geocoding or batch geocoding.

Happy Geocoding

Team GEOKEO.