GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • The Python Code
  • Tutorials
  • Ethical Hacking
  • Machine Learning
  • General Python Tutorials
  • Web Scraping
  • Finance
  • Computer Vision
  • Python Standard Library
  • Application Programming Interfaces
  • Database
  • Game Development
  • Web Programming
  • Digital Forensics

This view

  • Original page
  • New address

GeezerVison is showing thepythoncode.com — How to Get Geolocation in Python - The Python Code

Unlock the secrets of your code with our AI-powered Code Explainer. Take a look!

Geocoding is the process of transforming a description of a location (such as a physical address or the name of a place) into a pair of latitude and longitude on the Earth's surface for that place.

It also refers to converting geographic coordinates to a description of a location (such as an address); this is often called reverse geocoding. In this tutorial, we will learn how to do both with the help of the GeoPy library in Python.

However, if you want to geolocate IP addresses, then this tutorial is for you.

GeoPy is a Python client that provides several popular geocoding web services; it makes it easy for Python developers to locate the coordinates of an address, a city, or a country, and vice-versa.

To get started, let's install it:

pip3 install geopy

GeoPy provides many geocoding service wrappers, such as OpenStreetMap Nominatim, Google Geocoding API V3, Bing Maps, and more. In this tutorial, we gonna stick with OpenStreetMap Nominatim.

Here is what we'll be covering:

  • Getting Latitude and Longitude from an Address (Geocoding)
  • Getting Address from Latitude and Longitude (Reverse Geocoding)

Getting Latitude and Longitude from an Address (Geocoding)

In this section, we will use OpenStreetMap Nominatim API to get latitude and longitude from a physical address, city, or any location name.

Let's import the library first:

from geopy.geocoders import Nominatim
import time
from pprint import pprint

Notice we chose Nominatim geocoder, now creating a new instance of it:

# instantiate a new Nominatim client
app = Nominatim(user_agent="tutorial")

Now, let's try to get geographic data from an address:

# get location raw data
location = app.geocode("Nairobi, Kenya").raw
# print raw data
pprint(location)

Output:

{'boundingbox': ['-1.444471', '-1.163332', '36.6509378', '37.1038871'],
 'class': 'place',
 'display_name': 'Nairobi, Kenya',
 'icon': 'https://nominatim.openstreetmap.org/images/mapicons/poi_place_city.p.20.png',
 'importance': 0.845026759433763,
 'lat': '-1.2832533',
 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. '
            'https://osm.org/copyright',
 'lon': '36.8172449',
 'osm_id': 9185096,
 'osm_type': 'relation',
 'place_id': 273942566,
 'type': 'city'}

Awesome, we have latitude at lat attribute (in which we can access by location['lat']) and longitude at lon attribute, we also have access to the bounding box of the address at the boundingbox attribute.

As you can see, the Nominatim API does not require a full address (that consists of street, house number, and city), you can also pass business addresses and points of your interests, it supports that!

However, if you call this function repeatedly (such as iterating over a list of addresses), you will encounter a timed-out error, and that's because if you read the Nominatim Usage Policy, it requires you to use a maximum of 1 request per second, and that's absolutely acceptable since it's a free service.

As a result, the below function respects that requirement and sleeps for one second before making a request:

def get_location_by_address(address):
    """This function returns a location as raw from an address
    will repeat until success"""
    time.sleep(1)
    try:
        return app.geocode(address).raw
    except:
        return get_location_by_address(address)

So whenever a timed-out error is raised, we catch that and call the function recursively, and this function will sleep for another second and hopefully, retrieve the result:

address = "Makai Road, Masaki, Dar es Salaam, Tanzania"
location = get_location_by_address(address)
latitude = location["lat"]
longitude = location["lon"]
print(f"{latitude}, {longitude}")
# print all returned data
pprint(location)

Output:

