Spatial Accessibility and Ridership Analysis of Toronto Bike Share Using QGIS & Kepler.gl

Teresa Kao

Geovis Project Assignment, TMU Geography, SA8905, Fall 2025

Hi everyone, in this project, I explore how cycling infrastructure influences Bike Share ridership across Toronto. Specifically, I examine whether stations located within 5 meters of protected cycling lanes exhibit higher ridership than those near unprotected lanes, and identify high-ridership stations that lack nearby protected cycling infrastructure.

This tutorial walks through the full workflow using QGIS for spatial analysis and Kepler.gl for interactive mapping, filtering, and data exploration. By the end, you’ll be able to visualize ridership patterns, measure proximity to cycling lanes, and identify where additional stations or infrastructure could improve accessibility.

Preparing the Data in QGIS

Importing Cycling Network and Station Data

Import the cycling network shapefiles using Layer -> Add Layer -> Add Vector Layer, and load the Bike Share station CSV by assigning X = longitude, Y = latitude, and setting the CRS to EPSG:4326 (WGS84).

Reproject to UTM 17N for Distance Calculations

Beacuse Kepler.gl only supports GeoJSON in EPSG:4326, all layers are first reprojected in QGIS to EPSG:26917 (Right click -> Export -> Save Features As…), distance calculations are performed there, and the processed results are then exported bak to GeoJSON (EPSG:4326) for use in Kepler.gl.

Calculating Distance to the Nearest Cycling Lane

Use the Join Attributes by Nearest tool ( Processing Toolbox-> Join Attributes by Nearest), setting the Input Layer to stations dataset, the Join Layer to the cycling lane dataset, and Maximum neighbors to 1. This will generate an output layer with a new field (distance_to_lane_m) representing the distance in meters from each station to its nearest cycling lane.

Creating Distance Categories

Use the Field Calculator (∑) to create distance bins using the following expression :

<CASE
WHEN "dist_to_lane_m" <= 50 THEN '≤50m'
WHEN "dist_to_lane_m" <= 100 THEN '≤100m'
WHEN "dist_to_lane_m" <= 250 THEN '≤250m'
ELSE '>250m'
END>

Exporting to GeoJSON for Kepler.gl

Since Kepler.gl does not support shapefiles, export each layer as a GeoJSON (Right click -> Export -> Save Features As -> Format: GeoJSON -> CRS: EPSG:4326). The distance values will remain correct because they were already calculated in UTM projection.

Building Interactive Visualizations in Kepler.gl

Import Data

Go to Layer -> Add Layer -> choose data

  1. For Bike Share Stations, use the point layer and symbolize it by the distance_to_lane_m field, selecting a color scale and applying Custom Breaks to represent different distance ranges.
  2. For Protected Cycling Network, use the polygon layer and symbolize it by all the protected lane columns, applying a custom ordinal stroke color scale such as light green.
  3. For Unprotected Cycling Network, use the polygon layer and symbolize it by all the unprotected columns, applying a custom ordinal stroke color scale such as dark green.
  4. For Toronto Boudary, use the polygon layer and assign a simple stroke color to outline the study area.

Add Filters

The filter slider is what makes this visualization powerful. Go to Add Filter – > Select a dataset -> Choose the field (for example ridership, distance_to_lane)

Add Tooltips

Go to Tooltip -> Toggle ON -> Select fields to display. Enable tooltips so users can hover a station to see details, such as station name, ridership, distance to lane, capacity.

Exporting Your Interactive Map

Export image, table(csv), and map (shareable link) -> uses Mapbox Api to create an interactive online map that others can explore.

How this interactive map help answer the research question

This interactive map helps answer the research question in two ways.
First, by applying a filter on distance_to_lane_m, users can isolate stations located within 50 meters of a cycling lane and visually compare their ridership to stations farther away. Toggling between layers for protected and unprotected cycling lanes allows users to see whether higher ridership stations tend to cluster near protected infrastructure.

Based on the map, the majority of higher ridership stations are concentrated near protected cycling lanes, suggesting a positive relationship between ridership and proximity to safer cycling infrastructure.

Second, by applying a ridership filter (>30,000 trips), the map highlights high demand stations that lack nearby protected cycling lanes. These appear as busy stations located next to unprotected lanes or more than 50 meters away from any cycling facility.

Together, these filters highlight where cycling infrastructure is lacking, especially in the Yonge Church area and the Downtown East / Yonge–Dundas corridor, making it clear where protected lanes may be needed.

Final Interactive Map

Mapping Child Friendly City Initiatives in Canada and in the World using ArcGIS StoryMaps

Anastasiia Smirnova
SA8905 Geovis project, Fall 2022

Introduction

Through this project I wanted to gain and advance my skills in both storytelling and visualizing spatial data. Here you can learn more about my attempt of using ArcGIS StoryMaps to highlight the importance of including children in the urban planning agenda and to show the World- and Canada-wide spatial patterns of urban areas’ commitment to creating inclusive urban environments with children in mind.

