Building an automated Bus Tracker

Building an automated Bus Tracker

Around 2010, the CTA published a bus-tracking website for public use. Then, it was a lifesaver, but I was always frustrated about the effort it took. One had to input the bus route they were looking for, the direction of travel, and the bus stop they were closest to. In the time it took to navigate a drop-down menu of every bus and then every stop on that bus, you could miss it.

Years later, I decided to take programming seriously and enroll in a boot camp. After gaining admission, I thought of project ideas and remembered my frequent issues with the bus tracker website. I researched the CTA and learned they had a real-time bus-tracking API available. After briefly covering React, I decided to start the project.

I got an API key and started making requests. I learned I could get a list of vehicles and use the route numbers to get their positions within the city. I used geocoding to get the names of streets in a 3-5 block radius around a user's position. Then, I compared the coordinates with the bus positions to find the closest ones. I spent a week or so testing on my laptop and phone and shipped what I thought was a complete bus tracker.

I sent it out to some friends and soon learned it was non-functional in certain parts of the city. I double-checked my code and tests but didn't know what I did wrong. A while later, I realized that every bus I rode in Chicago was named after the street it serviced. The issue is many buses in Chicago service multiple streets and are named after the neighborhoods they depart from or where the route ends. I realized I could cross-reference the surrounding street names with a list of bus stops to find the routes that service them.

However, the bus stop requests weren't working for me. I thought I was dealing with a deprecated endpoint and old documentation, but I was too early in my career to believe myself. I figured I needed to learn to use the API properly and moved on.

Four years later, after working in different environments, starting many other side projects, and extensive studying, I decided to take another shot at it. I knew my original idea would work. I just had to find a way to source the data I needed to complete it. In 2020 and again in 2024, I dreaded the thought that I would have to write a Javascript object with every bus route as a key for an array of bus stops they service. There are 127 routes in Chicago and 100+ stops on some of those routes.

Coincidentally, I had semi-recently spent a day or so web-scraping and realized this could be what I needed. After researching the CTA and publicly available data, I devised a solution for scraping every bus stop in Chicago.

I used Node and Python to gather all of the data. I parsed the data to extract the bus stops and wrote a function to clean duplicates, remove unwanted text, and map the stops to their route numbers. I changed the logic of the bus tracker completely, so I had to rewrite some of the code, which helped a lot because my technique wasn't the best. After a few working tests at my residence, I went out for a field testing day and got better results than before.

As of today, this project exists as Transit, a fully automated bus tracker that covers the entire city of Chicago. In the coming months, I'm looking to make updates to make it more useful for riders. These may include prediction times, additional route info, and nearby trains. Delays in public transportation are common in Chicago, so the essence of the service is to know what is around you at a moment's notice.

You can check out the project here:

And you can follow me on Twitter @chrismojekwu_ for updates & random thoughts.