-6.7460493, 39.2750804
{'boundingbox': ['-6.7467061', '-6.7454602', '39.2741806', '39.2760514'],
 'class': 'highway',
 'display_name': 'Makai Road, Masaki, Msasani, Dar es-Salaam, Dar es Salaam, '
                 'Coastal Zone, 2585, Tanzania',
 'importance': 0.82,
 'lat': '-6.7460493',
 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. '
            'https://osm.org/copyright',
 'lon': '39.2750804',
 'osm_id': 23347726,
 'osm_type': 'way',
 'place_id': 89652779,
 'type': 'residential'}

Getting Address from Latitude and Longitude (Reverse Geocoding)

Now, to retrieve an address, city, country, and various other information only from latitude and longitude, we simply use the reverse() method instead of geocode(), which accepts coordinates (latitude and longitude) as a string separated by a comma.

The following function reverses the coordinates while respecting Nominatim usage policy:

def get_address_by_location(latitude, longitude, language="en"):
    """This function returns an address as raw from a location
    will repeat until success"""
    # build coordinates string to pass to reverse() function
    coordinates = f"{latitude}, {longitude}"
    # sleep for a second to respect Usage Policy
    time.sleep(1)
    try:
        return app.reverse(coordinates, language=language).raw
    except:
        return get_address_by_location(latitude, longitude)

So this function expects latitude and longitude as parameters and returns the raw geographic data, here is an example usage:

# define your coordinates
latitude = 36.723
longitude = 3.188
# get the address info
address = get_address_by_location(latitude, longitude)
# print all returned data
pprint(address)

Output:

{'address': {'country': 'Algeria',
             'country_code': 'dz',
             'county': 'Dar El Beida District',
             'postcode': '16110',
             'state': 'Algiers',
             'town': 'Bab Ezzouar'},
 'boundingbox': ['36.7231765', '36.7242661', '3.1866439', '3.1903998'],
 'display_name': 'Bab Ezzouar, Dar El Beida District, Algiers, 16110, Algeria',
 'lat': '36.72380363740118',
 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. '
            'https://osm.org/copyright',
 'lon': '3.188236679492425',
 'osm_id': 42812185,
 'osm_type': 'way',
 'place_id': 98075368}

So this will return all address data, including state, town, postcode, districts, and more. If you wish to return this information in a specific language, you can set language parameter to the language you desire, or you can set it to False for the default language for that specific location.

Conclusion

As always, we only saw simple examples of what GeoPy can do; I highly suggest you read the documentation if you're interested in more advanced utilities.

Learn also: How to Get Domain Name Information in Python.

Happy Coding ♥

Want to code smarter? Our Python Code Assistant is waiting to help you. Try it now!

View Full Code Create Code for Me
Sharing is caring!

Read also

How to Use Google Drive API in Python

Learn how you can use Google Drive API to list files, search for specific files or file types, download and upload files from/to Google Drive in Python.

How to Use Github API in Python

Using Github Application Programming Interface v3 to search for repositories, users, making a commit, deleting a file, and more in Python using requests and PyGithub libraries.

How to Use Google Custom Search Engine API in Python

Learning how to create your own Google Custom Search Engine and use its Application Programming Interface (API) in Python.

Comments

    Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!




    Get our free Python guides

    Join 50,000+ Python programmers and enthusiasts like you!

    Topics
    Ethical Hacking Machine Learning General Python Tutorials Web Scraping Finance Computer Vision Python Standard Library Application Programming Interfaces Database Game Development Web Programming Digital Forensics Natural Language Processing Healthcare PDF File Handling Python for Multimedia GUI Programming Cryptography Packet Manipulation Using Scapy
    New tutorials View all
    • How AI Text Detection Works: The Technology Behind Modern AI Detectors
    • Beyond Guesswork: How Python Helps Identify AI-Generated Text
    • Discover the Possibilities of Python Programming
    • How to Track Your AI Visibility with Python
    • How to Automate Excel Reports in Python using Openpyxl
    Popular tutorials View all
    • How to Convert Speech to Text in Python
    • How to Read Emails in Python
    • How to Extract Tables from PDF in Python
    • How to Control your Mouse in Python
    • How to Make a Keylogger in Python
    Ethical Hacking with Python EBook - Topic - Bottom CodingFleet - Topic - Bottom
    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.