I did it by mapping municipalities that are participating in UNICEF’s Child Friendly Cities Initiatives (CFCI), which aim to promote cities where the “ voices, needs, priorities and rights of children are an integral part of public policies, programs and decisions.”

Technology

I used ESRI’s ArcGIS Pro, Online Map Viewer and StoryMaps for my project. First, I used the desktop app (ArcGIS Pro) to import my data and create my initial maps. After that I uploaded the layers that I wanted to use as web layers to my ArcGIS account, and then I finalized them using ArcGIS online applications. I used the online map viewer to adjust symbology as necessary as was trying to figure out what worked better for each part of my story. It was easy to go back and forth between the Map Viewer and StoryMaps – to make the necessary changes, then to see how the updated maps work with the story, and then repeat these steps as needed. The Map viewer generally had the functionality I needed to change my map symbology and I did not have to go back to ArcGIS Pro too often to make modifications after I uploaded my layers online.

I liked the functionality of StoryMaps. I used the sidecar option to introduce my story, and for showing most of my maps. I find that this block type provides some of the most immersive experience while scrolling, so I used it for the parts of the story that I wanted to keep the reader’s attention on.

I found that the swipe option worked well for showing comparisons. In a regular map, it is often difficult to show all information you want without cluttering the map with too many layers and making the map unreadable. The swipe option can help solve this problem. As such, I used this function to show how many children did (not) live within the municipalities that were part of CFCI and therefore could (not) benefit from the initiative.

the map shows distribution of children and youth residences (on the left, yellow and red) and municipalities involved in CFCI (on the right, blue)

For inserting your maps to any blocks of StoryMaps, you can choose to either use your maps uploaded as images or insert the actual interactive online maps. While the image option has some benefits, such as more flexibility in styling the map and faster loading, the main benefit of inserting the actual online maps is interactivity. You can zoom in and out, search for a specific location, show/hide legend, learn more about each unit on the map and so on (as the creator of the story, you can edit and set restrictions of what readers can and cannot do with your online maps).

Since I wanted to keep my maps as simple visually as possible, I went with the second option. This way, if the reader wanted to learn more about my maps and the information they displayed, they could do so by using the interactive map functions.

Interesting findings

In addition to the main message of the project (the need to promote child friendly cities), the maps showed how the choice of data, scale and mapping methodology can influence the results and representation. On the CFCI website, the main map was showing all countries that were involved in the CFCI. The map did not consider how many municipalities in each country were actually involved in the initiatives.

The main map from the UNICEF CFCI website – CFCI countries

This way of displaying data may be misleading, since the level involvement of each country varied greatly. In some countries, most of the territory was part of CFCI, but some other countries only had a couple municipalities each with UNICEF’s child friendly initiatives.

For this story, in addition to the world CFCI country map similar to the one from the website, a proportional symbol map was created to show how many municipalities from each country were actually involved in the CFCI and I put these two maps in one sidecar block so that the reader could swipe back and forth to see how the distribution of CFCI changed with the change of the variable, and what the actual level of involvement if each country was.

A map from my StoryMap – Municipalities involved in CFCI

When zoomed in, even more information about the unevenness and clustering in the spatial distribution of the CFCI municipalities can be discovered.

The sidecar block (I used the float side by side option for my maps), and the smooth transitions it provided, worked well for showing the differences between the maps, as well as for zooming in into a smaller scale map.

Challenges

Some of the main challenges for me were associated with updating the maps if I wanted to change something. It took some time for me to figure out what could be done at which step of the process (with different apps) and how far back I had to go to modify something. As such I had trouble updating and modifying the legends for the maps.

Unfortunately, the options for adjusting the legends using the ArcStory editor or the online map viewer were limited. For instance, it was impossible to hide or edit the name of the column which contained data used in the map while using the online apps. Since I was creating my original layers in ArcGIS Pro, then uploading them as web layers, and then adjusting my maps further in the online map viewer, it was difficult to go back to change the original data in the end, just to modify one little line on the map legend. Only some parts of the legend could be modified using the online apps. So, one of the lessons I took from this experience is that you need to make sure all the column names are appropriate before making all the edits online if you are using a similar process as I did. It is also helpful to think about the legends right from the start.

Conclusion and results

In general, I am satisfied with the ArcGIS StoryMap platform. It was easy to use, and it did a good job of assisting me in creating a map-based story that looks clean and flows smoothly. I am planning on further exploring the StoryMap functionality in the future.

If you are interested in learning more about child friendly cities and seeing my StoryMap result, you can follow this link:

Canadian cities and towns for happy children (arcgis.com): Mapping Child Friendly City Initiatives in Canada and in the World using ArcGIS StoryMaps