Homework 4: Interacting with Data Using Processing

Due date: see class schedule.

In this homework you’ll gain experience with Processing, and developing interactive, graphical programs. You’ll also gain experience in setting up and using external libraries with Processing.

Your assignment in this homework is to create an interactive program that displays a map of geo-tagged tweets. Your program will read in a JSON file of tweets (provided on T-Square, in the resources folder, called tweets.json), analyze these to extract contents and location, and then display these on an interactive map. The map should allow users to zoom in/out and pan, and when the user hovers over the location of a tweet (as indicated by its on-screen marker), the tweet’s marker should be highlighted and additional information about the tweet should be displayed. If the user presses the mouse on a tweet’s marker, additional information should be displayed about it in the form of a popup area near the marker. The popup should be dismissed when the user releases the mouse button, and the marker should be returned to its initial visual appearance when the mouse moves out of it.

For mapping, we’ll use a Processing package called Unfolding Maps. Be sure to note that the version of Unfolding that is on the developer’s web site does not work with Processing 3. You’ll have to use the beta version, which is also available on T-Square in the resources folder.

An additional requirement of this assignment is that you must use a custom class of your definition that you will use to store the information about each tweet; this is to give experience in object-oriented programming.

In order to get set up for this project, you must first install Unfolding Maps on your computer. After downloading and expanding the ZIP file from t-square, you’ll need to install it in Processing’s library folder. To figure out where this is, go to the Preferences menu item in Processing, and look at the folder name indicated by the “Sketchbook location” item. Go to this folder on your computer. There may be a folder here called “libraries. If it’s not there, you should create it. Then, move the expanded “Unfolding” folder you got from the ZIP file under the “libraries” folder.

Next, you’ll need to place the “tweets.json” file on your computer in a location where Processing can easily access it. Go into Processing and create and save a new sketch for this homework assignment. Then, on your computer go into the folder where Processing saves its sketches (the “Sketchbook location” above). You should see a folder with the name of your sketch here. Go into this folder and make a new sub-folder called “data”, and put “tweets.json” inside this folder. This is the default location where Processing will look for files used by your homework sketch.

The full details of how to approach this assignment are:

  • Your program will define a new class, perhaps called TweetInfo, that you use to store the information you extract from each tweet. Instances of this class will also be used to draw the tweets on the screen, and support user interaction. You have some flexibility in how you define this class, but at a minimum you’ll likely want to have member variables for storing the text and user name information for a tweet, the lat/lon coordinates of the tweet, and perhaps other information such as a reference to the on-screen marker for the tweet.
  • Your program should read in the tweet JSON file using loadJSONObject(“tweets.json”). See below for details on how the tweet data is structured. Note that not all tweets are geo-tagged. If you encounter tweets without a location associated with them, you can skip them since they won’t be represented on the map.
  • As your program reads and processes the tweet data, it should create a TweetInfo object for each tweet to store the information read from the file. Your program will keep a list (or other data structure) of these TweetInfo objects so that it has a representation of all of the tweets.
  • To use Unfolding Maps, you will need to import the packages for that library. In Processing, go to the Sketch menu, then Import Library, and then select Unfolding. This will add the necessary import statements to your code. You only need to do this once. (If you don’t see the Unfolding menu item, then you didn’t correctly install the library in Processing. Go back to the instructions above on how to do that.)
  • There are many ways to implement the drawing and interactivity code. What I would suggest is that your draw() function first draw the map, and then iterate through all the TweetInfo objects in your program, and call a draw() method on each of them that you define. This method, defined by you as a part of your TextInfo class, is responsible for drawing the particular marker for the tweet on the map at the correct coordinates, as well as drawing the marker differently if the mouse is inside the marker, drawing the popup box if the mouse is inside a marker and pressed, and so forth.
  • Remember that the tweet markers should be drawn differently (e.g., highlighted) when the mouse is inside them. You should also display the text tweet near the marker when the mouse enters it. If the mouse is inside multiple tweet markers (because they are near the same location), then all should be highlighted and text for each should be displayed
  • The popup that is displayed when the user clicks inside a marker should appear as a box near the marker, containing the tweet text, user info, and date/time information. You can do something simple like just creating a rectangle with text drawn inside it.
  • The map must be zoomable, pannable, etc. You should get most of this behavior “for free” using MapUtils.createDefaultEventDispatcher() (see the Unfolding docs).
