Day 3: Working with Data and Writing Readable Code

Day 3: Working with Data and Writing Readable Code#

Note

Do not use AI tools to complete the exercises. The goal is to learn how to write code yourself, not to rely on AI tools.

Learning Goals#

  1. Use a clear and consistent directory structure in your project.

  2. Modularize your code for better reusability.

  3. Explain the differences between inheritance and composition in object-oriented programming.

  4. Name classes, functions, and variables in a way that makes their purpose clear to enhance code readability.

  5. Create static and interactive maps in Python.

  6. (Merge code from another branch into yours and resolve possible merge conflicts.)

Coding Goals#

We want to analyze pedestrian routes in regard to solar exposure and length in Heidelberg, generated by openrouteservice (ORS). This specialized version of openrouteservice considers the solar exposure of roads throughout the day and takes it into account when calculating the route. The routes were generated for different times of the day and different destinations, such as schools or workplaces.

routes from HEAL App

To analyze the routes, we need to write a class that can read the ORS response and calculate metrics for the routes. We will try to reuse code from the Line class we created on day 2. The data is available via heibox (see below).

Preparation#

  1. Pull the latest changes from the main branch of the Gitlab repository https://courses.gistools.geog.uni-heidelberg.de/advancedgeoscripting/advanced-geoscripting to your local repository:

git checkout main
git pull origin main

If you have local changes in your own branch that you want to keep, create commits. Otherwise, you may use git stash to temporarily remove your local changes.

  1. Create a new branch from the main branch, using your name and the suffix _day3 for the branch name (for example: lisa_day3).

  2. Download the generated routes from heiBOX: https://heibox.uni-heidelberg.de/f/5c03a0175317493a96f1/?dl=1 and store them in the directory ./data in your repository.

Exercises#

  1. First, take a look at the content of the ORS response. Open the file data/HEAL_routes_170/1pm/routes_heal_1_bus.geojson in the IDE. Find the following information in the file and its name. Extract the data using Python:

    • The coordinates of the route as a list.

    • The length of the route.

    • The duration of the route.

    • The route ID from the file name.

    • The destination type from the file name.

    • The time of day from the file name.

Since it is very cumbersome to extract the information from a dictionary, we will write a Route class that extracts and stores all relevant information.

  1. Write a Route class to handle the route data according to the specifications below.

    A Route object should be created by giving a path of the geojson file, e.g.

    route = Route("data/route_school_morning.geojson")
    

    The class should extract the following information from the file and store it as attributes in the class: - id: The ID of the route from the file name.
    - destination_type: The type of destination (e.g., “school”, “work”, etc.) from the file name.
    - time_of_day: The time of day when the route was generated, from the file name.
    - coordinates: A list of tuples containing the coordinates of the route.

    The class should contain the following methods from the Line class from day 2:
    - length: A method that calculates the length of the route using the Line class from day 1.
    - slopes: A method that calculates the slopes of the route segments using the Line class from day 1.

  2. Think about how we could build a Route class, so that it takes advantage of the methods we need from the existing Line class. We’ll discuss this in the group.

  3. Implement a basic version of the Route class that extracts the required attributes from the file name and stores the geometry of the route.

  4. Check if the length() method of the Line class works for the Route class. Write a test that uses the distance calculated by openrouteservice as a reference value.

  5. Add a method convert_coordinates() that converts the coordinates from WGS84 to UTM coordinates (for Heidelberg, use EPSG:25832).

  6. Push your changes to Gitlab and create a merge request.

Bonus#

  1. Write a method called plot() that plots the route on a static image with a basemap. Tip: Use geopandas and contextily for this.

  2. Write a method called explore() that creates an interactive map of the route using the explore method of GeoPandas.

  3. Write a method called as_dataframe() that converts the route to a GeoDataFrame.

  4. Write a method called get_solar_exposure which extracts the solar exposure index along the route from the values section of the ORS response. It should return a GeoDataFrame with the solar exposure index values for each segment of the route. The segments should be defined as LineString geometries.

Explanation for the values section in the ORS response:

  • First number: Start node

  • Second number: End node

  • Third number: Solar exposure index value from start node to end node

  • Value range: 0 (no sun) - 100 (all sun)

  1. Write a method that calculates the mean solar exposure index of the route. It should be a weighted mean depending on the length of the route segments.