One Year of Citibiking

Published October 24, 2017

This week’s project is an attempt to visualize a year’s worth of my Citi Bike trip history.  I chose to do this because I use the Citi Bike bike sharing system often (>500 times within the last year) and wanted to learn to work with maps and mapping APIs in javascript.  The end result is an animation from October 2016 to October 2017 displaying all rides as they happen.

Wish List:

  • Trips should display the full route as pulled from Google Maps’ Directions API.  This was partially implemented, but not finished.

  • Regular commuting routes should appear increasingly visible as the number of times they’ve been ridden increases.  I didn’t know whether to implement this by associating stations with a times-visited variable, or to make this happen visibly by drawing everything at a low alpha level, and having the stacking make it happen.

Data Sources:

The data for this project came from a few different places and in a few different formats:

  • I found my ride history on the Citi Bike website within the “Trips” menu (after I had logged in).  Unfortunately, this data did not come quite as neatly organized as I had hoped.  The “Export” function opened a web page from which I could copy and paste the data into a text file.  The individual trip datum (trip starting time, trip starting station, etc.) were separated by newlines, and each block of 5 lines made up the available data about a single trip.   I pulled a year’s worth of ride data (the maximum amount allowed at once) from this web interface, and copied it into a text file.  In my P5.js sketch, I use the loadStrings() function to separate this text into an array of strings, each composing a single line, and use a callback function to place each string into a Trip object and add that object to an array of Trip objects.

  • Citibike station information is made available in JSON format through the Citibike API, and contains, among other things, the name, latitude and longitude of each Citibike station.  Because the trip information I had downloaded did not contain the latitude and longitude, this would be vital to map any of my trips.  I loaded this information into my sketch using the loadJSON() function, using a callback function to add the name, latitude and longitude of each station into a Station object, which I then added into an array of Station Objects.

Code Organization:

  • There was a great degree of trial and error in my code organization.  As I slowly realized why certain organizational strategies made better logical sense and required less debugging, I would rewrite portions of my code to match these understandings.  At this point, trip and station data are stored separately in their own objects.  I would ideally like to have one set of trip objects, which contains all trip related information, including route data pulled from the Google Maps Directions API.  Unfortunately, when I tried to merge data from the two relatively large (>500 points each) arrays of objects (trips and stations), I ran into infinite loop errors.  Eventually I realized that this error was from the editor, and managed to solve it by switching to an offline text editor and using http-server to test my code.

  • I used the javascript Date() object to compare dates between the (somewhat confusingly named) “now” variable – which refers to the current time of the animation – and the start and end times of each trip.  The Date.parse() function managed to pull data from the Citi Bike trips textfile in the format “09/28/2017 7:54:16 AM” so that I could compare the two using boolean operators.

  • Google Maps Directions: I used the Google Maps Directions API, along with the origin and destination coordinates of Citi Bike stations, to pull route data.

  • All latitude/longitude to X,Y coordinate conversions were done using the Mappa library’s “latLngToPixel()” function.