Structure of the Tweet Data

Each tweet in the data file is in the same format as returned by the Twitter stream API, so you should be familiar with it: the attributes “text”, “user”, and so forth should exist. Since the stream API returns individual tweets, each as its own JSON object, I’ve edited the data file slightly to put them into a list structure so that they’re easier to process. You should be able to read in the data file using:

JSONArray tweets = loadJSONArray("tweets.json");

Each element in this JSONArray is a JSONObject that represents a single tweet.

Note that not all tweets have location data associated with them! In fact, most tweets will not have location data. Also, to complicate things slightly, the location data on tweets that do have it may exist in several places in the tweet data structure. This page has details on how location is represented in a tweet.

In a nutshell, here’s how your program should approach this:

  1. Most tweets will have a “root level” coordinates attribute, but this attribute may refer to null data (meaning that although the attribute is there, no coordinates are actually associated with the tweet). Your code should check this, and if coordinate data is present, your code should use this as the location of the tweet. By the twitter specification, coordinate data represents the exact location of the tweet. If present, the coordinates attribute will refer to a JSON list containing two elements, the longitude and latitude of the tweet.
  2. Tweets may also have a “root level” place attribute. Again, this attribute may refer to null data and, if so, your program should ignore it. If non-null, the place attribute will refer to a JSON object  describing the place. Some of the useful attributes in this object include “name” (a human-readable description of the place where the tweet originated), and—more helpful for this assignment—”bounding_box” which is a dictionary with an attribute called “coordinates” that refers to a list of four longitude/latitude pairs that defines a rectangle around where the tweet was posted. For this assignment, you can just use the first coordinate, which indicates the upper left rectangle of the box, as the location of the tweet.
  3. Your code can skip any tweets that cannot be geolocated (this will be most of the tweets in the file).

The data structure may seem a bit complicated, but it’s representative of “real world” JSON data, and deciphering its structure is a useful skill. Be sure to read the docs on the data structure and take a look at it in a plain text editor if you get stuck.

This assignment is a little different than some of the earlier ones, in that it will rely on you to do a bit of digging through the Processing and Unfolding documentation in order to create the features you need. This is a good experience for building software in the future, as this sort of digging is almost always required.

Turnin Instructions

To submit your program turn in just the Processing sketch file (the .pde file) via T-Square. Please do not submit the JSON data file.

Note that we’ll assume that the tweets file is called “tweets.json” and is in the data folder; don’t use a different name or put it in a different location, or we don’t be able to run your program without editing it.

Please don’t use additional, non-standard libraries that wouldn’t be installed by default on Processing (just to make our grading job easier).

If you implement any special features you think we should know about, include a README.txt file with details and submit your code with the README as a ZIP file.

Extra Credit

We’re using the pre-stored tweet file to make this assignment more manageable, so that you don’t also have to worry about connecting to twitter, authenticating, etc. For extra credit, you can implement a realtime version of the assignment that connects to twitter using the streaming API to pull down geo-tagged tweets in realtime. If you do this, I’d suggest using the OAuthP5 library (developed by the New York Times R&D Labs) as a good way to handle the authentication from within Processing. Please write your code to expect the authentication file to be contained in the data folder for your sketch, and called “oauthdata.txt”. We’ll put our authentication credentials in this location when grading.

There are lots of other ways to potentially make this project more interactive and fun, so let us know in your README file if you do something amazing that we want to be sure to notice.  🙂