Bonus: Working with APIs#

Apparently the best Pizza place in New York Lombardi’s pizza. Let’s assume you want to find a hotel with is as close as possible to this place.

lombardi_pizza_coords = (40.7215577, -73.9956097)

Exercise 3.1: Create an interactive map showing all hotels and the Lombardi’s pizza.

Exercise 3.2: Calculate the distance in meters between Lomabardi’s pizza and each hotel. Don’t forget to reproject the dataframe into a suitable coordinate references system.

Exercise 3.3: Create an interactive map which shows the points colored by the distance to the pizza place.

Calculate distance using openrouteservice#

The euclidean distance is not always a good estimate for the real distance. So we will use the openrouteservice API to calculate the real routes.

Preparation#

  1. Install openrouteservice-py in your environment using pip install openrouteservice.

  2. Create an account at https://openrouteservice.org/dev/#/login and generate a token/API key. Paste the API key below

api_key = ''

Example#

Here’s an example of how to generate a route by sending a request to the openrouteservice API.

from openrouteservice import Client
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[3], line 1
----> 1 from openrouteservice import Client

ModuleNotFoundError: No module named 'openrouteservice'
client = Client(key=api_key)
start_coords = (-73.9684581756592, 40.75580720140376)
destination_coords = (-73.9956097, 40.7215577)
response = client.directions([start_coords, destination_coords], 
                             profile='foot-walking',    
                             instructions=False, 
                             format='geojson')

Convert response to geodataframe

route_df = gpd.GeoDataFrame.from_features(response, crs='epsg:4326')

Plot route in interactive map

route_df.explore()
Make this Notebook Trusted to load map: File -> Trust Notebook

Routes between Pizza and hotels#

To reduce the amount of request to the openrouteservice API, we will only look at hotels within 4km distance of the pizza place.

Exercise: Select all hotels which are in 3 km euclidean distance of the pizza place.
Iterate over each row in the hotels dataframe and calculate the route between the hotel and the pizza place.

selected_hotels = 

Exercise: Iterate over the hotels geodataframe and calculate the route between each of the selected hotels and the pizza place. This includes:

  1. Store all routes in one GeoDataFrame.

  2. Extract the distance from the openrouteservice response and store it in a new column called distance_ors in the selected_hotels dataframe.

  1. Calculate the difference between the euclidean distance and the ors distance

  1. Plot everything on a nicely styled interactive map.

Find the nearest pizza place of each hotel#

This is an example of how to download data from OSM using the ohsome API.

from ohsome import OhsomeClient
ohsome_client = OhsomeClient()

Send request to ohsome API (see API endpoints and documentation).

ohsome_response = ohsome_client.elements.geometry.post(filter='cuisine=pizza', 
                                                       properties='tags',
                                                       bboxes=[-74.01722,  40.69631, -73.98163,  40.7473])

Convert to geopandas dataframe

pizza_df = ohsome_response.as_dataframe()
pizza_df.explore()
Make this Notebook Trusted to load map: File -> Trust Notebook

Now find the nearest pizza place for each hotel.

More on Pandas and vectorization#

Watch this talk by Sofia Heisler’s repository PyCon 2017: Optimizing Pandas Code for Performance to get a more indepth look into vecotrized computation using pandas.

→ Watch her talk on YouTube I really recommend it (especially if you like panda GIFs)

→ Read her blog post

GeoPandas is great, and now even fast!#

Geopandas make spatial analysis in Python a lot easier, but it used to have a bottleneck: geometric opertions are performed using shapely, which - as we have seen - is not the fastest, since it is performed in Python. In addition, operations along a series of shapely objects cannot be vectorized in Python.

But the GeoPandas developers also found a solution for this problem: Yet another package - PyGEOS. The PyGEOS packages allows vectorized geometric calculations based on the C library GEOS. In 2023, PyGEOS was merged with shapely in version 2.0. So now shapely and therefore also geopandas can perform vectorized geospatial operations.

–> FOSS4G Talk: State of GeoPandas and friends Unfortunately the presentation is not online, but here is a similar one.

Watch conference talks on YouTube or do tutorials on GitHub, they are a great way to stay up-to-date with current developments in the scientific Python world and great resource to learn

Resources#

Introducing pygeos

PyGEOS Documentation

Cythonize Pandas

https://stackoverflow.com/questions/52673285/performance-of-pandas-apply-vs-np-vectorize-to-create-new-column-from-existing-c

https://www.google.com/url?q=http://homepages.math.uic.edu/~jan/mcs275/running_cython.pdf&sa=U&ved=2ahUKEwiq_M3-vfrqAhWF-KQKHXBXCfwQFjAAegQICRAB&usg=AOvVaw0jX9BZrTt2aPsxKo30zmDb